From 032e15d985dd5bd3e2e9d439bbd618048155d703 Mon Sep 17 00:00:00 2001 From: pikiou Date: Wed, 1 Jun 2022 09:00:51 +0200 Subject: [PATCH] Add hosting form --- src/components/Asks/AskHosting.tsx | 39 +++++ src/components/VolunteerBoard/Board.tsx | 6 + .../VolunteerBoard/Hosting/Hosting.tsx | 61 ++++++++ .../VolunteerBoard/Hosting/styles.module.scss | 53 +++++++ .../HostingForm/HostingForm.tsx | 133 ++++++++++++++++++ .../HostingForm/HostingFormModal.tsx | 18 +++ .../HostingForm/styles.module.scss | 126 +++++++++++++++++ .../VolunteerBoard/hosting.utils.ts | 31 ++++ src/server/gsheets/volunteers.ts | 38 +++++ src/server/index.ts | 2 + src/services/volunteers.ts | 24 ++++ src/services/volunteersAccessors.ts | 4 + src/store/rootReducer.ts | 2 + src/store/ui.ts | 1 + src/store/volunteerHostingSet.ts | 60 ++++++++ 15 files changed, 598 insertions(+) create mode 100644 src/components/Asks/AskHosting.tsx create mode 100644 src/components/VolunteerBoard/Hosting/Hosting.tsx create mode 100755 src/components/VolunteerBoard/Hosting/styles.module.scss create mode 100644 src/components/VolunteerBoard/HostingForm/HostingForm.tsx create mode 100644 src/components/VolunteerBoard/HostingForm/HostingFormModal.tsx create mode 100755 src/components/VolunteerBoard/HostingForm/styles.module.scss create mode 100644 src/components/VolunteerBoard/hosting.utils.ts create mode 100644 src/store/volunteerHostingSet.ts diff --git a/src/components/Asks/AskHosting.tsx b/src/components/Asks/AskHosting.tsx new file mode 100644 index 0000000..8c21f81 --- /dev/null +++ b/src/components/Asks/AskHosting.tsx @@ -0,0 +1,39 @@ +import { get } from "lodash" +import { useCallback } from "react" +import { fetchVolunteerAsksSet } from "../../store/volunteerAsksSet" +import { useAskTools, addAsk, answerLaterOnProfile } from "./utils" +import ParticipationDetailsForm, { + fetchFor as fetchForParticipationDetailsForm, +} from "../VolunteerBoard/ParticipationDetailsForm/ParticipationDetailsForm" +import { useUserParticipationDetails } from "../VolunteerBoard/participationDetails.utils" + +export function AskParticipationDetails(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 [participationDetails] = useUserParticipationDetails() + const tshirtSize = get(participationDetails, "tshirtSize", "") + const food = get(participationDetails, "food", "") + const needToShow = !tshirtSize || !food + + addAsk( + asks, + id, + volunteerAsks, + false, + needToShow, + + {answerLaterOnProfile} + + ) +} + +// Fetch server-side data here +export const fetchFor = [...fetchForParticipationDetailsForm] diff --git a/src/components/VolunteerBoard/Board.tsx b/src/components/VolunteerBoard/Board.tsx index 6803e62..79ba71f 100644 --- a/src/components/VolunteerBoard/Board.tsx +++ b/src/components/VolunteerBoard/Board.tsx @@ -1,6 +1,8 @@ import { FC, memo } from "react" import DayWishes from "./DayWishes/DayWishes" import DayWishesFormModal from "./DayWishesForm/DayWishesFormModal" +import Hosting from "./Hosting/Hosting" +import HostingFormModal from "./HostingForm/HostingFormModal" import ParticipationDetails from "./ParticipationDetails/ParticipationDetails" import ParticipationDetailsFormModal from "./ParticipationDetailsForm/ParticipationDetailsFormModal" import TeamWishes from "./TeamWishes/TeamWishes" @@ -8,6 +10,7 @@ import TeamWishesFormModal from "./TeamWishesForm/TeamWishesFormModal" 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 fetchForParticipationDetailsForm } from "./ParticipationDetailsForm/ParticipationDetailsForm" import { fetchFor as fetchForTeamWishesForm } from "./TeamWishesForm/TeamWishesForm" import VolunteerTeam from "./VolunteerTeam/VolunteerTeam" @@ -22,6 +25,8 @@ const Board: FC = (): JSX.Element => ( + + ) @@ -29,6 +34,7 @@ export default memo(withUserConnected(Board)) export const fetchFor = [ ...fetchForDayWishesForm, + ...fetchForHostingForm, ...fetchForParticipationDetailsForm, ...fetchForTeamWishesForm, ] diff --git a/src/components/VolunteerBoard/Hosting/Hosting.tsx b/src/components/VolunteerBoard/Hosting/Hosting.tsx new file mode 100644 index 0000000..b0fb555 --- /dev/null +++ b/src/components/VolunteerBoard/Hosting/Hosting.tsx @@ -0,0 +1,61 @@ +import { FC, memo, useCallback } from "react" +import get from "lodash/get" +import styles from "./styles.module.scss" +import { useUserHosting } from "../hosting.utils" +import useAction from "../../../utils/useAction" +import { displayModal, MODAL_IDS } from "../../../store/ui" + +const Hosting: FC = (): JSX.Element | null => { + const [userWishes] = useUserHosting() + const needsHosting = get(userWishes, "needsHosting", false) + const canHostCount = get(userWishes, "canHostCount", 0) + const distanceToFestival = get(userWishes, "distanceToFestival", 0) + const comment = get(userWishes, "hostingComment", "") + const execDisplayModal = useAction(displayModal) + const onEdit = useCallback(() => execDisplayModal(MODAL_IDS.HOSTING), [execDisplayModal]) + + return ( +
+
Mon hébergement
+ {!needsHosting && ( +
+ Je n'ai pas besoin d'un hébergement proche du festival +
+ )} + {needsHosting && ( +
+ J'ai besoin d'un hébergement proche du festival +
+ )} + {canHostCount === 0 && distanceToFestival === 0 && ( +
+ Je ne peux héberger personnes de manière utile. +
+ )} + {canHostCount > 0 && ( +
+ Je peux héberger {canHostCount} personnes ! +
+ )} + {distanceToFestival > 0 && ( +
+ Je suis à {distanceToFestival} minutes du festival +
+ )} + + {comment && ( +
+ Mon commentaire : + {comment} +
+ )} +
+ +
+
+ ) +} + +export default memo(Hosting) diff --git a/src/components/VolunteerBoard/Hosting/styles.module.scss b/src/components/VolunteerBoard/Hosting/styles.module.scss new file mode 100755 index 0000000..93683a5 --- /dev/null +++ b/src/components/VolunteerBoard/Hosting/styles.module.scss @@ -0,0 +1,53 @@ +@import "../../../theme/variables"; +@import "../../../theme/mixins"; + +.title { + padding-bottom: 10px; + font-weight: bold; +} + +.hostingLabel { + margin-right: 5px; + font-style: bold; +} + +.hosting { + @include inner-content-wrapper(); + + position: relative; + padding-right: 90px; +} + +.hostingLabel, +.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/HostingForm/HostingForm.tsx b/src/components/VolunteerBoard/HostingForm/HostingForm.tsx new file mode 100644 index 0000000..57647fd --- /dev/null +++ b/src/components/VolunteerBoard/HostingForm/HostingForm.tsx @@ -0,0 +1,133 @@ +import { FC, memo, ReactNode, useCallback, useEffect, useRef, useState } from "react" +import classnames from "classnames" +import get from "lodash/get" +import set from "lodash/set" +import styles from "./styles.module.scss" +import { useUserHosting } from "../hosting.utils" +import FormButton from "../../Form/FormButton/FormButton" +import { fetchVolunteerHostingSetIfNeed } from "../../../store/volunteerHostingSet" +import IgnoreButton from "../../Form/IgnoreButton/IgnoreButton" + +type Props = { + children?: ReactNode | undefined + afterSubmit?: () => void | undefined +} + +const HostingForm: FC = ({ children, afterSubmit }): JSX.Element => { + const [needsHosting, setNeedsHosting] = useState(false) + const canHostCountRef = useRef(null) + const distanceRef = useRef(null) + const commentRef = useRef(null) + const [userWishes, saveWishes] = useUserHosting() + + const onNeedsHostingChange = (e: React.ChangeEvent) => + setNeedsHosting(e.target.checked) + + useEffect(() => { + if (!userWishes) return + setNeedsHosting(get(userWishes, "needsHosting", false)) + set(canHostCountRef, "current.value", `${get(userWishes, "canHostCount", 0)}`) + set(distanceRef, "current.value", `${get(userWishes, "distanceToFestival", 0)}`) + set(commentRef, "current.value", get(userWishes, "hostingComment", "")) + }, [commentRef, userWishes]) + + const onChoiceSubmit = useCallback(() => { + const canHostCount = +get(canHostCountRef, "current.value", "0") + const distanceToFestival = +get(distanceRef, "current.value", "0") + const hostingComment = get(commentRef, "current.value", "") + saveWishes(needsHosting, canHostCount, distanceToFestival, hostingComment) + if (afterSubmit) afterSubmit() + }, [needsHosting, commentRef, saveWishes, afterSubmit]) + + return ( +
+
Mes jours de présence
+
+
+
+ Cela t'arrangerait-il d'avoir un hébergement proche du festival ? +
+
+
+ +
+
+ {needsHosting && ( +
+
+ Il nous serait utile de savoir à quelle temps de transport tu te trouves + pour privilégier les bénévoles qui viennent de province à ceux qui viennent + de l'autre bout de Paris. +
+
+ )} +
+
+
+ Combien de bénévoles peux-tu héberger confortablement ? +
+
+
+ +
+
+
+
+
+ À combien de minutes de transport es-tu du festival ? (En voiture si tu es + en voiture, à vélo si tu as des vélos, sinon en transport en commun.) +
+
+
+ +
+
+
+ +