mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-08 08:34:20 +02:00
Team choice is now sorted
This commit is contained in:
parent
7c35bb5a5d
commit
c5d238c134
@ -5,6 +5,7 @@
|
||||
@include inner-content-wrapper();
|
||||
|
||||
position: relative;
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.daysLine,
|
||||
|
@ -5,6 +5,7 @@
|
||||
@include inner-content-wrapper();
|
||||
|
||||
position: relative;
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -5,7 +5,7 @@
|
||||
@include inner-content-wrapper();
|
||||
|
||||
position: relative;
|
||||
padding-right: 130px;
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.title {
|
||||
|
@ -16,27 +16,23 @@ type Props = {
|
||||
|
||||
const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => {
|
||||
const teams = useSelector(selectTeamList)
|
||||
const { addToSelection, toggleToSelection, isInSelection } = useSelection()
|
||||
const { selection, setSelection, toggleToSelection, isInSelection } = useSelection()
|
||||
const commentRef = useRef<HTMLTextAreaElement | null>(null)
|
||||
const [userWishes, saveWishes] = useUserTeamWishes()
|
||||
|
||||
useEffect(() => {
|
||||
if (!userWishes) return
|
||||
addToSelection(...get(userWishes, "teamWishes", []))
|
||||
setSelection(...get(userWishes, "teamWishes", []))
|
||||
set(commentRef, "current.value", get(userWishes, "teamWishesComment", ""))
|
||||
}, [userWishes, addToSelection])
|
||||
}, [userWishes, setSelection])
|
||||
|
||||
const onTeamClick = useCallback((id) => toggleToSelection(id), [toggleToSelection])
|
||||
|
||||
const onSubmit = useCallback(() => {
|
||||
const teamWishesComment = get(commentRef, "current.value", "")
|
||||
const teamWishes = teams
|
||||
.map((team) => team && team.id)
|
||||
.filter((id) => id && isInSelection(id))
|
||||
console.log("saveWishes")
|
||||
saveWishes({ teamWishes, teamWishesComment })
|
||||
saveWishes({ teamWishes: selection, teamWishesComment })
|
||||
if (afterSubmit) afterSubmit()
|
||||
}, [teams, isInSelection, saveWishes, afterSubmit])
|
||||
}, [selection, saveWishes, afterSubmit])
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
@ -45,34 +41,48 @@ const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => {
|
||||
<p>Sélectionne la ou les équipes que tu aimerais rejoindre.</p>
|
||||
<p>
|
||||
Pour plus d'informations sur les équipes,{" "}
|
||||
<a href="/teams" target="_blank">
|
||||
<a href="/equipes" target="_blank">
|
||||
clique ici
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
<ul className={styles.teamList}>
|
||||
{teams.map((team: any) => (
|
||||
<li
|
||||
key={team.id}
|
||||
className={classnames(
|
||||
styles.teamLine,
|
||||
isInSelection(team.id) && styles.active
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onTeamClick(team.id)}
|
||||
className={styles.teamButton}
|
||||
>
|
||||
{team.name}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className={styles.commentWrapper}>
|
||||
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
|
||||
<textarea id="day-choice-comment" ref={commentRef} />
|
||||
<div className={styles.formArea}>
|
||||
<div className={styles.leftCol}>
|
||||
<div>Mes choix dans l'ordre :</div>
|
||||
<ol className={styles.choiceList}>
|
||||
{selection.map((item) => {
|
||||
const team = teams.find((t: any) => t.id === item)
|
||||
if (!team) return null
|
||||
return <li>{team.name}</li>
|
||||
})}
|
||||
</ol>
|
||||
<div className={styles.commentWrapper}>
|
||||
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
|
||||
<textarea id="day-choice-comment" ref={commentRef} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<ul className={styles.teamList}>
|
||||
{teams.map((team: any) => (
|
||||
<li
|
||||
key={team.id}
|
||||
className={classnames(
|
||||
styles.teamItem,
|
||||
isInSelection(team.id) && styles.active
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => onTeamClick(team.id)}
|
||||
className={styles.teamButton}
|
||||
>
|
||||
{team.name}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.buttonWrapper}>
|
||||
<FormButton onClick={onSubmit}>Enregistrer</FormButton>
|
||||
|
@ -2,7 +2,7 @@
|
||||
@import "../../../theme/mixins";
|
||||
|
||||
.root {
|
||||
width: 470px;
|
||||
width: 680px;
|
||||
}
|
||||
|
||||
.title {
|
||||
@ -20,38 +20,43 @@
|
||||
}
|
||||
}
|
||||
|
||||
.inputWrapper {
|
||||
margin: 10px 0;
|
||||
.formArea {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
width: 170px;
|
||||
}
|
||||
input {
|
||||
width: 300px;
|
||||
border: 1px solid $color-grey-medium;
|
||||
outline: 0;
|
||||
}
|
||||
.leftCol {
|
||||
flex: 0 0 280px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.choiceList {
|
||||
margin: 5px 0 15px;
|
||||
padding: 0 0 0 30px;
|
||||
}
|
||||
|
||||
.teamList {
|
||||
@include clear-ul-style;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.teamLine {
|
||||
.teamItem {
|
||||
flex: 0 0 50%;
|
||||
position: relative;
|
||||
margin: 4px 0;
|
||||
background-color: $color-grey-lighter;
|
||||
box-sizing: border-box;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.teamButton {
|
||||
display: block;
|
||||
padding: 4px 6px;
|
||||
background: none;
|
||||
color: $color-grey-medium;
|
||||
border-radius: 0;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background-color: $color-grey-lighter;
|
||||
|
||||
.active & {
|
||||
background-color: $color-black;
|
||||
|
@ -2,50 +2,39 @@ import { useCallback, useMemo, useReducer } from "react"
|
||||
|
||||
type valueType = string | number
|
||||
|
||||
type selectionType = {
|
||||
[key: string]: boolean
|
||||
}
|
||||
|
||||
type State = {
|
||||
selection: selectionType
|
||||
selection: valueType[]
|
||||
}
|
||||
|
||||
type Action = { type: "add"; payload: valueType[] } | { type: "toggle"; payload: valueType }
|
||||
type Action = { type: "set"; payload: valueType[] } | { type: "toggle"; payload: valueType }
|
||||
|
||||
interface selectionHook {
|
||||
addToSelection: (...values: valueType[]) => void
|
||||
selection: valueType[]
|
||||
setSelection: (...values: valueType[]) => void
|
||||
toggleToSelection: (value: valueType) => void
|
||||
isInSelection: (value: valueType) => boolean
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
selection: {},
|
||||
selection: [],
|
||||
}
|
||||
|
||||
const buildIndex = (value: valueType) => `item_${value}`
|
||||
|
||||
const reducer = (state: State, action: Action): State => {
|
||||
switch (action.type) {
|
||||
case "add": {
|
||||
case "set": {
|
||||
const values = action.payload
|
||||
return {
|
||||
selection: values.reduce(
|
||||
(acc: selectionType, value: valueType) => ({
|
||||
...acc,
|
||||
[buildIndex(value)]: true,
|
||||
}),
|
||||
state.selection
|
||||
),
|
||||
}
|
||||
return { selection: values }
|
||||
}
|
||||
case "toggle": {
|
||||
const value = action.payload
|
||||
const index = buildIndex(value)
|
||||
const index = state.selection.findIndex((item) => item === value)
|
||||
if (index !== -1) {
|
||||
state.selection.splice(index, 1)
|
||||
} else {
|
||||
state.selection.push(value)
|
||||
}
|
||||
return {
|
||||
selection: {
|
||||
...state.selection,
|
||||
[index]: !state.selection[index],
|
||||
},
|
||||
selection: [...state.selection],
|
||||
}
|
||||
}
|
||||
default:
|
||||
@ -56,9 +45,9 @@ const reducer = (state: State, action: Action): State => {
|
||||
const useSelection = (): selectionHook => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState)
|
||||
|
||||
const addToSelection = useCallback(
|
||||
const setSelection = useCallback(
|
||||
(...values: valueType[]) => {
|
||||
dispatch({ type: "add", payload: values })
|
||||
dispatch({ type: "set", payload: values })
|
||||
},
|
||||
[dispatch]
|
||||
)
|
||||
@ -71,16 +60,13 @@ const useSelection = (): selectionHook => {
|
||||
)
|
||||
|
||||
const isInSelection = useCallback(
|
||||
(value: valueType) => {
|
||||
const index = buildIndex(value)
|
||||
return state.selection[index]
|
||||
},
|
||||
(value: valueType) => !!state.selection.find((item) => item === value),
|
||||
[state.selection]
|
||||
)
|
||||
|
||||
return useMemo(
|
||||
() => ({ addToSelection, toggleToSelection, isInSelection }),
|
||||
[addToSelection, toggleToSelection, isInSelection]
|
||||
() => ({ selection: state.selection, setSelection, toggleToSelection, isInSelection }),
|
||||
[state.selection, setSelection, toggleToSelection, isInSelection]
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
background-color: $color-white;
|
||||
border-radius: 15px;
|
||||
border: $border-large;
|
||||
width: 100%;
|
||||
|
||||
@include desktop {
|
||||
padding: 20px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user