connect to store ParticipationDetailsForm

This commit is contained in:
memeriau 2022-01-30 11:56:26 +01:00
parent 4800e12d9f
commit 444582c5cc
11 changed files with 173 additions and 118 deletions

View File

@ -1,14 +1,14 @@
import { FC, memo } from "react"
import DayWishes from "./DayWishes/DayWishes"
import DayWishesFormModal from "./DayWishesForm/DayWishesFormModal"
import DDayInformations from "./DDayInformations/DDaysInformations"
import ParticipationDetailsForm from "./ParticipationDetailsForm/ParticipationDetailsForm"
import withUserConnected from "../../utils/withUserConnected"
const Board: FC = (): JSX.Element => (
<div>
<DayWishes />
<DayWishesFormModal />
<DDayInformations />
<ParticipationDetailsForm />
</div>
)

View File

@ -1,76 +0,0 @@
import { FC, memo, useCallback, useRef, useState } from "react"
import styles from "./styles.module.scss"
const sizes = ["XS", "S", "M", "L", "XL", "XXL"]
const DDayInformations: FC = (): JSX.Element | null => {
const sizeRef = useRef<HTMLSelectElement | null>(null)
const dietRef = useRef<HTMLInputElement | null>(null)
const ageRef = useRef<HTMLInputElement | null>(null)
const commentRef = useRef<HTMLTextAreaElement | null>(null)
const [has2Shirts, setHas2Shirts] = useState<boolean | null>(null)
const onSubmit = useCallback(() => {
console.log("on submit")
}, [])
const onHas2ShirtsClick = useCallback(
(value) => {
setHas2Shirts(value)
},
[setHas2Shirts]
)
return (
<div className={styles.ddayInfo}>
<div className={styles.ddayTitle}>Informations pour le festival</div>
<div className={styles.ddayInfoShirtWrapper}>
<div className={styles.ddayShirtLabel}>J&apos;ai déjà 2 t-shirts</div>
<label>
<input type="radio" name="hasShirt" onClick={() => onHas2ShirtsClick(true)} />{" "}
Oui
</label>
<label>
<input type="radio" name="hasShirt" onClick={() => onHas2ShirtsClick(false)} />{" "}
Non
</label>
{has2Shirts === false && (
<div className={styles.ddayShirtSizes}>
<label>Taille</label>
<select ref={sizeRef}>
{sizes.map((size) => (
<option key={size} value={size}>
{size}
</option>
))}
</select>
</div>
)}
</div>
<div className={styles.ddayInfoInputWrapper}>
<label htmlFor="ddday-age">Age</label>
<input type="number" id="ddday-age" ref={ageRef} />
</div>
<div className={styles.ddayInfoInputWrapper}>
<label htmlFor="dday-diet">Régime alimentaire</label>
<input
id="dday-diet"
type="text"
ref={dietRef}
placeholder="végétarien ? halal ? ..."
/>
</div>
<div className={styles.ddayInfoCommentWrapper}>
<label htmlFor="dday-comment">Des commentaires ?</label>
<textarea id="dday-comment" ref={commentRef} />
</div>
<div className={styles.ddayButtonWrapper}>
<button type="submit" onClick={onSubmit}>
Enregistrer
</button>
</div>
</div>
)
}
export default memo(DDayInformations)

View File

@ -1,7 +1,7 @@
import { FC, memo, useCallback } from "react"
import get from "lodash/get"
import styles from "./styles.module.scss"
import { getDayLabel, useUserDayWishes } from "../days.utils"
import { getDayLabel, useUserDayWishes } from "../daysWishes.utils"
import useAction from "../../../utils/useAction"
import { displayModal, MODAL_IDS } from "../../../store/ui"

View File

