mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-09-11 22:06:29 +02:00
days wishes components
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
|
@@ -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]
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user