This commit is contained in:
OxSaitama 2023-07-10 16:14:15 +02:00
commit 27f6d50a0c
29 changed files with 957 additions and 1203 deletions

View File

@ -13,16 +13,16 @@ const nextConfig = {
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT,
NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID,
},
webpack: config => {
config.node = {
fs: 'empty',
child_process: 'empty',
net: 'empty',
dns: 'empty',
tls: 'empty',
};
return config;
},
// webpack: config => {
// config.node = {
// fs: 'empty',
// child_process: 'empty',
// net: 'empty',
// dns: 'empty',
// tls: 'empty',
// };
// return config;
// },
};
module.exports = nextConfig;

978
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,13 +23,15 @@
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
"form-data": "^4.0.0",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.52",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.55",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-select": "^5.7.2",
"sass": "^1.59.2",
"sharp": "^0.32.1",
"typescript": "4.9.5"
}
}

View File

@ -0,0 +1,38 @@
import BaseApiService from "@Front/Api/BaseApiService";
export default class User extends BaseApiService {
private static instance: User;
private readonly baseURl = this.getBaseUrl().concat("/idnot/user");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new User();
} else {
return this.instance;
}
}
public async login(uid: string) {
const url = new URL(this.baseURl.concat("/login/").concat(uid));
try {
return await this.postRequest(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async refreshToken(refreshToken: string): Promise<{ accessToken: string }> {
const url = new URL(this.baseURl.concat("/refresh-token"));
try {
return await this.postRequest(url, {}, refreshToken);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -1,4 +1,5 @@
import { FrontendVariables } from "@Front/Config/VariablesFront";
import CookieService from "@Front/Services/CookieService/CookieService";
export enum ContentType {
JSON = "application/json",
@ -21,11 +22,14 @@ export default abstract class BaseApiService {
}
protected buildHeaders(contentType: ContentType) {
const token = CookieService.getInstance().getCookie("leCoffreAccessToken");
const headers = new Headers();
if (contentType === ContentType.JSON) {
headers.set("Content-Type", contentType);
}
headers.set("Authorization", `Bearer ${token}`);
return headers;
}
@ -33,7 +37,7 @@ export default abstract class BaseApiService {
return JSON.stringify(body);
}
protected async getRequest<T>(url: URL) {
protected async getRequest<T>(url: URL, token?: string) {
const request = async () =>
await fetch(url, {
method: "GET",
@ -42,7 +46,7 @@ export default abstract class BaseApiService {
return this.sendRequest<T>(request);
}
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
return this.sendRequest<T>(
async () =>
await fetch(url, {
@ -64,7 +68,7 @@ export default abstract class BaseApiService {
);
}
protected async putRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
protected async putRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
const request = async () =>
await fetch(url, {
method: "PUT",
@ -86,7 +90,7 @@ export default abstract class BaseApiService {
return this.sendRequest<T>(request);
}
protected async deleteRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
protected async deleteRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
const request = async () =>
await fetch(url, {
method: "DELETE",
@ -97,7 +101,7 @@ export default abstract class BaseApiService {
return this.sendRequest<T>(request);
}
protected async putFormDataRequest<T>(url: URL, body: FormData) {
protected async putFormDataRequest<T>(url: URL, body: FormData, token?: string) {
const request = async () =>
await fetch(url, {
method: "PUT",

View File

@ -15,7 +15,7 @@ export type IPutDeedTypesParams = {
deed?: DeedType["deed"];
office?: DeedType["office"];
archived_at?: DeedType["archived_at"];
deed_type_has_document_types?: DeedType["deed_type_has_document_types"];
document_types?: DeedType["document_types"];
};
export default class DeedTypes extends BaseSuperAdmin {

View File

@ -15,7 +15,7 @@ export type IPutDeedsParams = {
description?: OfficeFolder["description"];
archived_description?: OfficeFolder["archived_description"];
status?: OfficeFolder["status"];
deed_has_document_types?: Deed["deed_has_document_types"];
document_types?: Deed["document_types"];
};
export default class Deeds extends BaseSuperAdmin {

View File

@ -88,7 +88,7 @@ export default class Folders extends BaseSuperAdmin {
public async delete(uid: string): Promise<OfficeFolder> {
const url = new URL(this.baseURl.concat(`/${uid}`));
const targetedFolder = await this.getByUid(uid);
if (targetedFolder.office_folder_has_customers) return Promise.reject(`The folder ${uid} contains customers`);
if (targetedFolder.customers) return Promise.reject(`The folder ${uid} contains customers`);
try {
return await this.deleteRequest(url);
} catch (err) {

View File

@ -15,7 +15,6 @@ export type IPutUsersParams = {
idNot?: User["idNot"];
contact?: User["contact"];
office_membership?: User["office_membership"];
office_folder_has_stakeholders?: User["office_folder_has_stakeholders"];
documents?: User["documents"];
};

View File

@ -59,10 +59,10 @@ export default class SearchBar extends React.Component<IProps, IState> {
const number = folder.folder_number.toLowerCase();
const value = event.target.value.toLowerCase();
if (folder.office_folder_has_customers) {
const customerNames = folder.office_folder_has_customers
if (folder.customers) {
const customerNames = folder.customers
.map((customer) => {
return `${customer.customer.contact?.first_name.toLowerCase()} ${customer.customer.contact?.last_name.toLowerCase()}`;
return `${customer.contact?.first_name.toLowerCase()} ${customer.contact?.last_name.toLowerCase()}`;
})
.join(", ");
return name.includes(value) || number.includes(value) || customerNames.includes(value);

View File

@ -1,4 +1,3 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
@ -9,12 +8,11 @@ import BackArrow from "@Front/Components/Elements/BackArrow";
import WindowStore from "@Front/Stores/WindowStore";
import classNames from "classnames";
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
import Image from "next/image";
import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
type IProps = {
title: string;
@ -39,7 +37,7 @@ export type IDashBoardFolder = {
description: OfficeFolder["description"];
deed?: OfficeFolder["deed"];
created_at: OfficeFolder["created_at"];
office_folder_has_customers?: OfficeFolder["office_folder_has_customers"];
customers?: OfficeFolder["customers"];
archived_description: OfficeFolder["archived_description"];
status: OfficeFolder["status"];
};
@ -118,9 +116,7 @@ export default class DefaultNotaryDashboard extends React.Component<IProps, ISta
include: {
deed: { include: { deed_type: true } },
office: true,
office_folder_has_customers: {
include: {
customer: {
customers: {
include: {
contact: true,
documents: {
@ -132,8 +128,6 @@ export default class DefaultNotaryDashboard extends React.Component<IProps, ISta
},
},
},
},
},
documents: {
include: {
depositor: {

View File

@ -10,7 +10,6 @@ import React from "react";
import classes from "./classes.module.scss";
import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
import Customer, { Document } from "le-coffre-resources/dist/Customer";
import { document } from "./../../../Components/Layouts/DesignSystem/dummyData";
type IProps = {
targetedCustormer: string; // MOCK
@ -69,7 +68,7 @@ export default class ClientDashboard extends Base<IProps, IState> {
Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
document correspondant.
</Typography>
<DepositDocument document={document} />
{/* <DepositDocument document={document} /> */}
</div>
</Confirm>
</div>

View File

@ -1,18 +0,0 @@
.root {
margin-left: 35px;
margin-right: 35px;
.section {
margin-bottom: 32px;
}
.sub-section {
margin-bottom: 24px;
}
.inline-flex {
display: inline-flex;
}
.folder-conatainer {
width: 389px;
}
}

View File

@ -1,347 +0,0 @@
import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer";
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
import {
Address,
Contact,
Customer,
Deed,
DeedType,
Document,
DocumentType,
File,
Office,
OfficeFolder,
OfficeFolderHasCustomer,
} from "le-coffre-resources/dist/Notary";
export const address: Address = {
uid: "a&2azedzaa3",
address: "123",
city: "France",
zip_code: 78140,
created_at: new Date(),
updated_at: new Date(),
};
export const office: Office = {
uid: "111zdazaefez213",
idNot: "12EE12",
name: "Office 1",
crpcen: "AZezdz",
address: address,
created_at: new Date(),
updated_at: new Date(),
office_status: "ACTIVATED",
};
export const deedType: DeedType = {
uid: "123azefezgzeg312",
name: "Acte mariage",
description: "dzsdaf",
archived_at: new Date(),
office: office,
created_at: new Date(),
updated_at: new Date(),
};
export const deed: Deed = {
uid: "zegefzeferg",
deed_type: deedType,
created_at: new Date(),
updated_at: new Date(),
};
export const contact: Contact = {
uid: "contact_1_uid",
first_name: "John",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
};
export const contact2: Contact = {
uid: "contact_2_uid",
first_name: "Customer2",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
};
export const docType: DocumentType = {
name: "Votre document",
uid: "fezezfazegezrgrezg",
created_at: new Date(),
updated_at: new Date(),
public_description: "",
private_description: "",
archived_at: new Date(),
office: office,
};
export const identityDocType: DocumentType = {
name: "Carte d'identité",
uid: "fezezfazegezrgrezg",
created_at: new Date(),
updated_at: new Date(),
public_description: "Carte d'identité public description",
private_description: "Carte d'identité private description",
archived_at: new Date(),
office: office,
};
export const customer: Customer = {
uid: "erhtgerfzeare",
contact: contact,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
};
export const customer2_mock: Customer = {
uid: "yregrgetergrt",
contact: contact2,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
};
export const folder: OfficeFolder = {
uid: "mkovrijvrezviev",
folder_number: "12331",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
};
export const document: Document = {
uid: "fzeafergreztyzgrf",
depositor: customer2_mock,
document_status: "ASKED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const fileMock: File = {
uid: "super_file_uid_1",
created_at: new Date(),
updated_at: new Date(),
document: document,
file_name: "file_1",
file_path:
"https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf",
archived_at: null,
mimetype: "image/png",
size: 0,
};
export const fileMock2: File = {
uid: "super_file_uid_2",
created_at: new Date(),
updated_at: new Date(),
document: document,
file_name: "file_2",
file_path:
"https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19",
archived_at: null,
mimetype: "image/png",
size: 0,
};
export const identityFile: File = {
uid: "identity_file_uid",
created_at: new Date(),
updated_at: new Date(),
document: document,
file_name: "file_3",
file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png",
archived_at: null,
mimetype: "image/png",
size: 0,
};
export const documentIdentity: Document = {
uid: "ethrthbkjtrbporjbh",
depositor: customer2_mock,
document_status: EDocumentStatus.DEPOSITED,
folder: folder,
document_type: identityDocType,
updated_at: new Date(),
created_at: new Date(),
files: [identityFile],
};
export const documentPending: Document = {
uid: "fzefeazdagrtetrury",
depositor: customer2_mock,
document_status: EDocumentStatus.DEPOSITED,
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
files: [fileMock, fileMock2],
};
export const documentDeposited: Document = {
uid: "uè§u§htfgrthytrgr",
depositor: customer2_mock,
document_status: "VALIDATED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
files: [fileMock],
};
export const customer2: Customer = {
uid: "yregrgetergrt",
contact: contact2,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
documents: [document, documentPending, documentDeposited, documentIdentity],
};
export const folderWithPendingDocument: OfficeFolder = {
uid: "ferzferzfezeefzdd",
folder_number: "00001",
name: "Mon dossier",
status: EFolderStatus.LIVE,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [],
};
export const folderWithPendingDocument1: OfficeFolder = {
uid: "gtrtyutyhretgytu",
folder_number: "00002",
name: "Mon dossier",
status: EFolderStatus.LIVE,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [documentDeposited],
};
export const folderWithPendingDocument2: OfficeFolder = {
uid: "adzefzefsfrefzrtgtr",
folder_number: "00003",
name: "Mon dossier",
status: EFolderStatus.LIVE,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document],
};
export const officeFolderHasCustomer1: OfficeFolderHasCustomer = {
uid: "ferzfergrzeyerezrz",
customer: customer,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
};
export const officeFolderHasCustomer2: OfficeFolderHasCustomer = {
uid: "tezrfzdfgrggeerry",
customer: customer2,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
};
export const folderWithPendingDocument3: OfficeFolder = {
uid: "mkovrijvrezviev",
folder_number: "00014",
name: "Mon dossier",
status: EFolderStatus.LIVE,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document, documentDeposited, documentPending, documentIdentity],
office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2],
};
export const document8: Document = {
uid: "eztreggrgbyunjukhg",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const folderWithPendingDocumentArchived1: OfficeFolder = {
uid: "gtrtyutyhrdazafad&éfytu",
folder_number: "00007",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [documentDeposited],
office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2],
};
export const folderWithPendingDocumentArchived2: OfficeFolder = {
uid: "adzefdazdaazzrtgtr",
folder_number: "00008",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document],
};
export const document2: Document = {
uid: "mejfihruehfoire",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument3,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const folders: OfficeFolder[] = [
folderWithPendingDocument,
folderWithPendingDocument1,
folderWithPendingDocument2,
folderWithPendingDocument3,
];
export const foldersArchived: OfficeFolder[] = [folderWithPendingDocumentArchived1, folderWithPendingDocumentArchived2];

View File

@ -1,319 +0,0 @@
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary";
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
import FolderContainer from "@Front/Components/DesignSystem/FolderContainer";
import FolderList from "@Front/Components/DesignSystem/FolderListContainer";
import HeaderLink from "@Front/Components/DesignSystem/Header/HeaderLink";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
import ToolTip from "@Front/Components/DesignSystem/ToolTip";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import UserFolder from "@Front/Components/DesignSystem/UserFolder";
import BasePage from "@Front/Components/Layouts/Base";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import Toasts, { IToast } from "@Front/Stores/Toasts";
import classes from "./classes.module.scss";
import { customer2, document, documentDeposited, documentPending, folder, folders, folderWithPendingDocument } from "./dummyData";
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
type IState = {
isModalDisplayed: boolean;
selectedOption?: IOption;
};
type IProps = {};
export default class DesignSystem extends BasePage<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
isModalDisplayed: false,
};
this.openModal = this.openModal.bind(this);
this.closeModal = this.closeModal.bind(this);
this.onSelectedOption = this.onSelectedOption.bind(this);
}
public override render(): JSX.Element {
const selectOptions: IOption[] = [
{ value: "1", label: "Divorce" },
{ value: "2", label: "Succession" },
{ value: "3", label: "Vente immobilière" },
];
return (
<DefaultTemplate title={"HomePage"}>
<div className={classes["root"]}>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H1}>Website design System</Typography>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_18}>
This page allows to gather all the design system of the site. A Design System is a library of components,
visuals and principles with reusable code. This evolving kit offers a UX and UI repository for designers and
developers of digital products and services. The construction of a design system offers many advantages.
This solution facilitates the work of the teams and reduces the "design debt" and the "technical debt". The
result is a coherent ecosystem and therefore a better experience for users and customers.
</Typography>
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Button components</Typography>
</div>
<Button variant={EButtonVariant.PRIMARY}>Primary</Button>
<Button variant={EButtonVariant.SECONDARY}>Secondary</Button>
<Button variant={EButtonVariant.GHOST}>Ghost</Button>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Toaster component</Typography>
</div>
<Button variant={EButtonVariant.PRIMARY} onClick={this.spawnToast}>
Spawn a toast
</Button>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Modal components</Typography>
</div>
<Button variant={EButtonVariant.PRIMARY} onClick={this.openModal}>
Show Modal
</Button>
<Confirm
isOpen={this.state.isModalDisplayed}
onClose={this.closeModal}
closeBtn
header={"Title"}
cancelText={"Cancel"}
confirmText={"Confirmer"}>
Lorem ipsum dolor sit amet consectetur. Aliquam nunc lobortis lacus vulputate sagittis sed tempor eget feugiat.
Elementum malesuada at sit elit.
</Confirm>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>HeaderLink components</Typography>
</div>
<div className={classes["inline-flex"]}>
<HeaderLink text={"Home"} path={"/"} />
<HeaderLink text={"Design-system"} path={"/design-system"} />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>CheckBox component</Typography>
</div>
<CheckBox
toolTip="Mon super tooltip"
option={{
label: "Check Box 1",
value: "box_1",
}}
/>
<CheckBox
option={{
label: "Check Box 2",
value: "box_2",
}}
/>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>RadioBox component</Typography>
</div>
<RadioBox name="RadioBox" toolTip="Radiobox with tooltip" value="box_1">
Radio Box 1
</RadioBox>
<RadioBox name="RadioBox" value="box_2">
Radio Box 2
</RadioBox>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Tool tip component</Typography>
</div>
<ToolTip title="toolTip" text="tooltip content" isNotFlex={true} />
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Input component</Typography>
</div>
<div className={classes["sub-section"]}>
<TextField name="input field" placeholder="input place hodler" />
</div>
<div className={classes["sub-section"]}>
<TextAreaField name="input field" placeholder="text area place hodler" />
</div>
<div className={classes["sub-section"]}>
<TextField name="input field" placeholder="number place hodler" />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Progress bar component</Typography>
</div>
<div className={classes["sub-section"]}>
<QuantityProgressBar currentNumber={10} total={100} title={"Complétion du dossier client"} />
</div>
<div className={classes["sub-section"]}>
<QuantityProgressBar currentNumber={30} total={100} title={"Complétion du dossier client"} />
</div>
<div className={classes["sub-section"]}>
<QuantityProgressBar currentNumber={70} total={100} title={"Complétion du dossier client"} />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Folder container component</Typography>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Folder with no document to validate</Typography>
<div className={classes["folder-conatainer"]}>
<FolderContainer folder={folder as IDashBoardFolder} />
</div>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Folder with document waiting for being validate</Typography>
<div className={classes["folder-conatainer"]}>
<FolderContainer folder={folderWithPendingDocument as IDashBoardFolder} />
</div>
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Select component</Typography>
</div>
<div className={classes["sub-section"]}>
<div className={classes["folder-conatainer"]}>
<SelectField
name="select"
options={selectOptions}
onChange={this.onSelectedOption}
placeholder={"Type d'acte"}
selectedOption={this.state.selectedOption}
/>
</div>
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Notary Documents</Typography>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Documents ASKED</Typography>
<div className={classes["folder-conatainer"]}>
<DocumentNotary document={document} folderUid="" />
</div>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Documents Depoited</Typography>
<div className={classes["folder-conatainer"]}>
<DocumentNotary document={documentPending} folderUid="" />
</div>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Documents VALIDATED</Typography>
<div className={classes["folder-conatainer"]}>
<DocumentNotary document={documentDeposited} folderUid="" />
</div>
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Notary Documents</Typography>
</div>
<div className={classes["sub-section"]}>
<UserFolder
customer={customer2}
folder={folder as IDashBoardFolder}
isOpened={true}
onChange={() => {
return;
}}
/>
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>MultiSelect</Typography>
</div>
<div className={classes["sub-section"]}>
<MultiSelect options={selectOptions} placeholder="Numéro CRPCEN" />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Document SearchBar</Typography>
</div>
<div className={classes["sub-section"]}>
<SearchBar folders={folders as IDashBoardFolder[]} />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Folder List</Typography>
</div>
<div className={classes["sub-section"]}>
<FolderList folders={folders as IDashBoardFolder[]} isArchived={false} />
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Preview Image/Pdf</Typography>
</div>
<div className={classes["sub-section"]}>
<div style={{ height: "500px" }}>
<FilePreview href="https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf" />
</div>
<FilePreview href="https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Vgs_Vr_Mt_TDY_Xme8qhw8quiin_Co_Bo_FBA_Vc9k6_H2d1_Bh_UU_162d84281d.jpeg" />
</div>
</div>
</div>
</DefaultTemplate>
);
}
private openModal() {
this.setState({
isModalDisplayed: true,
});
}
private closeModal() {
this.setState({
isModalDisplayed: false,
});
}
private spawnToast() {
const toast: IToast = {
title: "Un collaborateur veut rejoindre votre office",
text: "12:00 - 1 fev 2023",
};
Toasts.getInstance().open(toast);
}
private onSelectedOption(option: IOption) {
this.setState({
selectedOption: option,
});
}
}

View File

@ -2,21 +2,21 @@ import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import Module from "@Front/Config/Module";
import { TextField } from "@mui/material";
import { ECivility } from "le-coffre-resources/dist/Customer/Contact";
import { Customer, OfficeFolder, OfficeFolderHasCustomer } from "le-coffre-resources/dist/Notary";
import { Customer, OfficeFolder } from "le-coffre-resources/dist/Notary";
import Link from "next/link";
import { NextRouter, useRouter } from "next/router";
import BasePage from "../../Base";
import classes from "./classes.module.scss";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import { TextField } from "@mui/material";
enum ESelectedOption {
EXISTING_CUSTOMER = "existing_customer",
@ -108,10 +108,7 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
<TextField name="last_name" placeholder="Nom" />
<TextField name="first_name" placeholder="Prénom" />
<TextField name="email" placeholder="E-mail" />
<TextField
name="cell_phone_number"
placeholder="Numéro de téléphone"
/>
<TextField name="cell_phone_number" placeholder="Numéro de téléphone" />
<div className={classes["button-container"]}>
<Link href={backwardPath} className={classes["cancel-button"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
@ -150,24 +147,20 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
private async getFolderPreSelectedCustomers(folderUid: string): Promise<IOption[] | undefined> {
const query = {
q: {
office_folder_has_customers: {
include: {
customer: {
customers: {
include: {
contact: true,
},
},
},
},
},
};
let preExistingCustomers: IOption[] = [];
try {
const folder = await Folders.getInstance().getByUid(folderUid, query);
preExistingCustomers = folder.office_folder_has_customers!.map((folderHasCustomer) => {
preExistingCustomers = folder.customers!.map((customer) => {
return {
label: folderHasCustomer.customer.contact?.first_name + " " + folderHasCustomer.customer.contact?.last_name,
value: folderHasCustomer.customer.uid,
label: customer.contact?.first_name + " " + customer.contact?.last_name,
value: customer.uid,
};
});
} catch (error) {
@ -209,24 +202,26 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
values["civility"] = ECivility.MALE; // TODO: should maybe be deleted later or added to the form
const allCustomersToLink = this.state.selectedCustomers.concat(this.state.existingCustomers);
let customersToLink: Partial<OfficeFolderHasCustomer>[] = allCustomersToLink.map((customer) => {
let customersToLink: Partial<Customer>[] = allCustomersToLink.map((customer) => {
return {
customer: { uid: customer.value },
};
}) as Partial<OfficeFolderHasCustomer>[];
}) as Partial<Customer>[];
if (this.state.selectedOption === "new_customer") {
const customer: Customer = await Customers.getInstance().post({
contact: values,
});
if (!customer.uid) return;
customersToLink?.push({ customer: { uid: customer.uid } } as Partial<OfficeFolderHasCustomer>);
customersToLink?.push({ customer: { uid: customer.uid } } as Partial<Customer>);
}
if (customersToLink) {
const body = OfficeFolder.hydrate<OfficeFolder>({ office_folder_has_customers: customersToLink.map((customer) => {
return OfficeFolderHasCustomer.hydrate<OfficeFolderHasCustomer>(customer);
}) });
const body = OfficeFolder.hydrate<OfficeFolder>({
customers: customersToLink.map((customer) => {
return Customer.hydrate<Customer>(customer);
}),
});
await Folders.getInstance().put(this.props.selectedFolderUid, body);
this.props.router.push(`/folders/${this.props.selectedFolderUid}`);

View File

@ -169,8 +169,8 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
.map((document) => {
return document.document_type!.uid!;
});
const documentTypes = folder.deed!.deed_has_document_types!.filter((documentType) => {
if (userDocumentTypesUids.includes(documentType.document_type!.uid!)) return false;
const documentTypes = folder.deed!.document_types!.filter((documentType) => {
if (userDocumentTypesUids.includes(documentType!.uid!)) return false;
return true;
});
@ -182,9 +182,9 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
})
.map((documentType) => {
return {
label: documentType.document_type!.name!,
value: documentType.document_type!.uid!,
description: documentType.document_type!.private_description!,
label: documentType!.name!,
value: documentType!.uid!,
description: documentType!.private_description!,
};
});
@ -209,13 +209,11 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
public_description: this.state.visibleDescription,
});
const oldDocumentsType = this.state.folder?.deed?.deed_has_document_types!;
const oldDocumentsType = this.state.folder?.deed?.document_types!;
await Deeds.getInstance().put(this.state.folder?.deed?.uid!, {
deed_has_document_types: [
document_types: [
...oldDocumentsType,
{
document_type: documentType,
},
documentType,
],
});

View File

@ -13,7 +13,7 @@ import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Ty
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import { ValidationError } from "class-validator";
import { Deed, DeedType, Office, OfficeFolder, OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Notary";
import { Deed, DeedType, Office, OfficeFolder } from "le-coffre-resources/dist/Notary";
import User from "le-coffre-resources/dist/Notary";
import { NextRouter, useRouter } from "next/router";
import React from "react";
@ -243,13 +243,14 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
const usersMock = await Users.getInstance().get({ include: { office_membership: true } });
const userMock = usersMock[0];
let stakeholders = this.getStakeholders();
let testUsers = stakeholders.map((stakeholder) => ({
user_stakeholder: {
uid: stakeholder.user_stakeholder.uid,
},
}));
let stakeholders = this.state.collaborators;
if (this.state.folder_access === "select_collaborators") {
stakeholders = this.state.collaborators.filter((collaborator) => {
return this.state.formValues.collaborators?.some((selectedCollaborator) => {
return selectedCollaborator.value === collaborator.uid;
});
});
}
const officeFolderForm = OfficeFolder.hydrate<OfficeFolder>({
folder_number: values["folder_number"],
name: values["name"],
@ -262,13 +263,8 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
office: Office.hydrate<Office>({
uid: userMock?.office_membership?.uid,
}),
office_folder_has_stakeholder: testUsers.map((user) => {
return OfficeFolderHasStakeholder.hydrate<OfficeFolderHasStakeholder>({
user_stakeholder: User.hydrate<User>({
uid: user.user_stakeholder.uid,
}),
});
}),
customers: [],
stakeholders
});
try {
@ -313,25 +309,6 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
folder_access: e.target.value,
});
}
private getStakeholders() {
let collaborators: User[] = this.state.collaborators;
let office_folder_has_stakeholders = collaborators.map((collaborator) => {
return OfficeFolderHasStakeholder.hydrate<OfficeFolderHasStakeholder>({
user_stakeholder: collaborator,
});
});
if (this.state.folder_access === "select_collaborators") {
office_folder_has_stakeholders = office_folder_has_stakeholders.filter((collaborator) => {
return this.state.formValues.collaborators?.some((selectedCollaborator) => {
return selectedCollaborator.value === collaborator.user_stakeholder.uid;
});
});
}
return office_folder_has_stakeholders;
}
}
export default function CreateFolder(props: IProps): JSX.Element {

View File

@ -60,14 +60,14 @@ export default class ClientSection extends React.Component<IProps, IState> {
}
private renderCustomerFolders() {
const output = this.props.folder.office_folder_has_customers?.map((folderHasCustomer) => {
if (!folderHasCustomer.customer) return null;
const output = this.props.folder.customers?.map((customer) => {
if (!customer) return null;
return (
<UserFolder
folder={this.props.folder}
customer={folderHasCustomer.customer}
key={folderHasCustomer.customer.uid}
isOpened={this.state.openedCustomer === folderHasCustomer.customer.uid}
customer={customer}
key={customer.uid}
isOpened={this.state.openedCustomer === customer.uid}
onChange={this.changeUserFolder}
/>
);
@ -83,7 +83,7 @@ export default class ClientSection extends React.Component<IProps, IState> {
}
private doesFolderHaveCustomer(): boolean {
if (!this.props.folder?.office_folder_has_customers) return false;
return this.props.folder?.office_folder_has_customers!.length > 0;
if (!this.props.folder?.customers) return false;
return this.props.folder?.customers!.length > 0;
}
}

View File

@ -2,6 +2,7 @@ import ChevronIcon from "@Assets/Icons/chevron.svg";
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
@ -16,7 +17,6 @@ import { ChangeEvent } from "react";
import BasePage from "../../Base";
import classes from "./classes.module.scss";
import ClientSection from "./ClientSection";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
type IProps = {};
@ -155,8 +155,8 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
}
private doesFolderHaveCustomer(): boolean {
if (!this.state.selectedFolder?.office_folder_has_customers) return false;
return this.state.selectedFolder?.office_folder_has_customers!.length > 0;
if (!this.state.selectedFolder?.customers) return false;
return this.state.selectedFolder?.customers!.length > 0;
}
private onSelectedFolder(folder: IDashBoardFolder): void {
@ -189,8 +189,6 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
q: {
deed: { include: { deed_type: true } },
office: true,
office_folder_has_customers: {
include: {
customer: {
include: {
contact: true,
@ -203,8 +201,6 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
},
},
},
},
},
documents: {
include: {
depositor: {

View File

@ -1,20 +1,20 @@
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import BasePage from "../../Base";
import classes from "./classes.module.scss";
import Module from "@Front/Config/Module";
import User from "le-coffre-resources/dist/Notary";
import Link from "next/link";
import { NextRouter, useRouter } from "next/router";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import Module from "@Front/Config/Module";
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import { OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Customer";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import User from "le-coffre-resources/dist/Notary";
import BasePage from "../../Base";
import classes from "./classes.module.scss";
type IPropsClass = {
selectedFolderUid: string;
@ -104,25 +104,21 @@ class UpdateFolderCollaboratorsClass extends BasePage<IPropsClass, IState> {
const query = {
q: {
office: true,
office_folder_has_stakeholder: {
include: {
user_stakeholder: {
stakeholders: {
include: {
contact: true,
},
},
},
},
},
};
let folder = null;
try {
folder = await Folders.getInstance().getByUid(folderUid, query);
const preSelectedCollaborators: IOption[] = folder.office_folder_has_stakeholder!.map((collaborator) => {
const preSelectedCollaborators: IOption[] = folder.stakeholders!.map((collaborator) => {
return {
label: collaborator.user_stakeholder.contact?.first_name + " " + collaborator.user_stakeholder.contact?.last_name,
value: collaborator.user_stakeholder.uid,
label: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
value: collaborator.uid,
};
});
this.setState({ selectedCollaborators: preSelectedCollaborators });
@ -173,17 +169,13 @@ class UpdateFolderCollaboratorsClass extends BasePage<IPropsClass, IState> {
private async onFormSubmit(e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) {
try {
let collaboratorsUid: OfficeFolderHasStakeholder[];
let collaboratorsUid: User[] = this.state.availableCollaborators;
if (this.state.selectedOption === ERadioBoxValue.SELECTION) {
collaboratorsUid = this.state.selectedCollaborators.map(
(collaborator) => ({ user_stakeholder: { uid: collaborator.value } } as OfficeFolderHasStakeholder),
);
} else {
collaboratorsUid = this.state.availableCollaborators.map(
(collaborator) => ({ user_stakeholder: { uid: collaborator.uid } } as OfficeFolderHasStakeholder),
collaboratorsUid = this.state.selectedCollaborators.map((collaborator) =>
User.hydrate<User>({ uid: collaborator.value as string }),
);
}
await Folders.getInstance().put(this.props.selectedFolderUid, { office_folder_has_stakeholder: collaboratorsUid });
await Folders.getInstance().put(this.props.selectedFolderUid, { stakeholders: collaboratorsUid });
this.props.router.push(
Module.getInstance()
.get()

View File

@ -103,7 +103,7 @@ class UpdateFolderMetadataClass extends BasePage<IPropsClass, IState> {
q: {
deed: { include: { deed_type: true } },
office: true,
office_folder_has_customers: { include: { customer: { include: { contact: true } } } },
customers: { include: { contact: true } },
},
};
const folder = await Folders.getInstance().getByUid(this.props.folderUid, query);

View File

@ -40,14 +40,14 @@ export default class ClientSection extends React.Component<IProps, IState> {
}
private renderCustomerFolders() {
const output = this.props.folder.office_folder_has_customers?.map((folderHasCustomer) => {
if (!folderHasCustomer.customer) return null;
const output = this.props.folder.customers?.map((customer) => {
if (!customer) return null;
return (
<UserFolder
folder={this.props.folder}
customer={folderHasCustomer.customer}
key={folderHasCustomer.customer.uid}
isOpened={this.state.openedCustomer === folderHasCustomer.customer.uid}
customer={customer}
key={customer.uid}
isOpened={this.state.openedCustomer === customer.uid}
onChange={this.changeUserFolder}
/>
);
@ -62,7 +62,7 @@ export default class ClientSection extends React.Component<IProps, IState> {
}
private doesFolderHaveCustomer(): boolean {
if (!this.props.folder?.office_folder_has_customers) return false;
return this.props.folder?.office_folder_has_customers!.length > 0;
if (!this.props.folder?.customers) return false;
return this.props.folder?.customers!.length > 0;
}
}

View File

@ -108,7 +108,7 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
}
private doesFolderHaveCustomer(): boolean {
return this.state.selectedFolder?.office_folder_has_customers !== undefined;
return this.state.selectedFolder?.customers !== undefined;
}
private onSelectedFolder(folder: IDashBoardFolder): void {
@ -140,7 +140,7 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
q: {
deed: { include: { deed_type: "true" } },
office: "true",
office_folder_has_customers: { include: { customer: { include: { contact: true } } } },
customer: { include: { contact: true } },
},
};
const folder = await Folders.getInstance().getByUid(this.props.selectedFolderUid, query);

View File

@ -6,8 +6,9 @@ import CoffreIcon from "@Assets/Icons/coffre.svg";
import LandingImage from "./landing-connect.jpeg";
import Image from "next/image";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import { FrontendVariables } from "@Front/Config/VariablesFront";
// import { FrontendVariables } from "@Front/Config/VariablesFront";
import idNoteLogo from "@Assets/Icons/id-note-logo.svg";
import UserStore from "@Front/Stores/UserStore";
export default class LoginClass extends BasePage {
public override render(): JSX.Element {
@ -30,12 +31,17 @@ export default class LoginClass extends BasePage {
);
}
private redirectUserOnConnection() {
const variables = FrontendVariables.getInstance();
const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST;
const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT;
const clientId = variables.IDNOT_CLIENT_ID;
const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`;
window.location.assign(url);
private async redirectUserOnConnection() {
// const variables = FrontendVariables.getInstance();
// const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST;
await UserStore.instance.connect("U5eUoGpRu4");
// await JwtService.getInstance().checkJwt();
// window.location.assign("http://localhost:3000" + "/folders");
// const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT;
// const clientId = variables.IDNOT_CLIENT_ID;
// const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`;
// window.location.assign(url);
}
}

View File

@ -0,0 +1,44 @@
export default class CookieService {
private static instance: CookieService;
private constructor() {}
public static getInstance() {
return (this.instance ??= new this());
}
/**
* @description : set a cookie with a name and a value that expire in 7 days
* @throws {Error} If the name or the value is empty
*/
public setCookie(name: string, value: string) {
if (!name || !value) throw new Error("Cookie name or value is empty");
const date = new Date();
// Set it expire in 7 days
date.setTime(date.getTime() + 7 * 24 * 60 * 60 * 1000);
// Set it
document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/";
}
public getCookie(name: string) {
const value = "; " + document.cookie;
const parts = value.split("; " + name + "=");
if (parts.length == 2) {
return parts.pop()!.split(";").shift();
}
return;
}
public deleteCookie(name: string) {
const date = new Date();
// Set it expire in -1 days
date.setTime(date.getTime() + -1 * 24 * 60 * 60 * 1000);
// Set it
document.cookie = name + "=; expires=" + date.toUTCString() + "; path=/";
}
}

View File

@ -0,0 +1,52 @@
import jwt_decode from "jwt-decode";
import CookieService from "../CookieService/CookieService";
import User from "@Front/Api/Auth/IdNot/User";
enum PROVIDER_OPENID {
idNot = "idNot",
}
interface IUserJwtPayload {
userId: string;
openId: {
providerName: PROVIDER_OPENID;
userId: string | number;
};
office_Id: string;
role: string;
rules: string[];
exp: number;
}
export default class JwtService {
private static instance: JwtService;
private constructor() {}
public static getInstance() {
return (this.instance ??= new this());
}
/**
* @description : set a cookie with a name and a value that expire in 7 days
* @throws {Error} If the name or the value is empty
*/
public async checkJwt() {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return;
const decodedToken: IUserJwtPayload = jwt_decode(accessToken);
const now = Math.floor(Date.now() / 1000);
if (decodedToken.exp < now) {
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) return;
const newAccessToken: { accessToken: string } = await User.getInstance().refreshToken(refreshToken);
if (newAccessToken) {
CookieService.getInstance().setCookie("leCoffreAccessToken", newAccessToken.accessToken);
}
}
}
}

View File

@ -0,0 +1,57 @@
"use client";
import User from "@Front/Api/Auth/IdNot/User";
import CookieService from "@Front/Services/CookieService/CookieService";
import EventEmitter from "@Front/Services/EventEmitter";
export default class UserStore {
public static readonly instance = new this();
protected readonly event = new EventEmitter();
public accessToken: string | null = null;
public refreshToken: string | null = null;
private constructor() {}
public isConnected(): boolean {
return !!this.accessToken;
}
public async connect(idnotUid: string) {
try {
//call connection function
const user: any = await User.getInstance().login(idnotUid);
//Save tokens in cookies
CookieService.getInstance().setCookie("leCoffreAccessToken", user.accessToken);
CookieService.getInstance().setCookie("leCoffreRefreshToken", user.refreshToken);
this.event.emit("connection", this.accessToken);
} catch (error) {
console.error(error);
return false;
}
return true;
}
public async disconnect() {
try {
//Remove tokens from cookies
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
this.event.emit("disconnection", this.accessToken);
} catch (error) {
console.error(error);
}
}
public onDisconnect(callback: (userAddress: string) => void): () => void {
this.event.on("disconnection", callback);
return () => this.event.off("disconnection", callback);
}
public onConnect(callback: (userAddress: string) => void): () => void {
this.event.on("connection", callback);
return () => this.event.off("connection", callback);
}
}

View File

@ -1,5 +0,0 @@
import DesignSystem from "@Front/Components/Layouts/DesignSystem";
export default function Route() {
return <DesignSystem />;
}