Update node

This commit is contained in:
pikiou 2022-09-03 02:59:27 +02:00
parent b0862ab6d0
commit bd7dc7578e
30 changed files with 4490 additions and 12085 deletions

View File

@ -150,7 +150,7 @@
"@types/loadable__component": "^5.13.4",
"@types/loadable__server": "^5.12.6",
"@types/loadable__webpack-plugin": "^5.7.3",
"@types/mini-css-extract-plugin": "^2.0.1",
"@types/mini-css-extract-plugin": "^2.2.0",
"@types/morgan": "^1.9.3",
"@types/react-dom": "^17.0.8",
"@types/react-helmet": "^6.1.1",
@ -192,7 +192,7 @@
"imagemin-svgo": "^9.0.0",
"jest": "^27.0.6",
"lint-staged": "^11.0.0",
"mini-css-extract-plugin": "^2.1.0",
"mini-css-extract-plugin": "2.2.0",
"nodemon": "^2.0.9",
"npm-run-all": "^4.1.5",
"postcss": "^8.3.5",

View File

@ -50,6 +50,7 @@ const App = ({ route, location }: Route): JSX.Element => {
{/* Child routes won't render without this */}
{renderRoutes(route.routes)}
<ToastContainer />
<script>var browser = browser || chrome</script>
</div>
)
}

View File