@ -8,7 +8,7 @@ import {
daysChoiceSelectionDefaultState,
selectionChoices,
useUserDayWishes,
} from "../days.utils"
} from "../daysWishes.utils"
type Props = {
afterSubmit?: () => void | undefined

View File

@ -0,0 +1,99 @@
import { FC, memo, useCallback, useEffect, useRef, useState } from "react"
import get from "lodash/get"
import set from "lodash/set"
import styles from "./styles.module.scss"
import { tShirtSizes, useUserParticipationDetails } from "../participationDetails.utils"
const ParticipationDetailsForm: FC = (): JSX.Element | null => {
const sizeRef = useRef<HTMLSelectElement | null>(null)
const dietRef = useRef<HTMLInputElement | null>(null)
const ageRef = useRef<HTMLInputElement | null>(null)
const [has2Shirts, setHas2Shirts] = useState<boolean>(true)
const [participationDetails, saveParticipationDetails] = useUserParticipationDetails()
const onSubmit = useCallback(() => {
const age = get(ageRef, "current.value", "")
const teeshirtSize = has2Shirts ? "" : get(sizeRef, "current.value", "")
const food = get(dietRef, "current.value", "")
saveParticipationDetails({ age, teeshirtSize, food })
}, [has2Shirts, saveParticipationDetails])
const onHas2ShirtsClick = useCallback(
(value) => {
setHas2Shirts(value)
},
[setHas2Shirts]
)
useEffect(() => {
console.log("participationDetails", participationDetails)
const age = get(participationDetails, "age", "")
const teeshirtSize = get(participationDetails, "teeshirtSize", "")
const food = get(participationDetails, "food", "")
if (age) set(ageRef, "current.value", age)
if (teeshirtSize) set(sizeRef, "current.value", teeshirtSize)
setHas2Shirts(!teeshirtSize)
if (food) set(dietRef, "current.value", food)
}, [setHas2Shirts, participationDetails])
return (
<div className={styles.root}>
<div className={styles.title}>Informations pour le festival</div>
<div className={styles.tShirtWrapper}>
<div className={styles.tShirtLabel}>J&apos;ai déjà 2 t-shirts</div>
<label>
<input
type="radio"
name="hasShirt"
onClick={() => onHas2ShirtsClick(true)}
checked={has2Shirts}
/>{" "}
Oui
</label>
<label>
<input
type="radio"
name="hasShirt"
onClick={() => onHas2ShirtsClick(false)}
checked={!has2Shirts}
/>{" "}
Non
</label>
{has2Shirts === false && (
<div className={styles.tShirtSizes}>
<label>Taille</label>
<select ref={sizeRef}>
{tShirtSizes.map((size) => (
<option key={size} value={size}>
{size}
</option>
))}
</select>
</div>
)}
</div>
<div className={styles.inputWrapper}>
<label htmlFor="ddday-age">Age</label>
<input type="number" id="ddday-age" ref={ageRef} />
</div>
<div className={styles.inputWrapper}>
<label htmlFor="dday-diet">Préférence alimentaire</label>
<input
id="dday-diet"
type="text"
ref={dietRef}
placeholder="végétarien ? halal ? ..."
/>
</div>
<div className={styles.buttonWrapper}>
<button type="submit" onClick={onSubmit}>
Enregistrer
</button>
</div>
</div>
)
}
export default memo(ParticipationDetailsForm)

View File

@ -1,78 +1,62 @@
@import "../../../theme/variables";
@import "../../../theme/mixins";
.ddayInfo {
.root {
width: 470px;
}
.ddayTitle {
.title {
padding: 4px;
font-weight: bold;
text-align: center;
}
.ddayInfoInputWrapper {
.inputWrapper {
margin: 10px 0;
label {
display: inline-block;
width: 150px;
width: 170px;
}
input {
width: 320px;
width: 300px;
border: 1px solid $color-grey-medium;
outline: 0;
}
}
.ddayInfoShirtWrapper {
.tShirtWrapper {
margin: 10px 0;
height: 22px;
height: 28px;
label {
display: inline-block;
width: 60px;
width: 55px;
}
}
.ddayShirtLabel {
.tShirtLabel {
display: inline-block;
margin-top: 2px;
width: 150px;
margin-top: 6px;
width: 170px;
}
.ddayShirtSizes {
.tShirtSizes {
display: inline-block;
width: 200px;
width: 190px;
text-align: right;
select {
margin-left: 10px;
width: 60px;
width: 120px;
border: 1px solid $color-grey-medium;
border-radius: 4px;
background-color: $color-white;
outline: 0;
}
}
.ddayInfoCommentWrapper {
margin: 6px 0;
label {
display: block;
padding-left: 4px;
}
textarea {
width: 100%;
height: 50px;
padding: 5px;
border: 1px solid $color-grey-light;
background-color: $color-grey-lighter;
outline: 0;
}
}
.ddayButtonWrapper {
.buttonWrapper {
margin-bottom: 10px;
text-align: center;
}

View File

@ -5,9 +5,9 @@ import { AppState } from "../../store"
import { fetchVolunteerDayWishesSet } from "../../store/volunteerDayWishesSet"
import useAction from "../../utils/useAction"
const daysUtils = ["Jeudi", "Vendredi", "Samedi", "Dimanche", "Lundi"]
const daysWishesUtils = ["Jeudi", "Vendredi", "Samedi", "Dimanche", "Lundi"]
export const daysChoice = daysUtils.map((label) => ({
export const daysChoice = daysWishesUtils.map((label) => ({
id: label[0],
label,
}))

View File

@ -0,0 +1,43 @@
import { useCallback } from "react"
import { shallowEqual, useSelector } from "react-redux"
import useAction from "../../utils/useAction"
import { selectUserJwtToken } from "../../store/auth"
import { AppState } from "../../store"
import { fetchVolunteerParticipationDetailsSet } from "../../store/volunteerParticipationDetailsSet"
export const tShirtSizes = [
"XS",
"S",
"M",
"L",
"XL",
"XXL",
"Femme S",
"Femme M",
"Femme L",
"Femme XL",
]
export const useUserParticipationDetails = (): [any, any] => {
const save = useAction(fetchVolunteerParticipationDetailsSet)
const jwtToken = useSelector(selectUserJwtToken)
const userParticipationDetails = useSelector(
(state: AppState) => state.volunteerParticipationDetailsSet?.entity,
shallowEqual
)
const saveParticipationDetails = useCallback(
({ age, teeshirtSize, food }) => {
if (!userParticipationDetails) return
save(jwtToken, 0, {
id: userParticipationDetails.id,
age,
teeshirtSize,
food,
})
},
[userParticipationDetails, save, jwtToken]
)
return [userParticipationDetails, saveParticipationDetails]
}

View File

@ -7,6 +7,7 @@ import { fetchVolunteerDayWishesSetIfNeed } from "../../store/volunteerDayWishes
import { selectUserJwtToken } from "../../store/auth"
import Page from "../../components/Page/Page"
import Board from "../../components/VolunteerBoard/Board"
import { fetchVolunteerParticipationDetailsSetIfNeed } from "../../store/volunteerParticipationDetailsSet"
export type Props = RouteComponentProps
@ -25,6 +26,9 @@ const BoardPage: FC<Props> = (): JSX.Element => {
}
// Fetch server-side data here
export const loadData = (): AppThunk[] => [fetchVolunteerDayWishesSetIfNeed()]
export const loadData = (): AppThunk[] => [
fetchVolunteerDayWishesSetIfNeed(),
fetchVolunteerParticipationDetailsSetIfNeed(),
]
export default memo(BoardPage)

View File

@ -6,7 +6,7 @@ import { AppThunk } from "../../store"
import { fetchVolunteerDayWishesSetIfNeed } from "../../store/volunteerDayWishesSet"
import { selectUserJwtToken } from "../../store/auth"
import DayWishesForm from "../../components/VolunteerBoard/DayWishesForm/DayWishesForm"
import DDayInformations from "../../components/VolunteerBoard/DDayInformations/DDaysInformations"
import DDayInformations from "../../components/VolunteerBoard/ParticipationDetailsForm/ParticipationDetailsForm"
import styles from "./styles.module.scss"
export type Props = RouteComponentProps

View File

@ -13,8 +13,9 @@ button {
input[type="text"],
input[type="password"],
input[type="number"],
input[type="email"] {
input[type="email"],
select {
padding: 4px 6px;
border: 1px solid #333;
border: 1px solid $color-grey-medium;
border-radius: 4px;
}