days wishes components

This commit is contained in:
memeriau
2022-01-24 14:26:36 +01:00
parent 6d0134cb63
commit 3fd6741a78
7 changed files with 150 additions and 94 deletions

View File

@@ -1,10 +1,31 @@
import { FC, memo, useCallback, useState } from "react"
import { FC, memo, useCallback, useEffect, useRef, useState } from "react"
import classnames from "classnames"
import { daysChoice, daysChoiceSelectionDefaultState } from "./days.utils"
import get from "lodash/get"
import styles from "./styles.module.scss"
import {
daysChoice,
daysChoiceSelectionDefaultState,
selectionChoices,
useUserDayWishes,
} from "./days.utils"
const DayWishes: FC = (): JSX.Element | null => {
const [selection, setSelection] = useState(daysChoiceSelectionDefaultState)
const commentRef = useRef<HTMLTextAreaElement | null>(null)
const [userWishes, saveWishes] = useUserDayWishes()
useEffect(() => {
if (!userWishes) return
const newSelection = get(userWishes, "dayWishes", []).reduce(
(acc: selectionChoices, day: string) => ({
...acc,
[day]: true,
}),
daysChoice
)
setSelection(newSelection)
}, [setSelection, userWishes])
const onChoiceClick = useCallback(
(id) => {
setSelection({
@@ -14,24 +35,41 @@ const DayWishes: FC = (): JSX.Element | null => {
},
[selection, setSelection]
)
const onChoiceSubmit = useCallback(() => {
const comment = get(commentRef, "current.value", "")
const days = daysChoice.map(({ id }) => id).filter((id) => selection[id])
saveWishes(days, comment)
}, [selection, commentRef, saveWishes])
return (
<ul className={styles.dayWishes}>
{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 className={styles.dayWishes}>
<div className={styles.dayWishesTitle}>Jours de présence</div>
<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 className={styles.dayWishCommentWrapper}>
<label htmlFor="day-choice-comment">Commentaires</label>
<textarea id="day-choice-comment" ref={commentRef} />
</div>
<div className={styles.dayWishesButtonWrapper}>
<button type="submit" onClick={onChoiceSubmit}>
Enregistrer
</button>
</div>
</div>
)
}

View File

@@ -1,3 +1,10 @@
import { shallowEqual, useSelector } from "react-redux"
import { useCallback } from "react"
import { selectUserJwtToken } from "../../../store/auth"
import { AppState } from "../../../store"
import { fetchVolunteerDayWishesSet } from "../../../store/volunteerDayWishesSet"
import useAction from "../../../utils/useAction"
const daysUtils = ["Jeudi", "Vendredi", "Samedi", "Dimanche", "Lundi"]
export const daysChoice = daysUtils.map((label) => ({
@@ -5,7 +12,7 @@ export const daysChoice = daysUtils.map((label) => ({
label,
}))
interface selectionChoices {
export interface selectionChoices {
[key: string]: boolean
}
@@ -13,3 +20,26 @@ export const daysChoiceSelectionDefaultState = daysChoice.reduce((state, { id })
state[id] = false
return state
}, <selectionChoices>{})
export const useUserDayWishes = (): [any, any] => {
const save = useAction(fetchVolunteerDayWishesSet)
const jwtToken = useSelector(selectUserJwtToken)
const userWishes = useSelector(
(state: AppState) => state.volunteerDayWishesSet?.entity,
shallowEqual
)
const saveWishes = useCallback(
(days, comment) => {
if (!userWishes) return
save(jwtToken, 0, {
id: userWishes.id,
dayWishes: days,
dayWishesComment: comment,
})
},
[userWishes, save, jwtToken]
)
return [userWishes, saveWishes]
}

View File

@@ -2,6 +2,16 @@
@import "../../../theme/mixins";
.dayWishes {
width: 470px;
}
.dayWishesTitle {
padding: 4px;
font-weight: bold;
text-align: center;
}
.dayWishesList {
@include clear-ul-style;
}
@@ -12,7 +22,7 @@
.dayWishesButton {
margin: 0;
padding: 4px;
padding: 5px 0 4px;
border: 0;
border-radius: 0;
width: 90px;
@@ -26,3 +36,25 @@
background-color: $color-black;
}
}
.dayWishCommentWrapper {
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;
}
}
.dayWishesButtonWrapper {
margin-bottom: 10px;
text-align: center;
}