void - closeModal: (e: KeyboardEvent | MouseEvent) => void + closeModal: (e?: KeyboardEvent | MouseEvent) => void } export type ModalContainerProps = { onClose: () => void @@ -68,8 +68,8 @@ function ModalContainer( } } - function handleClose(e: KeyboardEvent | MouseEvent) { - e.preventDefault() + function handleClose(e?: KeyboardEvent | MouseEvent) { + e?.preventDefault() if (previousFocusedElement.current) previousFocusedElement.current.focus() onClose() } diff --git a/components/jeune/DeleteBeneficiaireActifModal.tsx b/components/jeune/DeleteBeneficiaireActifModal.tsx index cf8e163cc..45a01a5ed 100644 --- a/components/jeune/DeleteBeneficiaireActifModal.tsx +++ b/components/jeune/DeleteBeneficiaireActifModal.tsx @@ -20,7 +20,10 @@ import Textarea from 'components/ui/Form/Textarea' import { IllustrationName } from 'components/ui/IllustrationComponent' import InformationMessage from 'components/ui/Notifications/InformationMessage' import { ValueWithError } from 'components/ValueWithError' -import { BaseBeneficiaire, DetailBeneficiaire } from 'interfaces/beneficiaire' +import { + BaseBeneficiaire, + BeneficiaireWithActivity, +} from 'interfaces/beneficiaire' import { SuppressionBeneficiaireFormData } from 'interfaces/json/beneficiaire' import { MotifSuppressionBeneficiaire } from 'interfaces/referentiel' import useMatomo from 'utils/analytics/useMatomo' @@ -28,7 +31,7 @@ import { dateIsInInterval, toShortDate } from 'utils/date' import { usePortefeuille } from 'utils/portefeuilleContext' interface DeleteBeneficiaireActifModalProps { - beneficiaire: DetailBeneficiaire + beneficiaire: BeneficiaireWithActivity motifsSuppression: MotifSuppressionBeneficiaire[] onClose: () => void soumettreSuppression: ( @@ -36,15 +39,19 @@ interface DeleteBeneficiaireActifModalProps { ) => Promise } -export default function DeleteBeneficiaireActifModal({ - beneficiaire, - motifsSuppression, - onClose, - soumettreSuppression, -}: DeleteBeneficiaireActifModalProps) { +function DeleteBeneficiaireActifModal( + { + beneficiaire, + motifsSuppression, + onClose, + soumettreSuppression, + }: DeleteBeneficiaireActifModalProps, + ref: ForwardedRef +) { const [portefeuille] = usePortefeuille() const modalRef = useRef(null) + useImperativeHandle(ref, () => modalRef.current!) const [showModalConfirmation, setShowModalConfirmation] = useState(true) @@ -90,6 +97,7 @@ export default function DeleteBeneficiaireActifModal({ ) } +export default forwardRef(DeleteBeneficiaireActifModal) const ModalConfirmation = forwardRef( ( @@ -151,7 +159,7 @@ const ModalSuppressionForm = forwardRef( onSuppression, onClose, }: { - beneficiaire: DetailBeneficiaire + beneficiaire: BeneficiaireWithActivity motifsSuppression: MotifSuppressionBeneficiaire[] onSuppression: (payload: SuppressionBeneficiaireFormData) => Promise onClose: () => void diff --git a/components/jeune/DeleteJeuneInactifModal.tsx b/components/jeune/DeleteBeneficiaireInactifModal.tsx similarity index 74% rename from components/jeune/DeleteJeuneInactifModal.tsx rename to components/jeune/DeleteBeneficiaireInactifModal.tsx index a2087d7e4..0261015a0 100644 --- a/components/jeune/DeleteJeuneInactifModal.tsx +++ b/components/jeune/DeleteBeneficiaireInactifModal.tsx @@ -1,4 +1,9 @@ -import React, { useRef } from 'react' +import React, { + ForwardedRef, + forwardRef, + useImperativeHandle, + useRef, +} from 'react' import Modal, { ModalHandles } from 'components/Modal' import Button, { ButtonStyle } from 'components/ui/Button/Button' @@ -8,19 +13,19 @@ import useMatomo from 'utils/analytics/useMatomo' import { usePortefeuille } from 'utils/portefeuilleContext' interface DeleteJeuneInactifModalProps { - jeune: BaseBeneficiaire + beneficiaire: BaseBeneficiaire onClose: () => void onDelete: () => Promise } -export default function DeleteJeuneInactifModal({ - jeune, - onClose, - onDelete, -}: DeleteJeuneInactifModalProps) { +function DeleteBeneficiaireInactifModal( + { beneficiaire, onClose, onDelete }: DeleteJeuneInactifModalProps, + ref: ForwardedRef +) { const [portefeuille] = usePortefeuille() const modalRef = useRef(null) + useImperativeHandle(ref, () => modalRef.current!) useMatomo( 'Détail Jeune - Pop-in confirmation suppression', @@ -30,7 +35,7 @@ export default function DeleteJeuneInactifModal({ return ( @@ -58,3 +63,4 @@ export default function DeleteJeuneInactifModal({ ) } +export default forwardRef(DeleteBeneficiaireInactifModal) diff --git a/components/jeune/DeleteBeneficiaireModal.tsx b/components/jeune/DeleteBeneficiaireModal.tsx new file mode 100644 index 000000000..ce8d01f58 --- /dev/null +++ b/components/jeune/DeleteBeneficiaireModal.tsx @@ -0,0 +1,135 @@ +import dynamic from 'next/dynamic' +import { useRouter } from 'next/navigation' +import React, { useEffect, useRef, useState } from 'react' + +import Modal from 'components/Modal' +import { ModalHandles } from 'components/ModalContainer' +import Button, { ButtonStyle } from 'components/ui/Button/Button' +import { IllustrationName } from 'components/ui/IllustrationComponent' +import { BeneficiaireWithActivity } from 'interfaces/beneficiaire' +import { SuppressionBeneficiaireFormData } from 'interfaces/json/beneficiaire' +import { MotifSuppressionBeneficiaire } from 'interfaces/referentiel' +import { getMotifsSuppression } from 'services/beneficiaires.service' +import { useCurrentConversation } from 'utils/chat/currentConversationContext' +import { usePortefeuille } from 'utils/portefeuilleContext' + +const DeleteBeneficiaireActifModal = dynamic( + () => import('components/jeune/DeleteBeneficiaireActifModal') +) +const DeleteJeuneInactifModal = dynamic( + () => import('components/jeune/DeleteBeneficiaireInactifModal') +) + +type DeleteBeneficiaireModalProps = { + beneficiaire: BeneficiaireWithActivity + onClose: () => void + onError: () => void +} + +export default function DeleteBeneficiaireModal({ + beneficiaire, + onClose, + onError, +}: DeleteBeneficiaireModalProps) { + const router = useRouter() + const [portefeuille, setPortefeuille] = usePortefeuille() + const [currentConversation, setCurrentConversation] = useCurrentConversation() + + const modalRef = useRef(null) + + const [motifsSuppression, setMotifsSuppression] = useState< + MotifSuppressionBeneficiaire[] + >([]) + + const [ + showModaleSuccesDeleteBeneficiaire, + setShowModaleSuccesDeleteBeneficiaire, + ] = useState(false) + + async function archiverJeuneActif( + payload: SuppressionBeneficiaireFormData + ): Promise { + try { + const { archiverJeune } = await import('services/beneficiaires.service') + await archiverJeune(beneficiaire.id, payload) + + removeBeneficiaireFromPortefeuille(beneficiaire.id) + setShowModaleSuccesDeleteBeneficiaire(true) + } catch { + onError() + modalRef.current!.closeModal() + } + } + + async function supprimerJeuneInactif(): Promise { + try { + const { supprimerJeuneInactif: _supprimerJeuneInactif } = await import( + 'services/beneficiaires.service' + ) + await _supprimerJeuneInactif(beneficiaire.id) + + removeBeneficiaireFromPortefeuille(beneficiaire.id) + setShowModaleSuccesDeleteBeneficiaire(true) + } catch { + onError() + modalRef.current!.closeModal() + } + } + + function removeBeneficiaireFromPortefeuille(idBeneficiaire: string): void { + const updatedPortefeuille = [...portefeuille] + const index = updatedPortefeuille.findIndex( + ({ id }) => id === idBeneficiaire + ) + updatedPortefeuille.splice(index, 1) + setPortefeuille(updatedPortefeuille) + if (currentConversation?.conversation.id === idBeneficiaire) + setCurrentConversation(undefined) + } + + useEffect(() => { + if (beneficiaire.isActivated) { + getMotifsSuppression().then(setMotifsSuppression) + } + }, []) + + return ( + <> + {!showModaleSuccesDeleteBeneficiaire && beneficiaire.isActivated && ( + + )} + + {!showModaleSuccesDeleteBeneficiaire && !beneficiaire.isActivated && ( + + )} + + {showModaleSuccesDeleteBeneficiaire && ( + router.push('/mes-jeunes')} + titleIllustration={IllustrationName.Check} + > + + + )} + + ) +} diff --git a/components/layouts/Header.tsx b/components/layouts/Header.tsx index 47f819f8f..79c2ba5a3 100644 --- a/components/layouts/Header.tsx +++ b/components/layouts/Header.tsx @@ -1,6 +1,7 @@ import React from 'react' import { + ID_CONTENU, PAGE_ACTIONS_ROOT_ID, PAGE_NAVIGATION_ROOT_ID, } from 'components/globals' @@ -8,6 +9,8 @@ import { export default function Header() { return (