mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-09-11 13:56:29 +02:00
add component to display day wishes
This commit is contained in:
@@ -1,76 +1,30 @@
|
||||
import { FC, memo, useCallback, useEffect, useRef, useState } from "react"
|
||||
import classnames from "classnames"
|
||||
import { FC, memo } from "react"
|
||||
import get from "lodash/get"
|
||||
import set from "lodash/set"
|
||||
import styles from "./styles.module.scss"
|
||||
import {
|
||||
daysChoice,
|
||||
daysChoiceSelectionDefaultState,
|
||||
selectionChoices,
|
||||
useUserDayWishes,
|
||||
} from "./days.utils"
|
||||
import { getDayLabel, 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
|
||||
console.log("userWishes", userWishes)
|
||||
const newSelection = get(userWishes, "dayWishes", []).reduce(
|
||||
(acc: selectionChoices, day: string) => ({
|
||||
...acc,
|
||||
[day]: true,
|
||||
}),
|
||||
daysChoice
|
||||
)
|
||||
setSelection(newSelection)
|
||||
set(commentRef, "current.value", get(userWishes, "dayWishesComment", ""))
|
||||
}, [setSelection, commentRef, userWishes])
|
||||
|
||||
const onChoiceClick = useCallback(
|
||||
(id) => {
|
||||
setSelection({
|
||||
...selection,
|
||||
[id]: !selection[id],
|
||||
})
|
||||
},
|
||||
[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])
|
||||
const [userWishes] = useUserDayWishes()
|
||||
const dayWishesString = get(userWishes, "dayWishes", []).map(getDayLabel).join(", ")
|
||||
const comment = get(userWishes, "dayWishesComment", "")
|
||||
|
||||
return (
|
||||
<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 className={styles.daysLine}>
|
||||
<span className={styles.dayLineTitle}>Mes jours de présence :</span>
|
||||
{dayWishesString && <span>{dayWishesString}</span>}
|
||||
{!dayWishesString && <span>Non renseignés</span>}
|
||||
</div>
|
||||
<div className={styles.dayWishesButtonWrapper}>
|
||||
<button type="submit" onClick={onChoiceSubmit}>
|
||||
Enregistrer
|
||||
</button>
|
||||
{comment && (
|
||||
<div className={styles.commentLine}>
|
||||
<span className={styles.commentLineTitle}>Mon commentaire :</span>
|
||||
<span className={styles.commentLineText}>
|
||||
{get(userWishes, "dayWishesComment", "")}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.editButton}>
|
||||
<button type="button">Modifier</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@@ -2,59 +2,39 @@
|
||||
@import "../../../theme/mixins";
|
||||
|
||||
.dayWishes {
|
||||
width: 470px;
|
||||
@include inner-content-wrapper();
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dayWishesTitle {
|
||||
padding: 4px;
|
||||
.daysLine,
|
||||
.commentLine {
|
||||
span {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.dayLineTitle {
|
||||
padding-right: 5px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dayWishesList {
|
||||
@include clear-ul-style;
|
||||
.dayLineEmpty {
|
||||
color: $color-red;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.dayWishesItem {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
.commentLineTitle {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.dayWishesButton {
|
||||
margin: 0;
|
||||
padding: 5px 0 4px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
width: 90px;
|
||||
text-align: center;
|
||||
color: $color-grey-dark;
|
||||
background-color: $color-grey-light;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: $color-yellow;
|
||||
background-color: $color-black;
|
||||
}
|
||||
.commentLineText {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.dayWishCommentWrapper {
|
||||
margin: 6px 0;
|
||||
.editButton {
|
||||
@include vertical-center();
|
||||
|
||||
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;
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
}
|
||||
|
@@ -0,0 +1,78 @@
|
||||
import { FC, memo, 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 {
|
||||
daysChoice,
|
||||
daysChoiceSelectionDefaultState,
|
||||
selectionChoices,
|
||||
useUserDayWishes,
|
||||
} from "../days.utils"
|
||||
|
||||
const DayWishesForm: 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)
|
||||
set(commentRef, "current.value", get(userWishes, "dayWishesComment", ""))
|
||||
}, [setSelection, commentRef, userWishes])
|
||||
|
||||
const onChoiceClick = useCallback(
|
||||
(id) => {
|
||||
setSelection({
|
||||
...selection,
|
||||
[id]: !selection[id],
|
||||
})
|
||||
},
|
||||
[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 (
|
||||
<div className={styles.dayWishesForm}>
|
||||
<div className={styles.dayWishesTitle}>Mes 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">Un commentaire, une précision ?</label>
|
||||
<textarea id="day-choice-comment" ref={commentRef} />
|
||||
</div>
|
||||
<div className={styles.dayWishesButtonWrapper}>
|
||||
<button type="submit" onClick={onChoiceSubmit}>
|
||||
Enregistrer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(DayWishesForm)
|
60
src/components/VolunteerBoard/DayWishesForm/styles.module.scss
Executable file
60
src/components/VolunteerBoard/DayWishesForm/styles.module.scss
Executable file
@@ -0,0 +1,60 @@
|
||||
@import "../../../theme/variables";
|
||||
@import "../../../theme/mixins";
|
||||
|
||||
.dayWishesForm {
|
||||
width: 470px;
|
||||
}
|
||||
|
||||
.dayWishesTitle {
|
||||
padding: 4px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dayWishesList {
|
||||
@include clear-ul-style;
|
||||
}
|
||||
|
||||
.dayWishesItem {
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.dayWishesButton {
|
||||
margin: 0;
|
||||
padding: 5px 0 4px;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
width: 90px;
|
||||
text-align: center;
|
||||
color: $color-grey-dark;
|
||||
background-color: $color-grey-light;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: $color-yellow;
|
||||
background-color: $color-black;
|
||||
}
|
||||
}
|
||||
|
||||
.dayWishCommentWrapper {
|
||||
margin: 6px 0;
|
||||
|
||||
label {
|
||||
display: block;
|
||||
padding: 6px 0 2px 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;
|
||||
}
|
@@ -1,9 +1,9 @@
|
||||
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"
|
||||
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"]
|
||||
|
||||
@@ -43,3 +43,8 @@ export const useUserDayWishes = (): [any, any] => {
|
||||
|
||||
return [userWishes, saveWishes]
|
||||
}
|
||||
|
||||
export const getDayLabel = (id: string): string => {
|
||||
const matchingDay = daysChoice.find((day) => day.id === id)
|
||||
return matchingDay ? matchingDay.label : ""
|
||||
}
|
Reference in New Issue
Block a user