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(); @include inner-content-wrapper();
position: relative; position: relative;
padding-right: 90px;
} }
.daysLine, .daysLine,

View File

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

View File

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

View File

@ -16,27 +16,23 @@ type Props = {
const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => { const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => {
const teams = useSelector(selectTeamList) const teams = useSelector(selectTeamList)
const { addToSelection, toggleToSelection, isInSelection } = useSelection() const { selection, setSelection, toggleToSelection, isInSelection } = useSelection()
const commentRef = useRef<HTMLTextAreaElement | null>(null) const commentRef = useRef<HTMLTextAreaElement | null>(null)
const [userWishes, saveWishes] = useUserTeamWishes() const [userWishes, saveWishes] = useUserTeamWishes()
useEffect(() => { useEffect(() => {
if (!userWishes) return if (!userWishes) return
addToSelection(...get(userWishes, "teamWishes", [])) setSelection(...get(userWishes, "teamWishes", []))
set(commentRef, "current.value", get(userWishes, "teamWishesComment", "")) set(commentRef, "current.value", get(userWishes, "teamWishesComment", ""))
}, [userWishes, addToSelection]) }, [userWishes, setSelection])
const onTeamClick = useCallback((id) => toggleToSelection(id), [toggleToSelection]) const onTeamClick = useCallback((id) => toggleToSelection(id), [toggleToSelection])
const onSubmit = useCallback(() => { const onSubmit = useCallback(() => {
const teamWishesComment = get(commentRef, "current.value", "") const teamWishesComment = get(commentRef, "current.value", "")
const teamWishes = teams saveWishes({ teamWishes: selection, teamWishesComment })
.map((team) => team && team.id)
.filter((id) => id && isInSelection(id))
console.log("saveWishes")
saveWishes({ teamWishes, teamWishesComment })
if (afterSubmit) afterSubmit() if (afterSubmit) afterSubmit()
}, [teams, isInSelection, saveWishes, afterSubmit]) }, [selection, saveWishes, afterSubmit])
return ( return (
<div className={styles.root}> <div className={styles.root}>
@ -45,18 +41,34 @@ const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => {
<p>Sélectionne la ou les équipes que tu aimerais rejoindre.</p> <p>Sélectionne la ou les équipes que tu aimerais rejoindre.</p>
<p> <p>
Pour plus d&apos;informations sur les équipes,{" "} Pour plus d&apos;informations sur les équipes,{" "}
<a href="/teams" target="_blank"> <a href="/equipes" target="_blank">
clique ici clique ici
</a> </a>
. .
</p> </p>
</div> </div>
<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}> <ul className={styles.teamList}>
{teams.map((team: any) => ( {teams.map((team: any) => (
<li <li
key={team.id} key={team.id}
className={classnames( className={classnames(
styles.teamLine, styles.teamItem,
isInSelection(team.id) && styles.active isInSelection(team.id) && styles.active
)} )}
> >
@ -70,9 +82,7 @@ const TeamWishesForm: FC<Props> = ({ afterSubmit }): JSX.Element | null => {
</li> </li>
))} ))}
</ul> </ul>
<div className={styles.commentWrapper}> </div>
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
<textarea id="day-choice-comment" ref={commentRef} />
</div> </div>
<div className={styles.buttonWrapper}> <div className={styles.buttonWrapper}>
<FormButton onClick={onSubmit}>Enregistrer</FormButton> <FormButton onClick={onSubmit}>Enregistrer</FormButton>

View File

@ -2,7 +2,7 @@
@import "../../../theme/mixins"; @import "../../../theme/mixins";
.root { .root {
width: 470px; width: 680px;
} }
.title { .title {
@ -20,38 +20,43 @@
} }
} }
.inputWrapper { .formArea {
margin: 10px 0; display: flex;
margin-bottom: 10px;
}
label { .leftCol {
display: inline-block; flex: 0 0 280px;
width: 170px; margin-right: 20px;
}
input {
width: 300px;
border: 1px solid $color-grey-medium;
outline: 0;
} }
.choiceList {
margin: 5px 0 15px;
padding: 0 0 0 30px;
} }
.teamList { .teamList {
@include clear-ul-style; @include clear-ul-style;
display: flex;
flex-wrap: wrap;
flex-direction: row;
} }
.teamLine { .teamItem {
flex: 0 0 50%;
position: relative; position: relative;
margin: 4px 0; box-sizing: border-box;
background-color: $color-grey-lighter; padding: 2px;
} }
.teamButton { .teamButton {
display: block; display: block;
padding: 4px 6px; padding: 4px 6px;
background: none;
color: $color-grey-medium; color: $color-grey-medium;
border-radius: 0; border-radius: 0;
width: 100%; width: 100%;
text-align: left; text-align: left;
background-color: $color-grey-lighter;
.active & { .active & {
background-color: $color-black; background-color: $color-black;

View File

@ -2,50 +2,39 @@ import { useCallback, useMemo, useReducer } from "react"
type valueType = string | number type valueType = string | number
type selectionType = {
[key: string]: boolean
}
type State = { 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 { interface selectionHook {
addToSelection: (...values: valueType[]) => void selection: valueType[]
setSelection: (...values: valueType[]) => void
toggleToSelection: (value: valueType) => void toggleToSelection: (value: valueType) => void
isInSelection: (value: valueType) => boolean isInSelection: (value: valueType) => boolean
} }
const initialState: State = { const initialState: State = {
selection: {}, selection: [],
} }
const buildIndex = (value: valueType) => `item_${value}`
const reducer = (state: State, action: Action): State => { const reducer = (state: State, action: Action): State => {
switch (action.type) { switch (action.type) {
case "add": { case "set": {
const values = action.payload const values = action.payload
return { return { selection: values }
selection: values.reduce(
(acc: selectionType, value: valueType) => ({
...acc,
[buildIndex(value)]: true,
}),
state.selection
),
}
} }
case "toggle": { case "toggle": {
const value = action.payload 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 { return {
selection: { selection: [...state.selection],
...state.selection,
[index]: !state.selection[index],
},
} }
} }
default: default:
@ -56,9 +45,9 @@ const reducer = (state: State, action: Action): State => {
const useSelection = (): selectionHook => { const useSelection = (): selectionHook => {
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState)
const addToSelection = useCallback( const setSelection = useCallback(
(...values: valueType[]) => { (...values: valueType[]) => {
dispatch({ type: "add", payload: values }) dispatch({ type: "set", payload: values })
}, },
[dispatch] [dispatch]
) )
@ -71,16 +60,13 @@ const useSelection = (): selectionHook => {
) )
const isInSelection = useCallback( const isInSelection = useCallback(
(value: valueType) => { (value: valueType) => !!state.selection.find((item) => item === value),
const index = buildIndex(value)
return state.selection[index]
},
[state.selection] [state.selection]
) )
return useMemo( return useMemo(
() => ({ addToSelection, toggleToSelection, isInSelection }), () => ({ selection: state.selection, setSelection, toggleToSelection, isInSelection }),
[addToSelection, toggleToSelection, isInSelection] [state.selection, setSelection, toggleToSelection, isInSelection]
) )
} }

View File

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