mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-09-10 21:46:27 +02:00
Add Ask Discord
This commit is contained in:
67
src/components/Asks/AskDiscord.tsx
Normal file
67
src/components/Asks/AskDiscord.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useCallback } from "react"
|
||||
import { useSelector } from "react-redux"
|
||||
import { fetchVolunteerAsksSet } from "../../store/volunteerAsksSet"
|
||||
import styles from "./styles.module.scss"
|
||||
import { useAskTools, addAsk } from "./utils"
|
||||
import FormButton from "../Form/FormButton/FormButton"
|
||||
import {
|
||||
fetchVolunteerDiscordIdIfNeed,
|
||||
selectVolunteerDiscordId,
|
||||
} from "../../store/volunteerDiscordId"
|
||||
|
||||
export function AskDiscord(asks: JSX.Element[], id: number): void {
|
||||
const { dispatch, jwtToken, volunteerAsks } = useAskTools()
|
||||
const discordId: number | undefined = useSelector(selectVolunteerDiscordId)
|
||||
|
||||
const onSubmit = useCallback((): void => {
|
||||
dispatch(
|
||||
fetchVolunteerAsksSet(jwtToken, 0, {
|
||||
hiddenAsks: [...(volunteerAsks?.hiddenAsks || []), id],
|
||||
})
|
||||
)
|
||||
}, [dispatch, id, jwtToken, volunteerAsks?.hiddenAsks])
|
||||
|
||||
const needToShow = !discordId
|
||||
|
||||
addAsk(
|
||||
asks,
|
||||
id,
|
||||
volunteerAsks,
|
||||
true,
|
||||
needToShow,
|
||||
<div className={styles.formLine}>
|
||||
<p>
|
||||
Discord nous permet gratuitement et sans pub de s'écrire entre bénévoles via nos
|
||||
navigateurs ou smartphones. Et donc de s'organiser super efficacement !<br />
|
||||
C'est un peu déroutant au début, mais extrêmement pratique car à chaque sujet de
|
||||
discussion correspond un salon différent que tu peux demander à suivre ou ignorer
|
||||
totalement via la gestion des notifications.
|
||||
<br />
|
||||
Pour rejoindre le serveur PeL, voici le lien d'invitation à cliquer :{" "}
|
||||
<a href="https://discord.gg/eXhjKxSBB4" onClick={onSubmit}>
|
||||
https://discord.gg/eXhjKxSBB4
|
||||
</a>{" "}
|
||||
!
|
||||
</p>
|
||||
<p>
|
||||
Prends le temps de le rejoindre maintenant, c'est via cet outil que la plupart des
|
||||
équipes s'organisent !
|
||||
</p>
|
||||
<p>
|
||||
Pour s'y retrouver tellement on est nombreux (plus de 120), il est nécessaire
|
||||
d'avoir son prénom comme alias. Voir même d'avoir ensuite la première lettre de ton
|
||||
nom de famille si un autre bénévole présent sur le serveur a le même prénom. Pour
|
||||
changer ton alias uniquement sur le serveur PeL, il faut faire un clique droit sur
|
||||
l'icône ronde du serveur en haut à gauche, et aller dans “Modifier le profil du
|
||||
serveur”.
|
||||
</p>
|
||||
|
||||
<div className={styles.formButtons}>
|
||||
<FormButton onClick={onSubmit}>Ok, noté</FormButton>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// Fetch server-side data here
|
||||
export const fetchFor = [fetchVolunteerDiscordIdIfNeed]
|
@@ -191,7 +191,7 @@ export function AskPushNotif(asks: JSX.Element[], id: number): void {
|
||||
volunteerAsks,
|
||||
true,
|
||||
needToShow,
|
||||
<div className={styles.formLine} key="line-participation">
|
||||
<div className={styles.formLine}>
|
||||
<label>
|
||||
Acceptes-tu de recevoir une alerte dans ton navigateur quand on en aura
|
||||
d'autres à t'afficher ici ?<br />
|
||||
|
@@ -3,19 +3,21 @@ import React, { memo } from "react"
|
||||
import styles from "./styles.module.scss"
|
||||
import { useAskTools } from "./utils"
|
||||
import { AskWelcome } from "./AskWelcome"
|
||||
import { AskPushNotif } from "./AskPushNotif"
|
||||
import { AskDiscord, fetchFor as fetchForDiscord } from "./AskDiscord"
|
||||
import { AskDayWishes, fetchFor as fetchForDayWishes } from "./AskDayWishes"
|
||||
import { AskTeamWishes, fetchFor as fetchForTeamWishes } from "./AskTeamWishes"
|
||||
import {
|
||||
AskParticipationDetails,
|
||||
fetchFor as fetchForParticipationDetails,
|
||||
} from "./AskParticipationDetails"
|
||||
import { AskPushNotif } from "./AskPushNotif"
|
||||
|
||||
const Asks = (): JSX.Element | null => {
|
||||
const { volunteerAsks } = useAskTools()
|
||||
const asks: JSX.Element[] = []
|
||||
|
||||
AskWelcome(asks, 1)
|
||||
AskDiscord(asks, 3)
|
||||
|
||||
AskDayWishes(asks, 10)
|
||||
AskTeamWishes(asks, 11)
|
||||
@@ -28,7 +30,7 @@ const Asks = (): JSX.Element | null => {
|
||||
<div key="pushNotifs">
|
||||
<div className={styles.notificationsPage}>
|
||||
<div className={styles.notificationsContent}>
|
||||
<div className={styles.formLine} key="line-participation">
|
||||
<div className={styles.formLine}>
|
||||
<label>
|
||||
Tu as fait le tour des dernières infos ou questions importantes,
|
||||
merci ! :)
|
||||
@@ -54,6 +56,7 @@ export default memo(Asks)
|
||||
|
||||
// Fetch server-side data here
|
||||
export const fetchFor = [
|
||||
...fetchForDiscord,
|
||||
...fetchForDayWishes,
|
||||
...fetchForTeamWishes,
|
||||
...fetchForParticipationDetails,
|
||||
|
@@ -34,7 +34,7 @@ export function addAsk(
|
||||
volunteerAsks: VolunteerAsks | undefined,
|
||||
isNarrow: boolean,
|
||||
needToShow: boolean,
|
||||
children: JSX.Element
|
||||
children: JSX.Element | undefined
|
||||
): void {
|
||||
const hidden = volunteerAsks?.hiddenAsks || []
|
||||
if (_.includes(hidden, id) || !_.isEmpty(asks) || !needToShow) {
|
||||
|
@@ -778,7 +778,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
|
||||
{meeting}
|
||||
{helpBefore}
|
||||
{pelMemberQuestion}
|
||||
{pelMember && (
|
||||
{(potentialVolunteer || pelMember) && (
|
||||
<>
|
||||
{nameMobileEmail}
|
||||
{howToContact !== "Aucun" && submitButton}
|
||||
|
@@ -1,53 +0,0 @@
|
||||
import { 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 } from "../../store"
|
||||
import { fetchVolunteerIfNeed } from "../../store/volunteer"
|
||||
import { VolunteerInfo, VolunteerSet } from "../../components"
|
||||
import styles from "./styles.module.scss"
|
||||
|
||||
export type Props = RouteComponentProps<{ id: string }>
|
||||
|
||||
const VolunteerPage = ({ match }: Props): JSX.Element => {
|
||||
const { id: rawId } = match.params
|
||||
const id = +rawId
|
||||
const dispatch = useDispatch()
|
||||
const volunteer = useSelector((state: AppState) => state.volunteer, shallowEqual)
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchVolunteerIfNeed(id))
|
||||
}, [dispatch, id])
|
||||
|
||||
const renderInfo = () => {
|
||||
const volunteerInfo = volunteer
|
||||
|
||||
if (!volunteerInfo || volunteerInfo.readyStatus === "request") return <p>Loading...</p>
|
||||
|
||||
if (volunteerInfo.readyStatus === "failure" || !volunteerInfo.entity)
|
||||
return <p>Oops! Failed to load data.</p>
|
||||
|
||||
return (
|
||||
<div>
|
||||
<VolunteerInfo item={volunteerInfo.entity} />
|
||||
<VolunteerSet dispatch={dispatch} volunteer={volunteerInfo.entity} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.VolunteerPage}>
|
||||
<Helmet title="User Info" />
|
||||
{renderInfo()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface LoadDataArgs {
|
||||
params: { id: number }
|
||||
}
|
||||
|
||||
export const loadData = ({ params }: LoadDataArgs): AppThunk[] => [fetchVolunteerIfNeed(params.id)]
|
||||
|
||||
export default memo(VolunteerPage)
|
@@ -1,15 +0,0 @@
|
||||
import loadable from "@loadable/component"
|
||||
|
||||
import { Loading, ErrorBoundary } from "../../components"
|
||||
import { Props, loadData } from "./VolunteerPage"
|
||||
|
||||
const VolunteerPage = loadable(() => import("./VolunteerPage"), {
|
||||
fallback: <Loading />,
|
||||
})
|
||||
|
||||
export default (props: Props): JSX.Element => (
|
||||
<ErrorBoundary>
|
||||
<VolunteerPage {...props} />
|
||||
</ErrorBoundary>
|
||||
)
|
||||
export { loadData }
|
@@ -1,3 +0,0 @@
|
||||
.VolunteerPage {
|
||||
padding: 0 15px;
|
||||
}
|
@@ -8,7 +8,6 @@ import AsyncTeams, { loadData as loadTeamsData } from "../pages/Teams"
|
||||
import AsyncBoard, { loadData as loadBoardData } from "../pages/Board"
|
||||
import AsyncVolunteers, { loadData as loadVolunteersData } from "../pages/Volunteers"
|
||||
import AsyncWish, { loadData as loadWishData } from "../pages/Wish"
|
||||
import AsyncVolunteerPage, { loadData as loadVolunteerPageData } from "../pages/VolunteerPage"
|
||||
import Login from "../pages/Login"
|
||||
import Forgot from "../pages/Forgot"
|
||||
import NotFound from "../pages/NotFound"
|
||||
@@ -33,11 +32,6 @@ export default [
|
||||
component: AsyncRegisterPage,
|
||||
loadData: loadRegisterPage,
|
||||
},
|
||||
{
|
||||
path: "/VolunteerPage/:id",
|
||||
component: AsyncVolunteerPage,
|
||||
loadData: loadVolunteerPageData,
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
component: Login,
|
||||
|
@@ -23,9 +23,20 @@ const expressAccessor = new ExpressAccessors<VolunteerWithoutId, Volunteer>(
|
||||
)
|
||||
|
||||
export const volunteerListGet = expressAccessor.listGet()
|
||||
// export const volunteerAdd = expressAccessor.add()
|
||||
export const volunteerSet = expressAccessor.set()
|
||||
|
||||
export const volunteerDiscordId = expressAccessor.get(async (list, body, id) => {
|
||||
const requestedId = +body[0] || id
|
||||
if (requestedId !== id && requestedId !== 0) {
|
||||
throw Error(`On ne peut acceder qu'à ses propres envies de jours`)
|
||||
}
|
||||
const volunteer = list.find((v) => v.id === requestedId)
|
||||
if (!volunteer) {
|
||||
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
|
||||
}
|
||||
return _.pick(volunteer, "id", "discordId")
|
||||
})
|
||||
|
||||
export const volunteerPartialAdd = expressAccessor.add(async (list, body) => {
|
||||
const params = body[0]
|
||||
const volunteer = getByEmail(list, params.email)
|
||||
|
@@ -22,10 +22,11 @@ import { gameListGet } from "./gsheets/games"
|
||||
import { postulantAdd } from "./gsheets/postulants"
|
||||
import { teamListGet } from "./gsheets/teams"
|
||||
import {
|
||||
volunteerAsksSet,
|
||||
volunteerDayWishesSet,
|
||||
volunteerForgot,
|
||||
volunteerDiscordId,
|
||||
volunteerLogin,
|
||||
volunteerAsksSet,
|
||||
volunteerPartialAdd,
|
||||
volunteerParticipationDetailsSet,
|
||||
volunteerSet,
|
||||
@@ -92,7 +93,7 @@ app.post("/VolunteerForgot", volunteerForgot)
|
||||
app.get("/AnnouncementListGet", secure as RequestHandler, announcementListGet)
|
||||
app.post("/VolunteerSet", secure as RequestHandler, volunteerSet)
|
||||
app.get("/TeamListGet", teamListGet)
|
||||
// UNSAFE app.post("/VolunteerGet", secure as RequestHandler, volunteerGet)
|
||||
app.get("/VolunteerDiscordId", secure as RequestHandler, volunteerDiscordId)
|
||||
app.post("/VolunteerAsksSet", secure as RequestHandler, volunteerAsksSet)
|
||||
app.post(
|
||||
"/VolunteerParticipationDetailsSet",
|
||||
|
@@ -64,7 +64,7 @@ export default class ServiceAccessors<
|
||||
}
|
||||
}
|
||||
|
||||
secureListGet(): (jwt: string) => Promise<{
|
||||
securedListGet(): (jwt: string) => Promise<{
|
||||
data?: Element[]
|
||||
error?: Error
|
||||
}> {
|
||||
@@ -192,6 +192,37 @@ export default class ServiceAccessors<
|
||||
}
|
||||
}
|
||||
|
||||
securedCustomGet<InputElements extends Array<any>>(
|
||||
apiName: string
|
||||
): (
|
||||
jwt: string,
|
||||
...params: InputElements
|
||||
) => Promise<{
|
||||
data?: any
|
||||
error?: Error
|
||||
}> {
|
||||
interface ElementGetResponse {
|
||||
data?: any
|
||||
error?: Error
|
||||
}
|
||||
return async (jwt: string, ...params: InputElements): Promise<ElementGetResponse> => {
|
||||
try {
|
||||
const auth = { headers: { Authorization: `Bearer ${jwt}` } }
|
||||
const fullAxiosConfig = _.defaultsDeep(auth, axiosConfig)
|
||||
const { data } = await axios.get(
|
||||
`${config.API_URL}/${this.elementName}${apiName}`,
|
||||
{ ...fullAxiosConfig, params }
|
||||
)
|
||||
if (data.error) {
|
||||
throw Error(data.error)
|
||||
}
|
||||
return { data }
|
||||
} catch (error) {
|
||||
return { error: error as Error }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
securedCustomPost<InputElements extends Array<any>>(
|
||||
apiName: string
|
||||
): (
|
||||
|
@@ -7,4 +7,4 @@ const serviceAccessors = new ServiceAccessors<AnnouncementWithoutId, Announcemen
|
||||
// export const announcementAdd = serviceAccessors.add()
|
||||
// export const announcementSet = serviceAccessors.set()
|
||||
|
||||
export const announcementListGet = serviceAccessors.secureListGet()
|
||||
export const announcementListGet = serviceAccessors.securedListGet()
|
||||
|
@@ -139,6 +139,11 @@ export interface VolunteerForgot {
|
||||
message: string
|
||||
}
|
||||
|
||||
export interface VolunteerDiscordId {
|
||||
id: Volunteer["id"]
|
||||
discordId: Volunteer["discordId"]
|
||||
}
|
||||
|
||||
export interface VolunteerAsks {
|
||||
id: Volunteer["id"]
|
||||
firstname: Volunteer["firstname"]
|
||||
|
@@ -12,7 +12,7 @@ import {
|
||||
const serviceAccessors = new ServiceAccessors<VolunteerWithoutId, Volunteer>(elementName)
|
||||
|
||||
export const volunteerListGet = serviceAccessors.listGet()
|
||||
export const volunteerGet = serviceAccessors.get()
|
||||
export const volunteerDiscordIdGet = serviceAccessors.securedCustomGet<[number]>("DiscordId")
|
||||
export const volunteerPartialAdd = serviceAccessors.customPost<[Partial<Volunteer>]>("PartialAdd")
|
||||
export const volunteerSet = serviceAccessors.set()
|
||||
|
||||
|
@@ -1,78 +0,0 @@
|
||||
import axios from "axios"
|
||||
|
||||
import mockStore from "../../utils/mockStore"
|
||||
import volunteer, {
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
fetchVolunteer,
|
||||
initialState,
|
||||
} from "../volunteer"
|
||||
import { Volunteer, volunteerExample } from "../../services/volunteers"
|
||||
|
||||
jest.mock("axios")
|
||||
|
||||
const mockData: Volunteer = volunteerExample
|
||||
const { id } = mockData
|
||||
const mockError = "Oops! Something went wrong."
|
||||
|
||||
describe("volunteer reducer", () => {
|
||||
it("should handle initial state correctly", () => {
|
||||
// @ts-expect-error
|
||||
expect(volunteer(undefined, {})).toEqual(initialState)
|
||||
})
|
||||
|
||||
it("should handle requesting correctly", () => {
|
||||
expect(volunteer(undefined, { type: getRequesting.type, payload: id })).toEqual({
|
||||
readyStatus: "request",
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle success correctly", () => {
|
||||
expect(
|
||||
volunteer(undefined, {
|
||||
type: getSuccess.type,
|
||||
payload: mockData,
|
||||
})
|
||||
).toEqual({ readyStatus: "success", entity: mockData })
|
||||
})
|
||||
|
||||
it("should handle failure correctly", () => {
|
||||
expect(
|
||||
volunteer(undefined, {
|
||||
type: getFailure.type,
|
||||
payload: mockError,
|
||||
})
|
||||
).toEqual({ readyStatus: "failure", error: mockError })
|
||||
})
|
||||
})
|
||||
|
||||
describe("volunteer action", () => {
|
||||
it("fetches volunteer data successful", async () => {
|
||||
const { dispatch, getActions } = mockStore()
|
||||
const expectedActions = [
|
||||
{ type: getRequesting.type, payload: undefined },
|
||||
{ type: getSuccess.type, payload: mockData },
|
||||
]
|
||||
|
||||
// @ts-expect-error
|
||||
axios.get.mockResolvedValue({ data: mockData })
|
||||
|
||||
await dispatch(fetchVolunteer(id))
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
|
||||
it("fetches volunteer data failed", async () => {
|
||||
const { dispatch, getActions } = mockStore()
|
||||
const expectedActions = [
|
||||
{ type: getRequesting.type },
|
||||
{ type: getFailure.type, payload: mockError },
|
||||
]
|
||||
|
||||
// @ts-expect-error
|
||||
axios.get.mockRejectedValue({ message: mockError })
|
||||
|
||||
await dispatch(fetchVolunteer(id))
|
||||
expect(getActions()).toEqual(expectedActions)
|
||||
})
|
||||
})
|
@@ -35,9 +35,9 @@ export const auth = createSlice({
|
||||
|
||||
export const { setCurrentUser, logoutUser } = auth.actions
|
||||
|
||||
export const selectAuthData = (state: AppState): AuthState => state.auth
|
||||
const selectAuthData = (state: AppState): AuthState => state.auth
|
||||
|
||||
export const selectRouter = (state: AppState): AppState["router"] => state.router
|
||||
const selectRouter = (state: AppState): AppState["router"] => state.router
|
||||
|
||||
export const selectUserJwtToken = createSelector(selectAuthData, (authData) => authData.jwt)
|
||||
|
||||
|
@@ -7,8 +7,8 @@ import announcementList from "./announcementList"
|
||||
import postulantAdd from "./postulantAdd"
|
||||
import teamList from "./teamList"
|
||||
import ui from "./ui"
|
||||
import volunteer from "./volunteer"
|
||||
import volunteerAdd from "./volunteerPartialAdd"
|
||||
import volunteerDiscordId from "./volunteerDiscordId"
|
||||
import volunteerList from "./volunteerList"
|
||||
import volunteerSet from "./volunteerSet"
|
||||
import volunteerLogin from "./volunteerLogin"
|
||||
@@ -29,8 +29,8 @@ export default (history: History) => ({
|
||||
postulantAdd,
|
||||
teamList,
|
||||
ui,
|
||||
volunteer,
|
||||
volunteerAdd,
|
||||
volunteerDiscordId,
|
||||
volunteerList,
|
||||
volunteerSet,
|
||||
volunteerLogin,
|
||||
|
@@ -1,53 +0,0 @@
|
||||
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||
import { Volunteer } from "../services/volunteers"
|
||||
import { AppThunk, AppState } from "."
|
||||
import { volunteerGet } from "../services/volunteersAccessors"
|
||||
|
||||
type StateVolunteer = { entity?: Volunteer } & StateRequest
|
||||
|
||||
export const initialState: StateVolunteer = {
|
||||
readyStatus: "idle",
|
||||
}
|
||||
|
||||
const volunteer = createSlice({
|
||||
name: "volunteer",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (_) => ({
|
||||
readyStatus: "request",
|
||||
}),
|
||||
getSuccess: (_, { payload }: PayloadAction<Volunteer>) => ({
|
||||
readyStatus: "success",
|
||||
entity: payload,
|
||||
}),
|
||||
getFailure: (_, { payload }: PayloadAction<string>) => ({
|
||||
readyStatus: "failure",
|
||||
error: payload,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
export default volunteer.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = volunteer.actions
|
||||
|
||||
export const fetchVolunteer = elementFetch(
|
||||
volunteerGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) => toastError(`Erreur lors du chargement d'un bénévole: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchVolunteer = (state: AppState, id: number) =>
|
||||
state.volunteer.readyStatus !== "success" ||
|
||||
(state.volunteer.entity && state.volunteer.entity.id !== id)
|
||||
|
||||
export const fetchVolunteerIfNeed =
|
||||
(id: number): AppThunk =>
|
||||
(dispatch, getState) => {
|
||||
if (shouldFetchVolunteer(getState(), id)) return dispatch(fetchVolunteer(id))
|
||||
|
||||
return null
|
||||
}
|
65
src/store/volunteerDiscordId.ts
Normal file
65
src/store/volunteerDiscordId.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { PayloadAction, createSlice, createSelector } from "@reduxjs/toolkit"
|
||||
|
||||
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||
import { VolunteerDiscordId } from "../services/volunteers"
|
||||
import { AppThunk, AppState } from "."
|
||||
import { volunteerDiscordIdGet } from "../services/volunteersAccessors"
|
||||
|
||||
type StateVolunteerDiscordId = { entity?: VolunteerDiscordId } & StateRequest
|
||||
|
||||
export const initialState: StateVolunteerDiscordId = {
|
||||
readyStatus: "idle",
|
||||
}
|
||||
|
||||
const volunteerDiscordId = createSlice({
|
||||
name: "volunteerDiscordId",
|
||||
initialState,
|
||||
reducers: {
|
||||
getRequesting: (_) => ({
|
||||
readyStatus: "request",
|
||||
}),
|
||||
getSuccess: (_, { payload }: PayloadAction<VolunteerDiscordId>) => ({
|
||||
readyStatus: "success",
|
||||
entity: payload,
|
||||
}),
|
||||
getFailure: (_, { payload }: PayloadAction<string>) => ({
|
||||
readyStatus: "failure",
|
||||
error: payload,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
export default volunteerDiscordId.reducer
|
||||
export const { getRequesting, getSuccess, getFailure } = volunteerDiscordId.actions
|
||||
|
||||
export const fetchVolunteerDiscordId = elementFetch(
|
||||
volunteerDiscordIdGet,
|
||||
getRequesting,
|
||||
getSuccess,
|
||||
getFailure,
|
||||
(error: Error) =>
|
||||
toastError(`Erreur lors du chargement du discordId d'un bénévole: ${error.message}`)
|
||||
)
|
||||
|
||||
const shouldFetchVolunteerDiscordId = (state: AppState, id: number) =>
|
||||
state.volunteerDiscordId.readyStatus !== "success" ||
|
||||
(state.volunteerDiscordId.entity && state.volunteerDiscordId.entity.id !== id)
|
||||
|
||||
export const fetchVolunteerDiscordIdIfNeed =
|
||||
(id = 0): AppThunk =>
|
||||
(dispatch, getState) => {
|
||||
let jwt = ""
|
||||
|
||||
if (!id) {
|
||||
;({ jwt, id } = getState().auth)
|
||||
}
|
||||
if (shouldFetchVolunteerDiscordId(getState(), id))
|
||||
return dispatch(fetchVolunteerDiscordId(jwt, id))
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export const selectVolunteerDiscordId = createSelector(
|
||||
(state: AppState) => state,
|
||||
(state): number | undefined => state.volunteerDiscordId?.entity?.id
|
||||
)
|
Reference in New Issue
Block a user