mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-09 17:14:21 +02:00
Team choice is now sorted
This commit is contained in:
parent
7c35bb5a5d
commit
c5d238c134
@ -5,6 +5,7 @@
|
|||||||
@include inner-content-wrapper();
|
@include inner-content-wrapper();
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding-right: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.daysLine,
|
.daysLine,
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
@include inner-content-wrapper();
|
@include inner-content-wrapper();
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
padding-right: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
@include inner-content-wrapper();
|
@include inner-content-wrapper();
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-right: 130px;
|
padding-right: 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
@ -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,34 +41,48 @@ 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'informations sur les équipes,{" "}
|
Pour plus d'informations sur les équipes,{" "}
|
||||||
<a href="/teams" target="_blank">
|
<a href="/equipes" target="_blank">
|
||||||
clique ici
|
clique ici
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<ul className={styles.teamList}>
|
<div className={styles.formArea}>
|
||||||
{teams.map((team: any) => (
|
<div className={styles.leftCol}>
|
||||||
<li
|
<div>Mes choix dans l'ordre :</div>
|
||||||
key={team.id}
|
<ol className={styles.choiceList}>
|
||||||
className={classnames(
|
{selection.map((item) => {
|
||||||
styles.teamLine,
|
const team = teams.find((t: any) => t.id === item)
|
||||||
isInSelection(team.id) && styles.active
|
if (!team) return null
|
||||||
)}
|
return <li>{team.name}</li>
|
||||||
>
|
})}
|
||||||
<button
|
</ol>
|
||||||
type="button"
|
<div className={styles.commentWrapper}>
|
||||||
onClick={() => onTeamClick(team.id)}
|
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
|
||||||
className={styles.teamButton}
|
<textarea id="day-choice-comment" ref={commentRef} />
|
||||||
>
|
</div>
|
||||||
{team.name}
|
</div>
|
||||||
</button>
|
<div>
|
||||||
</li>
|
<ul className={styles.teamList}>
|
||||||
))}
|
{teams.map((team: any) => (
|
||||||
</ul>
|
<li
|
||||||
<div className={styles.commentWrapper}>
|
key={team.id}
|
||||||
<label htmlFor="day-choice-comment">Un commentaire, une précision ?</label>
|
className={classnames(
|
||||||
<textarea id="day-choice-comment" ref={commentRef} />
|
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>
|
||||||
<div className={styles.buttonWrapper}>
|
<div className={styles.buttonWrapper}>
|
||||||
<FormButton onClick={onSubmit}>Enregistrer</FormButton>
|
<FormButton onClick={onSubmit}>Enregistrer</FormButton>
|
||||||
|
@ -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;
|
.choiceList {
|
||||||
border: 1px solid $color-grey-medium;
|
margin: 5px 0 15px;
|
||||||
outline: 0;
|
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;
|
||||||
|
@ -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]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user