Add charter, Fix absence of meeting dates

This commit is contained in:
pikiou
2023-01-16 17:58:02 +01:00
parent 0f06aaea05
commit a906dfff07
21 changed files with 469 additions and 175 deletions

View File

@@ -19,10 +19,12 @@ export function AskDayWishes(asks: JSX.Element[], id: number): void {
}, [dispatch, id, jwtToken, volunteerAsks?.hiddenAsks])
const [userWishes] = useUserDayWishes()
const charter = get(userWishes, "charter", false) as boolean
const participation = get(userWishes, "active", "inconnu") as string
const newSelection = get(userWishes, "dayWishes", []) as string[]
const comment = get(userWishes, "dayWishesComment", "") as string
const needToShow = participation === "inconnu" || (newSelection.length === 0 && !comment)
const needToShow =
charter === false || participation === "inconnu" || (newSelection.length === 0 && !comment)
addAsk(
asks,

View File

@@ -3,8 +3,8 @@ import React, { memo } from "react"
import styles from "./styles.module.scss"
import { useAskTools } from "./utils"
import { AskWelcome } from "./AskWelcome"
import { AskBrunch, fetchFor as fetchForBrunch } from "./AskBrunch"
import { AskRetex, fetchFor as fetchForRetex } from "./AskRetex"
// import { AskBrunch, fetchFor as fetchForBrunch } from "./AskBrunch"
// import { AskRetex, fetchFor as fetchForRetex } from "./AskRetex"
import { AskDiscord, fetchFor as fetchForDiscord } from "./AskDiscord"
import { AskDayWishes, fetchFor as fetchForDayWishes } from "./AskDayWishes"
// import { AskHosting, fetchFor as fetchForHosting } from "./AskHosting"
@@ -22,8 +22,8 @@ const Asks = (): JSX.Element | null => {
const asks: JSX.Element[] = []
AskWelcome(asks, 1)
AskBrunch(asks, 2)
AskRetex(asks, 3)
// AskBrunch(asks, 2)
// AskRetex(asks, 3)
AskDiscord(asks, 5)
AskDayWishes(asks, 10)
@@ -66,8 +66,8 @@ export default memo(Asks)
// Fetch server-side data here
export const fetchFor = [
...fetchForBrunch,
...fetchForRetex,
// ...fetchForBrunch,
// ...fetchForRetex,
...fetchForDiscord,
...fetchForDayWishes,
// ...fetchForHosting,

View File

@@ -52,8 +52,8 @@ const MainMenu: FC = (): JSX.Element => {
<MenuItem name="Questions" pathname="/" />
<MenuItem name="Annonces" pathname="/annonces" />
<MenuItem name="Mon profil" pathname="/profil" />
<MenuItem name="Emprunter" pathname="/emprunter" />
<MenuItem name="Emprunts" pathname="/emprunts" />
{/* <MenuItem name="Emprunter" pathname="/emprunter" />
<MenuItem name="Emprunts" pathname="/emprunts" /> */}
{/* <MenuItem name="Mes connaissances" pathname="/connaissances" /> */}
<RestrictMenuItem
role={ROLES.ASSIGNER}

View File

@@ -17,6 +17,10 @@ import {
sendRadioboxDispatch,
sendTextDispatch,
} from "../input.utils"
import {
fetchMiscFestivalDateListIfNeed,
selectMiscFestivalDateList,
} from "../../store/miscFestivalDateList"
import {
fetchMiscMeetingDateListIfNeed,
selectMiscMeetingDateList,
@@ -49,9 +53,11 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
const [sending, setSending] = useState(false)
const [changingBackground, setChangingBackground] = useState(0)
const festivalDateList = useSelector(selectMiscFestivalDateList)
const meetingDateList = useSelector(selectMiscMeetingDateList)
const enableRegistering = true
const hasMeetingDates = meetingDateList.length > 0
useEffect(() => {
const timer = setInterval(() => {
@@ -149,13 +155,15 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
)
}
const festivalFullDate = _.find(festivalDateList, { id: 1 })?.date
const intro = (
<dl className={styles.registerIntro}>
<dt>Qu&apos;est-ce que Paris est Ludique ?</dt>
<dd>
<p>
Un festival en plein air dédié aux <b>jeux de société modernes</b> sous toutes
leurs formes. Les samedi 24 et dimanche 25 juin 2023 !
leurs formes.{festivalFullDate && ` Les ${festivalFullDate} !`}
</p>
<p>
En 2022, ce sont <b>18 000</b> visiteurs qui sont venus sous 300 chapiteaux et 2
@@ -362,43 +370,91 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
</dd>
</dl>
<div className={styles.inputWrapper}>
<div className={styles.leftCol}>
<div className={styles.multipleChoiceTitle}>
À quelle date pourrais-tu venir ?
{hasMeetingDates ? (
<div className={styles.inputWrapper}>
<div className={styles.leftCol}>
<div className={styles.multipleChoiceTitle}>
À quelle date pourrais-tu venir ?
</div>
</div>
<div className={styles.rightCol}>
<div className={styles.rightColContainer}>
{_.concat(
meetingDateList.map((meetingDetails) => ({
value: meetingDetails.meetingId,
desc: meetingDetails.meetingTitle,
})),
{ value: "", desc: "Aucune date possible" }
).map((option) => (
<label className={styles.longAnswerLabel} key={option.value}>
<input
type="radio"
name="firstMeeting"
value={option.value}
onChange={sendRadioboxDispatch(setFirstMeeting)}
checked={firstMeeting === option.value}
/>{" "}
{option.desc}
</label>
))}
</div>
</div>
</div>
<div className={styles.rightCol}>
<div className={styles.rightColContainer}>
{_.concat(
meetingDateList.map((meetingDetails) => ({
value: meetingDetails.meetingId,
desc: meetingDetails.meetingTitle,
})),
{ value: "", desc: "Aucune date possible" }
).map((option) => (
<label className={styles.longAnswerLabel} key={option.value}>
<input
type="radio"
name="firstMeeting"
value={option.value}
onChange={sendRadioboxDispatch(setFirstMeeting)}
checked={firstMeeting === option.value}
/>{" "}
{option.desc}
</label>
))}
</div>
</div>
</div>
) : null}
{firstMeeting !== "" && (
{!hasMeetingDates && (
<div className={styles.inputWrapper}>
<div className={styles.leftCol}>
<div className={styles.multipleChoiceTitle}>
Es-tu dispo un lundi ou mardi soir sur Paris pour nous rencontrer ?
</div>
</div>
<div className={styles.rightCol}>
<div className={styles.rightColContainer}>
{[
{ value: "", desc: "Rencontre sur Paris" },
{ value: "visio", desc: "Plutôt en visio" },
].map((option) => (
<label className={styles.longAnswerLabel} key={option.value}>
<input
type="radio"
name="firstMeeting"
value={option.value}
onChange={sendRadioboxDispatch(setFirstMeeting)}
checked={firstMeeting === option.value}
/>{" "}
{option.desc}
</label>
))}
</div>
</div>
</div>
)}
{(!hasMeetingDates || firstMeeting !== "") && (
<dl className={styles.registerIntro}>
<dd>
<p>
Top ! On fait en sorte qu'il y ait assez de bénévoles expérimentés pour
les nombreux curieux comme toi, donc pour ne pas gâcher leur temps on
compte sur ta présence :)
{!hasMeetingDates && firstMeeting === "" && (
<>
Top ! On te propose très vite des dates, ou à défaut, une visio
:)
</>
)}
{firstMeeting === "visio" && (
<>
Top ! On te recontacte très vite avec des dates pour une visio
avec 2 bénévoles et 2-3 autres personnes intéréssées comme toi
:)
</>
)}
{hasMeetingDates && firstMeeting !== "" && (
<>
Top ! On fait en sorte qu'il y ait assez de bénévoles
expérimentés pour les nombreux curieux comme toi, donc pour ne
pas gâcher leur temps on compte sur ta présence :)
</>
)}
</p>
<p>Si tu as un contre-temps, écris-nous à benevoles@parisestludique.fr</p>
<p>À très bientôt !</p>
@@ -406,20 +462,33 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
</dl>
)}
{firstMeeting === "" && (
<div className={styles.inputWrapper}>
<div className={styles.commentWrapper}>
<textarea
name="commentFirstMeeting"
id="commentFirstMeeting"
className={styles.inputWrapper}
placeholder="Mince. Quelles dates t'arrangeraient ? Ou si c'est plus simple, quels jours sont à éviter ? Est-ce trop loin de chez toi ? Préfères-tu nous rencontrer en visio ?"
value={commentFirstMeeting}
onChange={sendTextareaDispatch(setCommentFirstMeeting)}
/>
</div>
<div
className={classnames(
styles.inputWrapper,
!(firstMeeting === "" || firstMeeting === "visio") && styles.hidden
)}
>
<div className={styles.commentWrapper}>
<textarea
name="commentFirstMeeting"
id="commentFirstMeeting"
className={styles.inputWrapper}
placeholder={
(hasMeetingDates && firstMeeting === ""
? "Mince. Quelles dates t'arrangeraient ? Ou si c'est plus simple, quels jours sont à éviter ? Est-ce trop loin de chez toi ? Préfères-tu nous rencontrer en visio ?"
: "") +
(!hasMeetingDates && firstMeeting === ""
? "As-tu des contraintes horaires les lundis ? Les mardis ?"
: "") +
(firstMeeting === "visio"
? "As-tu des contraites en terme de jours de la semaine ? D'horaire ?"
: "")
}
value={commentFirstMeeting}
onChange={sendTextareaDispatch(setCommentFirstMeeting)}
/>
</div>
)}
</div>
</>
)
@@ -572,4 +641,4 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
export default memo(RegisterForm)
// Fetch server-side data here
export const fetchFor = [fetchMiscMeetingDateListIfNeed]
export const fetchFor = [fetchMiscFestivalDateListIfNeed, fetchMiscMeetingDateListIfNeed]

View File

@@ -221,3 +221,7 @@
height: 112px;
}
}
.hidden {
display: none;
}

View File

@@ -20,28 +20,29 @@ import { fetchFor as fetchForDayWishesForm } from "./DayWishesForm/DayWishesForm
import { fetchFor as fetchForPersonalInfoForm } from "./PersonalInfoForm/PersonalInfoForm"
import PersonalInfo from "./PersonalInfo/PersonalInfo"
import PersonalInfoFormModal from "./PersonalInfoForm/PersonalInfoFormModal"
import Brunch from "./Brunch/Brunch"
import BrunchFormModal from "./BrunchForm/BrunchFormModal"
import { fetchFor as fetchForBrunchForm } from "./BrunchForm/BrunchForm"
import Retex from "./Retex/Retex"
import RetexFormModal from "./RetexForm/RetexFormModal"
import { fetchFor as fetchForRetexForm } from "./RetexForm/RetexForm"
import { useRetex } from "./retex.utils"
// import Brunch from "./Brunch/Brunch"
// import BrunchFormModal from "./BrunchForm/BrunchFormModal"
// import { fetchFor as fetchForBrunchForm } from "./BrunchForm/BrunchForm"
// import Retex from "./Retex/Retex"
// import RetexFormModal from "./RetexForm/RetexFormModal"
// import { fetchFor as fetchForRetexForm } from "./RetexForm/RetexForm"
// import { useRetex } from "./retex.utils"
const Board: FC = (): JSX.Element => {
const [retex] = useRetex()
return (
<>
<ContentTitle title="Profil spécifique au festival" />
<PersonalInfo />
<PersonalInfoFormModal />
{retex && <Brunch />}
const Board: FC = (): JSX.Element => (
// {
// const [retex] = useRetex()
// return (
<>
<ContentTitle title="Profil spécifique au festival" />
<PersonalInfo />
<PersonalInfoFormModal />
{/* {retex && <Brunch />}
{retex && <BrunchFormModal />}
{retex && <Retex />}
{retex && <RetexFormModal />}
<DayWishes />
<DayWishesFormModal />
{/* <ParticipationDetails />
{retex && <RetexFormModal />} */}
<DayWishes />
<DayWishesFormModal />
{/* <ParticipationDetails />
<ParticipationDetailsFormModal />
<TeamWishes />
<TeamWishesFormModal />
@@ -50,16 +51,17 @@ const Board: FC = (): JSX.Element => {
<HostingFormModal />
<Meals />
<MealsFormModal /> */}
</>
)
}
</>
)
// )
// }
export default memo(withUserConnected(Board))
export const fetchFor = [
...fetchForPersonalInfoForm,
...fetchForRetexForm,
...fetchForBrunchForm,
// ...fetchForRetexForm,
// ...fetchForBrunchForm,
...fetchForDayWishesForm,
// ...fetchForHostingForm,
// ...fetchForMealsForm,

View File

@@ -7,6 +7,7 @@ import { displayModal, MODAL_IDS } from "../../../store/ui"
const DayWishes: FC = (): JSX.Element | null => {
const [userWishes] = useUserDayWishes()
const charter = get(userWishes, "charter", false)
const participation = get(userWishes, "active", "inconnu")
const dayWishesString = get(userWishes, "dayWishes", []).map(getDayLabel).join(", ")
const comment = get(userWishes, "dayWishesComment", "")
@@ -15,7 +16,13 @@ const DayWishes: FC = (): JSX.Element | null => {
return (
<div className={styles.dayWishes}>
<div className={styles.title}>Mes présences</div>
<div className={styles.title}>Mon engagement</div>
{!charter && (
<div className={styles.lineEmpty}>
Je n'ai pas encore accepté la charte du bénévole :(
</div>
)}
{participation === "non" && (
<div className={styles.participationLabel}>
Je <b>ne participerai pas</b> à PeL 2023 :(

View File

@@ -1,4 +1,5 @@
import { FC, memo, ReactNode, useCallback, useEffect, useRef, useState } from "react"
import _ from "lodash"
import { useSelector } from "react-redux"
import classnames from "classnames"
import get from "lodash/get"
@@ -17,6 +18,10 @@ import {
fetchMiscDiscordInvitationIfNeed,
selectMiscDiscordInvitation,
} from "../../../store/miscDiscordInvitation"
import {
fetchMiscFestivalDateListIfNeed,
selectMiscFestivalDateList,
} from "../../../store/miscFestivalDateList"
type Props = {
children?: ReactNode | undefined
@@ -24,17 +29,24 @@ type Props = {
}
const DayWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
const [charterState, setCharter] = useState(false)
const [participationState, setParticipation] = useState("inconnu")
const [selection, setSelection] = useState(daysChoiceSelectionDefaultState)
const commentRef = useRef<HTMLTextAreaElement | null>(null)
const [userWishes, saveWishes] = useUserDayWishes()
const discordInvitation = useSelector(selectMiscDiscordInvitation)
const festivalDateList = useSelector(selectMiscFestivalDateList)
const onCharteChange = (e: React.ChangeEvent<HTMLInputElement>) =>
setCharter(e.target.value === "oui")
const onParticipationChange = (e: React.ChangeEvent<HTMLInputElement>) =>
setParticipation(e.target.value)
const festivalShortDate = _.find(festivalDateList, { id: 2 })?.date
useEffect(() => {
if (!userWishes) return
const charter = get(userWishes, "charter", false)
const participation = get(userWishes, "active", "inconnu")
const dayWishes = get(userWishes, "dayWishes", []) as string[]
const newSelection = dayWishes.reduce(
@@ -44,6 +56,7 @@ const DayWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
}),
{} as SelectionChoices
)
setCharter(charter)
setParticipation(participation)
setSelection(newSelection)
set(commentRef, "current.value", get(userWishes, "dayWishesComment", ""))
@@ -61,94 +74,142 @@ const DayWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
const onChoiceSubmit = useCallback(() => {
const comment = get(commentRef, "current.value", "")
const days = daysChoice.map(({ id }) => id).filter((id) => selection[id])
saveWishes(participationState, days, comment)
saveWishes(charterState, participationState, days, comment)
if (afterSubmit) afterSubmit()
}, [participationState, selection, commentRef, saveWishes, afterSubmit])
}, [saveWishes, charterState, participationState, afterSubmit, selection])
return (
<div>
<div className={styles.title}>Mes jours de présence</div>
<div className={styles.title}>Mon engagement</div>
<div className={classnames(styles.inputWrapper, styles.noBottomMargin)}>
<div className={styles.oneCol}>
En tant que bénévole, il nexiste <b>aucun lien de subordination</b> entre
lassociation et toi.
<br />
Il n'y a <b>pas de rémunération</b>, mais il est attendu que tu sois :<br />
<b>Accueillant et sincère</b> avec les autres bénévoles comme avec les visiteurs
et les exposants;
<br />
<b>Humble et à lécoute</b> pour permettre le travail en équipe et la
collaboration;
<br />
<b>Neutre et tolérant</b> politiquement et religieusement pour éviter la
discorde.
<br />
</div>
</div>
<div className={classnames(styles.inputWrapper, styles.noBottomMargin)}>
<div className={styles.leftCol}>
<div className={styles.participationTitle}>
Si les conditions sanitaires te le permettent, souhaites-tu être bénévole à
PeL les 24 & 25 juin 2023 ?
<div className={styles.charteTitle}>
Acceptes-tu de respecter cette charte ?
</div>
</div>
<div className={styles.rightCol}>
<label className={styles.participationLabel}>
<label className={styles.charteLabel}>
<input
type="radio"
value="oui"
name="participation"
onChange={onParticipationChange}
checked={participationState === "oui"}
name="charte"
onChange={onCharteChange}
checked={charterState}
/>{" "}
Oui
</label>
<label className={styles.participationLabel}>
<label className={styles.charteLabel}>
<input
type="radio"
value="non"
name="participation"
onChange={onParticipationChange}
checked={participationState === "non"}
name="charte"
onChange={onCharteChange}
checked={!charterState}
/>{" "}
Non
</label>
<label className={styles.participationLabel}>
<input
type="radio"
value="peut-etre"
name="participation"
onChange={onParticipationChange}
checked={participationState === "peut-etre"}
/>{" "}
Je ne sais pas encore
</label>
</div>
</div>
{participationState === "peut-etre" ? (
<div>
On te le reproposera dans quelques temps.
<br />
Si tu as besoin d&apos;infos, viens nous en parler sur le serveur Discord ! Pour
le rejoindre,{" "}
<a href={discordInvitation} target="_blank" rel="noreferrer">
clique ici{" "}
</a>
.
</div>
) : null}
<div className={styles.inputWrapper}>
<div className={styles.leftCol}>
<div className={styles.dayWishesTitle}>
Quels jours viendras-tu ?<br />
Il est tôt pour le dire, tu peux y repondre plus tard sur la page profil.
<br />
(Minimum 2 jours dont l'un sera samedi ou dimanche, idéalement samedi{" "}
<b>et</b> dimanche ^^)
{charterState ? (
<>
<div className={classnames(styles.inputWrapper, styles.noBottomMargin)}>
<div className={styles.leftCol}>
<div className={styles.participationTitle}>
Souhaites-tu être bénévole à PeL{" "}
{festivalShortDate && `les ${festivalShortDate}`} ?
</div>
</div>
<div className={styles.rightCol}>
<label className={styles.participationLabel}>
<input
type="radio"
value="oui"
name="participation"
onChange={onParticipationChange}
checked={participationState === "oui"}
/>{" "}
Oui
</label>
<label className={styles.participationLabel}>
<input
type="radio"
value="non"
name="participation"
onChange={onParticipationChange}
checked={participationState === "non"}
/>{" "}
Non
</label>
<label className={styles.participationLabel}>
<input
type="radio"
value="peut-etre"
name="participation"
onChange={onParticipationChange}
checked={participationState === "peut-etre"}
/>{" "}
Je ne sais pas encore
</label>
</div>
</div>
</div>
<div className={styles.rightCol}>
<ul className={styles.dayWishesList}>
{daysChoice.map(({ id, label }) => (
<li key={id} className={styles.dayWishesItem}>
<button
type="button"
onClick={() => onChoiceClick(id)}
className={classnames(
styles.dayWishesButton,
selection[id] && styles.active
)}
>
{label}
</button>
</li>
))}
</ul>
</div>
</div>
{participationState === "peut-etre" ? (
<div>
On te le reproposera dans quelques temps.
<br />
Si tu as besoin d&apos;infos, viens nous en parler sur le serveur
Discord ! Pour le rejoindre,{" "}
<a href={discordInvitation} target="_blank" rel="noreferrer">
clique ici{" "}
</a>
.
</div>
) : null}
<div className={styles.inputWrapper}>
<div className={styles.leftCol}>
<div className={styles.dayWishesTitle}>
Quels jours viendras-tu ?<br />
(Minimum 2 jours dont l'un sera samedi ou dimanche, idéalement
samedi <b>et</b> dimanche ^^)
</div>
</div>
<div className={styles.rightCol}>
<ul className={styles.dayWishesList}>
{daysChoice.map(({ id, label }) => (
<li key={id} className={styles.dayWishesItem}>
<button
type="button"
onClick={() => onChoiceClick(id)}
className={classnames(
styles.dayWishesButton,
selection[id] && styles.active
)}
>
{label}
</button>
</li>
))}
</ul>
</div>
</div>
</>
) : null}
<div className={styles.dayWishCommentWrapper}>
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
<textarea id="day-choice-comment" ref={commentRef} />
@@ -184,4 +245,8 @@ DayWishesForm.defaultProps = {
export default memo(DayWishesForm)
// Fetch server-side data here
export const fetchFor = [fetchVolunteerDayWishesSetIfNeed, fetchMiscDiscordInvitationIfNeed]
export const fetchFor = [
fetchVolunteerDayWishesSetIfNeed,
fetchMiscDiscordInvitationIfNeed,
fetchMiscFestivalDateListIfNeed,
]

View File

@@ -28,13 +28,19 @@
text-align: center;
}
.participationTitle {
.oneCol {
width: 100%;
}
.participationTitle,
.charteTitle {
display: inline-block;
width: 320px;
margin-bottom: 10px;
}
.participationLabel {
.participationLabel,
.charteLabel {
text-align: left;
display: inline-block;
margin-bottom: 10px;

View File

@@ -23,6 +23,7 @@ export const daysChoiceSelectionDefaultState = daysChoice.reduce((state, { id })
}, <SelectionChoices>{})
type SetFunction = (
charter: VolunteerDayWishes["charter"],
active: VolunteerDayWishes["active"],
dayWishes: VolunteerDayWishes["dayWishes"],
dayWishesComment: VolunteerDayWishes["dayWishesComment"]
@@ -37,10 +38,11 @@ export const useUserDayWishes = (): [VolunteerDayWishes | undefined, SetFunction
)
const saveWishes: SetFunction = useCallback(
(active, dayWishes, dayWishesComment) => {
(charter, active, dayWishes, dayWishesComment) => {
if (!userWishes) return
save(jwtToken, 0, {
id: userWishes.id,
charter,
active,
dayWishes,
dayWishesComment,