mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-09 17:14:21 +02:00
Add volunteerDayWishesSet in store
This commit is contained in:
parent
fc65a2d42b
commit
93e82a36ee
93
src/pages/DayWishes/DayWishes.tsx
Normal file
93
src/pages/DayWishes/DayWishes.tsx
Normal file
@ -0,0 +1,93 @@
|
||||
import { FC, memo, useCallback, useEffect, useState } from "react"
|
||||
import { RouteComponentProps } from "react-router-dom"
|
||||
import { useSelector, shallowEqual, useDispatch } from "react-redux"
|
||||
|
||||
import { AppState, AppThunk } from "../../store"
|
||||
import {
|
||||
fetchVolunteerDayWishesSet,
|
||||
fetchVolunteerDayWishesSetIfNeed,
|
||||
} from "../../store/volunteerDayWishesSet"
|
||||
import { VolunteerDayWishes } from "../../services/volunteers"
|
||||
import { selectUserJwtToken } from "../../store/auth"
|
||||
|
||||
export type Props = RouteComponentProps
|
||||
|
||||
let prevWishes: VolunteerDayWishes | undefined
|
||||
|
||||
const HomePage: FC<Props> = (): JSX.Element => {
|
||||
const dispatch = useDispatch()
|
||||
const jwtToken = useSelector(selectUserJwtToken)
|
||||
|
||||
const wishesForm = useSelector((state: AppState) => {
|
||||
const wishes = state.volunteerDayWishesSet?.entity
|
||||
if (wishes) {
|
||||
prevWishes = wishes
|
||||
return wishes
|
||||
}
|
||||
return prevWishes
|
||||
}, shallowEqual)
|
||||
|
||||
const [dayWishes, setDayWishes] = useState(wishesForm?.dayWishes.join(",") || "")
|
||||
const [dayWishesComment, setDayWishesComment] = useState(wishesForm?.dayWishesComment || "")
|
||||
|
||||
useEffect(() => {
|
||||
setDayWishes(wishesForm?.dayWishes.join(",") || "")
|
||||
setDayWishesComment(wishesForm?.dayWishesComment || "")
|
||||
}, [wishesForm])
|
||||
|
||||
const onDayWishesChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setDayWishes(e.target.value)
|
||||
const onDayWishesCommentChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setDayWishesComment(e.target.value)
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(event: React.SyntheticEvent): void => {
|
||||
event.preventDefault()
|
||||
if (!wishesForm) {
|
||||
console.error("NO FORM WISHES RECEIVED")
|
||||
return // Form should not even appear if this happens
|
||||
}
|
||||
dispatch(
|
||||
fetchVolunteerDayWishesSet(jwtToken, 0, {
|
||||
id: wishesForm.id,
|
||||
dayWishes: (dayWishes || "").split(","),
|
||||
dayWishesComment,
|
||||
})
|
||||
)
|
||||
},
|
||||
[dispatch, jwtToken, wishesForm, dayWishes, dayWishesComment]
|
||||
)
|
||||
|
||||
if (jwtToken === undefined) return <p>Loading...</p>
|
||||
|
||||
if (jwtToken) {
|
||||
return (
|
||||
<form>
|
||||
<input
|
||||
type="text"
|
||||
id="dayWishes"
|
||||
required
|
||||
value={dayWishes}
|
||||
onChange={onDayWishesChanged}
|
||||
/>
|
||||
<br />
|
||||
<input
|
||||
type="text"
|
||||
id="dayWishesComment"
|
||||
required
|
||||
value={dayWishesComment}
|
||||
onChange={onDayWishesCommentChanged}
|
||||
/>
|
||||
<button type="button" onClick={onSubmit}>
|
||||
Envoyer
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
return <div>Besoin d'être identifié</div>
|
||||
}
|
||||
|
||||
// Fetch server-side data here
|
||||
export const loadData = (): AppThunk[] => [fetchVolunteerDayWishesSetIfNeed()]
|
||||
|
||||
export default memo(HomePage)
|
16
src/pages/DayWishes/index.tsx
Executable file
16
src/pages/DayWishes/index.tsx
Executable file
@ -0,0 +1,16 @@
|
||||
import loadable from "@loadable/component"
|
||||
|
||||
import { Loading, ErrorBoundary } from "../../components"
|
||||
import { Props, loadData } from "./DayWishes"
|
||||
|
||||
const HomePage = loadable(() => import("./DayWishes"), {
|
||||
fallback: <Loading />,
|
||||
})
|
||||
|
||||
export default (props: Props): JSX.Element => (
|
||||
<ErrorBoundary>
|
||||
<HomePage {...props} />
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
||||
export { loadData }
|
1
src/pages/DayWishes/styles.module.scss
Executable file
1
src/pages/DayWishes/styles.module.scss
Executable file
@ -0,0 +1 @@
|
||||
@import "../../theme/mixins";
|
@ -28,17 +28,17 @@ const HomePage: FC<Props> = (): JSX.Element => {
|
||||
}, shallowEqual)
|
||||
|
||||
const [teamWishes, setTeamWishes] = useState(wishesForm?.teamWishes.join(",") || "")
|
||||
const [teamWishComment, setTeamWishComment] = useState(wishesForm?.teamWishComment || "")
|
||||
const [teamWishesComment, setTeamWishesComment] = useState(wishesForm?.teamWishesComment || "")
|
||||
|
||||
useEffect(() => {
|
||||
setTeamWishes(wishesForm?.teamWishes.join(",") || "")
|
||||
setTeamWishComment(wishesForm?.teamWishComment || "")
|
||||
setTeamWishesComment(wishesForm?.teamWishesComment || "")
|
||||
}, [wishesForm])
|
||||
|
||||
const onTeamWishesChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setTeamWishes(e.target.value)
|
||||
const onTeamWishCommentChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setTeamWishComment(e.target.value)
|
||||
const onTeamWishesCommentChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setTeamWishesComment(e.target.value)
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(event: React.SyntheticEvent): void => {
|
||||
@ -51,11 +51,11 @@ const HomePage: FC<Props> = (): JSX.Element => {
|
||||
fetchVolunteerTeamWishesSet(jwtToken, 0, {
|
||||
id: wishesForm.id,
|
||||
teamWishes: (teamWishes || "").split(","),
|
||||
teamWishComment,
|
||||
teamWishesComment,
|
||||
})
|
||||
)
|
||||
},
|
||||
[dispatch, jwtToken, wishesForm, teamWishes, teamWishComment]
|
||||
[dispatch, jwtToken, wishesForm, teamWishes, teamWishesComment]
|
||||
)
|
||||
|
||||
if (jwtToken === undefined) return <p>Loading...</p>
|
||||
@ -73,10 +73,10 @@ const HomePage: FC<Props> = (): JSX.Element => {
|
||||
<br />
|
||||
<input
|
||||
type="text"
|
||||
id="teamWishComment"
|
||||
id="teamWishesComment"
|
||||
required
|
||||
value={teamWishComment}
|
||||
onChange={onTeamWishCommentChanged}
|
||||
value={teamWishesComment}
|
||||
onChange={onTeamWishesCommentChanged}
|
||||
/>
|
||||
<button type="button" onClick={onSubmit}>
|
||||
Envoyer
|
||||
|
@ -4,6 +4,7 @@ import App from "../app"
|
||||
import AsyncHome, { loadData as loadHomeData } from "../pages/Home"
|
||||
import AsyncPreRegisterPage, { loadData as loadPreRegisterPage } from "../pages/PreRegister"
|
||||
import AsyncTeams, { loadData as loadTeamsData } from "../pages/Teams"
|
||||
import AsyncDayWishes, { loadData as loadDayWishesData } from "../pages/DayWishes"
|
||||
import AsyncTeamWishes, { loadData as loadTeamWishesData } from "../pages/TeamWishes"
|
||||
import AsyncWish, { loadData as loadWishData } from "../pages/Wish"
|
||||
import AsyncVolunteerPage, { loadData as loadVolunteerPageData } from "../pages/VolunteerPage"
|
||||
@ -44,6 +45,11 @@ export default [
|
||||
component: AsyncTeams,
|
||||
loadData: loadTeamsData,
|
||||
},
|
||||
{
|
||||
path: "/dayWishes",
|
||||
component: AsyncDayWishes,
|
||||
loadData: loadDayWishesData,
|
||||
},
|
||||
{
|
||||
path: "/teamWishes",
|
||||
component: AsyncTeamWishes,
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
VolunteerNotifs,
|
||||
VolunteerTeamWishes,
|
||||
translationVolunteer,
|
||||
VolunteerDayWishes,
|
||||
} from "../../services/volunteers"
|
||||
import { canonicalEmail } from "../../utils/standardization"
|
||||
import { getJwt } from "../secure"
|
||||
@ -92,14 +93,14 @@ export const volunteerForgot = expressAccessor.set(
|
||||
|
||||
export const volunteerNotifsSet = expressAccessor.set(
|
||||
async (list: Volunteer[], body: RequestBody, id: number) => {
|
||||
const requestedId = +body[0]
|
||||
const requestedId = +body[0] || id
|
||||
if (requestedId !== id && requestedId !== 0) {
|
||||
throw Error(`On ne peut acceder qu'à ses propres notifs`)
|
||||
}
|
||||
const notifChanges = body[1]
|
||||
const volunteer = list.find((v) => v.id === id)
|
||||
const volunteer = list.find((v) => v.id === requestedId)
|
||||
if (!volunteer) {
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${id}`)
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
|
||||
}
|
||||
const newVolunteer = _.cloneDeep(volunteer)
|
||||
|
||||
@ -122,23 +123,22 @@ export const volunteerNotifsSet = expressAccessor.set(
|
||||
|
||||
export const volunteerTeamWishesSet = expressAccessor.set(
|
||||
async (list: Volunteer[], body: RequestBody, id: number) => {
|
||||
console.log("volunteerTeamWishesSet", body)
|
||||
const requestedId = +body[0]
|
||||
const requestedId = +body[0] || id
|
||||
if (requestedId !== id && requestedId !== 0) {
|
||||
throw Error(`On ne peut acceder qu'à ses propres notifs`)
|
||||
throw Error(`On ne peut acceder qu'à ses propres envies d'équipes`)
|
||||
}
|
||||
const wishes = body[1] as VolunteerTeamWishes
|
||||
const volunteer = list.find((v) => v.id === id)
|
||||
const volunteer = list.find((v) => v.id === requestedId)
|
||||
if (!volunteer) {
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${id}`)
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
|
||||
}
|
||||
const newVolunteer = _.cloneDeep(volunteer)
|
||||
|
||||
if (wishes.teamWishes !== undefined) {
|
||||
newVolunteer.teamWishes = wishes.teamWishes
|
||||
}
|
||||
if (wishes.teamWishComment !== undefined) {
|
||||
newVolunteer.teamWishComment = wishes.teamWishComment
|
||||
if (wishes.teamWishesComment !== undefined) {
|
||||
newVolunteer.teamWishesComment = wishes.teamWishesComment
|
||||
}
|
||||
|
||||
return {
|
||||
@ -146,12 +146,42 @@ export const volunteerTeamWishesSet = expressAccessor.set(
|
||||
toCaller: {
|
||||
id: newVolunteer.id,
|
||||
teamWishes: newVolunteer.teamWishes,
|
||||
teamWishComment: newVolunteer.teamWishComment,
|
||||
teamWishesComment: newVolunteer.teamWishesComment,
|
||||
} as VolunteerTeamWishes,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
export const volunteerDayWishesSet = expressAccessor.set(
|
||||
async (list: Volunteer[], body: RequestBody, id: number) => {
|
||||
const requestedId = +body[0] || id
|
||||
if (requestedId !== id && requestedId !== 0) {
|
||||
throw Error(`On ne peut acceder qu'à ses propres envies de jours`)
|
||||
}
|
||||
const wishes = body[1] as VolunteerDayWishes
|
||||
const volunteer = list.find((v) => v.id === requestedId)
|
||||
if (!volunteer) {
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
|
||||
}
|
||||
const newVolunteer = _.cloneDeep(volunteer)
|
||||
|
||||
if (wishes.dayWishes !== undefined) {
|
||||
newVolunteer.dayWishes = wishes.dayWishes
|
||||
}
|
||||
if (wishes.dayWishesComment !== undefined) {
|
||||
newVolunteer.dayWishesComment = wishes.dayWishesComment
|
||||
}
|
||||
|
||||
return {
|
||||
toDatabase: newVolunteer,
|
||||
toCaller: {
|
||||
id: newVolunteer.id,
|
||||
dayWishes: newVolunteer.dayWishes,
|
||||
dayWishesComment: newVolunteer.dayWishesComment,
|
||||
} as VolunteerDayWishes,
|
||||
}
|
||||
}
|
||||
)
|
||||
function getByEmail(list: Volunteer[], rawEmail: string): Volunteer | undefined {
|
||||
const email = canonicalEmail(rawEmail || "")
|
||||
const volunteer = list.find((v) => canonicalEmail(v.email) === email)
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
volunteerForgot,
|
||||
volunteerNotifsSet,
|
||||
volunteerTeamWishesSet,
|
||||
volunteerDayWishesSet,
|
||||
} from "./gsheets/volunteers"
|
||||
import { wishListGet, wishAdd } from "./gsheets/wishes"
|
||||
import config from "../config"
|
||||
@ -76,6 +77,7 @@ app.post("/VolunteerSet", secure as RequestHandler, volunteerSet)
|
||||
app.get("/TeamListGet", teamListGet)
|
||||
// UNSAFE app.post("/VolunteerGet", secure as RequestHandler, volunteerGet)
|
||||
app.post("/VolunteerNotifsSet", secure as RequestHandler, volunteerNotifsSet)
|
||||
app.post("/VolunteerDayWishesSet", secure as RequestHandler, volunteerDayWishesSet)
|
||||
app.post("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
|
||||
|
||||
// Push notification subscription
|
||||
|
@ -14,8 +14,6 @@ export default function notificationsSubscribe(
|
||||
): void {
|
||||
const subscription = request.body
|
||||
|
||||
console.log(subscription)
|
||||
|
||||
const payload = JSON.stringify({
|
||||
title: "Hello!",
|
||||
body: "It works.",
|
||||
|
@ -21,11 +21,13 @@ export class Volunteer {
|
||||
|
||||
active = ""
|
||||
|
||||
participingDays = []
|
||||
dayWishes: string[] = []
|
||||
|
||||
dayWishesComment = ""
|
||||
|
||||
teamWishes: string[] = []
|
||||
|
||||
teamWishComment = ""
|
||||
teamWishesComment = ""
|
||||
|
||||
hiddenNotifs: number[] = []
|
||||
|
||||
@ -51,9 +53,10 @@ export const translationVolunteer: { [k in keyof Volunteer]: string } = {
|
||||
adult: "majeur",
|
||||
privileges: "privilege",
|
||||
active: "actif",
|
||||
participingDays: "joursPrésent",
|
||||
dayWishes: "enviesJours",
|
||||
dayWishesComment: "commentaireEnviesJours",
|
||||
teamWishes: "enviesEquipe",
|
||||
teamWishComment: "commentaireEnviesEquipe",
|
||||
teamWishesComment: "commentaireEnviesEquipe",
|
||||
hiddenNotifs: "notifsCachees",
|
||||
created: "creation",
|
||||
password1: "passe1",
|
||||
@ -75,9 +78,10 @@ export const volunteerExample: Volunteer = {
|
||||
adult: 1,
|
||||
privileges: 0,
|
||||
active: "inconnu",
|
||||
participingDays: [],
|
||||
dayWishes: [],
|
||||
dayWishesComment: "",
|
||||
teamWishes: [],
|
||||
teamWishComment: "",
|
||||
teamWishesComment: "",
|
||||
hiddenNotifs: [],
|
||||
created: new Date(0),
|
||||
password1: "$2y$10$fSxY9AIuxSiEjwF.J3eXGubIxUPkdq9d5fqpbl8ASimSjNj4SR.9O",
|
||||
@ -112,21 +116,29 @@ export interface VolunteerForgot {
|
||||
export const volunteerForgot = serviceAccessors.customPost<[{ email: string }]>("Forgot")
|
||||
|
||||
export interface VolunteerNotifs {
|
||||
id: number
|
||||
firstname: string
|
||||
adult: number
|
||||
active: string
|
||||
hiddenNotifs: number[]
|
||||
pushNotifSubscription: string
|
||||
acceptsNotifs: string
|
||||
id: Volunteer["id"]
|
||||
firstname: Volunteer["firstname"]
|
||||
adult: Volunteer["adult"]
|
||||
active: Volunteer["active"]
|
||||
hiddenNotifs: Volunteer["hiddenNotifs"]
|
||||
pushNotifSubscription: Volunteer["pushNotifSubscription"]
|
||||
acceptsNotifs: Volunteer["acceptsNotifs"]
|
||||
}
|
||||
export const volunteerNotifsSet =
|
||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerNotifs>]>("NotifsSet")
|
||||
|
||||
export interface VolunteerTeamWishes {
|
||||
id: number
|
||||
teamWishes: string[]
|
||||
teamWishComment: string
|
||||
id: Volunteer["id"]
|
||||
teamWishes: Volunteer["teamWishes"]
|
||||
teamWishesComment: Volunteer["teamWishesComment"]
|
||||
}
|
||||
export const volunteerTeamWishesSet =
|
||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerTeamWishes>]>("TeamWishesSet")
|
||||
|
||||
export interface VolunteerDayWishes {
|
||||
id: Volunteer["id"]
|
||||
dayWishes: Volunteer["dayWishes"]
|
||||
dayWishesComment: Volunteer["dayWishesComment"]
|
||||
}
|
||||
export const volunteerDayWishesSet =
|
||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerDayWishes>]>("DayWishesSet")
|
||||
|
@ -13,6 +13,7 @@ import volunteerSet from "./volunteerSet"
|
||||
import volunteerLogin from "./volunteerLogin"
|
||||
import volunteerForgot from "./volunteerForgot"
|
||||
import volunteerNotifsSet from "./volunteerNotifsSet"
|
||||
import volunteerDayWishesSet from "./volunteerDayWishesSet"
|
||||
import volunteerTeamWishesSet from "./volunteerTeamWishesSet"
|
||||
import wishAdd from "./wishAdd"
|
||||
import wishList from "./wishList"
|
||||
@ -32,6 +33,7 @@ export default (history: History) => ({
|
||||
volunteerLogin,
|
||||
volunteerForgot,
|
||||
volunteerNotifsSet,
|
||||
volunteerDayWishesSet,
|
||||
volunteerTeamWishesSet,
|
||||
wishAdd,
|
||||
wishList,
|
||||
|
58
src/store/volunteerDayWishesSet.ts
Normal file
58
src/store/volunteerDayWishesSet.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||
import { VolunteerDayWishes, volunteerDayWishesSet } from "../services/volunteers"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
type StateVolunteerDayWishesSet = { entity?: VolunteerDayWishes } & StateRequest
|
||||
|
||||
export const initialState: StateVolunteerDayWishesSet = {
|
||||
readyStatus: "idle",
|
||||
}
|
||||
|
||||
const volunteerDayWishesSetSlice = createSlice({
|
||||
name: "volunteerDayWishesSet",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (_) => ({
|
||||
readyStatus: "request",
|
||||
}),
|
||||
getSuccess: (_, { payload }: PayloadAction<VolunteerDayWishes>) => ({
|
||||
readyStatus: "success",
|
||||
entity: payload,
|
||||
}),
|
||||
getFailure: (_, { payload }: PayloadAction<string>) => ({
|
||||
readyStatus: "failure",
|
||||
error: payload,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
export default volunteerDayWishesSetSlice.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = volunteerDayWishesSetSlice.actions
|
||||
|
||||
export const fetchVolunteerDayWishesSet = elementFetch(
|
||||
volunteerDayWishesSet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des notifications: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchVolunteerDayWishesSet = (state: AppState, id: number) =>
|
||||
state.volunteerDayWishesSet?.readyStatus !== "success" ||
|
||||
(state.volunteerDayWishesSet?.entity && state.volunteerDayWishesSet?.entity?.id !== id)
|
||||
|
||||
export const fetchVolunteerDayWishesSetIfNeed =
|
||||
(id = 0, wishes: Partial<VolunteerDayWishes> = {}): AppThunk =>
|
||||
(dispatch, getState) => {
|
||||
let jwt = ""
|
||||
|
||||
if (!id) {
|
||||
;({ id, jwt } = getState().auth)
|
||||
}
|
||||
if (shouldFetchVolunteerDayWishesSet(getState(), id))
|
||||
return dispatch(fetchVolunteerDayWishesSet(jwt, id, wishes))
|
||||
|
||||
return null
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user