🔨 email reminder

This commit is contained in:
Max S 2024-08-27 12:15:41 +02:00
parent 1e4ab173ee
commit 62b51b4047
10 changed files with 105 additions and 33 deletions

View File

@ -4,11 +4,11 @@ import Tooltip from "../ToolTip";
import Typography, { ETypo, ETypoColor } from "../Typography";
import classes from "./classes.module.scss";
import classNames from "classnames";
import { IOptionOld } from "../Form/SelectFieldOld";
import { IOption } from "../Form/SelectFieldOld";
type IProps = {
name?: string;
option: IOptionOld;
option: IOption;
toolTip?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
checked: boolean;

View File

@ -10,9 +10,9 @@ import classes from "./classes.module.scss";
import { NextRouter, useRouter } from "next/router";
type IProps = {
selectedOption?: IOptionOld;
onChange?: (selectedOption: IOptionOld) => void;
options: IOptionOld[];
selectedOption?: IOption;
onChange?: (selectedOption: IOption) => void;
options: IOption[];
hasBorderRightCollapsed?: boolean;
placeholder?: string;
className?: string;
@ -21,7 +21,7 @@ type IProps = {
errors?: ValidationError;
};
export type IOptionOld = {
export type IOption = {
value: unknown;
label: string;
icon?: ReactNode;
@ -32,7 +32,7 @@ type IState = {
isOpen: boolean;
listWidth: number;
listHeight: number;
selectedOption: IOptionOld | null;
selectedOption: IOption | null;
errors: ValidationError | null;
};
@ -187,7 +187,7 @@ class SelectFieldClass extends React.Component<IPropsClass, IState> {
});
}
private onSelect(option: IOptionOld, e: React.MouseEvent<HTMLLIElement, MouseEvent>) {
private onSelect(option: IOption, e: React.MouseEvent<HTMLLIElement, MouseEvent>) {
if (this.props.disabled) return;
this.props.onChange && this.props.onChange(option);
this.setState({

View File

@ -13,14 +13,14 @@ import React, { useCallback, useEffect, useState } from "react";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import classes from "./classes.module.scss";
import ParameterDocuments from "./ParameterDocuments";
import { IOptionOld } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import backgroundImage from "@Assets/images/background_refonte.svg";
export default function AskDocuments() {
const router = useRouter();
let { folderUid, customerUid } = router.query;
const [isCreateDocumentModalVisible, setIsCreateDocumentModalVisible] = useState<boolean>(false);
const [documentTypes, setDocumentTypes] = useState<IOptionOld[]>([]);
const [documentTypes, setDocumentTypes] = useState<IOption[]>([]);
const [folder, setFolder] = useState<OfficeFolder | null>(null);
const closeModal = () => setIsCreateDocumentModalVisible(false);
@ -62,7 +62,7 @@ export default function AskDocuments() {
);
const getAvailableDocuments = useCallback(
async (folder: OfficeFolder): Promise<IOptionOld[]> => {
async (folder: OfficeFolder): Promise<IOption[]> => {
// Getting already asked documents UIDs in an array
const userDocumentTypesUids = folder
.documents!.filter((document) => document.depositor!.uid! === customerUid!)
@ -81,7 +81,7 @@ export default function AskDocuments() {
if (!documentTypes) return [];
// Else, return an array document types formatted as IOPtions
const documentTypesOptions: IOptionOld[] = documentTypes.map((documentType) => {
const documentTypesOptions: IOption[] = documentTypes.map((documentType) => {
return {
label: documentType!.name!,
value: documentType!.uid!,

View File

@ -1,5 +1,7 @@
@import "@Themes/constants.scss";
.root {
display: flex;
flex-direction: column;
gap: var(--spacing-md, 16px);
}

View File

@ -1,7 +1,10 @@
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import Modal from "@Front/Components/DesignSystem/Modal";
import Separator, { ESeperatorColor } from "@Front/Components/DesignSystem/Separator";
import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography";
import Customer from "le-coffre-resources/dist/Customer";
import React, { useCallback } from "react";
import React, { useCallback, useMemo, useState } from "react";
import classes from "./classes.module.scss";
@ -14,11 +17,52 @@ type IProps = {
export default function ReminderModal(props: IProps) {
const { isOpen, onClose, onRemindSuccess, customer } = props;
const [selectedOptions, setSelectedOptions] = useState<IOption[]>([]);
const [isAllSelected, setIsAllSelected] = useState(false);
const onRemind = useCallback(() => {
console.log("selectedOptions", selectedOptions);
onRemindSuccess();
onClose?.();
}, [onClose, onRemindSuccess]);
}, [onClose, onRemindSuccess, selectedOptions]);
const documentsOptions: IOption[] = useMemo(
() =>
customer.documents?.map((document) => {
return {
label: document.document_type?.name ?? "",
value: document.document_type?.uid ?? "",
};
}) ?? [],
[customer],
);
const handleOnChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const { value, checked } = e.target;
const optionSelected = documentsOptions.find((option) => option.value === value);
if (checked && optionSelected) {
setSelectedOptions((prev) => [...prev, optionSelected]);
} else {
setSelectedOptions((prev) => prev.filter((option) => option.value !== value));
}
},
[documentsOptions],
);
const handleSelectAll = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const { checked } = e.target;
if (checked) {
setSelectedOptions(documentsOptions);
setIsAllSelected(true);
} else {
setSelectedOptions([]);
setIsAllSelected(false);
}
},
[documentsOptions],
);
return (
<Modal
@ -31,6 +75,21 @@ export default function ReminderModal(props: IProps) {
<Typography typo={ETypo.TEXT_MD_LIGHT}>
Sélectionnez le(s) document(s) pour lequel vous souhaitez relancer le client.
</Typography>
<CheckBox
option={{ label: "Tous les documents", value: "all-documents" }}
checked={isAllSelected}
onChange={handleSelectAll}
/>
<Separator color={ESeperatorColor.LIGHT} />
{documentsOptions.map((option) => (
<CheckBox
key={option.value as string}
option={option}
onChange={handleOnChange}
checked={isAllSelected}
disabled={isAllSelected}
/>
))}
</div>
</Modal>
);

View File

@ -13,10 +13,12 @@ import Link from "next/link";
type IProps = {
customer: Customer;
doesCustomerHaveDocument: boolean;
isAnchored: boolean;
};
export default function EmailReminder(props: IProps) {
const { customer } = props;
const { customer, doesCustomerHaveDocument, isAnchored } = props;
const { isOpen, open, close } = useOpenable();
const router = useRouter();
@ -24,14 +26,17 @@ export default function EmailReminder(props: IProps) {
return (
<div className={classes["root"]}>
<Button
onClick={open}
rightIcon={<EnvelopeIcon />}
variant={EButtonVariant.PRIMARY}
styletype={EButtonstyletype.OUTLINED}
fullwidth>
Relancer par mail
</Button>
{!isAnchored && (
<Button
onClick={open}
rightIcon={<EnvelopeIcon />}
variant={EButtonVariant.PRIMARY}
styletype={EButtonstyletype.OUTLINED}
fullwidth
disabled={doesCustomerHaveDocument}>
Relancer par mail
</Button>
)}
<div className={classes["reminder-info"]}>
<Link
title={"Voir l'historique des relances"}
@ -41,11 +46,13 @@ export default function EmailReminder(props: IProps) {
<IconButton icon={<ClockIcon />} variant={EIconButtonVariant.NEUTRAL} />
</Link>
<div className={classes["info"]}>
{/* TODO: mettre la date de la dernière relance */}
<Typography typo={ETypo.TEXT_XS_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Dernière relance: todo
Dernière relance: -
</Typography>
{/* TODO: mettre le nombre de relance */}
<Typography typo={ETypo.TEXT_XS_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Nombre de relance: todo
Nombre de relance: -
</Typography>
</div>
</div>

View File

@ -35,7 +35,7 @@ $mobile-breakpoint: 664px;
.button-container {
display: flex;
flex-direction: column;
gap: var(--spacing-lg, 24px);
gap: var(--spacing-md, 16px);
}
@media screen and (max-width: $screen-s) {

View File

@ -115,7 +115,11 @@ export default function ClientView(props: IProps) {
</Button>
</Link>
)}
<EmailReminder customer={customer} />
<EmailReminder
customer={customer}
doesCustomerHaveDocument={!doesCustomerHaveDocument}
isAnchored={anchorStatus !== AnchorStatus.NOT_ANCHORED}
/>
</div>
</div>

View File

@ -1,7 +1,7 @@
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import Select, { IOptionOld } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
@ -81,7 +81,7 @@ export default function UpdateFolderMetadata() {
const deedOption = {
label: selectedFolder?.deed?.deed_type?.name,
value: selectedFolder?.deed?.deed_type?.uid,
} as IOptionOld;
} as IOption;
const openingDate = new Date(selectedFolder?.created_at ?? "");
if (!selectedFolder?.created_at) return <></>;
const defaultValue = openingDate.toISOString().split("T")[0];

View File

@ -1,6 +1,6 @@
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import Select, { IOptionOld } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
@ -18,7 +18,7 @@ type IProps = {
};
type IState = {
selectedFolder: OfficeFolder | null;
selectedOption?: IOptionOld;
selectedOption?: IOption;
};
class UpdateFolderMetadataClass extends BasePage<IProps, IState> {
constructor(props: IProps) {
@ -74,7 +74,7 @@ class UpdateFolderMetadataClass extends BasePage<IProps, IState> {
);
}
private onSelectedOption(option: IOptionOld) {
private onSelectedOption(option: IOption) {
this.setState({
selectedOption: option,
});