mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-08 08:34:20 +02:00
Add teamList in store
This commit is contained in:
parent
1011a293d0
commit
d5eeb44d2f
63
src/pages/Teams/Teams.tsx
Normal file
63
src/pages/Teams/Teams.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { FC, useEffect, memo } from "react"
|
||||
import { RouteComponentProps } from "react-router-dom"
|
||||
import { useDispatch, useSelector, shallowEqual } from "react-redux"
|
||||
import { Helmet } from "react-helmet"
|
||||
|
||||
import { AppState, AppThunk, EntitiesRequest } from "../../store"
|
||||
import { Team } from "../../services/teams"
|
||||
import { fetchTeamListIfNeed } from "../../store/teamList"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
export type Props = RouteComponentProps
|
||||
|
||||
function useList(
|
||||
stateToProp: (state: AppState) => EntitiesRequest<Team>,
|
||||
fetchDataIfNeed: () => AppThunk
|
||||
) {
|
||||
const dispatch = useDispatch()
|
||||
const { ids, entities, readyStatus } = useSelector(stateToProp, shallowEqual)
|
||||
|
||||
// Fetch client-side data here
|
||||
useEffect(() => {
|
||||
dispatch(fetchDataIfNeed())
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [dispatch])
|
||||
|
||||
return () => {
|
||||
if (!readyStatus || readyStatus === "idle" || readyStatus === "request")
|
||||
return <p>Loading...</p>
|
||||
|
||||
if (readyStatus === "failure") return <p>Oops, Failed to load!</p>
|
||||
|
||||
return ids.map((id) => {
|
||||
const team = entities[id]
|
||||
return team === undefined ? null : (
|
||||
<div key={id}>
|
||||
<b>{team.name}</b>:{team.description}
|
||||
<br />
|
||||
Avant: {team.before}
|
||||
<br />
|
||||
Pendant: {team.during}
|
||||
<br />
|
||||
Après: {team.after}
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const TeamsPage: FC<Props> = (): JSX.Element => (
|
||||
<div className={styles.teamsPage}>
|
||||
<div className={styles.teamsContent}>
|
||||
<Helmet title="TeamsPage" />
|
||||
{useList((state: AppState) => state.teamList, fetchTeamListIfNeed)()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
// Fetch server-side data here
|
||||
export const loadData = (): AppThunk[] => [fetchTeamListIfNeed()]
|
||||
|
||||
export default memo(TeamsPage)
|
16
src/pages/Teams/index.tsx
Executable file
16
src/pages/Teams/index.tsx
Executable file
@ -0,0 +1,16 @@
|
||||
import loadable from "@loadable/component"
|
||||
|
||||
import { Loading, ErrorBoundary } from "../../components"
|
||||
import { Props, loadData } from "./Teams"
|
||||
|
||||
const Teams = loadable(() => import("./Teams"), {
|
||||
fallback: <Loading />,
|
||||
})
|
||||
|
||||
export default (props: Props): JSX.Element => (
|
||||
<ErrorBoundary>
|
||||
<Teams {...props} />
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
||||
export { loadData }
|
9
src/pages/Teams/styles.module.scss
Executable file
9
src/pages/Teams/styles.module.scss
Executable file
@ -0,0 +1,9 @@
|
||||
@import "../../theme/mixins";
|
||||
|
||||
.teamsPage {
|
||||
@include page-wrapper-center;
|
||||
}
|
||||
|
||||
.teamsContent {
|
||||
@include page-content-wrapper(600px);
|
||||
}
|
@ -3,6 +3,7 @@ import { RouteConfig } from "react-router-config"
|
||||
import App from "../app"
|
||||
import AsyncHome, { loadData as loadHomeData } from "../pages/Home"
|
||||
import AsyncPreRegisterPage, { loadData as loadPreRegisterPage } from "../pages/PreRegister"
|
||||
import AsyncTeams, { loadData as loadTeamsData } from "../pages/Teams"
|
||||
import AsyncWish, { loadData as loadWishData } from "../pages/Wish"
|
||||
import AsyncVolunteerPage, { loadData as loadVolunteerPageData } from "../pages/VolunteerPage"
|
||||
import Login from "../pages/Login"
|
||||
@ -37,6 +38,11 @@ export default [
|
||||
path: "/forgot",
|
||||
component: Forgot,
|
||||
},
|
||||
{
|
||||
path: "/teams",
|
||||
component: AsyncTeams,
|
||||
loadData: loadTeamsData,
|
||||
},
|
||||
{
|
||||
path: "/wish",
|
||||
component: AsyncWish,
|
||||
|
@ -21,10 +21,12 @@ export type ElementWithId<ElementNoId> = { id: number } & ElementNoId
|
||||
export class SheetNames {
|
||||
JavGames = "Jeux JAV"
|
||||
|
||||
Volunteers = "Membres"
|
||||
|
||||
PreVolunteers = "PreMembres"
|
||||
|
||||
Teams = "Equipes"
|
||||
|
||||
Volunteers = "Membres"
|
||||
|
||||
Wishes = "Envies d'aider"
|
||||
}
|
||||
export const sheetNames = new SheetNames()
|
||||
|
10
src/server/gsheets/teams.ts
Normal file
10
src/server/gsheets/teams.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import ExpressAccessors from "./expressAccessors"
|
||||
import { Team, TeamWithoutId, translationTeam } from "../../services/teams"
|
||||
|
||||
const expressAccessor = new ExpressAccessors<TeamWithoutId, Team>(
|
||||
"Teams",
|
||||
new Team(),
|
||||
translationTeam
|
||||
)
|
||||
|
||||
export const teamListGet = expressAccessor.listGet()
|
@ -18,14 +18,15 @@ import ssr from "./ssr"
|
||||
import certbotRouter from "../routes/certbot"
|
||||
import { secure } from "./secure"
|
||||
import { javGameListGet } from "./gsheets/javGames"
|
||||
import { wishListGet, wishAdd } from "./gsheets/wishes"
|
||||
import { preVolunteerAdd, preVolunteerCountGet } from "./gsheets/preVolunteers"
|
||||
import { teamListGet } from "./gsheets/teams"
|
||||
import {
|
||||
volunteerNotifsSet,
|
||||
volunteerSet,
|
||||
volunteerLogin,
|
||||
volunteerForgot,
|
||||
} from "./gsheets/volunteers"
|
||||
import { wishListGet, wishAdd } from "./gsheets/wishes"
|
||||
import config from "../config"
|
||||
import notificationsSubscribe from "./notificationsSubscribe"
|
||||
import checkAccess from "./checkAccess"
|
||||
@ -71,6 +72,7 @@ app.post("/VolunteerForgot", volunteerForgot)
|
||||
|
||||
// Secured APIs
|
||||
app.post("/VolunteerSet", secure as RequestHandler, volunteerSet)
|
||||
app.get("/TeamListGet", teamListGet)
|
||||
// UNSAFE app.post("/VolunteerGet", secure as RequestHandler, volunteerGet)
|
||||
app.post("/VolunteerNotifsSet", secure as RequestHandler, volunteerNotifsSet)
|
||||
|
||||
|
39
src/services/teams.ts
Normal file
39
src/services/teams.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import ServiceAccessors from "./accessors"
|
||||
|
||||
export class Team {
|
||||
id = 0
|
||||
|
||||
name = ""
|
||||
|
||||
min = 0
|
||||
|
||||
max = 0
|
||||
|
||||
description = ""
|
||||
|
||||
before = ""
|
||||
|
||||
during = ""
|
||||
|
||||
after = ""
|
||||
}
|
||||
|
||||
export const translationTeam: { [k in keyof Team]: string } = {
|
||||
id: "id",
|
||||
name: "nom",
|
||||
min: "min",
|
||||
max: "max",
|
||||
description: "description",
|
||||
before: "avant",
|
||||
during: "pendant",
|
||||
after: "après",
|
||||
}
|
||||
|
||||
const elementName = "Team"
|
||||
|
||||
export type TeamWithoutId = Omit<Team, "id">
|
||||
|
||||
const serviceAccessors = new ServiceAccessors<TeamWithoutId, Team>(elementName)
|
||||
|
||||
export const teamListGet = serviceAccessors.listGet()
|
||||
export const teamGet = serviceAccessors.get()
|
@ -2,9 +2,10 @@ import { History } from "history"
|
||||
import { connectRouter } from "connected-react-router"
|
||||
|
||||
import auth from "./auth"
|
||||
import wishAdd from "./wishAdd"
|
||||
import wishList from "./wishList"
|
||||
import javGameList from "./javGameList"
|
||||
import preVolunteerAdd from "./preVolunteerAdd"
|
||||
import preVolunteerCount from "./preVolunteerCount"
|
||||
import teamList from "./teamList"
|
||||
import volunteer from "./volunteer"
|
||||
import volunteerAdd from "./volunteerAdd"
|
||||
import volunteerList from "./volunteerList"
|
||||
@ -12,16 +13,17 @@ import volunteerSet from "./volunteerSet"
|
||||
import volunteerLogin from "./volunteerLogin"
|
||||
import volunteerForgot from "./volunteerForgot"
|
||||
import volunteerNotifsSet from "./volunteerNotifsSet"
|
||||
import preVolunteerAdd from "./preVolunteerAdd"
|
||||
import preVolunteerCount from "./preVolunteerCount"
|
||||
import wishAdd from "./wishAdd"
|
||||
import wishList from "./wishList"
|
||||
|
||||
// Use inferred return type for making correctly Redux types
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export default (history: History) => ({
|
||||
auth,
|
||||
wishAdd,
|
||||
wishList,
|
||||
javGameList,
|
||||
preVolunteerAdd,
|
||||
preVolunteerCount,
|
||||
teamList,
|
||||
volunteer,
|
||||
volunteerAdd,
|
||||
volunteerList,
|
||||
@ -29,8 +31,8 @@ export default (history: History) => ({
|
||||
volunteerLogin,
|
||||
volunteerForgot,
|
||||
volunteerNotifsSet,
|
||||
preVolunteerAdd,
|
||||
preVolunteerCount,
|
||||
wishAdd,
|
||||
wishList,
|
||||
router: connectRouter(history) as any,
|
||||
// Register more reducers...
|
||||
})
|
||||
|
48
src/store/teamList.ts
Normal file
48
src/store/teamList.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, elementListFetch } from "./utils"
|
||||
import { Team, teamListGet } from "../services/teams"
|
||||
import { AppThunk, AppState } from "."
|
||||
|
||||
const teamAdapter = createEntityAdapter<Team>()
|
||||
|
||||
export const initialState = teamAdapter.getInitialState({
|
||||
readyStatus: "idle",
|
||||
} as StateRequest)
|
||||
|
||||
const teamList = createSlice({
|
||||
name: "teamList",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (state) => {
|
||||
state.readyStatus = "request"
|
||||
},
|
||||
getSuccess: (state, { payload }: PayloadAction<Team[]>) => {
|
||||
state.readyStatus = "success"
|
||||
teamAdapter.setAll(state, payload)
|
||||
},
|
||||
getFailure: (state, { payload }: PayloadAction<string>) => {
|
||||
state.readyStatus = "failure"
|
||||
state.error = payload
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default teamList.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = teamList.actions
|
||||
|
||||
export const fetchTeamList = elementListFetch(
|
||||
teamListGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement des équipes: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchTeamList = (state: AppState) => state.teamList.readyStatus !== "success"
|
||||
|
||||
export const fetchTeamListIfNeed = (): AppThunk => (dispatch, getState) => {
|
||||
if (shouldFetchTeamList(getState())) return dispatch(fetchTeamList())
|
||||
|
||||
return null
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user