Team choice is now sorted

This commit is contained in:
memeriau 2022-02-28 22:45:52 +01:00
parent 7c35bb5a5d
commit c5d238c134
7 changed files with 86 additions and 82 deletions

View File

@ -5,6 +5,7 @@
@include inner-content-wrapper();
position: relative;
padding-right: 90px;
}
.daysLine,

View File

@ -5,6 +5,7 @@
@include inner-content-wrapper();
position: relative;
padding-right: 90px;
}
.title {

View File

@ -5,7 +5,7 @@
@include inner-content-wrapper();
position: relative;
padding-right: 130px;
padding-right: 90px;
}
.title {

View File

@ -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&apos;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&apos;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>

View File

@ -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;

View File

@ -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]
)
}

View File

@ -28,6 +28,7 @@
background-color: $color-white;
border-radius: 15px;
border: $border-large;
width: 100%;
@include desktop {
padding: 20px;