mirror of
https://github.com/Paris-est-Ludique/intranet.git
synced 2025-06-10 01:24:20 +02:00
Add volunteerParticipationDetailsSet to store
This commit is contained in:
parent
1e302e6c31
commit
f890ab505b
@ -11,6 +11,7 @@ import {
|
|||||||
VolunteerTeamWishes,
|
VolunteerTeamWishes,
|
||||||
translationVolunteer,
|
translationVolunteer,
|
||||||
VolunteerDayWishes,
|
VolunteerDayWishes,
|
||||||
|
VolunteerParticipationDetails,
|
||||||
} from "../../services/volunteers"
|
} from "../../services/volunteers"
|
||||||
import { canonicalEmail } from "../../utils/standardization"
|
import { canonicalEmail } from "../../utils/standardization"
|
||||||
import { getJwt } from "../secure"
|
import { getJwt } from "../secure"
|
||||||
@ -87,6 +88,32 @@ export const volunteerForgot = expressAccessor.set(async (list, bodyArray) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function generatePassword(): string {
|
||||||
|
const s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
|
return Array(16)
|
||||||
|
.join()
|
||||||
|
.split(",")
|
||||||
|
.map(() => s.charAt(Math.floor(Math.random() * s.length)))
|
||||||
|
.join("")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendForgetEmail(email: string, password: string): Promise<void> {
|
||||||
|
const apiKey = process.env.SENDGRID_API_KEY || ""
|
||||||
|
if (__DEV__ || apiKey === "") {
|
||||||
|
console.error(`Fake sending forget email to ${email} with password ${password}`)
|
||||||
|
} else {
|
||||||
|
sgMail.setApiKey(apiKey)
|
||||||
|
const msg = {
|
||||||
|
to: email,
|
||||||
|
from: "contact@parisestludique.fr",
|
||||||
|
subject: "Nouveau mot de passe pour le site de Paris est Ludique",
|
||||||
|
text: `Voici le nouveau mot de passe : ${password}\nL'ancien fonctionne encore, si tu t'en rappelles.`,
|
||||||
|
html: `Voici le nouveau mot de passe : <strong>${password}</strong><br />L'ancien fonctionne encore, si tu t'en rappelles.`,
|
||||||
|
}
|
||||||
|
await sgMail.send(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const volunteerNotifsSet = expressAccessor.set(async (list, body, id) => {
|
export const volunteerNotifsSet = expressAccessor.set(async (list, body, id) => {
|
||||||
const requestedId = +body[0] || id
|
const requestedId = +body[0] || id
|
||||||
if (requestedId !== id && requestedId !== 0) {
|
if (requestedId !== id && requestedId !== 0) {
|
||||||
@ -172,34 +199,42 @@ export const volunteerDayWishesSet = expressAccessor.set(async (list, body, id)
|
|||||||
} as VolunteerDayWishes,
|
} as VolunteerDayWishes,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
function getByEmail(list: Volunteer[], rawEmail: string): Volunteer | undefined {
|
|
||||||
|
export const volunteerParticipationDetailsSet = expressAccessor.set(async (list, body, id) => {
|
||||||
|
const requestedId = +body[0] || id
|
||||||
|
if (requestedId !== id && requestedId !== 0) {
|
||||||
|
throw Error(`On ne peut acceder qu'à ses propres infos d'age, taille et alimentation`)
|
||||||
|
}
|
||||||
|
const wishes = body[1] as VolunteerParticipationDetails
|
||||||
|
const volunteer = list.find((v) => v.id === requestedId)
|
||||||
|
if (!volunteer) {
|
||||||
|
throw Error(`Il n'y a aucun bénévole avec cet identifiant ${requestedId}`)
|
||||||
|
}
|
||||||
|
const newVolunteer = _.cloneDeep(volunteer)
|
||||||
|
|
||||||
|
if (wishes.age !== undefined) {
|
||||||
|
newVolunteer.age = wishes.age
|
||||||
|
}
|
||||||
|
if (wishes.teeshirtSize !== undefined) {
|
||||||
|
newVolunteer.teeshirtSize = wishes.teeshirtSize
|
||||||
|
}
|
||||||
|
if (wishes.food !== undefined) {
|
||||||
|
newVolunteer.food = wishes.food
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
toDatabase: newVolunteer,
|
||||||
|
toCaller: {
|
||||||
|
id: newVolunteer.id,
|
||||||
|
age: newVolunteer.age,
|
||||||
|
teeshirtSize: newVolunteer.teeshirtSize,
|
||||||
|
food: newVolunteer.food,
|
||||||
|
} as VolunteerParticipationDetails,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function getByEmail<T extends { email: string }>(list: T[], rawEmail: string): T | undefined {
|
||||||
const email = canonicalEmail(rawEmail || "")
|
const email = canonicalEmail(rawEmail || "")
|
||||||
const volunteer = list.find((v) => canonicalEmail(v.email) === email)
|
const volunteer = list.find((v) => canonicalEmail(v.email) === email)
|
||||||
return volunteer
|
return volunteer
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePassword(): string {
|
|
||||||
const s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
|
||||||
return Array(16)
|
|
||||||
.join()
|
|
||||||
.split(",")
|
|
||||||
.map(() => s.charAt(Math.floor(Math.random() * s.length)))
|
|
||||||
.join("")
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendForgetEmail(email: string, password: string): Promise<void> {
|
|
||||||
const apiKey = process.env.SENDGRID_API_KEY || ""
|
|
||||||
if (__DEV__ || apiKey === "") {
|
|
||||||
console.error(`Fake sending forget email to ${email} with password ${password}`)
|
|
||||||
} else {
|
|
||||||
sgMail.setApiKey(apiKey)
|
|
||||||
const msg = {
|
|
||||||
to: email,
|
|
||||||
from: "contact@parisestludique.fr",
|
|
||||||
subject: "Nouveau mot de passe pour le site de Paris est Ludique",
|
|
||||||
text: `Voici le nouveau mot de passe : ${password}\nL'ancien fonctionne encore, si tu t'en rappelles.`,
|
|
||||||
html: `Voici le nouveau mot de passe : <strong>${password}</strong><br />L'ancien fonctionne encore, si tu t'en rappelles.`,
|
|
||||||
}
|
|
||||||
await sgMail.send(msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
volunteerLogin,
|
volunteerLogin,
|
||||||
volunteerForgot,
|
volunteerForgot,
|
||||||
volunteerNotifsSet,
|
volunteerNotifsSet,
|
||||||
|
volunteerParticipationDetailsSet,
|
||||||
volunteerTeamWishesSet,
|
volunteerTeamWishesSet,
|
||||||
volunteerDayWishesSet,
|
volunteerDayWishesSet,
|
||||||
} from "./gsheets/volunteers"
|
} from "./gsheets/volunteers"
|
||||||
@ -77,6 +78,11 @@ app.post("/VolunteerSet", secure as RequestHandler, volunteerSet)
|
|||||||
app.get("/TeamListGet", teamListGet)
|
app.get("/TeamListGet", teamListGet)
|
||||||
// UNSAFE app.post("/VolunteerGet", secure as RequestHandler, volunteerGet)
|
// UNSAFE app.post("/VolunteerGet", secure as RequestHandler, volunteerGet)
|
||||||
app.post("/VolunteerNotifsSet", secure as RequestHandler, volunteerNotifsSet)
|
app.post("/VolunteerNotifsSet", secure as RequestHandler, volunteerNotifsSet)
|
||||||
|
app.post(
|
||||||
|
"/VolunteerParticipationDetailsSet",
|
||||||
|
secure as RequestHandler,
|
||||||
|
volunteerParticipationDetailsSet
|
||||||
|
)
|
||||||
app.post("/VolunteerDayWishesSet", secure as RequestHandler, volunteerDayWishesSet)
|
app.post("/VolunteerDayWishesSet", secure as RequestHandler, volunteerDayWishesSet)
|
||||||
app.post("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
|
app.post("/VolunteerTeamWishesSet", secure as RequestHandler, volunteerTeamWishesSet)
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ export class Volunteer {
|
|||||||
|
|
||||||
photo = ""
|
photo = ""
|
||||||
|
|
||||||
food = ""
|
|
||||||
|
|
||||||
adult = 1
|
adult = 1
|
||||||
|
|
||||||
privileges = 0
|
privileges = 0
|
||||||
@ -25,6 +23,12 @@ export class Volunteer {
|
|||||||
|
|
||||||
dayWishesComment = ""
|
dayWishesComment = ""
|
||||||
|
|
||||||
|
age = 0
|
||||||
|
|
||||||
|
teeshirtSize = ""
|
||||||
|
|
||||||
|
food = ""
|
||||||
|
|
||||||
teamWishes: string[] = []
|
teamWishes: string[] = []
|
||||||
|
|
||||||
teamWishesComment = ""
|
teamWishesComment = ""
|
||||||
@ -49,12 +53,14 @@ export const translationVolunteer: { [k in keyof Volunteer]: string } = {
|
|||||||
email: "mail",
|
email: "mail",
|
||||||
mobile: "telephone",
|
mobile: "telephone",
|
||||||
photo: "photo",
|
photo: "photo",
|
||||||
food: "alimentation",
|
|
||||||
adult: "majeur",
|
adult: "majeur",
|
||||||
privileges: "privilege",
|
privileges: "privilege",
|
||||||
active: "actif",
|
active: "actif",
|
||||||
dayWishes: "enviesJours",
|
dayWishes: "enviesJours",
|
||||||
dayWishesComment: "commentaireEnviesJours",
|
dayWishesComment: "commentaireEnviesJours",
|
||||||
|
age: "age",
|
||||||
|
teeshirtSize: "teeshirt",
|
||||||
|
food: "alimentation",
|
||||||
teamWishes: "enviesEquipe",
|
teamWishes: "enviesEquipe",
|
||||||
teamWishesComment: "commentaireEnviesEquipe",
|
teamWishesComment: "commentaireEnviesEquipe",
|
||||||
hiddenNotifs: "notifsCachees",
|
hiddenNotifs: "notifsCachees",
|
||||||
@ -74,12 +80,14 @@ export const volunteerExample: Volunteer = {
|
|||||||
email: "pakouille.lakouille@yahoo.fr",
|
email: "pakouille.lakouille@yahoo.fr",
|
||||||
mobile: "0675650392",
|
mobile: "0675650392",
|
||||||
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
|
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
|
||||||
food: "Végétarien",
|
|
||||||
adult: 1,
|
adult: 1,
|
||||||
privileges: 0,
|
privileges: 0,
|
||||||
active: "inconnu",
|
active: "inconnu",
|
||||||
dayWishes: [],
|
dayWishes: [],
|
||||||
dayWishesComment: "",
|
dayWishesComment: "",
|
||||||
|
age: 33,
|
||||||
|
teeshirtSize: "FM",
|
||||||
|
food: "Végétarien",
|
||||||
teamWishes: [],
|
teamWishes: [],
|
||||||
teamWishesComment: "",
|
teamWishesComment: "",
|
||||||
hiddenNotifs: [],
|
hiddenNotifs: [],
|
||||||
@ -142,3 +150,14 @@ export interface VolunteerDayWishes {
|
|||||||
}
|
}
|
||||||
export const volunteerDayWishesSet =
|
export const volunteerDayWishesSet =
|
||||||
serviceAccessors.securedCustomPost<[number, Partial<VolunteerDayWishes>]>("DayWishesSet")
|
serviceAccessors.securedCustomPost<[number, Partial<VolunteerDayWishes>]>("DayWishesSet")
|
||||||
|
|
||||||
|
export interface VolunteerParticipationDetails {
|
||||||
|
id: Volunteer["id"]
|
||||||
|
age: Volunteer["age"]
|
||||||
|
teeshirtSize: Volunteer["teeshirtSize"]
|
||||||
|
food: Volunteer["food"]
|
||||||
|
}
|
||||||
|
export const volunteerParticipationDetailsSet =
|
||||||
|
serviceAccessors.securedCustomPost<[number, Partial<VolunteerParticipationDetails>]>(
|
||||||
|
"ParticipationDetailsSet"
|
||||||
|
)
|
||||||
|
@ -13,6 +13,7 @@ import volunteerSet from "./volunteerSet"
|
|||||||
import volunteerLogin from "./volunteerLogin"
|
import volunteerLogin from "./volunteerLogin"
|
||||||
import volunteerForgot from "./volunteerForgot"
|
import volunteerForgot from "./volunteerForgot"
|
||||||
import volunteerNotifsSet from "./volunteerNotifsSet"
|
import volunteerNotifsSet from "./volunteerNotifsSet"
|
||||||
|
import volunteerParticipationDetailsSet from "./volunteerParticipationDetailsSet"
|
||||||
import volunteerDayWishesSet from "./volunteerDayWishesSet"
|
import volunteerDayWishesSet from "./volunteerDayWishesSet"
|
||||||
import volunteerTeamWishesSet from "./volunteerTeamWishesSet"
|
import volunteerTeamWishesSet from "./volunteerTeamWishesSet"
|
||||||
import wishAdd from "./wishAdd"
|
import wishAdd from "./wishAdd"
|
||||||
@ -33,6 +34,7 @@ export default (history: History) => ({
|
|||||||
volunteerLogin,
|
volunteerLogin,
|
||||||
volunteerForgot,
|
volunteerForgot,
|
||||||
volunteerNotifsSet,
|
volunteerNotifsSet,
|
||||||
|
volunteerParticipationDetailsSet,
|
||||||
volunteerDayWishesSet,
|
volunteerDayWishesSet,
|
||||||
volunteerTeamWishesSet,
|
volunteerTeamWishesSet,
|
||||||
wishAdd,
|
wishAdd,
|
||||||
|
65
src/store/volunteerParticipationDetailsSet.ts
Normal file
65
src/store/volunteerParticipationDetailsSet.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
|
||||||
|
|
||||||
|
import { StateRequest, toastError, elementFetch } from "./utils"
|
||||||
|
import {
|
||||||
|
VolunteerParticipationDetails,
|
||||||
|
volunteerParticipationDetailsSet,
|
||||||
|
} from "../services/volunteers"
|
||||||
|
import { AppThunk, AppState } from "."
|
||||||
|
|
||||||
|
type StateVolunteerParticipationDetailsSet = {
|
||||||
|
entity?: VolunteerParticipationDetails
|
||||||
|
} & StateRequest
|
||||||
|
|
||||||
|
export const initialState: StateVolunteerParticipationDetailsSet = {
|
||||||
|
readyStatus: "idle",
|
||||||
|
}
|
||||||
|
|
||||||
|
const volunteerParticipationDetailsSetSlice = createSlice({
|
||||||
|
name: "volunteerParticipationDetailsSet",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
getRequesting: (_) => ({
|
||||||
|
readyStatus: "request",
|
||||||
|
}),
|
||||||
|
getSuccess: (_, { payload }: PayloadAction<VolunteerParticipationDetails>) => ({
|
||||||
|
readyStatus: "success",
|
||||||
|
entity: payload,
|
||||||
|
}),
|
||||||
|
getFailure: (_, { payload }: PayloadAction<string>) => ({
|
||||||
|
readyStatus: "failure",
|
||||||
|
error: payload,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default volunteerParticipationDetailsSetSlice.reducer
|
||||||
|
export const { getRequesting, getSuccess, getFailure } =
|
||||||
|
volunteerParticipationDetailsSetSlice.actions
|
||||||
|
|
||||||
|
export const fetchVolunteerParticipationDetailsSet = elementFetch(
|
||||||
|
volunteerParticipationDetailsSet,
|
||||||
|
getRequesting,
|
||||||
|
getSuccess,
|
||||||
|
getFailure,
|
||||||
|
(error: Error) => toastError(`Erreur lors du chargement des notifications: ${error.message}`)
|
||||||
|
)
|
||||||
|
|
||||||
|
const shouldFetchVolunteerParticipationDetailsSet = (state: AppState, id: number) =>
|
||||||
|
state.volunteerParticipationDetailsSet?.readyStatus !== "success" ||
|
||||||
|
(state.volunteerParticipationDetailsSet?.entity &&
|
||||||
|
state.volunteerParticipationDetailsSet?.entity?.id !== id)
|
||||||
|
|
||||||
|
export const fetchVolunteerParticipationDetailsSetIfNeed =
|
||||||
|
(id = 0, wishes: Partial<VolunteerParticipationDetails> = {}): AppThunk =>
|
||||||
|
(dispatch, getState) => {
|
||||||
|
let jwt = ""
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
;({ id, jwt } = getState().auth)
|
||||||
|
}
|
||||||
|
if (shouldFetchVolunteerParticipationDetailsSet(getState(), id))
|
||||||
|
return dispatch(fetchVolunteerParticipationDetailsSet(jwt, id, wishes))
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user