Rename all french to english

This commit is contained in:
pikiou 2021-12-08 10:46:53 +01:00
parent d63f906206
commit 1844c6acad
66 changed files with 653 additions and 625 deletions

View File

@ -315,13 +315,13 @@ export { SCOPES }
class Test {
id = 5
envies = ""
wishes = ""
dateAjout: Date = new Date(0)
ignore = false
membres: number[] = []
volunteers: number[] = []
equipes: string[] = []
@ -335,10 +335,10 @@ async function testGSheetAPi(): Promise<void> {
const dataset: Test[] = [
{
id: 1,
envies: "Présenter le festival et son organisation à un nouveau bénévol au téléphone",
wishes: "Présenter le festival et son organisation à un nouveau bénévol au téléphone",
dateAjout: new Date("2021-10-18T22:00:00.000Z"),
ignore: true,
membres: [2, 5, 6, 4, 2, 7],
volunteers: [2, 5, 6, 4, 2, 7],
equipes: ["Accueillir les bénévoles"],
datesPossibles: [
new Date("2021-11-18T23:00:00.000Z"),
@ -349,34 +349,34 @@ async function testGSheetAPi(): Promise<void> {
},
{
id: 5,
envies: "Créer de jolies pages webs",
wishes: "Créer de jolies pages webs",
dateAjout: new Date("2021-10-18T22:00:00.000Z"),
ignore: false,
membres: [7],
volunteers: [7],
equipes: ["Site Web Public", "Force Orange"],
datesPossibles: [],
tictactoe: [],
},
{
id: 6,
envies: "Modérer un salon Discord",
wishes: "Modérer un salon Discord",
dateAjout: new Date("2021-10-18T22:00:00.000Z"),
ignore: true,
membres: [],
volunteers: [],
equipes: [],
datesPossibles: [new Date("2024-10-18T22:00:00.000Z")],
tictactoe: [false, false, false, false, true, true, true, true],
},
]
// console.log("Lecture des Membres...")
// const datasetMembresLu = await getList<Membre>("Membres", new Membre())
// if (!datasetMembresLu) {
// console.log("ECHEC de la lecture des membres", datasetMembresLu)
// console.log("Lecture des Volunteers...")
// const datasetVolunteersLu = await getList<Volunteer>("Volunteers", new Volunteer())
// if (!datasetVolunteersLu) {
// console.log("ECHEC de la lecture des volunteers", datasetVolunteersLu)
// return
// }
// console.log("Extraction des membres réussie")
// await fs.writeFile("membres.json", JSON.stringify(datasetMembresLu))
// console.log("Extraction des volunteers réussie")
// await fs.writeFile("volunteers.json", JSON.stringify(datasetVolunteersLu))
console.log("Test d'écriture...")
const resultatEcriture = await setList<Test>("Tests de l'API", dataset)

View File

@ -5,15 +5,15 @@ import { render } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import mockStore from "../../../utils/mockStore"
import JeuJavList from "../index"
import JavGameList from "../index"
describe("<List />", () => {
const renderHelper = (reducer = { readyStatus: "idle" }) => {
const { dispatch, ProviderWithStore } = mockStore({ jeuJavList: reducer })
const { dispatch, ProviderWithStore } = mockStore({ javGameList: reducer })
const { container } = render(
<ProviderWithStore>
<MemoryRouter>
<JeuJavList ids={[5]} />
<JavGameList ids={[5]} />
</MemoryRouter>
</ProviderWithStore>
)

View File

@ -2,7 +2,7 @@
exports[`<List /> renders 1`] = `
<div
class="JeuJavList"
class="JavGameList"
>
<h4>
Jeux JAV

View File

@ -10,10 +10,10 @@ interface Props {
ids: EntityId[]
}
const JeuJavList = ({ ids }: Props) => {
const { entities: jeuxJav } = useSelector((state: AppState) => state.jeuJavList, shallowEqual)
const JavGameList = ({ ids }: Props) => {
const { entities: jeuxJav } = useSelector((state: AppState) => state.javGameList, shallowEqual)
return (
<div className={styles.JeuJavList}>
<div className={styles.JavGameList}>
<h4>Jeux JAV</h4>
<ul>
{ids.map((id) => {
@ -33,4 +33,4 @@ const JeuJavList = ({ ids }: Props) => {
)
}
export default memo(JeuJavList)
export default memo(JavGameList)

View File

@ -1,20 +0,0 @@
import { memo } from "react"
import { Membre } from "../../services/membres"
import styles from "./styles.module.scss"
interface Props {
item: Membre
}
const MembreInfo = ({ item }: Props) => (
<div className={styles.MembreCard}>
<h4>Membre Info</h4>
<ul>
<li>Prénom: {item.firstname}</li>
<li>Nom: {item.lastname}</li>
</ul>
</div>
)
export default memo(MembreInfo)

View File

@ -4,7 +4,7 @@ import { toast } from "react-toastify"
import _ from "lodash"
import styles from "./styles.module.scss"
import { fetchPreMemberAdd } from "../../store/preMemberAdd"
import { fetchPreMemberAdd } from "../../store/preVolunteerAdd"
import { AppDispatch, AppState } from "../../store"
interface Props {
@ -142,7 +142,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
Certains bénévoles sont visiteurs le samedi ou le dimanche pour vivre le
festival de l&apos;intérieur. Les deux jours avant et le jour après le
festival, ceux qui le peuvent viennent préparer et ranger. Bref, chacun
participe à la hauteur de ses envies et disponibilités !
participe à la hauteur de ses wishes et disponibilités !
</p>
<p>
Le samedi soir quand les visiteurs sont partis, nous prolongeons la fête en
@ -228,7 +228,7 @@ const RegisterForm = ({ dispatch }: Props): JSX.Element => {
<textarea
name="message"
id="message"
placeholder="Des petits mots sympas, questions, envies, des infos sur toi, des compétences dont tu aimerais te servir... ou rien de tout ça et nous en discuterons au téléphone :)"
placeholder="Des petits mots sympas, questions, wishes, des infos sur toi, des compétences dont tu aimerais te servir... ou rien de tout ça et nous en discuterons au téléphone :)"
value={comment}
onChange={onCommentChanged}
/>

View File

@ -4,20 +4,20 @@
import { render } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import MembreInfo from "../index"
import VolunteerInfo from "../index"
describe("<MembreInfo />", () => {
describe("<VolunteerInfo />", () => {
it("renders", () => {
const tree = render(
<MemoryRouter>
<MembreInfo
<VolunteerInfo
item={{
id: 1,
firstname: "Aupeix",
lastname: "Amélie",
email: "pakouille.lakouille@yahoo.fr",
mobile: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
food: "Végétarien",
adult: 1,
privileges: 0,

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<MembreInfo /> renders 1`] = `
exports[`<VolunteerInfo /> renders 1`] = `
<div
class="MembreCard"
class="VolunteerCard"
>
<h4>
Membre Info
Volunteer Info
</h4>
<ul>
<li>

View File

@ -0,0 +1,20 @@
import { memo } from "react"
import { Volunteer } from "../../services/volunteers"
import styles from "./styles.module.scss"
interface Props {
item: Volunteer
}
const VolunteerInfo = ({ item }: Props) => (
<div className={styles.VolunteerCard}>
<h4>Volunteer Info</h4>
<ul>
<li>Prénom: {item.firstname}</li>
<li>Nom: {item.lastname}</li>
</ul>
</div>
)
export default memo(VolunteerInfo)

View File

@ -1,4 +1,4 @@
.membre-card {
.volunteer-card {
ul {
padding-left: 17px;
}

View File

@ -4,13 +4,13 @@
import { render } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import MembreList from "../index"
import VolunteerList from "../index"
describe("<MembreList />", () => {
describe("<VolunteerList />", () => {
it("renders", () => {
const tree = render(
<MemoryRouter>
<MembreList
<VolunteerList
items={[
{
id: 1,
@ -18,7 +18,7 @@ describe("<MembreList />", () => {
lastname: "Amélie",
email: "pakouille.lakouille@yahoo.fr",
mobile: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
food: "Végétarien",
adult: 1,
privileges: 0,

View File

@ -1,16 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<MembreList /> renders 1`] = `
exports[`<VolunteerList /> renders 1`] = `
<div
class="user-list"
>
<h4>
Membre List
Volunteer List
</h4>
<ul>
<li>
<a
href="/Membre/1"
href="/Volunteer/1"
>
<b>
Aupeix

View File

@ -1,20 +1,20 @@
import { memo } from "react"
import { Link } from "react-router-dom"
import { Membre } from "../../services/membres"
import { Volunteer } from "../../services/volunteers"
import styles from "./styles.module.scss"
interface Props {
items: Membre[]
items: Volunteer[]
}
const MembreList = ({ items }: Props) => (
const VolunteerList = ({ items }: Props) => (
<div className={styles["user-list"]}>
<h4>Membre List</h4>
<h4>Volunteer List</h4>
<ul>
{items.map(({ id, lastname, firstname }) => (
<li key={id}>
<Link to={`/Membre/${id}`}>
<Link to={`/Volunteer/${id}`}>
<b>{firstname}</b> {lastname}
</Link>
</li>
@ -23,4 +23,4 @@ const MembreList = ({ items }: Props) => (
</div>
)
export default memo(MembreList)
export default memo(VolunteerList)

View File

@ -4,22 +4,22 @@
import { render } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import MembreSet from "../index"
import VolunteerSet from "../index"
describe("<SetMembre />", () => {
describe("<SetVolunteer />", () => {
it("renders", () => {
const dispatch = jest.fn()
const tree = render(
<MemoryRouter>
<MembreSet
<VolunteerSet
dispatch={dispatch}
membre={{
volunteer={{
id: 1,
firstname: "Aupeix",
lastname: "Amélie",
email: "pakouille.lakouille@yahoo.fr",
mobile: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
food: "Végétarien",
adult: 1,
privileges: 0,

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SetMembre /> renders 1`] = `
exports[`<SetVolunteer /> renders 1`] = `
<section
class="MembreList"
class="VolunteerList"
>
<h2>
Modifier un membre
Modifier un volunteer
</h2>
<form>
<label

View File

@ -3,19 +3,19 @@ import { toast } from "react-toastify"
import { AppDispatch } from "../../store"
import { fetchMembreSet } from "../../store/membreSet"
import { Membre } from "../../services/membres"
import { fetchVolunteerSet } from "../../store/volunteerSet"
import { Volunteer } from "../../services/volunteers"
import styles from "./styles.module.scss"
interface Props {
dispatch: AppDispatch
membre: Membre
volunteer: Volunteer
}
const MembreSet = ({ dispatch, membre }: Props) => {
const [firstname, setFirstname] = useState(membre.firstname)
const [lastname, setName] = useState(membre.lastname)
const [adult, setAdult] = useState(membre.adult)
const VolunteerSet = ({ dispatch, volunteer }: Props) => {
const [firstname, setFirstname] = useState(volunteer.firstname)
const [lastname, setName] = useState(volunteer.lastname)
const [adult, setAdult] = useState(volunteer.adult)
const onFirstnameChanged = (e: React.ChangeEvent<HTMLInputElement>) =>
setFirstname(e.target.value)
@ -25,8 +25,8 @@ const MembreSet = ({ dispatch, membre }: Props) => {
const onSavePostClicked = () => {
if (firstname && lastname) {
dispatch(
fetchMembreSet({
...membre,
fetchVolunteerSet({
...volunteer,
firstname,
lastname,
adult,
@ -45,8 +45,8 @@ const MembreSet = ({ dispatch, membre }: Props) => {
}
}
return (
<section className={styles.MembreList}>
<h2>Modifier un membre</h2>
<section className={styles.VolunteerList}>
<h2>Modifier un volunteer</h2>
<form>
<label htmlFor="postFirstname">
Prénom:
@ -85,4 +85,4 @@ const MembreSet = ({ dispatch, membre }: Props) => {
</section>
)
}
export default memo(MembreSet)
export default memo(VolunteerSet)

View File

@ -4,14 +4,14 @@
import { render } from "@testing-library/react"
import { MemoryRouter } from "react-router-dom"
import AddEnvie from "../index"
import WishAdd from "../index"
describe("<AddEnvie />", () => {
describe("<WishAdd />", () => {
it("renders", () => {
const dispatch = jest.fn()
const tree = render(
<MemoryRouter>
<AddEnvie dispatch={dispatch} />
<WishAdd dispatch={dispatch} />
</MemoryRouter>
).container.firstChild

View File

@ -1,11 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<AddEnvie /> renders 1`] = `
exports[`<WishAdd /> renders 1`] = `
<section
class="EnvieList"
class="WishList"
>
<h2>
Ajouter une nouvelle envie
Ajouter une nouvelle wish
</h2>
<form>
<label

View File

@ -3,13 +3,13 @@ import { toast } from "react-toastify"
import styles from "./styles.module.scss"
import { AppDispatch } from "../../store"
import { fetchEnvieAdd } from "../../store/envieAdd"
import { fetchWishAdd } from "../../store/wishAdd"
interface Props {
dispatch: AppDispatch
}
const AddEnvie = ({ dispatch }: Props) => {
const WishAdd = ({ dispatch }: Props) => {
const [domain, setDomain] = useState("")
const [wish, setWish] = useState("")
const [details, setDetails] = useState("")
@ -28,7 +28,7 @@ const AddEnvie = ({ dispatch }: Props) => {
const onSavePostClicked = () => {
if (domain && wish) {
dispatch(
fetchEnvieAdd({
fetchWishAdd({
domain,
wish,
details,
@ -43,7 +43,7 @@ const AddEnvie = ({ dispatch }: Props) => {
setTeams([""])
setAddedDate("")
} else {
toast.warning("Il faut au moins préciser un domain et l'envie", {
toast.warning("Il faut au moins préciser un domain et l'wish", {
position: "top-center",
autoClose: 6000,
hideProgressBar: true,
@ -55,8 +55,8 @@ const AddEnvie = ({ dispatch }: Props) => {
}
}
return (
<section className={styles.EnvieList}>
<h2>Ajouter une nouvelle envie</h2>
<section className={styles.WishList}>
<h2>Ajouter une nouvelle wish</h2>
<form>
<label htmlFor="postDomain">
Domaine:
@ -108,4 +108,4 @@ const AddEnvie = ({ dispatch }: Props) => {
</section>
)
}
export default memo(AddEnvie)
export default memo(WishAdd)

View File

@ -1,9 +1,9 @@
import MembreList from "./MembreList"
import JeuJavList from "./JeuJavList"
import MembreInfo from "./MembreInfo"
import MembreSet from "./MembreSet"
import VolunteerList from "./VolunteerList"
import JavGameList from "./JavGameList"
import VolunteerInfo from "./VolunteerInfo"
import VolunteerSet from "./VolunteerSet"
import ErrorBoundary from "./ErrorBoundary"
import Loading from "./Loading"
import AddEnvie from "./AddEnvie"
import WishAdd from "./WishAdd"
export { MembreList, JeuJavList, MembreInfo, MembreSet, ErrorBoundary, Loading, AddEnvie }
export { VolunteerList, JavGameList, VolunteerInfo, VolunteerSet, ErrorBoundary, Loading, WishAdd }

View File

@ -4,9 +4,9 @@ import { useDispatch, useSelector, shallowEqual } from "react-redux"
import { Helmet } from "react-helmet"
import { AppState, AppThunk, EntitiesRequest } from "../../store"
import { fetchJeuJavListIfNeed } from "../../store/jeuJavList"
import { fetchEnvieListIfNeed } from "../../store/envieList"
import { JeuJavList, AddEnvie } from "../../components"
import { fetchJavGameListIfNeed } from "../../store/javGameList"
import { fetchWishListIfNeed } from "../../store/wishList"
import { JavGameList, WishAdd } from "../../components"
import styles from "./styles.module.scss"
export type Props = RouteComponentProps
@ -30,7 +30,7 @@ function useList<Entity>(
if (readyStatus === "failure") return <p>Oops, Failed to load list!</p>
return <JeuJavList ids={ids} />
return <JavGameList ids={ids} />
}
}
@ -39,9 +39,9 @@ const Home: FC<Props> = (): JSX.Element => {
return (
<div className={styles.home}>
<Helmet title="Home" />
<AddEnvie dispatch={dispatch} />
{/* {useList((state: AppState) => state.envieList, fetchEnvieListifNeed)()} */}
{useList((state: AppState) => state.jeuJavList, fetchJeuJavListIfNeed)()}
<WishAdd dispatch={dispatch} />
{/* {useList((state: AppState) => state.wishList, fetchWishListifNeed)()} */}
{useList((state: AppState) => state.javGameList, fetchJavGameListIfNeed)()}
{/* <button type="button" onClick={() => setList([{id: 3, joueurs: 4, duree: 5, description: "abcd"}])}>
Set list!
</button> */}
@ -51,8 +51,8 @@ const Home: FC<Props> = (): JSX.Element => {
// Fetch server-side data here
export const loadData = (): AppThunk[] => [
fetchEnvieListIfNeed(),
fetchJeuJavListIfNeed(),
fetchWishListIfNeed(),
fetchJavGameListIfNeed(),
// More pre-fetched actions...
]

View File

@ -4,40 +4,40 @@ import { useDispatch, useSelector, shallowEqual } from "react-redux"
import { Helmet } from "react-helmet"
import { AppState, AppThunk } from "../../store"
import { fetchMembreIfNeed } from "../../store/membre"
import { MembreInfo, MembreSet } from "../../components"
import { fetchVolunteerIfNeed } from "../../store/volunteer"
import { VolunteerInfo, VolunteerSet } from "../../components"
import styles from "./styles.module.scss"
export type Props = RouteComponentProps<{ id: string }>
const MembrePage = ({ match }: Props): JSX.Element => {
const VolunteerPage = ({ match }: Props): JSX.Element => {
const { id: rawId } = match.params
const id = +rawId
const dispatch = useDispatch()
const membre = useSelector((state: AppState) => state.membre, shallowEqual)
const volunteer = useSelector((state: AppState) => state.volunteer, shallowEqual)
useEffect(() => {
dispatch(fetchMembreIfNeed(id))
dispatch(fetchVolunteerIfNeed(id))
}, [dispatch, id])
const renderInfo = () => {
const membreInfo = membre
const volunteerInfo = volunteer
if (!membreInfo || membreInfo.readyStatus === "request") return <p>Loading...</p>
if (!volunteerInfo || volunteerInfo.readyStatus === "request") return <p>Loading...</p>
if (membreInfo.readyStatus === "failure" || !membreInfo.entity)
if (volunteerInfo.readyStatus === "failure" || !volunteerInfo.entity)
return <p>Oops! Failed to load data.</p>
return (
<div>
<MembreInfo item={membreInfo.entity} />
<MembreSet dispatch={dispatch} membre={membreInfo.entity} />
<VolunteerInfo item={volunteerInfo.entity} />
<VolunteerSet dispatch={dispatch} volunteer={volunteerInfo.entity} />
</div>
)
}
return (
<div className={styles.membre}>
<div className={styles.volunteer}>
<Helmet title="User Info" />
{renderInfo()}
</div>
@ -48,6 +48,6 @@ interface LoadDataArgs {
params: { id: number }
}
export const loadData = ({ params }: LoadDataArgs): AppThunk[] => [fetchMembreIfNeed(params.id)]
export const loadData = ({ params }: LoadDataArgs): AppThunk[] => [fetchVolunteerIfNeed(params.id)]
export default memo(MembrePage)
export default memo(VolunteerPage)

View File

@ -1,15 +1,15 @@
import loadable from "@loadable/component"
import { Loading, ErrorBoundary } from "../../components"
import { Props, loadData } from "./MembrePage"
import { Props, loadData } from "./VolunteerPage"
const MembrePage = loadable(() => import("./MembrePage"), {
const VolunteerPage = loadable(() => import("./VolunteerPage"), {
fallback: <Loading />,
})
export default (props: Props): JSX.Element => (
<ErrorBoundary>
<MembrePage {...props} />
<VolunteerPage {...props} />
</ErrorBoundary>
)
export { loadData }

View File

@ -1,3 +1,3 @@
.membre {
.volunteer {
padding: 0 15px;
}

View File

@ -2,7 +2,7 @@ import { RouteConfig } from "react-router-config"
import App from "../app"
import AsyncHome, { loadData as loadHomeData } from "../pages/Home"
import AsyncMembrePage, { loadData as loadMembrePageData } from "../pages/MembrePage"
import AsyncVolunteerPage, { loadData as loadVolunteerPageData } from "../pages/VolunteerPage"
import Login from "../pages/Login"
import Register from "../pages/Register"
import NotFound from "../pages/NotFound"
@ -17,9 +17,9 @@ export default [
component: Register,
},
{
path: "/MembrePage/:id",
component: AsyncMembrePage,
loadData: loadMembrePageData,
path: "/VolunteerPage/:id",
component: AsyncVolunteerPage,
loadData: loadVolunteerPageData,
},
{
path: "/login",

View File

@ -9,7 +9,14 @@ const CRED_PATH = path.resolve(process.cwd(), "access/gsheets.json")
export type ElementWithId = unknown & { id: number }
export default function getAccessors<
export const sheetNames: { [name: string]: string } = {
JavGames: "Jeux JAV",
Volunteers: "Membres",
PreVolunteers: "PreMembres",
Wishes: "Envies d'aider",
}
export function getAccessors<
// eslint-disable-next-line @typescript-eslint/ban-types
ElementNoId extends object,
Element extends ElementNoId & ElementWithId
@ -52,10 +59,10 @@ export default function getAccessors<
})
}
async function get(membreId: number): Promise<Element | undefined> {
async function get(volunteerId: number): Promise<Element | undefined> {
// No need to addDBOperation here, since listGet does it already
const list = await listGet()
return list.find((element) => element.id === membreId)
return list.find((element) => element.id === volunteerId)
}
async function setList(elements: Element[]): Promise<true | undefined> {

View File

@ -1,15 +0,0 @@
import getExpressAccessors from "./expressAccessors"
import { Envie, EnvieWithoutId, translationEnvie } from "../../services/envies"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
EnvieWithoutId,
Envie
>("Envies d'aider", new Envie(), translationEnvie)
export const envieListGet = listGetRequest()
export const envieGet = getRequest()
export const envieAdd = addRequest()
export const envieSet = setRequest()

View File

@ -1,5 +1,5 @@
import { Request, Response, NextFunction } from "express"
import getAccessors, { ElementWithId } from "./accessors"
import { ElementWithId, getAccessors } from "./accessors"
export default function getExpressAccessors<
// eslint-disable-next-line @typescript-eslint/ban-types

View File

@ -0,0 +1,16 @@
import getExpressAccessors from "./expressAccessors"
import { sheetNames } from "./accessors"
import { JavGame, JavGameWithoutId, translationJavGame } from "../../services/javGames"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
JavGameWithoutId,
JavGame
>(sheetNames.JavGames, new JavGame(), translationJavGame)
export const javGameListGet = listGetRequest()
export const javGameGet = getRequest()
export const javGameAdd = addRequest()
export const javGameSet = setRequest()

View File

@ -1,15 +0,0 @@
import getExpressAccessors from "./expressAccessors"
import { JeuJav, JeuJavWithoutId, translationJeuJav } from "../../services/jeuxJav"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
JeuJavWithoutId,
JeuJav
>("Jeux JAV", new JeuJav(), translationJeuJav)
export const jeuJavListGet = listGetRequest()
export const jeuJavGet = getRequest()
export const jeuJavAdd = addRequest()
export const jeuJavSet = setRequest()

View File

@ -1,15 +0,0 @@
import getExpressAccessors from "./expressAccessors"
import { Membre, MembreWithoutId, translationMember } from "../../services/membres"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
MembreWithoutId,
Membre
>("Membres", new Membre(), translationMember)
export const membreListGet = listGetRequest()
export const membreGet = getRequest()
export const membreAdd = addRequest()
export const membreSet = setRequest()

View File

@ -1,10 +1,11 @@
import getExpressAccessors from "./expressAccessors"
import { PreMember, PreMemberWithoutId, translationPreMember } from "../../services/preMembers"
import { sheetNames } from "./accessors"
import { PreMember, PreMemberWithoutId, translationPreMember } from "../../services/preVolunteers"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
PreMemberWithoutId,
PreMember
>("PreMembres", new PreMember(), translationPreMember)
>(sheetNames.PreVolunteers, new PreMember(), translationPreMember)
export const preMemberListGet = listGetRequest()

View File

@ -0,0 +1,16 @@
import getExpressAccessors from "./expressAccessors"
import { sheetNames } from "./accessors"
import { Volunteer, VolunteerWithoutId, translationMember } from "../../services/volunteers"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
VolunteerWithoutId,
Volunteer
>(sheetNames.Volunteers, new Volunteer(), translationMember)
export const volunteerListGet = listGetRequest()
export const volunteerGet = getRequest()
export const volunteerAdd = addRequest()
export const volunteerSet = setRequest()

View File

@ -0,0 +1,16 @@
import getExpressAccessors from "./expressAccessors"
import { sheetNames } from "./accessors"
import { Wish, WishWithoutId, translationWish } from "../../services/wishes"
const { listGetRequest, getRequest, setRequest, addRequest } = getExpressAccessors<
WishWithoutId,
Wish
>(sheetNames.Wishes, new Wish(), translationWish)
export const wishListGet = listGetRequest()
export const wishGet = getRequest()
export const wishAdd = addRequest()
export const wishSet = setRequest()

View File

@ -16,10 +16,10 @@ import ssr from "./ssr"
import certbotRouter from "../routes/certbot"
import { secure } from "./secure"
import { jeuJavListGet } from "./gsheets/jeuJav"
import { envieListGet, envieAdd } from "./gsheets/envies"
import { preMemberAdd } from "./gsheets/preMembers"
import { membreGet, membreSet } from "./gsheets/membres"
import { javGameListGet } from "./gsheets/javGames"
import { wishListGet, wishAdd } from "./gsheets/wishes"
import { preMemberAdd } from "./gsheets/preVolunteers"
import { volunteerGet, volunteerSet } from "./gsheets/volunteers"
import loginHandler from "./userManagement/login"
import config from "../config"
@ -54,14 +54,14 @@ app.post("/api/user/login", loginHandler)
* APIs
*/
// Google Sheets API
app.get("/JeuJavListGet", jeuJavListGet)
app.get("/EnvieListGet", envieListGet)
app.post("/EnvieAdd", envieAdd)
app.get("/JavGameListGet", javGameListGet)
app.get("/WishListGet", wishListGet)
app.post("/WishAdd", wishAdd)
app.post("/PreMemberAdd", preMemberAdd)
// Secured APIs
app.get("/MembreGet", secure as RequestHandler, membreGet)
app.post("/MembreSet", secure as RequestHandler, membreSet)
app.get("/VolunteerGet", secure as RequestHandler, volunteerGet)
app.post("/VolunteerSet", secure as RequestHandler, volunteerSet)
// Use React server-side rendering middleware
app.get("*", ssr)

View File

@ -3,11 +3,12 @@
*/
import _ from "lodash"
import { getAccessors } from "../../gsheets/accessors"
import { login } from "../login"
// Could do a full test with: wget --header='Content-Type:application/json' --post-data='{"email":"pikiou.sub@gmail.com","password":"mot de passe"}' http://localhost:3000/api/user/login
// Full test with Bearer: wget --header='Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoicGlraW91c3ViQGdlYWlsLmNvbSIsInBlcm1pc3Npb25zIjpbXSwiaWF0IjoxNjM4MjUzODgzLCJleHAiOjE2Mzg4NTg2ODN9.MknJ4NfcVlgW2ODeimfwZI1a4z8asdEXtHwHgViy6c4' http://localhost:3000/MembreGet?id=1
// Full test with Bearer: wget --header='Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoicGlraW91c3ViQGdlYWlsLmNvbSIsInBlcm1pc3Npb25zIjpbXSwiaWF0IjoxNjM4MjUzODgzLCJleHAiOjE2Mzg4NTg2ODN9.MknJ4NfcVlgW2ODeimfwZI1a4z8asdEXtHwHgViy6c4' http://localhost:3000/VolunteerGet?id=1
const mockUser = {
email: "my.email@gmail.com",
@ -15,15 +16,19 @@ const mockUser = {
firstname: "monPrénom",
}
jest.mock("../../gsheets/accessors", () => () => ({
listGet: () => [mockUser],
}))
jest.mock("../../gsheets/accessors")
describe("login with", () => {
beforeAll(() => {
;(getAccessors as jest.Mock).mockImplementation(() => ({
listGet: () => [mockUser],
}))
})
it("right password", async () => {
const res = await login("my.email@gmail.com", "12345678")
expect(_.omit(res, "jwt")).toEqual({
membre: {
volunteer: {
firstname: mockUser.firstname,
},
})

View File

@ -1,17 +1,15 @@
import { Request, Response, NextFunction } from "express"
import bcrypt from "bcrypt"
import {
Membre,
Volunteer,
MemberLogin,
emailRegexp,
passwordMinLength,
translationMember,
} from "../../services/membres"
import getAccessors from "../gsheets/accessors"
} from "../../services/volunteers"
import { getAccessors, sheetNames } from "../gsheets/accessors"
import { getJwt } from "../secure"
const { listGet } = getAccessors("Membres", new Membre(), translationMember)
export default async function loginHandler(
request: Request,
response: Response,
@ -33,6 +31,8 @@ export default async function loginHandler(
}
export async function login(rawEmail: string, rawPassword: string): Promise<MemberLogin> {
const { listGet } = getAccessors(sheetNames.Volunteers, new Volunteer(), translationMember)
const email = rawEmail.replace(/^\s*/, "").replace(/\s*$/, "")
if (!emailRegexp.test(email)) {
throw Error("Email invalid")
@ -46,13 +46,13 @@ export async function login(rawEmail: string, rawPassword: string): Promise<Memb
throw Error("Mot de passe trop court")
}
const membres: Membre[] = await listGet()
const membre = membres.find((m) => m.email === email)
if (!membre) {
const volunteers: Volunteer[] = await listGet()
const volunteer = volunteers.find((m) => m.email === email)
if (!volunteer) {
throw Error("Cet email ne correspond à aucun utilisateur")
}
const passwordMatch = await bcrypt.compare(password, membre.password.replace(/^\$2y/, "$2a"))
const passwordMatch = await bcrypt.compare(password, volunteer.password.replace(/^\$2y/, "$2a"))
if (!passwordMatch) {
throw Error("Mauvais mot de passe pour cet email")
}
@ -60,8 +60,8 @@ export async function login(rawEmail: string, rawPassword: string): Promise<Memb
const jwt = await getJwt(email)
return {
membre: {
firstname: membre.firstname,
volunteer: {
firstname: volunteer.firstname,
},
jwt,
}

View File

@ -75,7 +75,7 @@ export function listGet<Element>(
export function add<ElementNoId extends object, Element extends ElementNoId & ElementWithId>(
elementName: string,
translation: ElementTranslation
): (membreWithoutId: ElementNoId) => Promise<{
): (volunteerWithoutId: ElementNoId) => Promise<{
data?: Element
error?: Error
}> {
@ -83,12 +83,13 @@ export function add<ElementNoId extends object, Element extends ElementNoId & El
data?: Element
error?: Error
}
return async (membreWithoutId: ElementNoId): Promise<ElementGetResponse> => {
return async (volunteerWithoutId: ElementNoId): Promise<ElementGetResponse> => {
try {
const invertedTranslationWithoutId = _.invert(_.omit(translation, "id"))
const frenchDataWithoutId = _.mapValues(
invertedTranslationWithoutId,
(englishProp: string, _frenchProp: string) => (membreWithoutId as any)[englishProp]
(englishProp: string, _frenchProp: string) =>
(volunteerWithoutId as any)[englishProp]
)
const { data } = await axios.post(
@ -114,7 +115,7 @@ export function add<ElementNoId extends object, Element extends ElementNoId & El
export function set<Element>(
elementName: string,
translation: ElementTranslation
): (membre: Element) => Promise<{
): (volunteer: Element) => Promise<{
data?: Element
error?: Error
}> {
@ -122,12 +123,12 @@ export function set<Element>(
data?: Element
error?: Error
}
return async (membre: Element): Promise<ElementGetResponse> => {
return async (volunteer: Element): Promise<ElementGetResponse> => {
try {
const invertedTranslation = _.invert(translation)
const frenchData = _.mapValues(
invertedTranslation,
(englishProp: string) => (membre as any)[englishProp]
(englishProp: string) => (volunteer as any)[englishProp]
)
const { data } = await axios.post(

View File

@ -1,36 +0,0 @@
import { get, listGet, add, set } from "./accessors"
export class Envie {
id = 0
domain = ""
wish = ""
details = ""
teams: string[] = []
addedDate = ""
}
export const translationEnvie: { [k in keyof Envie]: string } = {
id: "id",
domain: "domaine",
wish: "envies",
details: "precisions",
teams: "equipes",
addedDate: "dateAjout",
}
const elementName = "Envie"
export type EnvieWithoutId = Omit<Envie, "id">
export const envieGet = get<Envie>(elementName, translationEnvie)
export const envieListGet = listGet<Envie>(elementName, translationEnvie)
export const envieAdd = add<EnvieWithoutId, Envie>(elementName, translationEnvie)
export const envieSet = set<Envie>(elementName, translationEnvie)

View File

@ -1,6 +1,6 @@
import { get, listGet, add, set } from "./accessors"
export class JeuJav {
export class JavGame {
id = 0
title = ""
@ -32,7 +32,7 @@ export class JeuJav {
bggPhoto = ""
}
export const translationJeuJav: { [k in keyof JeuJav]: string } = {
export const translationJavGame: { [k in keyof JavGame]: string } = {
id: "id",
title: "titre",
author: "auteur",
@ -50,14 +50,14 @@ export const translationJeuJav: { [k in keyof JeuJav]: string } = {
bggPhoto: "bggPhoto",
}
const elementName = "JeuJav"
const elementName = "JavGame"
export type JeuJavWithoutId = Omit<JeuJav, "id">
export type JavGameWithoutId = Omit<JavGame, "id">
export const jeuJavGet = get<JeuJav>(elementName, translationJeuJav)
export const javGameGet = get<JavGame>(elementName, translationJavGame)
export const jeuJavListGet = listGet<JeuJav>(elementName, translationJeuJav)
export const javGameListGet = listGet<JavGame>(elementName, translationJavGame)
export const jeuJavAdd = add<JeuJavWithoutId, JeuJav>(elementName, translationJeuJav)
export const javGameAdd = add<JavGameWithoutId, JavGame>(elementName, translationJavGame)
export const jeuJavSet = set<JeuJav>(elementName, translationJeuJav)
export const javGameSet = set<JavGame>(elementName, translationJavGame)

View File

@ -1,6 +1,6 @@
import { get, listGet, add, set } from "./accessors"
export class Membre {
export class Volunteer {
id = 0
lastname = ""
@ -28,7 +28,7 @@ export class Membre {
password = ""
}
export const translationMember: { [k in keyof Membre]: string } = {
export const translationMember: { [k in keyof Volunteer]: string } = {
id: "id",
lastname: "nom",
firstname: "prenom",
@ -44,26 +44,26 @@ export const translationMember: { [k in keyof Membre]: string } = {
password: "passe",
}
const elementName = "Membre"
const elementName = "Volunteer"
export const emailRegexp =
/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i
export const passwordMinLength = 4
export interface MemberLogin {
membre?: {
volunteer?: {
firstname: string
}
jwt?: string
error?: string
}
export type MembreWithoutId = Omit<Membre, "id">
export type VolunteerWithoutId = Omit<Volunteer, "id">
export const membreGet = get<Membre>(elementName, translationMember)
export const volunteerGet = get<Volunteer>(elementName, translationMember)
export const membreListGet = listGet<Membre>(elementName, translationMember)
export const volunteerListGet = listGet<Volunteer>(elementName, translationMember)
export const membreAdd = add<MembreWithoutId, Membre>(elementName, translationMember)
export const volunteerAdd = add<VolunteerWithoutId, Volunteer>(elementName, translationMember)
export const membreSet = set<Membre>(elementName, translationMember)
export const volunteerSet = set<Volunteer>(elementName, translationMember)

36
src/services/wishes.ts Normal file
View File

@ -0,0 +1,36 @@
import { get, listGet, add, set } from "./accessors"
export class Wish {
id = 0
domain = ""
wish = ""
details = ""
teams: string[] = []
addedDate = ""
}
export const translationWish: { [k in keyof Wish]: string } = {
id: "id",
domain: "domaine",
wish: "wishes",
details: "precisions",
teams: "equipes",
addedDate: "dateAjout",
}
const elementName = "Wish"
export type WishWithoutId = Omit<Wish, "id">
export const wishGet = get<Wish>(elementName, translationWish)
export const wishListGet = listGet<Wish>(elementName, translationWish)
export const wishAdd = add<WishWithoutId, Wish>(elementName, translationWish)
export const wishSet = set<Wish>(elementName, translationWish)

View File

@ -2,14 +2,14 @@ import axios from "axios"
import _ from "lodash"
import mockStore from "../../utils/mockStore"
import JeuJavList, {
import JavGameList, {
initialState,
getRequesting,
getSuccess,
getFailure,
fetchJeuJavList,
} from "../jeuJavList"
import { JeuJav } from "../../services/jeuxJav"
fetchJavGameList,
} from "../javGameList"
import { JavGame } from "../../services/javGames"
jest.mock("axios")
@ -33,7 +33,7 @@ const mockFrenchData: any[] = [
ean: "3421272101313",
},
]
const mockEnglishData: JeuJav[] = [
const mockEnglishData: JavGame[] = [
{
id: 5,
title: "6 qui prend!",
@ -55,14 +55,14 @@ const mockEnglishData: JeuJav[] = [
]
const mockError = "Oops! Something went wrong."
describe("JeuJavList reducer", () => {
describe("JavGameList reducer", () => {
it("should handle initial state", () => {
// @ts-expect-error
expect(JeuJavList(undefined, {})).toEqual(initialState)
expect(JavGameList(undefined, {})).toEqual(initialState)
})
it("should handle requesting correctly", () => {
expect(JeuJavList(undefined, { type: getRequesting.type })).toEqual({
expect(JavGameList(undefined, { type: getRequesting.type })).toEqual({
readyStatus: "request",
ids: [],
entities: {},
@ -70,16 +70,18 @@ describe("JeuJavList reducer", () => {
})
it("should handle success correctly", () => {
expect(JeuJavList(undefined, { type: getSuccess.type, payload: mockEnglishData })).toEqual({
expect(JavGameList(undefined, { type: getSuccess.type, payload: mockEnglishData })).toEqual(
{
...initialState,
readyStatus: "success",
ids: _.map(mockEnglishData, "id"),
entities: _.keyBy(mockEnglishData, "id"),
})
}
)
})
it("should handle failure correctly", () => {
expect(JeuJavList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
expect(JavGameList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
...initialState,
readyStatus: "failure",
error: mockError,
@ -87,8 +89,8 @@ describe("JeuJavList reducer", () => {
})
})
describe("JeuJavList action", () => {
it("fetches JeuJav list successful", async () => {
describe("JavGameList action", () => {
it("fetches JavGame list successful", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type, payload: undefined },
@ -98,11 +100,11 @@ describe("JeuJavList action", () => {
// @ts-expect-error
axios.get.mockResolvedValue({ data: mockFrenchData })
await dispatch(fetchJeuJavList())
await dispatch(fetchJavGameList())
expect(getActions()).toEqual(expectedActions)
})
it("fetches JeuJav list failed", async () => {
it("fetches JavGame list failed", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type },
@ -112,7 +114,7 @@ describe("JeuJavList action", () => {
// @ts-expect-error
axios.get.mockRejectedValue({ message: mockError })
await dispatch(fetchJeuJavList())
await dispatch(fetchJavGameList())
expect(getActions()).toEqual(expectedActions)
})
})

View File

@ -1,8 +1,14 @@
import axios from "axios"
import mockStore from "../../utils/mockStore"
import membre, { getRequesting, getSuccess, getFailure, fetchMembre, initialState } from "../membre"
import { Membre } from "../../services/membres"
import volunteer, {
getRequesting,
getSuccess,
getFailure,
fetchVolunteer,
initialState,
} from "../volunteer"
import { Volunteer } from "../../services/volunteers"
jest.mock("axios")
@ -12,7 +18,7 @@ const mockFrenchData: any = {
prenom: "Amélie",
mail: "pakouille.lakouille@yahoo.fr",
telephone: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
alimentation: "Végétarien",
majeur: 1,
privilege: 0,
@ -22,13 +28,13 @@ const mockFrenchData: any = {
passe: "$2y$10$fSxY9AIuxSiEjwF.J3eXGubIxUPlobkyRrNIal8ASimSjNj4SR.9O",
}
const mockEnglishData: Membre = {
const mockEnglishData: Volunteer = {
id: 1,
lastname: "Aupeix",
firstname: "Amélie",
email: "pakouille.lakouille@yahoo.fr",
mobile: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
food: "Végétarien",
adult: 1,
privileges: 0,
@ -40,21 +46,21 @@ const mockEnglishData: Membre = {
const { id } = mockEnglishData
const mockError = "Oops! Something went wrong."
describe("membre reducer", () => {
describe("volunteer reducer", () => {
it("should handle initial state correctly", () => {
// @ts-expect-error
expect(membre(undefined, {})).toEqual(initialState)
expect(volunteer(undefined, {})).toEqual(initialState)
})
it("should handle requesting correctly", () => {
expect(membre(undefined, { type: getRequesting.type, payload: id })).toEqual({
expect(volunteer(undefined, { type: getRequesting.type, payload: id })).toEqual({
readyStatus: "request",
})
})
it("should handle success correctly", () => {
expect(
membre(undefined, {
volunteer(undefined, {
type: getSuccess.type,
payload: mockEnglishData,
})
@ -63,7 +69,7 @@ describe("membre reducer", () => {
it("should handle failure correctly", () => {
expect(
membre(undefined, {
volunteer(undefined, {
type: getFailure.type,
payload: mockError,
})
@ -71,8 +77,8 @@ describe("membre reducer", () => {
})
})
describe("membre action", () => {
it("fetches membre data successful", async () => {
describe("volunteer action", () => {
it("fetches volunteer data successful", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type, payload: undefined },
@ -82,11 +88,11 @@ describe("membre action", () => {
// @ts-expect-error
axios.get.mockResolvedValue({ data: mockFrenchData })
await dispatch(fetchMembre(id))
await dispatch(fetchVolunteer(id))
expect(getActions()).toEqual(expectedActions)
})
it("fetches membre data failed", async () => {
it("fetches volunteer data failed", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type },
@ -96,7 +102,7 @@ describe("membre action", () => {
// @ts-expect-error
axios.get.mockRejectedValue({ message: mockError })
await dispatch(fetchMembre(id))
await dispatch(fetchVolunteer(id))
expect(getActions()).toEqual(expectedActions)
})
})

View File

@ -2,14 +2,14 @@ import axios from "axios"
import _ from "lodash"
import mockStore from "../../utils/mockStore"
import membreList, {
import volunteerList, {
initialState,
getRequesting,
getSuccess,
getFailure,
fetchMembreList,
} from "../membreList"
import { Membre } from "../../services/membres"
fetchVolunteerList,
} from "../volunteerList"
import { Volunteer } from "../../services/volunteers"
jest.mock("axios")
@ -20,7 +20,7 @@ const mockFrenchData: any[] = [
prenom: "Amélie",
mail: "pakouille.lakouille@yahoo.fr",
telephone: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
alimentation: "Végétarien",
majeur: 1,
privilege: 0,
@ -31,14 +31,14 @@ const mockFrenchData: any[] = [
},
]
const mockEnglishData: Membre[] = [
const mockEnglishData: Volunteer[] = [
{
id: 1,
lastname: "Aupeix",
firstname: "Amélie",
email: "pakouille.lakouille@yahoo.fr",
mobile: "0675650392",
photo: "images/membres/$taille/amélie_aupeix.jpg",
photo: "images/volunteers/$taille/amélie_aupeix.jpg",
food: "Végétarien",
adult: 1,
privileges: 0,
@ -50,14 +50,14 @@ const mockEnglishData: Membre[] = [
]
const mockError = "Oops! Something went wrong."
describe("membreList reducer", () => {
describe("volunteerList reducer", () => {
it("should handle initial state", () => {
// @ts-expect-error
expect(membreList(undefined, {})).toEqual(initialState)
expect(volunteerList(undefined, {})).toEqual(initialState)
})
it("should handle requesting correctly", () => {
expect(membreList(undefined, { type: getRequesting.type })).toEqual({
expect(volunteerList(undefined, { type: getRequesting.type })).toEqual({
readyStatus: "request",
ids: [],
entities: {},
@ -65,7 +65,9 @@ describe("membreList reducer", () => {
})
it("should handle success correctly", () => {
expect(membreList(undefined, { type: getSuccess.type, payload: mockEnglishData })).toEqual({
expect(
volunteerList(undefined, { type: getSuccess.type, payload: mockEnglishData })
).toEqual({
...initialState,
readyStatus: "success",
ids: _.map(mockEnglishData, "id"),
@ -74,7 +76,7 @@ describe("membreList reducer", () => {
})
it("should handle failure correctly", () => {
expect(membreList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
expect(volunteerList(undefined, { type: getFailure.type, payload: mockError })).toEqual({
...initialState,
readyStatus: "failure",
error: mockError,
@ -82,8 +84,8 @@ describe("membreList reducer", () => {
})
})
describe("membreList action", () => {
it("fetches membre list successful", async () => {
describe("volunteerList action", () => {
it("fetches volunteer list successful", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type, payload: undefined },
@ -93,11 +95,11 @@ describe("membreList action", () => {
// @ts-expect-error
axios.get.mockResolvedValue({ data: mockFrenchData })
await dispatch(fetchMembreList())
await dispatch(fetchVolunteerList())
expect(getActions()).toEqual(expectedActions)
})
it("fetches membre list failed", async () => {
it("fetches volunteer list failed", async () => {
const { dispatch, getActions } = mockStore()
const expectedActions = [
{ type: getRequesting.type },
@ -107,7 +109,7 @@ describe("membreList action", () => {
// @ts-expect-error
axios.get.mockRejectedValue({ message: mockError })
await dispatch(fetchMembreList())
await dispatch(fetchVolunteerList())
expect(getActions()).toEqual(expectedActions)
})
})

View File

@ -1,38 +0,0 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
import { Envie, envieAdd } from "../services/envies"
const envieAdapter = createEntityAdapter<Envie>()
const envieAddSlice = createSlice({
name: "addEnvie",
initialState: envieAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Envie>) => {
state.readyStatus = "success"
envieAdapter.addOne(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default envieAddSlice.reducer
export const { getRequesting, getSuccess, getFailure } = envieAddSlice.actions
export const fetchEnvieAdd = elementAddFetch(
envieAdd,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors de l'ajout d'une envie: ${error.message}`),
() => toastSuccess("Envie ajoutée !")
)

View File

@ -1,46 +0,0 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { Envie, envieListGet } from "../services/envies"
import { AppThunk, AppState } from "."
const envieAdapter = createEntityAdapter<Envie>()
const envieList = createSlice({
name: "getEnvieList",
initialState: envieAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Envie[]>) => {
state.readyStatus = "success"
envieAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default envieList.reducer
export const { getRequesting, getSuccess, getFailure } = envieList.actions
export const fetchEnvieList = elementListFetch(
envieListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des envies: ${error.message}`)
)
const shouldFetchEnvieList = (state: AppState) => state.envieList.readyStatus !== "success"
export const fetchEnvieListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchEnvieList(getState())) return dispatch(fetchEnvieList())
return null
}

48
src/store/javGameList.ts Normal file
View File

@ -0,0 +1,48 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { JavGame, javGameListGet } from "../services/javGames"
import { AppThunk, AppState } from "."
const javGameAdapter = createEntityAdapter<JavGame>()
export const initialState = javGameAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest)
const javGameList = createSlice({
name: "javGameList",
initialState,
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<JavGame[]>) => {
state.readyStatus = "success"
javGameAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default javGameList.reducer
export const { getRequesting, getSuccess, getFailure } = javGameList.actions
export const fetchJavGameList = elementListFetch(
javGameListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des jeux JAV: ${error.message}`)
)
const shouldFetchJavGameList = (state: AppState) => state.javGameList.readyStatus !== "success"
export const fetchJavGameListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchJavGameList(getState())) return dispatch(fetchJavGameList())
return null
}

View File

@ -1,48 +0,0 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { JeuJav, jeuJavListGet } from "../services/jeuxJav"
import { AppThunk, AppState } from "."
const jeuJavAdapter = createEntityAdapter<JeuJav>()
export const initialState = jeuJavAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest)
const jeuJavList = createSlice({
name: "jeuJavList",
initialState,
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<JeuJav[]>) => {
state.readyStatus = "success"
jeuJavAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default jeuJavList.reducer
export const { getRequesting, getSuccess, getFailure } = jeuJavList.actions
export const fetchJeuJavList = elementListFetch(
jeuJavListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des jeux JAV: ${error.message}`)
)
const shouldFetchJeuJavList = (state: AppState) => state.jeuJavList.readyStatus !== "success"
export const fetchJeuJavListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchJeuJavList(getState())) return dispatch(fetchJeuJavList())
return null
}

View File

@ -1,51 +0,0 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementFetch } from "./utils"
import { Membre, membreGet } from "../services/membres"
import { AppThunk, AppState } from "."
type StateMembre = { entity?: Membre } & StateRequest
export const initialState: StateMembre = {
readyStatus: "idle",
}
const membre = createSlice({
name: "membre",
initialState,
reducers: {
getRequesting: (_) => ({
readyStatus: "request",
}),
getSuccess: (_, { payload }: PayloadAction<Membre>) => ({
readyStatus: "success",
entity: payload,
}),
getFailure: (_, { payload }: PayloadAction<string>) => ({
readyStatus: "failure",
error: payload,
}),
},
})
export default membre.reducer
export const { getRequesting, getSuccess, getFailure } = membre.actions
export const fetchMembre = elementFetch(
membreGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement d'un membre: ${error.message}`)
)
const shouldFetchMembre = (state: AppState, id: number) =>
state.membre.readyStatus !== "success" || (state.membre.entity && state.membre.entity.id !== id)
export const fetchMembreIfNeed =
(id: number): AppThunk =>
(dispatch, getState) => {
if (shouldFetchMembre(getState(), id)) return dispatch(fetchMembre(id))
return null
}

View File

@ -1,38 +0,0 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
import { Membre, membreAdd } from "../services/membres"
const membreAdapter = createEntityAdapter<Membre>()
const membreAddSlice = createSlice({
name: "addMembre",
initialState: membreAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Membre>) => {
state.readyStatus = "success"
membreAdapter.addOne(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default membreAddSlice.reducer
export const { getRequesting, getSuccess, getFailure } = membreAddSlice.actions
export const fetchMembreAdd = elementAddFetch(
membreAdd,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors de l'ajout d'une membre: ${error.message}`),
() => toastSuccess("Membre ajoutée !")
)

View File

@ -1,48 +0,0 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { Membre, membreListGet } from "../services/membres"
import { AppThunk, AppState } from "."
const membreAdapter = createEntityAdapter<Membre>()
export const initialState = membreAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest)
const membreList = createSlice({
name: "membreList",
initialState,
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Membre[]>) => {
state.readyStatus = "success"
membreAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default membreList.reducer
export const { getRequesting, getSuccess, getFailure } = membreList.actions
export const fetchMembreList = elementListFetch(
membreListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des membres: ${error.message}`)
)
const shouldFetchMembreList = (state: AppState) => state.membreList.readyStatus !== "success"
export const fetchMembreListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchMembreList(getState())) return dispatch(fetchMembreList())
return null
}

View File

@ -1,7 +1,7 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, elementAddFetch } from "./utils"
import { PreMember, preMemberAdd } from "../services/preMembers"
import { PreMember, preMemberAdd } from "../services/preVolunteers"
const preMemberAdapter = createEntityAdapter<PreMember>()

View File

@ -1,25 +1,25 @@
import { History } from "history"
import { connectRouter } from "connected-react-router"
import envieAdd from "./envieAdd"
import envieList from "./envieList"
import jeuJavList from "./jeuJavList"
import membre from "./membre"
import membreAdd from "./membreAdd"
import membreList from "./membreList"
import membreSet from "./membreSet"
import preMemberAdd from "./preMemberAdd"
import wishAdd from "./wishAdd"
import wishList from "./wishList"
import javGameList from "./javGameList"
import volunteer from "./volunteer"
import volunteerAdd from "./volunteerAdd"
import volunteerList from "./volunteerList"
import volunteerSet from "./volunteerSet"
import preMemberAdd from "./preVolunteerAdd"
// Use inferred return type for making correctly Redux types
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export default (history: History) => ({
envieAdd,
envieList,
jeuJavList,
membre,
membreAdd,
membreList,
membreSet,
wishAdd,
wishList,
javGameList,
volunteer,
volunteerAdd,
volunteerList,
volunteerSet,
preMemberAdd,
router: connectRouter(history) as any,
// Register more reducers...

View File

@ -64,7 +64,7 @@ export function elementFetch<Element>(
}
export function elementAddFetch<Element>(
elementAddService: (membreWithoutId: Omit<Element, "id">) => Promise<{
elementAddService: (volunteerWithoutId: Omit<Element, "id">) => Promise<{
data?: Element | undefined
error?: Error | undefined
}>,
@ -77,12 +77,12 @@ export function elementAddFetch<Element>(
successMessage: () => void = () => {
/* Meant to be empty */
}
): (membreWithoutId: Omit<Element, "id">) => AppThunk {
return (membreWithoutId: Omit<Element, "id">): AppThunk =>
): (volunteerWithoutId: Omit<Element, "id">) => AppThunk {
return (volunteerWithoutId: Omit<Element, "id">): AppThunk =>
async (dispatch) => {
dispatch(getRequesting())
const { error, data } = await elementAddService(membreWithoutId)
const { error, data } = await elementAddService(volunteerWithoutId)
if (error) {
dispatch(getFailure(error.message))
@ -125,7 +125,7 @@ export function elementListFetch<Element>(
}
export function elementSet<Element>(
elementSetService: (membre: Element) => Promise<{
elementSetService: (volunteer: Element) => Promise<{
data?: Element | undefined
error?: Error | undefined
}>,

52
src/store/volunteer.ts Normal file
View File

@ -0,0 +1,52 @@
import { PayloadAction, createSlice } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementFetch } from "./utils"
import { Volunteer, volunteerGet } from "../services/volunteers"
import { AppThunk, AppState } from "."
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 volunteer: ${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
}

38
src/store/volunteerAdd.ts Normal file
View File

@ -0,0 +1,38 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
import { Volunteer, volunteerAdd } from "../services/volunteers"
const volunteerAdapter = createEntityAdapter<Volunteer>()
const volunteerAddSlice = createSlice({
name: "addVolunteer",
initialState: volunteerAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Volunteer>) => {
state.readyStatus = "success"
volunteerAdapter.addOne(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default volunteerAddSlice.reducer
export const { getRequesting, getSuccess, getFailure } = volunteerAddSlice.actions
export const fetchVolunteerAdd = elementAddFetch(
volunteerAdd,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors de l'ajout d'une volunteer: ${error.message}`),
() => toastSuccess("Volunteer ajoutée !")
)

View File

@ -0,0 +1,48 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { Volunteer, volunteerListGet } from "../services/volunteers"
import { AppThunk, AppState } from "."
const volunteerAdapter = createEntityAdapter<Volunteer>()
export const initialState = volunteerAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest)
const volunteerList = createSlice({
name: "volunteerList",
initialState,
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Volunteer[]>) => {
state.readyStatus = "success"
volunteerAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default volunteerList.reducer
export const { getRequesting, getSuccess, getFailure } = volunteerList.actions
export const fetchVolunteerList = elementListFetch(
volunteerListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des volunteers: ${error.message}`)
)
const shouldFetchVolunteerList = (state: AppState) => state.volunteerList.readyStatus !== "success"
export const fetchVolunteerListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchVolunteerList(getState())) return dispatch(fetchVolunteerList())
return null
}

View File

@ -1,22 +1,22 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, toastSuccess, elementSet } from "./utils"
import { Membre, membreSet } from "../services/membres"
import { Volunteer, volunteerSet } from "../services/volunteers"
const membreAdapter = createEntityAdapter<Membre>()
const volunteerAdapter = createEntityAdapter<Volunteer>()
const membreSetSlice = createSlice({
name: "membreSet",
initialState: membreAdapter.getInitialState({
const volunteerSetSlice = createSlice({
name: "volunteerSet",
initialState: volunteerAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Membre>) => {
getSuccess: (state, { payload }: PayloadAction<Volunteer>) => {
state.readyStatus = "success"
membreAdapter.setOne(state, payload)
volunteerAdapter.setOne(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
@ -25,14 +25,14 @@ const membreSetSlice = createSlice({
},
})
export default membreSetSlice.reducer
export const { getRequesting, getSuccess, getFailure } = membreSetSlice.actions
export default volunteerSetSlice.reducer
export const { getRequesting, getSuccess, getFailure } = volunteerSetSlice.actions
export const fetchMembreSet = elementSet(
membreSet,
export const fetchVolunteerSet = elementSet(
volunteerSet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors de la modification d'un membre: ${error.message}`),
() => toastSuccess("Membre modifié !")
(error: Error) => toastError(`Erreur lors de la modification d'un volunteer: ${error.message}`),
() => toastSuccess("Volunteer modifié !")
)

38
src/store/wishAdd.ts Normal file
View File

@ -0,0 +1,38 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, toastSuccess, elementAddFetch } from "./utils"
import { Wish, wishAdd } from "../services/wishes"
const wishAdapter = createEntityAdapter<Wish>()
const wishAddSlice = createSlice({
name: "addWish",
initialState: wishAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Wish>) => {
state.readyStatus = "success"
wishAdapter.addOne(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default wishAddSlice.reducer
export const { getRequesting, getSuccess, getFailure } = wishAddSlice.actions
export const fetchWishAdd = elementAddFetch(
wishAdd,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors de l'ajout d'une wish: ${error.message}`),
() => toastSuccess("Wish ajoutée !")
)

46
src/store/wishList.ts Normal file
View File

@ -0,0 +1,46 @@
import { PayloadAction, createSlice, createEntityAdapter } from "@reduxjs/toolkit"
import { StateRequest, toastError, elementListFetch } from "./utils"
import { Wish, wishListGet } from "../services/wishes"
import { AppThunk, AppState } from "."
const wishAdapter = createEntityAdapter<Wish>()
const wishList = createSlice({
name: "getWishList",
initialState: wishAdapter.getInitialState({
readyStatus: "idle",
} as StateRequest),
reducers: {
getRequesting: (state) => {
state.readyStatus = "request"
},
getSuccess: (state, { payload }: PayloadAction<Wish[]>) => {
state.readyStatus = "success"
wishAdapter.setAll(state, payload)
},
getFailure: (state, { payload }: PayloadAction<string>) => {
state.readyStatus = "failure"
state.error = payload
},
},
})
export default wishList.reducer
export const { getRequesting, getSuccess, getFailure } = wishList.actions
export const fetchWishList = elementListFetch(
wishListGet,
getRequesting,
getSuccess,
getFailure,
(error: Error) => toastError(`Erreur lors du chargement des wishes: ${error.message}`)
)
const shouldFetchWishList = (state: AppState) => state.wishList.readyStatus !== "success"
export const fetchWishListIfNeed = (): AppThunk => (dispatch, getState) => {
if (shouldFetchWishList(getState())) return dispatch(fetchWishList())
return null
}