better display of team candidates

This commit is contained in:
memeriau 2022-05-02 23:44:30 +02:00
parent 10d7a2d6ec
commit 724706d308
7 changed files with 143 additions and 62 deletions

View File

@ -3,18 +3,17 @@ import ContentTitle from "../ui/Content/ContentTitle"
import withUserConnected from "../../utils/withUserConnected"
import { fetchTeamListIfNeed } from "../../store/teamList"
import { fetchVolunteerListIfNeed } from "../../store/volunteerList"
import VolunteersWithTeamWishes from "./VolunteersWithTeamWishes"
import TeamsWithCandidates from "./TeamsWithCandidates"
import withUserRole from "../../utils/withUserRole"
import ROLES from "../../utils/roles.constants"
const TeamAssignment: FC = (): JSX.Element => (
<>
<ContentTitle title="Choix par équipes" />
<ContentTitle title="Gestion des équipes" />
<TeamsWithCandidates />
<ContentTitle title="Choix des bénévoles" />
<VolunteersWithTeamWishes />
</>
)
export default memo(withUserConnected(TeamAssignment))
export default withUserRole(ROLES.ASSIGNER, memo(withUserConnected(TeamAssignment)))
export const fetchFor = [fetchTeamListIfNeed, fetchVolunteerListIfNeed]

View File

