Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
nicobret committed Dec 20, 2024
1 parent c5bdf20 commit 938d58b
Show file tree
Hide file tree
Showing 29 changed files with 217 additions and 204 deletions.
2 changes: 1 addition & 1 deletion app/src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function App() {
const { ok, user } = await api.checkToken();

if (!ok || !user) {
dispatch(setYoung(null));
dispatch(setYoung());
return;
}

Expand Down
8 changes: 4 additions & 4 deletions app/src/hooks/usePermissions.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import useAuth from "@/services/useAuth";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";
import { YOUNG_SOURCE, YOUNG_STATUS } from "snu-lib";

export default function usePermissions() {
const { young } = useAuth();
const cohort = getCohort(young.cohort);
const { cohort } = useCohort();

return {
hasAccessToAVenir: young.source === YOUNG_SOURCE.VOLONTAIRE,
hasAccessToDesistement: young.status !== YOUNG_STATUS.WITHDRAWN && young.status !== YOUNG_STATUS.ABANDONED,
canModifyInscription: new Date() < new Date(cohort.inscriptionModificationEndDate),
hasAccessToNavigation: ![YOUNG_STATUS.IN_PROGRESS, YOUNG_STATUS.REINSCRIPTION].includes(young.status),
canModifyInscription: cohort.inscriptionModificationEndDate ? new Date() < new Date(cohort.inscriptionModificationEndDate) : false,
hasAccessToNavigation: ![YOUNG_STATUS.IN_PROGRESS, YOUNG_STATUS.REINSCRIPTION].includes(young.status as any),
};
}
3 changes: 2 additions & 1 deletion app/src/redux/auth/actions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import * as Sentry from "@sentry/react";
import { YoungType } from "snu-lib";

export const authActions = {
SETYOUNG: "SETYOUNG",
};

export function setYoung(young) {
export function setYoung(young?: YoungType) {
if (young) Sentry.setUser({ id: young._id, email: young.email, username: `${young.firstName} ${young.lastName}` });
else Sentry.setUser(null);
return { type: authActions.SETYOUNG, young };
Expand Down
7 changes: 6 additions & 1 deletion app/src/redux/auth/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { YoungType } from "snu-lib";

import { authActions } from "./actions";

type Action = {
type: string;
young?: YoungType;
};

export type AuthState = {
// TODO: use API route response
Auth: {
Expand All @@ -13,7 +18,7 @@ const initState = {
young: null,
};

export default function reducer(state = initState, action) {
export default function reducer(state = initState, action: Action) {
switch (action.type) {
case authActions.SETYOUNG:
return { ...state, young: action.young };
Expand Down
9 changes: 9 additions & 0 deletions app/src/redux/cohort/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CohortType } from "snu-lib";

export const authActions = {
SETCOHORT: "SETCOHORT",
};

export function setCohort(cohort?: CohortType) {
return { type: authActions.SETCOHORT, cohort };
}
28 changes: 28 additions & 0 deletions app/src/redux/cohort/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { CohortType } from "snu-lib";

import { authActions } from "./actions";

type Action = {
type: string;
cohort?: CohortType;
};

export type CohortState = {
// TODO: use API route response
Cohort: {
cohort: CohortType;
};
};

const initState = {
cohort: null,
};

export default function reducer(state = initState, action: Action) {
switch (action.type) {
case authActions.SETCOHORT:
return { ...state, cohort: action.cohort };
default:
return state;
}
}
3 changes: 2 additions & 1 deletion app/src/redux/reducers.js → app/src/redux/reducers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { reducer as toastr } from "react-redux-toastr";

import Auth from "./auth/reducer";
import Cohort from "./cohort/reducer";

export default { Auth, toastr };
export default { Auth, Cohort, toastr };
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import ChangedDepartmentInfoModalContent from "./ChangedDepartmentInfoModalConte
import ChooseCohortModalContent from "./ChooseCohortModalContent";
import { updateYoung } from "../../../../../../services/young.service";
import { capture } from "../../../../../../sentry";
import { isCohortDone } from "../../../../../../utils/cohorts";
import { YOUNG_STATUS_PHASE1, YOUNG_STATUS, translate, calculateAge, getCohortPeriod, isCle } from "snu-lib";
import { getCohort } from "@/utils/cohorts";
import { YOUNG_STATUS_PHASE1, YOUNG_STATUS, translate, calculateAge, getCohortPeriod, isCle, CohortType } from "snu-lib";
import useCohort from "@/services/useCohort";
import api from "../../../../../../services/api";
import { setYoung } from "../../../../../../redux/auth/actions";
import { setCohort } from "@/redux/cohort/actions";

const changeAddressSteps = {
CONFIRM: "CONFIRM",
Expand All @@ -25,18 +25,19 @@ const changeAddressSteps = {
};

const ChangeAddressModal = ({ onClose, isOpen, young }) => {
const currentCohort = getCohort(young?.cohort);
const [newCohortName, setNewCohortName] = useState();
const [newAddress, setNewAddress] = useState();
const { cohort: currentCohort, isCohortDone } = useCohort();
const [availableCohorts, setAvailableCohorts] = useState<CohortType[]>([]);
const [selectedCohortId, setSelectedCohortId] = useState<string>();
const newCohort = availableCohorts.find((c) => c._id === selectedCohortId);
const [newAddress, setNewAddress] = useState<any>();
const [step, setStep] = useState(changeAddressSteps.CONFIRM);
const [isLoading, setLoading] = useState(false);
const [availableCohorts, setAvailableCohorts] = useState([]);

const dispatch = useDispatch();

const onCancel = () => {
setStep(changeAddressSteps.CONFIRM);
setNewCohortName(undefined);
setSelectedCohortId(undefined);
setNewAddress(undefined);
onClose();
};
Expand All @@ -56,7 +57,7 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
}
};

const checkIfGoalIsReached = async (cohortName, address) => {
const checkIfGoalIsReached = async (cohortName: string, address) => {
try {
setLoading(true);
const res = await api.get(`/inscription-goal/${cohortName}/department/${address.department}/reached`);
Expand All @@ -70,7 +71,7 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
}
};

const checkInscriptionGoal = async (cohortName, address) => {
const checkInscriptionGoal = async (cohortName: string, address) => {
try {
const isGoalReached = await checkIfGoalIsReached(cohortName, address);
if (isGoalReached && young.status === YOUNG_STATUS.VALIDATED) {
Expand Down Expand Up @@ -105,17 +106,17 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
try {
const data = await fetchAvailableCohorts(address);
const isArray = Array.isArray(data);
let cohorts = [];
let cohorts: CohortType[] = [];
// get all available cohorts except the current one
if (isArray) {
const isCurrentCohortAvailable = data.find((cohort) => cohort.name === young.cohort);
if (isCurrentCohortAvailable) return checkInscriptionGoal(young.cohort, address);
cohorts = data.map((cohort) => cohort.name).filter((cohort) => cohort !== young.cohort);
cohorts = data.filter((cohort) => cohort.id !== young.cohortId);
}
// if no available cohort, check eligibility and add "à venir" cohort
// @todo : this date should come from the db
if (cohorts.length === 0 && calculateAge(young.birthdateAt, new Date("2023-09-30")) < 18) {
cohorts.push("à venir");
cohorts.push({ name: "à venir" });
}
// if any available cohort, show modal to choose one
if (cohorts.length > 0) {
Expand All @@ -131,21 +132,24 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
}
};

const chooseNewCohort = async (cohort) => {
setNewCohortName(cohort);
if (cohort === "à venir") {
updateAddress(newAddress, young.status, cohort);
const chooseNewCohort = async (cohort: CohortType) => {
setSelectedCohortId(cohort._id);
if (cohort.name === "à venir") {
updateAddress(newAddress, young.status);
} else {
checkInscriptionGoal(cohort, newAddress);
checkInscriptionGoal(cohort.name, newAddress);
}
};

const updateAddress = async (address = newAddress, status = young.status, cohort = newCohortName || young.cohort) => {
const updateAddress = async (address = newAddress, status = young.status) => {
if (!newCohort) throw new Error("newCohort is required");
try {
setLoading(true);
const { title, message, data: updatedYoung } = await updateYoung("address", { ...address, status, cohort });
const dataToUpdate = { ...address, status, cohortId: newCohort._id, cohortName: newCohort.name };
const { title, message, data: updatedYoung } = await updateYoung("address", dataToUpdate);
toastr.success(title, message);
dispatch(setYoung(updatedYoung));
dispatch(setCohort(newCohort));
setStep(changeAddressSteps.CONFIRM);
onClose();
} catch (error) {
Expand All @@ -157,7 +161,7 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
}
};

const cantChangeAddress = young.statusPhase1 === YOUNG_STATUS_PHASE1.AFFECTED && !isCohortDone(young.cohort);
const cantChangeAddress = young.statusPhase1 === YOUNG_STATUS_PHASE1.AFFECTED && !isCohortDone;

return (
<Modal
Expand Down Expand Up @@ -193,7 +197,7 @@ const ChangeAddressModal = ({ onClose, isOpen, young }) => {
<ChooseCohortModalContent
onCancel={onCancel}
onConfirm={chooseNewCohort}
cohorts={availableCohorts.map((cohort) => ({ value: cohort, label: cohort === "à venir" ? "Séjour à venir" : `Séjour ${getCohortPeriod(getCohort(cohort))}` }))}
cohorts={availableCohorts.map((cohort) => ({ value: cohort._id, label: cohort.name === "à venir" ? "Séjour à venir" : `Séjour ${getCohortPeriod(cohort)}` }))}
currentCohortPeriod={getCohortPeriod(currentCohort)}
isLoading={isLoading}
/>
Expand Down
9 changes: 5 additions & 4 deletions app/src/scenes/account/scenes/general/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { BiLoaderAlt } from "react-icons/bi";
import { useLocation } from "react-router-dom";
import { toastr } from "react-redux-toastr";
import { PHONE_ZONES } from "snu-lib";
import { useDispatch, useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { setYoung } from "@/redux/auth/actions";
import { validateEmail, validatePhoneNumber } from "@/utils/form-validation.utils";
import { updateYoung } from "@/services/young.service";
Expand All @@ -19,7 +19,8 @@ import ButtonLight from "@/components/ui/buttons/ButtonLight";
import ChangeAddressModal from "./components/ChangeAddressModal";
import ChangeEmailModal from "./components/ChangeEmailModal";
import InlineButton from "@/components/dsfr/ui/buttons/InlineButton";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";
import useAuth from "@/services/useAuth";

const getInitialFormValues = (young) => ({
lastName: young.lastName || "",
Expand All @@ -35,8 +36,8 @@ const getInitialFormValues = (young) => ({
});

const AccountGeneralPage = () => {
const young = useSelector((state) => state.Auth.young);
const cohort = getCohort(young.cohort);
const { young } = useAuth();
const { cohort } = useCohort();
const cantUpdatePSC1 = cohort.isAssignmentAnnouncementsOpenForYoung;
const dispatch = useDispatch();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import React from "react";
import { HiOutlineInformationCircle } from "react-icons/hi";
import useAuth from "@/services/useAuth";
import { getCohortPeriod, YOUNG_STATUS } from "snu-lib";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";

const CurrentSejourNotice = () => {
const { young } = useAuth();
const cohort = getCohort(young.cohort);
const { cohort } = useCohort();
const cohortPeriod = getCohortPeriod(cohort);
const sejourIsDone = new Date() > new Date(cohort.endAt);
const sejourIsDone = new Date() > new Date(cohort.dateEnd);

const text =
young.status === YOUNG_STATUS.WITHDRAWN ? (
Expand Down
5 changes: 2 additions & 3 deletions app/src/scenes/changeSejour/scenes/ChangeSejourMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import useAuth from "@/services/useAuth";
import { HiArrowRight } from "react-icons/hi";
import { CohortGroupType, CohortType, getCohortPeriod, getCohortYear } from "snu-lib";
import plausibleEvent from "@/services/plausible";
import { getCohort } from "@/utils/cohorts";
import Loader from "@/components/Loader";
import { knowledgebaseURL } from "@/config";
import NoSejourSection from "../components/NoSejourSection";
Expand All @@ -15,6 +14,7 @@ import { capitalizeFirstLetter } from "@/scenes/inscription2023/steps/stepConfir
import usePermissions from "@/hooks/usePermissions";
import { useLocation } from "react-router-dom";
import ErrorNotice from "@/components/ui/alerts/ErrorNotice";
import useCohort from "@/services/useCohort";

export default function ChangeSejour() {
const groups = useCohortGroups();
Expand Down Expand Up @@ -47,8 +47,7 @@ export default function ChangeSejour() {
}

function Sejours({ cohorts }: { cohorts: CohortType[] }) {
const { young } = useAuth();
const cohort = getCohort(young.cohort);
const { cohort } = useCohort();
return (
<section id="changement-de-sejour" className="text-center">
<h2 className="text-base font-bold md:text-2xl">S'inscrire à un autre séjour en {getCohortYear(cohort)}</h2>
Expand Down
9 changes: 4 additions & 5 deletions app/src/scenes/changeSejour/scenes/NewChoiceSejour.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import useAuth from "@/services/useAuth";
import ReasonForm from "../components/ReasonForm";
import ResponsiveModal from "@/components/modals/ResponsiveModal";
import ChangeSejourContainer from "../components/ChangeSejourContainer";
import { getCohortPeriod, YOUNG_STATUS } from "snu-lib";
import { getCohortPeriod } from "snu-lib";
import useChangeSejour from "../lib/useChangeSejour";
import { HiOutlineCheckCircle, HiOutlineXCircle } from "react-icons/hi2";
import { capitalizeFirstLetter } from "@/scenes/inscription2023/steps/stepConfirm";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";
import useInscriptionGoal from "../lib/useInscriptionGoal";
import Loader from "@/components/Loader";
import ErrorNotice from "@/components/ui/alerts/ErrorNotice";
Expand Down Expand Up @@ -38,11 +37,11 @@ export default function NewChoiceSejour() {
}

function Modal({ open, setOpen, newCohortPeriod, reason, message }) {
const { young } = useAuth();
const { cohort: currentCohort } = useCohort();
const queryParams = new URLSearchParams(window.location.search);
const cohortId = queryParams.get("cohortid") || "";
const cohortName = queryParams.get("cohortName") || "";
const oldCohortPeriod = capitalizeFirstLetter(getCohortPeriod(getCohort(young.cohort)));
const oldCohortPeriod = capitalizeFirstLetter(getCohortPeriod(currentCohort));
const history = useHistory();
const sejourMutation = useChangeSejour();
const goalQuery = useInscriptionGoal(cohortName);
Expand Down
7 changes: 3 additions & 4 deletions app/src/scenes/changeSejour/scenes/PrevenirSejour.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import React, { useState } from "react";
import ReasonForm from "../components/ReasonForm";
import { useHistory } from "react-router-dom";
import useAuth from "@/services/useAuth";
import ChangeSejourContainer from "../components/ChangeSejourContainer";
import ResponsiveModal from "@/components/modals/ResponsiveModal";
import { getCohortPeriod } from "snu-lib";
import useChangeSejour from "../lib/useChangeSejour";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";
import { capitalizeFirstLetter } from "@/scenes/inscription2023/steps/stepConfirm";
import { HiOutlineXCircle } from "react-icons/hi2";
import { HiOutlineCheckCircle } from "react-icons/hi2";
Expand All @@ -26,9 +25,9 @@ export default function PrevenirSejour() {
}

function Modal({ open, setOpen, reason, message }) {
const { young } = useAuth();
const { cohort } = useCohort();
const history = useHistory();
const date = capitalizeFirstLetter(getCohortPeriod(getCohort(young.cohort)));
const date = capitalizeFirstLetter(getCohortPeriod(cohort));
const { mutate, isPending: loading } = useChangeSejour();

const handleChangeCohort = async () => {
Expand Down
4 changes: 2 additions & 2 deletions app/src/scenes/home/EnAttente.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { YOUNG_STATUS } from "../../utils";
import { getCohort } from "@/utils/cohorts";
import useCohort from "@/services/useCohort";
import useAuth from "@/services/useAuth";
import HomeContainer from "@/components/layout/HomeContainer";
import HomeHeader from "@/components/layout/HomeHeader";
Expand All @@ -13,7 +13,7 @@ import SejourNotice from "./components/SejourNotice";
export default function EnAttente() {
const { young, isCLE } = useAuth();
const title = `${young.firstName}, bienvenue sur votre compte ${isCLE ? "élève" : "volontaire"}`;
const cohort = getCohort(young.cohort);
const { cohort } = useCohort();

return (
<HomeContainer>
Expand Down
Loading

0 comments on commit 938d58b

Please sign in to comment.