211 lines
7.6 KiB
TypeScript
211 lines
7.6 KiB
TypeScript
import backgroundImage from "@Assets/images/background_refonte.svg";
|
|
import DeedTypes from "@Front/Api/LeCoffreApi/Notary/DeedTypes/DeedTypes";
|
|
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
|
import Users from "@Front/Api/LeCoffreApi/Notary/Users/Users";
|
|
import Button from "@Front/Components/DesignSystem/Button";
|
|
import { IOption } from "@Front/Components/DesignSystem/Dropdown/DropdownMenu/DropdownOption";
|
|
import Form from "@Front/Components/DesignSystem/Form";
|
|
import AutocompleteMultiSelectField from "@Front/Components/DesignSystem/Form/AutocompleteMultiSelectField";
|
|
import SelectField from "@Front/Components/DesignSystem/Form/SelectField";
|
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
|
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
|
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
|
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
|
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
|
import JwtService from "@Front/Services/JwtService/JwtService";
|
|
import { ValidationError } from "class-validator/types/validation/ValidationError";
|
|
import { Deed, Office, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
|
import User from "le-coffre-resources/dist/Notary";
|
|
import { DeedType } from "le-coffre-resources/dist/Notary";
|
|
import { useRouter } from "next/router";
|
|
import React, { useCallback, useEffect, useState } from "react";
|
|
|
|
import classes from "./classes.module.scss";
|
|
|
|
export default function CreateFolder(): JSX.Element {
|
|
/**
|
|
* State
|
|
*/
|
|
const [folderAccessType, setFolderAccessType] = useState<"whole_office" | "select_collaborators">("select_collaborators");
|
|
const [availableDeedTypes, setAvailableDeedTypes] = useState<DeedType[]>([]);
|
|
const [availableCollaborators, setAvailableCollaborators] = useState<User[]>([]);
|
|
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
|
const [selectedCollaborators, setSelectedCollaborators] = useState<User[]>([]);
|
|
|
|
/**
|
|
* Hooks call
|
|
*/
|
|
const router = useRouter();
|
|
|
|
/**
|
|
* Callbacks
|
|
*/
|
|
|
|
const onFormSubmit = async (
|
|
e: React.FormEvent<HTMLFormElement> | null,
|
|
values: {
|
|
[key: string]: any;
|
|
},
|
|
) => {
|
|
const officeId = JwtService.getInstance().decodeJwt()?.office_Id;
|
|
|
|
const officeFolderForm = OfficeFolder.hydrate<OfficeFolder>({
|
|
folder_number: values["folder_number"],
|
|
name: values["name"],
|
|
description: values["description"],
|
|
deed: Deed.hydrate<Deed>({
|
|
deed_type: DeedType.hydrate<DeedType>({
|
|
uid: values["deed"],
|
|
}),
|
|
}),
|
|
office: Office.hydrate<Office>({
|
|
uid: officeId,
|
|
}),
|
|
customers: [],
|
|
stakeholders: folderAccessType === "whole_office" ? availableCollaborators : selectedCollaborators,
|
|
});
|
|
|
|
try {
|
|
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: true });
|
|
} catch (validationErrors) {
|
|
setValidationError(validationErrors as ValidationError[]);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const newOfficeFolder = await Folders.getInstance().post(officeFolderForm);
|
|
if (!newOfficeFolder) return;
|
|
router.push(`/folders/${newOfficeFolder.uid}`);
|
|
} catch (backError) {
|
|
if (!Array.isArray(backError)) return;
|
|
setValidationError(backError as ValidationError[]);
|
|
return;
|
|
}
|
|
};
|
|
|
|
const radioOnChange = (e: React.ChangeEvent<HTMLInputElement>) =>
|
|
setFolderAccessType(e.target.value as "whole_office" | "select_collaborators");
|
|
|
|
const onSelectedCollaboratorsChange = useCallback(
|
|
(options: IOption[] | null) => {
|
|
if (!options) return;
|
|
const collaborators = availableCollaborators.filter((collaborator) => options.find((option) => option.id === collaborator.uid));
|
|
setSelectedCollaborators(collaborators);
|
|
},
|
|
[availableCollaborators],
|
|
);
|
|
|
|
/**
|
|
* UseEffect
|
|
*/
|
|
useEffect(() => {
|
|
DeedTypes.getInstance()
|
|
.get({ where: { archived_at: null } })
|
|
.then((deedTypes) => setAvailableDeedTypes(deedTypes));
|
|
// no need to pass query 'where' param here, default query for notaries include only users which are in the same office as the caller
|
|
Users.getInstance()
|
|
.get({
|
|
include: { contact: true },
|
|
})
|
|
.then((users) => {
|
|
setAvailableCollaborators(users);
|
|
// set default selected collaborators to the connected user
|
|
const currentUser = users.find((user) => user.uid === JwtService.getInstance().decodeJwt()?.userId);
|
|
if (currentUser) {
|
|
setSelectedCollaborators([currentUser]);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
/**
|
|
* Renderer
|
|
*/
|
|
return (
|
|
<DefaultDoubleSidePage title={"Dossier"} image={backgroundImage} type="background" showHeader={true}>
|
|
<div className={classes["root"]}>
|
|
<BackArrow />
|
|
<div className={classes["header"]}>
|
|
<Typography typo={ETypo.DISPLAY_LARGE} color={ETypoColor.COLOR_GENERIC_BLACK} className={classes["title"]}>
|
|
Créer un dossier
|
|
</Typography>
|
|
<Typography typo={ETypo.TITLE_H5} color={ETypoColor.COLOR_PRIMARY_500} className={classes["subtitle"]}>
|
|
Informations du dossier
|
|
</Typography>
|
|
</div>
|
|
|
|
<Form onSubmit={onFormSubmit} className={classes["form"]}>
|
|
<TextField
|
|
name="folder_number"
|
|
label="Numéro de dossier"
|
|
placeholder="Entrer le numéro de dossier"
|
|
validationError={validationError.find((error) => error.property === "folder_number")}
|
|
/>
|
|
<TextField
|
|
name="name"
|
|
label="Intitulé"
|
|
placeholder="Entrer l'intitulé du dossier"
|
|
validationError={validationError.find((error) => error.property === "name")}
|
|
/>
|
|
<SelectField
|
|
name="deed"
|
|
label="Type d'acte"
|
|
placeholder="Sélectionner un type d'acte"
|
|
options={
|
|
availableDeedTypes.map((deedType) => ({
|
|
id: deedType.uid,
|
|
label: deedType.name,
|
|
})) as IOption[]
|
|
}
|
|
validationError={validationError.find((error) => error.property === "deed")}
|
|
/>
|
|
|
|
<TextAreaField
|
|
name="description"
|
|
label="Note de dossier"
|
|
placeholder="Renseigner une note"
|
|
validationError={validationError.find((error) => error.property === "description")}
|
|
required={false}
|
|
/>
|
|
|
|
<div className={classes["bottom-container"]}>
|
|
<Typography typo={ETypo.TITLE_H5} color={ETypoColor.COLOR_PRIMARY_500}>
|
|
Donner l'accès au dossier
|
|
</Typography>
|
|
<div className={classes["radio-container"]}>
|
|
<RadioBox name="file_access" onChange={radioOnChange} value="whole_office" label="Sélectionner tout l'office" />
|
|
<RadioBox
|
|
name="file_access"
|
|
defaultChecked
|
|
onChange={radioOnChange}
|
|
value="select_collaborators"
|
|
label="Sélectionner certains collaborateurs"
|
|
/>
|
|
</div>
|
|
{folderAccessType === "select_collaborators" && (
|
|
<div className={classes["collaborators-container"]}>
|
|
<AutocompleteMultiSelectField
|
|
label="Sélectionner les collaborateurs"
|
|
options={availableCollaborators.map((collaborator) => ({
|
|
label: collaborator.contact?.last_name.concat(" ", collaborator.contact.first_name) ?? "",
|
|
id: collaborator.uid ?? "",
|
|
}))}
|
|
selectedOptions={selectedCollaborators.map((collaborator) => ({
|
|
label: collaborator.contact?.last_name.concat(" ", collaborator.contact.first_name) ?? "",
|
|
id: collaborator.uid ?? "",
|
|
}))}
|
|
onSelectionChange={onSelectedCollaboratorsChange}
|
|
validationError={validationError.find((error) => error.property === "stakeholders")}
|
|
/>
|
|
</div>
|
|
)}
|
|
<div className={classes["buttons-container"]}>
|
|
<Button type="submit">Créer le dossier</Button>
|
|
</div>
|
|
</div>
|
|
</Form>
|
|
</div>
|
|
</DefaultDoubleSidePage>
|
|
);
|
|
}
|