@ -28,7 +28,13 @@ const selectTeamsWithVolunteersCandidates = createSelector(
return {
id,
name,
volunteers: volunteersSelection,
volunteersWithoutTeam: volunteersSelection.filter((volunteer) => !volunteer.team),
volunteersWithCurrentTeam: volunteersSelection.filter(
(volunteer) => volunteer.team === id
),
volunteersWithOtherTeam: volunteersSelection.filter(
(volunteer) => volunteer.team && volunteer.team !== id
),
}
})
)
@ -49,57 +55,93 @@ const DaysDisplay: FC<PropsDaysDisplay> = ({ dayWishes }): JSX.Element => (
</span>
)
type Props = {
type TeamWithCandidatesVolunteerProps = {
volunteer: any
teamId: number
}
const TeamWithCandidates: FC<Props> = ({ teamId }): JSX.Element | null => {
const teams = useSelector(selectTeamsWithVolunteersCandidates)
const currentTeam = teams.find((t) => t.id === teamId)
const TeamWithCandidatesVolunteer: FC<TeamWithCandidatesVolunteerProps> = ({
teamId,
volunteer,
}): JSX.Element => {
const { id, lastname, firstname, teamWishes, dayWishes, team } = volunteer
const [, saveTeam] = useTeamAssign()
const onTeamSelected = useCallback(
(volunteer, selectedTeamId) => {
saveTeam(volunteer, selectedTeamId)
(selectedVolunteer, selectedTeamId) => {
saveTeam(selectedVolunteer, selectedTeamId)
},
[saveTeam]
)
return (
<li key={id}>
<span className={styles.volunteerName}>
{firstname} {lastname} (<DaysDisplay dayWishes={dayWishes} />)
</span>
{teamWishes.map((teamWish: any) => {
const active = teamWish.id === team
const current = teamWish.id === teamId
return (
<button
key={teamWish.id}
type="button"
onClick={() => onTeamSelected({ id, team }, teamWish.id)}
className={classnames(
styles.teamWishButton,
current && styles.teamCurrent,
active && styles.teamActive
)}
>
{teamWish.name}
</button>
)
})}
</li>
)
}
type TeamWithCandidatesProps = {
teamId: number
}
const TeamWithCandidates: FC<TeamWithCandidatesProps> = ({ teamId }): JSX.Element => {
const teams = useSelector(selectTeamsWithVolunteersCandidates)
const currentTeam = teams.find((t) => t.id === teamId)
if (!currentTeam) return <div />
return (
<div>
<div className={styles.teamHeaderName}>Equipe {currentTeam.name}</div>
<TeamMembers teamId={teamId} />
<div>Bénévoles intéressés ({currentTeam.volunteers.length}) :</div>
<div>Bénévoles intéressés :</div>
<ul>
{currentTeam.volunteers.map(
({ id, lastname, firstname, teamWishes, dayWishes, team }) => (
<li key={id}>
<span className={styles.volunteerName}>
{firstname} {lastname} (<DaysDisplay dayWishes={dayWishes} />)
</span>
{teamWishes.map((teamWish) => {
const active = teamWish.id === team
const current = teamWish.id === teamId
return (
<button
key={teamWish.id}
type="button"
onClick={() => onTeamSelected({ id, team }, teamWish.id)}
className={classnames(
styles.teamWishButton,
current && styles.teamCurrent,
active && styles.teamActive
)}
>
{teamWish.name}
</button>
)
})}
</li>
)
)}
{currentTeam.volunteersWithoutTeam.map((volunteer) => (
<TeamWithCandidatesVolunteer
key={volunteer.id}
teamId={teamId}
volunteer={volunteer}
/>
))}
</ul>
<ul>
{currentTeam.volunteersWithCurrentTeam.map((volunteer) => (
<TeamWithCandidatesVolunteer
key={volunteer.id}
teamId={teamId}
volunteer={volunteer}
/>
))}
</ul>
<ul>
{currentTeam.volunteersWithOtherTeam.map((volunteer) => (
<TeamWithCandidatesVolunteer
key={volunteer.id}
teamId={teamId}
volunteer={volunteer}
/>
))}
</ul>
</div>
)

View File

@ -3,8 +3,6 @@ import { useSelector } from "react-redux"
import { selectTeamList } from "../../store/teamList"
import TeamWithCandidates from "./TeamWithCandidates"
import styles from "./styles.module.scss"
import withUserRole from "../../utils/withUserRole"
import ROLES from "../../utils/roles.constants"
const TeamsWithCandidates: FC = (): JSX.Element => {
const teams = useSelector(selectTeamList)
@ -27,4 +25,4 @@ const TeamsWithCandidates: FC = (): JSX.Element => {
)
}
export default withUserRole(ROLES.ASSIGNER, memo(TeamsWithCandidates))
export default memo(TeamsWithCandidates)

View File

@ -4,6 +4,7 @@ import { createSelector } from "@reduxjs/toolkit"
import { selectVolunteerListAlphaSorted } from "../../store/volunteerList"
import { selectTeamList } from "../../store/teamList"
import styles from "./styles.module.scss"
import ContentTitle from "../ui/Content/ContentTitle"
const selectVolunteersWithTeamWishes = createSelector(
selectVolunteerListAlphaSorted,
@ -23,24 +24,52 @@ const selectVolunteersWithTeamWishes = createSelector(
}))
)
const selectVolunteersWithTeam = createSelector(selectVolunteersWithTeamWishes, (volunteers) =>
volunteers.filter((volunteer) => volunteer.teamObject)
)
const selectVolunteersWithoutTeam = createSelector(selectVolunteersWithTeamWishes, (volunteers) =>
volunteers.filter((volunteer) => !volunteer.teamObject)
)
const VolunteersWithTeamWishes: FC = (): JSX.Element => {
const volunteers = useSelector(selectVolunteersWithTeamWishes)
const volunteersWithTeam = useSelector(selectVolunteersWithTeam)
const volunteersWithoutTeam = useSelector(selectVolunteersWithoutTeam)
return (
<div>
<div>Bénévoles ayant choisi des équipes ({volunteers.length}) :</div>
<ul>
{volunteers.map(({ id, lastname, firstname, teamWishes, teamObject }) => (
<li key={id}>
<span className={styles.volunteerName}>
{firstname} {lastname}{" "}
</span>
<span className={styles.teamActive}>{teamObject?.name} </span>
<span>{teamWishes.join(", ")}</span>
</li>
))}
</ul>
</div>
<>
<ContentTitle title="Choix des bénévoles" />
<div>
<div>Bénévoles en attente d'équipe ({volunteersWithoutTeam.length}) :</div>
<ul>
{volunteersWithoutTeam.map(
({ id, lastname, firstname, teamWishes, teamObject }) => (
<li key={id}>
<span className={styles.volunteerName}>
{firstname} {lastname}{" "}
</span>
<span className={styles.teamActive}>{teamObject?.name} </span>
<span>{teamWishes.join(", ")}</span>
</li>
)
)}
</ul>
<div>Bénévoles dans une équipe ({volunteersWithTeam.length}) :</div>
<ul>
{volunteersWithTeam.map(
({ id, lastname, firstname, teamWishes, teamObject }) => (
<li key={id}>
<span className={styles.volunteerName}>
{firstname} {lastname}{" "}
</span>
<span className={styles.teamActive}>{teamObject?.name} </span>
<span>{teamWishes.join(", ")}</span>
</li>
)
)}
</ul>
</div>
</>
)
}

View File

@ -7,7 +7,9 @@ type Props = {
const Page: FC<Props> = ({ children }): JSX.Element => (
<div className={styles.pageWrapper}>
<div className={styles.pageContent}>{children}</div>
{React.Children.map(children, (child) => (
<div className={styles.pageContent}>{child}</div>
))}
</div>
)

View File

@ -6,6 +6,7 @@ import { AppThunk } from "../../store"
import { selectUserJwtToken } from "../../store/auth"
import Page from "../../components/ui/Page/Page"
import { TeamAssignment, fetchForTeamAssignment } from "../../components"
import VolunteersWithTeamWishes from "../../components/TeamAssignment/VolunteersWithTeamWishes"
export type Props = RouteComponentProps
@ -15,9 +16,14 @@ const TeamAssignmentPage: FC<Props> = (): JSX.Element => {
if (jwtToken === undefined) return <p>Loading...</p>
if (jwtToken) {
return (
<Page>
<TeamAssignment />
</Page>
<>
<Page>
<TeamAssignment />
</Page>
<Page>
<VolunteersWithTeamWishes />
</Page>
</>
)
}
return <div>Besoin d'être identifié</div>

View File

@ -16,6 +16,7 @@
display: flex;
justify-content: center;
align-content: center;
width: 100%;
}
@mixin page-wrapper-center {
@ -35,6 +36,10 @@
padding: 20px;
width: $desktopWidth;
}
&::after {
flex-basis: 100%;
}
}
@mixin inner-content-wrapper() {