diff --git a/src/components/Asks/AskMeals.tsx b/src/components/Asks/AskMeals.tsx
new file mode 100644
index 0000000..65ba699
--- /dev/null
+++ b/src/components/Asks/AskMeals.tsx
@@ -0,0 +1,38 @@
+import { get } from "lodash"
+import { useCallback } from "react"
+import { fetchVolunteerAsksSet } from "../../store/volunteerAsksSet"
+import { useAskTools, addAsk, answerLaterOnProfile } from "./utils"
+import MealsForm, { fetchFor as fetchForMealsForm } from "../VolunteerBoard/MealsForm/MealsForm"
+import { useUserMeals } from "../VolunteerBoard/meals.utils"
+
+export function AskMeals(asks: JSX.Element[], id: number): void {
+ const { dispatch, jwtToken, volunteerAsks } = useAskTools()
+
+ const onSubmit = useCallback((): void => {
+ dispatch(
+ fetchVolunteerAsksSet(jwtToken, 0, {
+ hiddenAsks: [...(volunteerAsks?.hiddenAsks || []), id],
+ })
+ )
+ }, [dispatch, id, jwtToken, volunteerAsks?.hiddenAsks])
+
+ const [meals] = useUserMeals()
+ const needsMeals = get(meals, "needsMeals", false)
+ const canHostCount = get(meals, "canHostCount", 0)
+ const distanceToFestival = get(meals, "distanceToFestival", 0)
+ const mealsComment = get(meals, "mealsComment", "")
+ const needToShow =
+ !needsMeals && canHostCount === 0 && distanceToFestival === 0 && mealsComment === ""
+
+ addAsk(
+ asks,
+ id,
+ volunteerAsks,
+ false,
+ needToShow,
+ {answerLaterOnProfile}
+ )
+}
+
+// Fetch server-side data here
+export const fetchFor = [...fetchForMealsForm]
diff --git a/src/components/Asks/index.tsx b/src/components/Asks/index.tsx
index 028a02c..7aad7b0 100644
--- a/src/components/Asks/index.tsx
+++ b/src/components/Asks/index.tsx
@@ -6,6 +6,7 @@ import { AskWelcome } from "./AskWelcome"
import { AskDiscord, fetchFor as fetchForDiscord } from "./AskDiscord"
import { AskDayWishes, fetchFor as fetchForDayWishes } from "./AskDayWishes"
import { AskHosting, fetchFor as fetchForHosting } from "./AskHosting"
+import { AskMeals, fetchFor as fetchForMeals } from "./AskMeals"
import { AskTeamWishes, fetchFor as fetchForTeamWishes } from "./AskTeamWishes"
import {
AskParticipationDetails,
@@ -24,6 +25,7 @@ const Asks = (): JSX.Element | null => {
AskTeamWishes(asks, 11)
AskParticipationDetails(asks, 12)
AskHosting(asks, 20)
+ AskMeals(asks, 22)
AskPushNotif(asks, 99)
@@ -61,6 +63,7 @@ export const fetchFor = [
...fetchForDiscord,
...fetchForDayWishes,
...fetchForHosting,
+ ...fetchForMeals,
...fetchForTeamWishes,
...fetchForParticipationDetails,
]
diff --git a/src/components/RegisterForm/index.tsx b/src/components/RegisterForm/index.tsx
index 260f49d..5bcb36a 100644
--- a/src/components/RegisterForm/index.tsx
+++ b/src/components/RegisterForm/index.tsx
@@ -55,6 +55,8 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
const meetingDateList = useSelector(selectMiscMeetingDateList)
+ const enableRegistering = false
+
useEffect(() => {
const timer = setInterval(() => {
setChangingBackground((changingBackground + 1) % animations.length)
@@ -234,20 +236,33 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
-
- Si l'expérience vous tente, remplissez le formulaire suivant pour devenir
- bénévole !
- Vous pouvez aussi juste nous rencontrer avant de vous décider à devenir bénévole, on
- comprend qu'un saut pareil dans l'inconnu soit difficile.
-
- Dans les deux cas, venez rencontrer une poignée d'entre nous dans un bar/resto près
- de Châtelet ! :) Sur inscription uniquement...
-
-
+
+ {!enableRegistering && (
+
+ L'inscription est clôturée pour l'édition 2022, mais si l'expérience vous tente,
+ remplissez le formulaire suivant pour devenir bénévole à PeL 2023 !
+ Dès septembre on se rencontrera sur Paris en petits groupes pour discuter du
+ festival, du bénévolat et surtout faire connaissance :)
+
+
+ )}
+
+ {enableRegistering && (
+
+ Si l'expérience vous tente, remplissez le formulaire suivant pour devenir
+ bénévole !
+ Vous pouvez aussi juste nous rencontrer avant de vous décider à devenir
+ bénévole, on comprend qu'un saut pareil dans l'inconnu soit difficile.
+
+ Dans les deux cas, venez rencontrer une poignée d'entre nous dans un bar/resto
+ près de Châtelet ! :) Sur inscription uniquement...
+
+
+ )}
)
- const potentialVolunteerQuestion = (
+ const potentialVolunteerQuestion = enableRegistering && (
Je veux devenir bénévole :
@@ -431,7 +446,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
>
)
- const meeting = (
+ const meeting = enableRegistering && (
<>
{!potentialVolunteer && Faisons connaissance ! }
@@ -535,7 +550,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
>
)
- const helpBefore = !potentialVolunteer && (
+ const helpBefore = enableRegistering && !potentialVolunteer && (
<>
Bénévolat en amont du festival
@@ -608,7 +623,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
>
)
- const pelMemberQuestion = !potentialVolunteer && (
+ const pelMemberQuestion = enableRegistering && !potentialVolunteer && (
<>
Association Paris est Ludique
@@ -784,7 +799,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
{(potentialVolunteer || !alreadyVolunteer) && (
<>
- {commentQuestion}
+ {enableRegistering && commentQuestion}
{cameAsVisitor}
{meeting}
{helpBefore}
@@ -792,6 +807,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
{(potentialVolunteer || pelMember) && (
<>
{nameMobileEmail}
+ {!enableRegistering && commentQuestion}
{howToContact !== "Aucun" && submitButton}
>
)}
diff --git a/src/components/VolunteerBoard/Board.tsx b/src/components/VolunteerBoard/Board.tsx
index 79ba71f..678c246 100644
--- a/src/components/VolunteerBoard/Board.tsx
+++ b/src/components/VolunteerBoard/Board.tsx
@@ -3,6 +3,8 @@ import DayWishes from "./DayWishes/DayWishes"
import DayWishesFormModal from "./DayWishesForm/DayWishesFormModal"
import Hosting from "./Hosting/Hosting"
import HostingFormModal from "./HostingForm/HostingFormModal"
+import Meals from "./Meals/Meals"
+import MealsFormModal from "./MealsForm/MealsFormModal"
import ParticipationDetails from "./ParticipationDetails/ParticipationDetails"
import ParticipationDetailsFormModal from "./ParticipationDetailsForm/ParticipationDetailsFormModal"
import TeamWishes from "./TeamWishes/TeamWishes"
@@ -11,6 +13,7 @@ import withUserConnected from "../../utils/withUserConnected"
import ContentTitle from "../ui/Content/ContentTitle"
import { fetchFor as fetchForDayWishesForm } from "./DayWishesForm/DayWishesForm"
import { fetchFor as fetchForHostingForm } from "./HostingForm/HostingForm"
+import { fetchFor as fetchForMealsForm } from "./MealsForm/MealsForm"
import { fetchFor as fetchForParticipationDetailsForm } from "./ParticipationDetailsForm/ParticipationDetailsForm"
import { fetchFor as fetchForTeamWishesForm } from "./TeamWishesForm/TeamWishesForm"
import VolunteerTeam from "./VolunteerTeam/VolunteerTeam"
@@ -27,6 +30,8 @@ const Board: FC = (): JSX.Element => (
+
+
>
)
@@ -35,6 +40,7 @@ export default memo(withUserConnected(Board))
export const fetchFor = [
...fetchForDayWishesForm,
...fetchForHostingForm,
+ ...fetchForMealsForm,
...fetchForParticipationDetailsForm,
...fetchForTeamWishesForm,
]
diff --git a/src/components/VolunteerBoard/Meals/Meals.tsx b/src/components/VolunteerBoard/Meals/Meals.tsx
new file mode 100644
index 0000000..fd6e155
--- /dev/null
+++ b/src/components/VolunteerBoard/Meals/Meals.tsx
@@ -0,0 +1,65 @@
+import { FC, memo, useCallback } from "react"
+import { find, get } from "lodash"
+import styles from "./styles.module.scss"
+import { useUserMeals, mealDays, MealOption } from "../meals.utils"
+import useAction from "../../../utils/useAction"
+import { displayModal, MODAL_IDS } from "../../../store/ui"
+import { useUserDayWishes } from "../daysWishes.utils"
+
+const Meals: FC = (): JSX.Element | null => {
+ const [userMeals] = useUserMeals()
+ const [userWishes] = useUserDayWishes()
+ const meals = get(userMeals, "meals", [])
+ const dayWishesString = get(userWishes, "dayWishes", [])
+ const execDisplayModal = useAction(displayModal)
+ const onEdit = useCallback(() => execDisplayModal(MODAL_IDS.MEALS), [execDisplayModal])
+ const mealChoices = mealDays.map((meal, i: number) =>
+ find(meal.options, { abbr: meals[i] || "" })
+ ) as MealOption[]
+
+ function getMealElement(i: number): JSX.Element {
+ const mealChoice = mealChoices[i]
+ return (
+
+ {mealDays[i].name}, {mealChoice.title}
+
+ )
+ }
+
+ return (
+
+
Mes repas
+ {dayWishesString.includes("S") ? (
+ <>
+ {getMealElement(0)}
+
+ Samedi soir, apéro dînatoire
+
+ >
+ ) : (
+
+ Non bénévole le samedi
+
+ )}
+
+ {dayWishesString.includes("D") ? (
+ <>
+ {getMealElement(1)}
+ {getMealElement(2)}
+ >
+ ) : (
+
+ Non bénévole le dimanche
+
+ )}
+
+
+
+ Modifier
+
+
+
+ )
+}
+
+export default memo(Meals)
diff --git a/src/components/VolunteerBoard/Meals/styles.module.scss b/src/components/VolunteerBoard/Meals/styles.module.scss
new file mode 100755
index 0000000..a81d4f0
--- /dev/null
+++ b/src/components/VolunteerBoard/Meals/styles.module.scss
@@ -0,0 +1,53 @@
+@import "../../../theme/variables";
+@import "../../../theme/mixins";
+
+.title {
+ padding-bottom: 10px;
+ font-weight: bold;
+}
+
+.mealsLabel {
+ margin-right: 5px;
+ font-style: bold;
+}
+
+.meals {
+ @include inner-content-wrapper();
+
+ position: relative;
+ padding-right: 90px;
+}
+
+.mealsLabel,
+.commentLine {
+ margin-bottom: 5px;
+ span {
+ display: inline-block;
+ }
+}
+
+.lineEmpty {
+ color: $color-red;
+ font-style: italic;
+}
+
+.commentLineTitle {
+ padding-right: 5px;
+}
+
+.commentLineText {
+ font-style: italic;
+}
+
+.editButton {
+ @include vertical-center();
+
+ position: absolute;
+ right: 20px;
+
+ button {
+ color: $color-green;
+ font-weight: bold;
+ cursor: pointer;
+ }
+}
diff --git a/src/components/VolunteerBoard/MealsForm/MealsForm.tsx b/src/components/VolunteerBoard/MealsForm/MealsForm.tsx
new file mode 100644
index 0000000..122d941
--- /dev/null
+++ b/src/components/VolunteerBoard/MealsForm/MealsForm.tsx
@@ -0,0 +1,152 @@
+import { get } from "lodash"
+import { FC, memo, ReactNode, useCallback, useEffect, useState } from "react"
+import classnames from "classnames"
+import styles from "./styles.module.scss"
+import { mealDays, MealOption, useUserMeals } from "../meals.utils"
+import FormButton from "../../Form/FormButton/FormButton"
+import { fetchVolunteerMealsSetIfNeed } from "../../../store/volunteerMealsSet"
+import IgnoreButton from "../../Form/IgnoreButton/IgnoreButton"
+import { useUserDayWishes } from "../daysWishes.utils"
+import { fetchVolunteerDayWishesSetIfNeed } from "../../../store/volunteerDayWishesSet"
+
+type Props = {
+ children?: ReactNode | undefined
+ afterSubmit?: () => void | undefined
+}
+
+const MealsForm: FC = ({ children, afterSubmit }): JSX.Element => {
+ const [saturdayLunchMeal, setSaturdayLunchMeal] = useState("")
+ const [sundayLunchMeal, setSundayLunchMeal] = useState("")
+ const [sundayDinnerMeal, setSundayDinnerMeal] = useState("")
+ const [userMeals, saveMeals] = useUserMeals()
+ const [userWishes] = useUserDayWishes()
+ const meals = get(userMeals, "meals", [])
+ const dayWishesString = get(userWishes, "dayWishes", [])
+
+ useEffect(() => {
+ setSaturdayLunchMeal(meals[0] || "")
+ setSundayLunchMeal(meals[1] || "")
+ setSundayDinnerMeal(meals[2] || "")
+ }, [meals])
+
+ const onChoiceSubmit = useCallback(() => {
+ saveMeals([saturdayLunchMeal, sundayLunchMeal, sundayDinnerMeal])
+ if (afterSubmit) afterSubmit()
+ }, [saveMeals, saturdayLunchMeal, sundayLunchMeal, sundayDinnerMeal, afterSubmit])
+
+ const getBreakfeastElement = (dayName: string): JSX.Element => (
+
+ {dayName} matin , petit dej à 8h avec jus de pomme, multifruit, café, brioches et
+ quatre-quarts, crêpes si bénévoles motivés.
+
+ )
+
+ const getMealElement = (i: number, meal: string, setMeal: (m: string) => void): JSX.Element => (
+
+
+
+ {mealDays[i].name}
+ {i === 0 && <>, accompagné d'un délicieux brownie tout chocolat>}
+ {i === 1 && (
+ <>, accompagné du même brownie. Enfin, un autre que celui de la veille>
+ )}{" "}
+ :
+
+
+
+ {mealDays[i].options.map((option: MealOption) => (
+
+ setMeal(option.abbr)}
+ checked={meal === option.abbr}
+ />{" "}
+ {option.title}
+
+ ))}
+
+
+ )
+
+ const getNotVolunteerElement = (dayName: string): JSX.Element => (
+
+
{dayName} matin/midi/soir , comme tu n'es pas bénévole ce jour-là, on a rien
+ prévu. Mais{" "}
+
+ contacte-nous
+ {" "}
+ si tu veux qu'on te prévoie un dîner.{" "}
+ {dayName === "Dimanche" && (
+ <>
+ Surtout dimanche soir si tu redeviens bénévole pour nous aider à ranger un peu
+ le festival !
+ >
+ )}
+
+ )
+
+ return (
+
+
Mes repas
+ {dayWishesString.includes("S") ? (
+ <>
+ {getBreakfeastElement("Samedi")}
+ {getMealElement(0, saturdayLunchMeal, setSaturdayLunchMeal)}
+
+ Samedi soir , apéro dînatoire
+
+ >
+ ) : (
+ getNotVolunteerElement("Samedi")
+ )}
+
+
+
+ {dayWishesString.includes("D") ? (
+ <>
+ {getBreakfeastElement("Dimanche")}
+ {getMealElement(1, sundayLunchMeal, setSundayLunchMeal)}
+ {getMealElement(2, sundayDinnerMeal, setSundayDinnerMeal)}
+ >
+ ) : (
+ getNotVolunteerElement("Dimanche")
+ )}
+
+
+
+ Jeudi, vendredi et lundi , chacun improvise. Peut-être resto à proximité.
+
+
+
+ Enregistrer
+ {children === undefined && (
+ <>
+ {" "}
+
+ Annuler
+ {" "}
+ >
+ )}
+ {children !== undefined && (
+ <>
+ {" "}
+
+ {children}
+ {" "}
+ >
+ )}
+
+
+ )
+}
+
+MealsForm.defaultProps = {
+ children: undefined,
+ afterSubmit: undefined,
+}
+
+export default memo(MealsForm)
+
+// Fetch server-side data here
+export const fetchFor = [fetchVolunteerMealsSetIfNeed, fetchVolunteerDayWishesSetIfNeed]
diff --git a/src/components/VolunteerBoard/MealsForm/MealsFormModal.tsx b/src/components/VolunteerBoard/MealsForm/MealsFormModal.tsx
new file mode 100644
index 0000000..12bc91f
--- /dev/null
+++ b/src/components/VolunteerBoard/MealsForm/MealsFormModal.tsx
@@ -0,0 +1,18 @@
+import { FC, memo, useCallback } from "react"
+import { hideModal, MODAL_IDS } from "../../../store/ui"
+import Modal from "../../Modal/Modal"
+import useAction from "../../../utils/useAction"
+import MealsForm from "./MealsForm"
+
+const MealsFormModal: FC = (): JSX.Element => {
+ const execHideModal = useAction(hideModal)
+ const afterFormSubmit = useCallback(() => execHideModal(), [execHideModal])
+
+ return (
+
+
+
+ )
+}
+
+export default memo(MealsFormModal)
diff --git a/src/components/VolunteerBoard/MealsForm/styles.module.scss b/src/components/VolunteerBoard/MealsForm/styles.module.scss
new file mode 100755
index 0000000..7b76bbe
--- /dev/null
+++ b/src/components/VolunteerBoard/MealsForm/styles.module.scss
@@ -0,0 +1,122 @@
+@import "../../../theme/variables";
+@import "../../../theme/mixins";
+
+.title {
+ padding: 15px 0;
+ font-weight: bold;
+ text-align: center;
+}
+
+.inputWrapper {
+ margin: 25px 0;
+
+ @include desktop {
+ display: flex;
+ }
+}
+
+.leftCol {
+ flex: 0 0 320px;
+}
+
+.rightCol {
+ width: 100%;
+ text-align: center;
+}
+
+.needsMealsTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.mealsLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 220px;
+}
+
+.canHostCountTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.canHostCountLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 80px;
+}
+
+.distanceToFestivalTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.distanceToFestivalLabel {
+ text-align: left;
+ display: inline-block;
+ margin-bottom: 10px;
+ width: 80px;
+}
+
+.mealsTitle {
+ display: inline-block;
+ width: 320px;
+ margin-bottom: 10px;
+}
+
+.mealsList {
+ @include clear-ul-style;
+
+ display: inline-block;
+ width: 204px;
+ text-align: center;
+}
+
+.mealsItem {
+ display: inline-block;
+ margin: 3px;
+}
+
+.mealsButton {
+ margin: 0;
+ padding: 7px 2px 6px;
+ border: 0;
+ border-radius: 0;
+ width: 90px;
+ text-align: center;
+ color: $color-grey-dark;
+ background-color: $color-grey-light;
+ cursor: pointer;
+
+ &.active {
+ color: $color-yellow;
+ background-color: $color-black;
+ }
+}
+
+.mealsCommentWrapper {
+ margin: 6px 0 14px;
+
+ label {
+ display: block;
+ padding: 6px 0 2px 4px;
+ }
+ textarea {
+ width: 100%;
+ height: 50px;
+ padding: 5px;
+ border: 1px solid $color-grey-light;
+ background-color: $color-grey-lighter;
+ outline: 0;
+ }
+}
+
+.buttonWrapper {
+ margin-bottom: 10px;
+ text-align: center;
+}
diff --git a/src/components/VolunteerBoard/hosting.utils.ts b/src/components/VolunteerBoard/hosting.utils.ts
index aea33ad..dd0179e 100644
--- a/src/components/VolunteerBoard/hosting.utils.ts
+++ b/src/components/VolunteerBoard/hosting.utils.ts
@@ -4,8 +4,16 @@ import { selectUserJwtToken } from "../../store/auth"
import { AppState } from "../../store"
import { fetchVolunteerHostingSet } from "../../store/volunteerHostingSet"
import useAction from "../../utils/useAction"
+import { VolunteerHosting } from "../../services/volunteers"
-export const useUserHosting = (): [any, any] => {
+type SetFunction = (
+ needsHosting: VolunteerHosting["needsHosting"],
+ canHostCount: VolunteerHosting["canHostCount"],
+ distanceToFestival: VolunteerHosting["distanceToFestival"],
+ hostingComment: VolunteerHosting["hostingComment"]
+) => void
+
+export const useUserHosting = (): [VolunteerHosting | undefined, SetFunction] => {
const save = useAction(fetchVolunteerHostingSet)
const jwtToken = useSelector(selectUserJwtToken)
const userWishes = useSelector(
diff --git a/src/components/VolunteerBoard/meals.utils.ts b/src/components/VolunteerBoard/meals.utils.ts
new file mode 100644
index 0000000..9c8b978
--- /dev/null
+++ b/src/components/VolunteerBoard/meals.utils.ts
@@ -0,0 +1,69 @@
+import { shallowEqual, useSelector } from "react-redux"
+import { useCallback } from "react"
+import { selectUserJwtToken } from "../../store/auth"
+import { AppState } from "../../store"
+import { fetchVolunteerMealsSet } from "../../store/volunteerMealsSet"
+import useAction from "../../utils/useAction"
+import { VolunteerMeals } from "../../services/volunteers"
+
+export type MealOption = { abbr: string; title: string }
+export type MealDay = {
+ name: string
+ options: MealOption[]
+}
+
+export const mealDays: MealDay[] = [
+ {
+ name: "Samedi midi",
+ options: [
+ { abbr: "V", title: "Sandwich végétarien" },
+ { abbr: "F", title: "Sandwich fromage" },
+ { abbr: "P", title: "Sandwich poulet" },
+ { abbr: "", title: "Pas de repas" },
+ ],
+ },
+ {
+ name: "Dimanche midi",
+ options: [
+ { abbr: "V", title: "Sandwich végétarien" },
+ { abbr: "F", title: "Sandwich fromage" },
+ { abbr: "P", title: "Sandwich poulet" },
+ { abbr: "", title: "Pas de repas" },
+ ],
+ },
+ {
+ name: "Dimanche soir",
+ options: [
+ {
+ abbr: "V",
+ title: "Lasagnes végétariennes accompagnées de ratatouille et haricots verts",
+ },
+ { abbr: "P", title: "Aiguillettes de poulet accompagnées de riz thaï" },
+ { abbr: "", title: "Pas de repas" },
+ ],
+ },
+]
+
+type SetFunction = (meals: VolunteerMeals["meals"]) => void
+
+export const useUserMeals = (): [VolunteerMeals | undefined, SetFunction] => {
+ const save = useAction(fetchVolunteerMealsSet)
+ const jwtToken = useSelector(selectUserJwtToken)
+ const userWishes = useSelector(
+ (state: AppState) => state.volunteerMealsSet?.entity,
+ shallowEqual
+ )
+
+ const saveWishes = useCallback(
+ (meals) => {
+ if (!userWishes) return
+ save(jwtToken, 0, {
+ id: userWishes.id,
+ meals,
+ })
+ },
+ [userWishes, save, jwtToken]
+ )
+
+ return [userWishes, saveWishes]
+}
diff --git a/src/server/gsheets/postulants.ts b/src/server/gsheets/postulants.ts
index e7b1322..2bf8782 100644
--- a/src/server/gsheets/postulants.ts
+++ b/src/server/gsheets/postulants.ts
@@ -71,8 +71,8 @@ async function sendMeetingEmail(
to: email,
from: "contact@parisestludique.fr",
subject: "Première rencontre Paris est Ludique",
- text: `Salut ${firstname},\n\nNous allons te contacter prochainement pour trouver ensemble un moyen de se rencontrer.\n\nÀ bientôt :)\nPierre`,
- html: `Salut ${firstname}, Nous allons te contacter prochainement pour trouver ensemble un moyen de se rencontrer. À bientôt :) Pierre`,
+ text: `Salut ${firstname},\n\nTon inscription est bien prise en compte !\n\nNous te contacterons pour trouver un moyen de se rencontrer.\n\nÀ bientôt :)\nPierre`,
+ html: `Salut ${firstname}, Ton inscription est bien prise en compte ! Nous te contacterons pour trouver un moyen de se rencontrer. À bientôt :) Pierre`,
}
await sgMail.send(msg)
}
diff --git a/src/server/gsheets/volunteers.ts b/src/server/gsheets/volunteers.ts
index 1822a59..1ca81da 100644
--- a/src/server/gsheets/volunteers.ts
+++ b/src/server/gsheets/volunteers.ts
@@ -12,6 +12,7 @@ import {
translationVolunteer,
VolunteerDayWishes,
VolunteerHosting,
+ VolunteerMeals,
VolunteerParticipationDetails,
VolunteerTeamAssign,
VolunteerKnowledge,
@@ -362,6 +363,30 @@ export const volunteerHostingSet = expressAccessor.set(async (list, body, id) =>
}
})
+export const volunteerMealsSet = expressAccessor.set(async (list, body, id) => {
+ const requestedId = +body[0] || id
+ if (requestedId !== id && requestedId !== 0) {
+ throw Error(`On ne peut acceder qu'à ses propres repas`)
+ }
+ const wishes = body[1] as VolunteerMeals
+ const volunteer: Volunteer | undefined = 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.meals !== undefined) {
+ newVolunteer.meals = wishes.meals
+ }
+
+ return {
+ toDatabase: newVolunteer,
+ toCaller: {
+ id: newVolunteer.id,
+ meals: newVolunteer.meals,
+ } as VolunteerMeals,
+ }
+})
export const volunteerParticipationDetailsSet = expressAccessor.set(async (list, body, id) => {
const requestedId = +body[0] || id
if (requestedId !== id && requestedId !== 0) {
diff --git a/src/server/index.ts b/src/server/index.ts
index b7e050f..32c1274 100755
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -27,9 +27,9 @@ import {
volunteerDayWishesSet,
volunteerForgot,
volunteerHostingSet,
+ volunteerMealsSet,
volunteerDiscordId,
volunteerLogin,
- volunteerPartialAdd,
volunteerParticipationDetailsSet,
volunteerSet,
volunteerTeamWishesSet,
@@ -94,7 +94,7 @@ app.get("/MiscMeetingDateListGet", miscMeetingDateListGet)
app.get("/WishListGet", wishListGet)
app.post("/WishAdd", wishAdd)
app.post("/PostulantAdd", postulantAdd)
-app.post("/VolunteerPartialAdd", volunteerPartialAdd)
+// Disabling registration app.post("/VolunteerPartialAdd", volunteerPartialAdd)
app.post("/VolunteerLogin", volunteerLogin)
app.post("/VolunteerForgot", volunteerForgot)
app.get("/VolunteerListGet", secure as RequestHandler, volunteerListGet)
@@ -113,6 +113,7 @@ app.post(
)
app.post("/VolunteerDayWishesSet", secure as RequestHandler, volunteerDayWishesSet)
app.post("/VolunteerHostingSet", secure as RequestHandler, volunteerHostingSet)
+app.post("/VolunteerMealsSet", secure as RequestHandler, volunteerMealsSet)
app.post("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
app.post("/VolunteerTeamAssignSet", secure as RequestHandler, volunteerTeamAssignSet)
diff --git a/src/services/volunteers.ts b/src/services/volunteers.ts
index 6715c5b..b6f7511 100644
--- a/src/services/volunteers.ts
+++ b/src/services/volunteers.ts
@@ -67,6 +67,8 @@ export class Volunteer implements VolunteerPartial {
distanceToFestival = 0
hostingComment = ""
+
+ meals: string[] = []
}
export const translationVolunteer: { [k in keyof Volunteer]: string } = {
@@ -104,6 +106,7 @@ export const translationVolunteer: { [k in keyof Volunteer]: string } = {
canHostCount: "nombreHébergés",
distanceToFestival: "distanceAuFestival",
hostingComment: "commentaireHébergement",
+ meals: "repas",
}
export class VolunteerPartial {
@@ -153,6 +156,7 @@ export const volunteerExample: Volunteer = {
canHostCount: 0,
distanceToFestival: 0,
hostingComment: "",
+ meals: [],
}
export const emailRegexp =
@@ -205,6 +209,11 @@ export interface VolunteerHosting {
hostingComment: Volunteer["hostingComment"]
}
+export interface VolunteerMeals {
+ id: Volunteer["id"]
+ meals: Volunteer["meals"]
+}
+
export interface VolunteerParticipationDetails {
id: Volunteer["id"]
tshirtSize: Volunteer["tshirtSize"]
diff --git a/src/services/volunteersAccessors.ts b/src/services/volunteersAccessors.ts
index dbb1efe..40a963e 100644
--- a/src/services/volunteersAccessors.ts
+++ b/src/services/volunteersAccessors.ts
@@ -11,6 +11,7 @@ import {
VolunteerWithoutId,
VolunteerDiscordId,
VolunteerKnowledge,
+ VolunteerMeals,
} from "./volunteers"
const serviceAccessors = new ServiceAccessors(elementName)
@@ -42,6 +43,9 @@ export const volunteerDayWishesSet =
export const volunteerHostingSet =
serviceAccessors.securedCustomPost<[number, Partial]>("HostingSet")
+export const volunteerMealsSet =
+ serviceAccessors.securedCustomPost<[number, Partial]>("MealsSet")
+
export const volunteerParticipationDetailsSet =
serviceAccessors.securedCustomPost<[number, Partial]>(
"ParticipationDetailsSet"
diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts
index 0bc15d4..7642271 100644
--- a/src/store/rootReducer.ts
+++ b/src/store/rootReducer.ts
@@ -17,6 +17,7 @@ import volunteerDayWishesSet from "./volunteerDayWishesSet"
import volunteerDiscordId from "./volunteerDiscordId"
import volunteerForgot from "./volunteerForgot"
import volunteerHostingSet from "./volunteerHostingSet"
+import volunteerMealsSet from "./volunteerMealsSet"
import volunteerList from "./volunteerList"
import volunteerLogin from "./volunteerLogin"
import volunteerKnowledgeSet from "./volunteerKnowledgeSet"
@@ -46,6 +47,7 @@ export default (history: History) => ({
volunteerDiscordId,
volunteerForgot,
volunteerHostingSet,
+ volunteerMealsSet,
volunteerList,
volunteerLogin,
volunteerKnowledgeSet,
diff --git a/src/store/ui.ts b/src/store/ui.ts
index f97b6fa..2de7700 100644
--- a/src/store/ui.ts
+++ b/src/store/ui.ts
@@ -29,6 +29,7 @@ export const selectActiveModalId = createSelector(selectUiData, (ui) => ui.modal
export const MODAL_IDS = {
DAYWISHES: "DAYWISHES",
HOSTING: "HOSTING",
+ MEALS: "MEALS",
PARTICIPATIONDETAILS: "PARTICIPATIONDETAILS",
TEAMWISHES: "TEAMWISHES",
}
diff --git a/src/store/volunteerMealsSet.ts b/src/store/volunteerMealsSet.ts
new file mode 100644
index 0000000..59a8246
--- /dev/null
+++ b/src/store/volunteerMealsSet.ts
@@ -0,0 +1,60 @@
+import { PayloadAction, createSlice } from "@reduxjs/toolkit"
+
+import { StateRequest, toastError, elementFetch } from "./utils"
+import { VolunteerMeals } from "../services/volunteers"
+import { AppThunk, AppState } from "."
+import { volunteerMealsSet } from "../services/volunteersAccessors"
+
+type StateVolunteerMealsSet = { entity?: VolunteerMeals } & StateRequest
+
+export const initialState: StateVolunteerMealsSet = {
+ readyStatus: "idle",
+}
+
+const volunteerMealsSetSlice = createSlice({
+ name: "volunteerMealsSet",
+ initialState,
+ reducers: {
+ getRequesting: (_) => ({
+ readyStatus: "request",
+ }),
+ getSuccess: (_, { payload }: PayloadAction) => ({
+ readyStatus: "success",
+ entity: payload,
+ }),
+ getFailure: (_, { payload }: PayloadAction) => ({
+ readyStatus: "failure",
+ error: payload,
+ }),
+ },
+})
+
+export default volunteerMealsSetSlice.reducer
+export const { getRequesting, getSuccess, getFailure } = volunteerMealsSetSlice.actions
+
+export const fetchVolunteerMealsSet = elementFetch(
+ volunteerMealsSet,
+ getRequesting,
+ getSuccess,
+ getFailure,
+ (error: Error) =>
+ toastError(`Erreur lors du chargement des choix de jours de présence: ${error.message}`)
+)
+
+const shouldFetchVolunteerMealsSet = (state: AppState, id: number) =>
+ state.volunteerMealsSet?.readyStatus !== "success" ||
+ (state.volunteerMealsSet?.entity && state.volunteerMealsSet?.entity?.id !== id)
+
+export const fetchVolunteerMealsSetIfNeed =
+ (id = 0, wishes: Partial = {}): AppThunk =>
+ (dispatch, getState) => {
+ let jwt = ""
+
+ if (!id) {
+ ;({ jwt, id } = getState().auth)
+ }
+ if (shouldFetchVolunteerMealsSet(getState(), id))
+ return dispatch(fetchVolunteerMealsSet(jwt, id, wishes))
+
+ return null
+ }