mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-08 08:34:20 +02:00
Add volunteerTeamWishesSet in store
This commit is contained in:
parent
d5eeb44d2f
commit
fc65a2d42b
93
src/pages/TeamWishes/TeamWishes.tsx
Normal file
93
src/pages/TeamWishes/TeamWishes.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 {
|
||||
fetchVolunteerTeamWishesSet,
|
||||
fetchVolunteerTeamWishesSetIfNeed,
|
||||
} from "../../store/volunteerTeamWishesSet"
|
||||
import { VolunteerTeamWishes } from "../../services/volunteers"
|
||||
import { selectUserJwtToken } from "../../store/auth"
|
||||
|
||||
export type Props = RouteComponentProps
|
||||
|
||||
let prevWishes: VolunteerTeamWishes | undefined
|
||||
|
||||
const HomePage: FC<Props> = (): JSX.Element => {
|
||||
const dispatch = useDispatch()
|
||||
const jwtToken = useSelector(selectUserJwtToken)
|
||||
|
||||
const wishesForm = useSelector((state: AppState) => {
|
||||
const wishes = state.volunteerTeamWishesSet?.entity
|
||||
if (wishes) {
|
||||
prevWishes = wishes
|
||||
return wishes
|
||||
}
|
||||
return prevWishes
|
||||
}, shallowEqual)
|
||||
|
||||
const [teamWishes, setTeamWishes] = useState(wishesForm?.teamWishes.join(",") || "")
|
||||
const [teamWishComment, setTeamWishComment] = useState(wishesForm?.teamWishComment || "")
|
||||
|
||||
useEffect(() => {
|
||||
setTeamWishes(wishesForm?.teamWishes.join(",") || "")
|
||||
setTeamWishComment(wishesForm?.teamWishComment || "")
|
||||
}, [wishesForm])
|
||||
|
||||
const onTeamWishesChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setTeamWishes(e.target.value)
|
||||
const onTeamWishCommentChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setTeamWishComment(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(
|
||||
fetchVolunteerTeamWishesSet(jwtToken, 0, {
|
||||
id: wishesForm.id,
|
||||
teamWishes: (teamWishes || "").split(","),
|
||||
teamWishComment,
|
||||
})
|
||||
)
|
||||
},
|
||||
[dispatch, jwtToken, wishesForm, teamWishes, teamWishComment]
|
||||
)
|
||||
|
||||
if (jwtToken === undefined) return <p>Loading...</p>
|
||||
|
||||
if (jwtToken) {
|
||||
return (
|
||||
<form>
|
||||
<input
|
||||
type="text"
|
||||
id="teamWishes"
|
||||
required
|
||||
value={teamWishes}
|
||||
onChange={onTeamWishesChanged}
|
||||
/>
|
||||
<br />
|
||||
<input
|
||||
type="text"
|
||||
id="teamWishComment"
|
||||
required
|
||||
value={teamWishComment}
|
||||
onChange={onTeamWishCommentChanged}
|
||||
/>
|
||||
<button type="button" onClick={onSubmit}>
|
||||
Envoyer
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
return <div>Besoin d'être identifié</div>
|
||||
}
|
||||
|
||||
// Fetch server-side data here
|
||||
export const loadData = (): AppThunk[] => [fetchVolunteerTeamWishesSetIfNeed()]
|
||||
|
||||
export default memo(HomePage)
|
16
src/pages/TeamWishes/index.tsx
Executable file
16
src/pages/TeamWishes/index.tsx
Executable file
@ -0,0 +1,16 @@
|
||||
import loadable from "@loadable/component"
|
||||
|
||||
import { Loading, ErrorBoundary } from "../../components"
|
||||
import { Props, loadData } from "./TeamWishes"
|
||||
|
||||
const HomePage = loadable(() => import("./TeamWishes"), {
|
||||
fallback: <Loading />,
|
||||
})
|
||||
|
||||
export default (props: Props): JSX.Element => (
|
||||
<ErrorBoundary>
|
||||
<HomePage {...props} />
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
||||
export { loadData }
|
1
src/pages/TeamWishes/styles.module.scss
Executable file
1
src/pages/TeamWishes/styles.module.scss
Executable file
@ -0,0 +1 @@
|
||||
@import "../../theme/mixins";
|
@ -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 AsyncTeamWishes, { loadData as loadTeamWishesData } from "../pages/TeamWishes"
|
||||
import AsyncWish, { loadData as loadWishData } from "../pages/Wish"
|
||||
import AsyncVolunteerPage, { loadData as loadVolunteerPageData } from "../pages/VolunteerPage"
|
||||
import Login from "../pages/Login"
|
||||
@ -43,6 +44,11 @@ export default [
|
||||
component: AsyncTeams,
|
||||
loadData: loadTeamsData,
|
||||
},
|
||||
{
|
||||
path: "/teamWishes",
|
||||
component: AsyncTeamWishes,
|
||||
loadData: loadTeamWishesData,
|
||||
},
|
||||
{
|
||||
path: "/wish",
|
||||
component: AsyncWish,
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
VolunteerWithoutId,
|
||||
VolunteerLogin,
|
||||
VolunteerNotifs,
|
||||
VolunteerTeamWishes,
|
||||
translationVolunteer,
|
||||
} from "../../services/volunteers"
|
||||
import { canonicalEmail } from "../../utils/standardization"
|
||||
@ -119,6 +120,38 @@ 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]
|
||||
if (requestedId !== id && requestedId !== 0) {
|
||||
throw Error(`On ne peut acceder qu'à ses propres notifs`)
|
||||
}
|
||||
const wishes = body[1] as VolunteerTeamWishes
|
||||
const volunteer = list.find((v) => v.id === id)
|
||||
if (!volunteer) {
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${id}`)
|
||||
}
|
||||
const newVolunteer = _.cloneDeep(volunteer)
|
||||
|
||||
if (wishes.teamWishes !== undefined) {
|
||||
newVolunteer.teamWishes = wishes.teamWishes
|
||||
}
|
||||
if (wishes.teamWishComment !== undefined) {
|
||||
newVolunteer.teamWishComment = wishes.teamWishComment
|
||||
}
|
||||
|
||||
return {
|
||||
toDatabase: newVolunteer,
|
||||
toCaller: {
|
||||
id: newVolunteer.id,
|
||||
teamWishes: newVolunteer.teamWishes,
|
||||
teamWishComment: newVolunteer.teamWishComment,
|
||||
} as VolunteerTeamWishes,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function getByEmail(list: Volunteer[], rawEmail: string): Volunteer | undefined {
|
||||
const email = canonicalEmail(rawEmail || "")
|
||||
const volunteer = list.find((v) => canonicalEmail(v.email) === email)
|
||||
|
@ -21,10 +21,11 @@ import { javGameListGet } from "./gsheets/javGames"
|
||||
import { preVolunteerAdd, preVolunteerCountGet } from "./gsheets/preVolunteers"
|
||||
import { teamListGet } from "./gsheets/teams"
|
||||
import {
|
||||
volunteerNotifsSet,
|
||||
volunteerSet,
|
||||
volunteerLogin,
|
||||
volunteerForgot,
|
||||
volunteerNotifsSet,
|
||||
volunteerTeamWishesSet,
|
||||
} from "./gsheets/volunteers"
|
||||
import { wishListGet, wishAdd } from "./gsheets/wishes"
|
||||
import config from "../config"
|
||||
@ -75,6 +76,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("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
|
||||
|
||||
// Push notification subscription
|
||||
app.post("/notifications/subscribe", notificationsSubscribe)
|
||||
|
@ -21,6 +21,12 @@ export class Volunteer {
|
||||
|
||||
active = ""
|
||||
|
||||
participingDays = []
|
||||
|
||||
teamWishes: string[] = []
|
||||
|
||||
teamWishComment = ""
|
||||
|
||||
hiddenNotifs: number[] = []
|
||||
|
||||
created = new Date()
|
||||
@ -45,6 +51,9 @@ export const translationVolunteer: { [k in keyof Volunteer]: string } = {
|
||||
adult: "majeur",
|
||||
privileges: "privilege",
|
||||
active: "actif",
|
||||
participingDays: "joursPrésent",
|
||||
teamWishes: "enviesEquipe",
|
||||
teamWishComment: "commentaireEnviesEquipe",
|
||||
hiddenNotifs: "notifsCachees",
|
||||
created: "creation",
|
||||
password1: "passe1",
|
||||
@ -66,6 +75,9 @@ export const volunteerExample: Volunteer = {
|
||||
adult: 1,
|
||||
privileges: 0,
|
||||
active: "inconnu",
|
||||
participingDays: [],
|
||||
teamWishes: [],
|
||||
teamWishComment: "",
|
||||
hiddenNotifs: [],
|
||||
created: new Date(0),
|
||||
password1: "$2y$10$fSxY9AIuxSiEjwF.J3eXGubIxUPkdq9d5fqpbl8ASimSjNj4SR.9O",
|
||||
@ -110,3 +122,11 @@ export interface VolunteerNotifs {
|
||||
}
|
||||
export const volunteerNotifsSet =
|
||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerNotifs>]>("NotifsSet")
|
||||
|
||||
export interface VolunteerTeamWishes {
|
||||
id: number
|
||||
teamWishes: string[]
|
||||
teamWishComment: string
|
||||
}
|
||||
export const volunteerTeamWishesSet =
|
||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerTeamWishes>]>("TeamWishesSet")
|
||||
|
@ -13,6 +13,7 @@ import volunteerSet from "./volunteerSet"
|
||||
import volunteerLogin from "./volunteerLogin"
|
||||
import volunteerForgot from "./volunteerForgot"
|
||||
import volunteerNotifsSet from "./volunteerNotifsSet"
|
||||
import volunteerTeamWishesSet from "./volunteerTeamWishesSet"
|
||||
import wishAdd from "./wishAdd"
|
||||
import wishList from "./wishList"
|
||||
|
||||
@ -31,6 +32,7 @@ export default (history: History) => ({
|
||||
volunteerLogin,
|
||||
volunteerForgot,
|
||||
volunteerNotifsSet,
|
||||
volunteerTeamWishesSet,
|
||||
wishAdd,
|
||||
wishList,
|
||||
router: connectRouter(history) as any,
|
||||
|
58
src/store/volunteerTeamWishesSet.ts
Normal file
58
src/store/volunteerTeamWishesSet.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||
import { VolunteerTeamWishes, volunteerTeamWishesSet } from "../services/volunteers"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
type StateVolunteerTeamWishesSet = { entity?: VolunteerTeamWishes } & StateRequest
|
||||
|
||||
export const initialState: StateVolunteerTeamWishesSet = {
|
||||
readyStatus: "idle",
|
||||
}
|
||||
|
||||
const volunteerTeamWishesSetSlice = createSlice({
|
||||
name: "volunteerTeamWishesSet",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (_) => ({
|
||||
readyStatus: "request",
|
||||
}),
|
||||
getSuccess: (_, { payload }: PayloadAction<VolunteerTeamWishes>) => ({
|
||||
readyStatus: "success",
|
||||
entity: payload,
|
||||
}),
|
||||
getFailure: (_, { payload }: PayloadAction<string>) => ({
|
||||
readyStatus: "failure",
|
||||
error: payload,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
export default volunteerTeamWishesSetSlice.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = volunteerTeamWishesSetSlice.actions
|
||||
|
||||
export const fetchVolunteerTeamWishesSet = elementFetch(
|
||||
volunteerTeamWishesSet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des notifications: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchVolunteerTeamWishesSet = (state: AppState, id: number) =>
|
||||
state.volunteerTeamWishesSet?.readyStatus !== "success" ||
|
||||
(state.volunteerTeamWishesSet?.entity && state.volunteerTeamWishesSet?.entity?.id !== id)
|
||||
|
||||
export const fetchVolunteerTeamWishesSetIfNeed =
|
||||
(id = 0, wishes: Partial<VolunteerTeamWishes> = {}): AppThunk =>
|
||||
(dispatch, getState) => {
|
||||
let jwt = ""
|
||||
|
||||
if (!id) {
|
||||
;({ id, jwt } = getState().auth)
|
||||
}
|
||||
if (shouldFetchVolunteerTeamWishesSet(getState(), id))
|
||||
return dispatch(fetchVolunteerTeamWishesSet(jwt, id, wishes))
|
||||
|
||||
return null
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user