@ -7,7 +7,7 @@ import { Volunteer } from "../../services/volunteers"
import styles from "./styles.module.scss"
import { toastError } from "../../store/utils"
interface Props {
interface Props extends JSX.IntrinsicAttributes {
volunteer: Volunteer
saveVolunteer: (newVolunteer: Partial<Volunteer>) => void
addBefore?: () => void

View File

@ -19,9 +19,9 @@ export function AskDayWishes(asks: JSX.Element[], id: number): void {
}, [dispatch, id, jwtToken, volunteerAsks?.hiddenAsks])
const [userWishes] = useUserDayWishes()
const participation = get(userWishes, "active", "inconnu")
const newSelection = get(userWishes, "dayWishes", [])
const comment = get(userWishes, "dayWishesComment", "")
const participation = get(userWishes, "active", "inconnu") as string
const newSelection = get(userWishes, "dayWishes", []) as string[]
const comment = get(userWishes, "dayWishesComment", "") as string
const needToShow = participation === "inconnu" || (newSelection.length === 0 && !comment)
addAsk(

View File

@ -1,39 +0,0 @@
/**
* @jest-environment jsdom
*/
import { ReactNode } from "react"
import { render, screen } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import ErrorBoundary from "../index"
describe("<ErrorBoundary />", () => {
const tree = (children?: ReactNode) =>
render(
<MemoryRouter>
<ErrorBoundary>{children}</ErrorBoundary>
</MemoryRouter>
).container.firstChild
it("renders nothing if no children", () => {
expect(tree()).toMatchSnapshot()
})
it("renders children if no error", () => {
expect(
tree(
<div>
<h1>I am PeL</h1>
</div>
)
).toMatchSnapshot()
})
it("renders error view if an error occurs", () => {
console.error = jest.fn()
tree(<div>{new Error()}</div>)
expect(screen.getByTestId("error-view")).toBeInTheDocument()
})
})

View File

@ -1,11 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<ErrorBoundary /> renders children if no error 1`] = `
<div>
<h1>
I am PeL
</h1>
</div>
`;
exports[`<ErrorBoundary /> renders nothing if no children 1`] = `null`;

View File

@ -1,7 +1,7 @@
import { ReactNode, PureComponent } from "react"
interface Props {
children?: ReactNode
children: ReactNode | undefined
}
interface State {
error: Error | null

View File

@ -1,4 +1,5 @@
import React, { memo, useCallback } from "react"
import type {} from "redux-thunk/extend-redux"
import { AppDispatch } from "../../store"
import { fetchVolunteerForgot } from "../../store/volunteerForgot"
import styles from "./styles.module.scss"

View File

@ -1,5 +1,6 @@
import { memo, useEffect, useState } from "react"
import { useSelector, shallowEqual } from "react-redux"
import type {} from "redux-thunk/extend-redux"
import { toast } from "react-toastify"
import _ from "lodash"
import classnames from "classnames"

View File

@ -7,7 +7,10 @@ import { selectTeamList } from "../../store/teamList"
import styles from "./styles.module.scss"
import { useTeamAssign } from "./teamAssign.utils"
import TeamMembers from "../TeamMembers/TeamMembers"
import { Volunteer } from "../../services/volunteers"
type NamedWishes = { id: number; name: string }
type VolunteerWithTeamWishesNames = Omit<Volunteer, "teamWishes"> & { teamWishes: NamedWishes[] }
const selectTeamsWithVolunteersCandidates = createSelector(
selectVolunteerListAlphaSorted,
selectTeamList,
@ -15,7 +18,9 @@ const selectTeamsWithVolunteersCandidates = createSelector(
teams.map(({ id, name }: any) => {
const volunteersSelection = volunteers
.filter((volunteer) => volunteer.teamWishes.includes(id))
.map((volunteer) => ({
.map(
(volunteer) =>
({
...volunteer,
teamWishes: volunteer.teamWishes.map((wishId) => {
const matchingTeam = teams.find((team: any) => wishId === team?.id)
@ -24,7 +29,8 @@ const selectTeamsWithVolunteersCandidates = createSelector(
name: matchingTeam?.name,
}
}),
}))
} as VolunteerWithTeamWishesNames)
)
return {
id,
name,
@ -56,7 +62,7 @@ const DaysDisplay: FC<PropsDaysDisplay> = ({ dayWishes }): JSX.Element => (
)
type TeamWithCandidatesVolunteerProps = {
volunteer: any
volunteer: VolunteerWithTeamWishesNames
teamId: number
}
@ -68,8 +74,8 @@ const TeamWithCandidatesVolunteer: FC<TeamWithCandidatesVolunteerProps> = ({
const [, saveTeam] = useTeamAssign()
const onTeamSelected = useCallback(
(selectedVolunteer, selectedTeamId) => {
saveTeam(selectedVolunteer, selectedTeamId)
(selectedVolunteerId: number, selectedTeamId: number) => {
saveTeam(selectedVolunteerId, selectedTeamId)
},
[saveTeam]
)
@ -86,7 +92,7 @@ const TeamWithCandidatesVolunteer: FC<TeamWithCandidatesVolunteerProps> = ({
<button
key={teamWish.id}
type="button"
onClick={() => onTeamSelected({ id, team }, teamWish.id)}
onClick={() => onTeamSelected(id, teamWish.id)}
className={classnames(
styles.teamWishButton,
current && styles.teamCurrent,

View File

@ -5,8 +5,11 @@ import { AppState } from "../../store"
import useAction from "../../utils/useAction"
import { fetchVolunteerTeamAssignSet } from "../../store/volunteerTeamAssignSet"
import { refreshVolunteerList } from "../../store/volunteerList"
import { VolunteerTeamAssign } from "../../services/volunteers"
export const useTeamAssign = (): [any, any] => {
type SetFunction = (id: VolunteerTeamAssign["id"], team: VolunteerTeamAssign["team"]) => void
export const useTeamAssign = (): [VolunteerTeamAssign | undefined, SetFunction] => {
const save = useAction(fetchVolunteerTeamAssignSet)
const refreshVolunteers = useAction(refreshVolunteerList)
const jwtToken = useSelector(selectUserJwtToken)
@ -15,11 +18,11 @@ export const useTeamAssign = (): [any, any] => {
shallowEqual
)
const saveWishes = useCallback(
async (volunteer, teamId) => {
const saveWishes: SetFunction = useCallback(
async (id, team) => {
await save(jwtToken, 0, {
volunteer: volunteer.id,
team: volunteer.team === teamId ? 0 : teamId,
id,
team,
})
refreshVolunteers(jwtToken)
},

View File

@ -7,7 +7,7 @@ import styles from "./styles.module.scss"
import {
daysChoice,
daysChoiceSelectionDefaultState,
selectionChoices,
SelectionChoices,
useUserDayWishes,
} from "../daysWishes.utils"
import FormButton from "../../Form/FormButton/FormButton"
@ -36,12 +36,13 @@ const DayWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
useEffect(() => {
if (!userWishes) return
const participation = get(userWishes, "active", "inconnu")
const newSelection = get(userWishes, "dayWishes", []).reduce(
(acc: selectionChoices, day: string) => ({
const dayWishes = get(userWishes, "dayWishes", []) as string[]
const newSelection = dayWishes.reduce(
(acc: SelectionChoices, day: string) => ({
...acc,
[day]: true,
}),
daysChoice
{} as SelectionChoices
)
setParticipation(participation)
setSelection(newSelection)
@ -49,7 +50,7 @@ const DayWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
}, [setParticipation, setSelection, commentRef, userWishes])
const onChoiceClick = useCallback(
(id) => {
(id: string) => {
setSelection({
...selection,
[id]: !selection[id],

View File

@ -9,8 +9,8 @@ import { useUserDayWishes } from "../daysWishes.utils"
const Meals: FC = (): JSX.Element | null => {
const [userMeals] = useUserMeals()
const [userWishes] = useUserDayWishes()
const meals = get(userMeals, "meals", [])
const dayWishesString = get(userWishes, "dayWishes", [])
const meals = get(userMeals, "meals", []) as string[]
const dayWishesString = get(userWishes, "dayWishes", []) as string[]
// const execDisplayModal = useAction(displayModal)
// const onEdit = useCallback(() => execDisplayModal(MODAL_IDS.MEALS), [execDisplayModal])
const mealChoices = mealDays.map((meal, i: number) =>

View File

@ -21,7 +21,7 @@ const MealsForm: FC<Props> = ({ children, afterSubmit }): JSX.Element => {
const [userMeals, saveMeals] = useUserMeals()
const [userWishes] = useUserDayWishes()
const meals = get(userMeals, "meals", [])
const dayWishesString = get(userWishes, "dayWishes", [])
const dayWishesString = get(userWishes, "dayWishes", []) as string[]
useEffect(() => {
setSaturdayLunchMeal(meals[0] || "")

View File

@ -23,24 +23,19 @@ const ParticipationDetailsForm: FC<Props> = ({ children, afterSubmit }): JSX.Ele
const onSubmit = useCallback(() => {
const tshirtSize = get(sizeRef, "current.value", "")
const food = get(dietRef, "current.value", "")
saveParticipationDetails({
tshirtSize,
tshirtCount: tshirtCountState,
adult: adultState,
food,
})
saveParticipationDetails(tshirtSize, tshirtCountState, adultState, food)
if (afterSubmit) afterSubmit()
}, [tshirtCountState, adultState, saveParticipationDetails, afterSubmit])
const onTshirtCountChange = useCallback(
(value) => {
(value: number) => {
setTshirtCount(value)
},
[setTshirtCount]
)
const onAdultChange = useCallback(
(value) => {
(value: number) => {
setAdult(value)
},
[setAdult]

View File

@ -28,11 +28,11 @@ const TeamWishesForm: FC<Props> = ({ children, afterSubmit }): JSX.Element | nul
set(commentRef, "current.value", get(userWishes, "teamWishesComment", ""))
}, [userWishes, setSelection])
const onTeamClick = useCallback((id) => toggleToSelection(id), [toggleToSelection])
const onTeamClick = useCallback((id: number) => toggleToSelection(id), [toggleToSelection])
const onSubmit = useCallback(() => {
const teamWishesComment = get(commentRef, "current.value", "")
saveWishes({ teamWishes: selection, teamWishesComment })
saveWishes(selection as number[], teamWishesComment)
if (afterSubmit) afterSubmit()
}, [selection, saveWishes, afterSubmit])

View File

@ -4,6 +4,7 @@ import { selectUserJwtToken } from "../../store/auth"
import { AppState } from "../../store"
import { fetchVolunteerDayWishesSet } from "../../store/volunteerDayWishesSet"
import useAction from "../../utils/useAction"
import { VolunteerDayWishes } from "../../services/volunteers"
const daysWishesUtils = ["Jeudi", "Vendredi", "Samedi", "Dimanche", "Lundi"]
@ -12,16 +13,22 @@ export const daysChoice = daysWishesUtils.map((label) => ({
label,
}))
export interface selectionChoices {
export interface SelectionChoices {
[key: string]: boolean
}
export const daysChoiceSelectionDefaultState = daysChoice.reduce((state, { id }) => {
state[id] = false
return state
}, <selectionChoices>{})
}, <SelectionChoices>{})
export const useUserDayWishes = (): [any, any] => {
type SetFunction = (
active: VolunteerDayWishes["active"],
dayWishes: VolunteerDayWishes["dayWishes"],
dayWishesComment: VolunteerDayWishes["dayWishesComment"]
) => void
export const useUserDayWishes = (): [VolunteerDayWishes | undefined, SetFunction] => {
const save = useAction(fetchVolunteerDayWishesSet)
const jwtToken = useSelector(selectUserJwtToken)
const userWishes = useSelector(
@ -29,14 +36,14 @@ export const useUserDayWishes = (): [any, any] => {
shallowEqual
)
const saveWishes = useCallback(
(active, days, comment) => {
const saveWishes: SetFunction = useCallback(
(active, dayWishes, dayWishesComment) => {
if (!userWishes) return
save(jwtToken, 0, {
id: userWishes.id,
active,
dayWishes: days,
dayWishesComment: comment,
dayWishes,
dayWishesComment,
})
},
[userWishes, save, jwtToken]

View File

@ -21,7 +21,7 @@ export const useUserHosting = (): [VolunteerHosting | undefined, SetFunction] =>
shallowEqual
)
const saveWishes = useCallback(
const saveWishes: SetFunction = useCallback(
(needsHosting, canHostCount, distanceToFestival, hostingComment) => {
if (!userWishes) return
save(jwtToken, 0, {

View File

@ -54,7 +54,7 @@ export const useUserMeals = (): [VolunteerMeals | undefined, SetFunction] => {
shallowEqual
)
const saveWishes = useCallback(
const saveWishes: SetFunction = useCallback(
(meals) => {
if (!userWishes) return
save(jwtToken, 0, {

View File

@ -4,6 +4,7 @@ import useAction from "../../utils/useAction"
import { selectUserJwtToken } from "../../store/auth"
import { AppState } from "../../store"
import { fetchVolunteerParticipationDetailsSet } from "../../store/volunteerParticipationDetailsSet"
import { VolunteerParticipationDetails } from "../../services/volunteers"
export const tshirtSizes = [
"XXS",
@ -25,7 +26,17 @@ export const tshirtSizes = [
export const foodDefaultValue = "Aucune"
export const useUserParticipationDetails = (): [any, any] => {
type SetFunction = (
tshirtSize: VolunteerParticipationDetails["tshirtSize"],
tshirtCount: VolunteerParticipationDetails["tshirtCount"],
adult: VolunteerParticipationDetails["adult"],
food: VolunteerParticipationDetails["food"]
) => void
export const useUserParticipationDetails = (): [
VolunteerParticipationDetails | undefined,
SetFunction
] => {
const save = useAction(fetchVolunteerParticipationDetailsSet)
const jwtToken = useSelector(selectUserJwtToken)
const userParticipationDetails = useSelector(
@ -33,8 +44,8 @@ export const useUserParticipationDetails = (): [any, any] => {
shallowEqual
)
const saveParticipationDetails = useCallback(
({ tshirtSize, tshirtCount, adult, food }) => {
const saveParticipationDetails: SetFunction = useCallback(
(tshirtSize, tshirtCount, adult, food) => {
if (!userParticipationDetails) return
save(jwtToken, 0, {
id: userParticipationDetails.id,

View File

@ -20,7 +20,7 @@ export const useUserPersonalInfo = (): [VolunteerPersonalInfo | undefined, SetFu
shallowEqual
)
const saveWishes = useCallback(
const saveWishes: SetFunction = useCallback(
(firstname, lastname, photo) => {
if (!userWishes) return
save(jwtToken, 0, {

View File

@ -6,7 +6,12 @@ import { AppState } from "../../store"
import { fetchVolunteerTeamWishesSet } from "../../store/volunteerTeamWishesSet"
import { VolunteerTeamWishes } from "../../services/volunteers"
export const useUserTeamWishes = (): [VolunteerTeamWishes | undefined, any] => {
type SetFunction = (
teamWishes: VolunteerTeamWishes["teamWishes"],
teamWishesComment: VolunteerTeamWishes["teamWishesComment"]
) => void
export const useUserTeamWishes = (): [VolunteerTeamWishes | undefined, SetFunction] => {
const save = useAction(fetchVolunteerTeamWishesSet)
const jwtToken = useSelector(selectUserJwtToken)
const userTeamWishes = useSelector(
@ -14,8 +19,8 @@ export const useUserTeamWishes = (): [VolunteerTeamWishes | undefined, any] => {
shallowEqual
)
const saveTeamWishes = useCallback(
({ teamWishes, teamWishesComment }) => {
const saveTeamWishes: SetFunction = useCallback(
(teamWishes, teamWishesComment) => {
if (!userTeamWishes) return
save(jwtToken, 0, {
id: userTeamWishes.id,

View File

@ -2,7 +2,7 @@ export default {
HOST: "localhost",
PORT: 3000,
API_URL: "http://localhost:3000",
GOOGLE_SHEET_ID: "1pMMKcYx6NXLOqNn6pLHJTPMTOLRYZmSNg2QQcAu7-Pw",
GOOGLE_SHEET_ID: "1p8TDSNlgKC7sm1a_wX44NrkpWEH3-Zey1O2ZjYfPsn4",
APP: {
htmlAttributes: { lang: "en" },
title: "Force Orange",

View File

@ -375,7 +375,7 @@ export class Sheet<
return null
}
// Authentication
const doc = new GoogleSpreadsheet("1pMMKcYx6NXLOqNn6pLHJTPMTOLRYZmSNg2QQcAu7-Pw")
const doc = new GoogleSpreadsheet("1p8TDSNlgKC7sm1a_wX44NrkpWEH3-Zey1O2ZjYfPsn4")
await doc.useServiceAccountAuth(JSON.parse(creds))
await doc.loadInfo()
return doc.sheetsByTitle[this.sheetName]

View File

@ -491,9 +491,9 @@ export const volunteerTeamAssignSet = expressAccessor.set(async (list, body, _id
}
const teamAssign = body[1] as VolunteerTeamAssign
const volunteer: Volunteer | undefined = list.find((v) => v.id === teamAssign.volunteer)
const volunteer: Volunteer | undefined = list.find((v) => v.id === teamAssign.id)
if (!volunteer) {
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${teamAssign.volunteer}`)
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${teamAssign.id}`)
}
const newVolunteer: Volunteer = cloneDeep(volunteer)
newVolunteer.team = teamAssign.team

View File

@ -227,7 +227,6 @@ export interface VolunteerPersonalInfo {
export interface VolunteerTeamAssign {
id: Volunteer["id"]
volunteer: number
team: Volunteer["team"]
}

View File

@ -64,10 +64,9 @@ export const fetchVolunteerKnowledgeSetIfNeed =
return null
}
export const useVolunteerKnowledge = (): [
VolunteerKnowledge | undefined,
(newVolunteerKnowledge: VolunteerKnowledge) => void
] => {
type SetFunction = (newVolunteerKnowledge: VolunteerKnowledge) => void
export const useVolunteerKnowledge = (): [VolunteerKnowledge | undefined, SetFunction] => {
const save = useAction(fetchVolunteerKnowledgeSet)
const jwtToken = useSelector(selectUserJwtToken)
const volunteerKnowledge = useSelector(
@ -75,8 +74,8 @@ export const useVolunteerKnowledge = (): [
shallowEqual
)
const saveVolunteerKnowledge = useCallback(
(newVolunteerKnowledge: VolunteerKnowledge) => {
const saveVolunteerKnowledge: SetFunction = useCallback(
(newVolunteerKnowledge) => {
save(jwtToken, 0, newVolunteerKnowledge)
},
[save, jwtToken]

View File

@ -2,7 +2,7 @@ import React from "react"
import { useSelector } from "react-redux"
import { isUserConnected } from "../store/auth"
function withUserConnected<T>(Component: React.ComponentType<T>) {
function withUserConnected<T extends JSX.IntrinsicAttributes>(Component: React.ComponentType<T>) {
return (props: T): JSX.Element | null => {
const connected = useSelector(isUserConnected)
return connected ? <Component {...props} /> : null

View File

@ -2,7 +2,7 @@ import React from "react"
import { useSelector } from "react-redux"
import { selectUserRoles } from "../store/auth"
function withUserRole<T>(
function withUserRole<T extends JSX.IntrinsicAttributes>(
requiredRole: string,
Component: React.ComponentType<T>,
doShowMissingRole: true | null = true

16350
yarn.lock

File diff suppressed because it is too large Load Diff