Fix some issues

This commit is contained in:
Anthony Janin 2025-07-16 10:32:54 +02:00
parent 1a397a8a5d
commit 649f930a1b
11 changed files with 144 additions and 76 deletions

View File

@ -80,7 +80,7 @@ export default class CustomerService extends AbstractService {
public static getCustomers(): Promise<any[]> {
// Check if we have valid cache
const items: any[] = this.getItems('_customers_');
const items: any[] = [];//this.getItems('_customers_');
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
@ -108,7 +108,7 @@ export default class CustomerService extends AbstractService {
// Check if we have valid cache
const item: any = this.getItem('_customers_', uid);
if (item) {
return Promise.resolve(item);
//return Promise.resolve(item);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {

View File

@ -80,7 +80,7 @@ export default class DocumentService extends AbstractService {
public static getDocuments(): Promise<any[]> {
// Check if we have valid cache
const items: any[] = this.getItems('_documents_');
const items: any[] = [];//this.getItems('_documents_');
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
@ -108,7 +108,7 @@ export default class DocumentService extends AbstractService {
// Check if we have valid cache
const item: any = this.getItem('_documents_', uid);
if (item) {
return Promise.resolve(item);
//return Promise.resolve(item);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {

View File

@ -96,7 +96,7 @@ export default class FolderService extends AbstractService {
public static getFolders(): Promise<any[]> {
// Check if we have valid cache
const items: any[] = this.getItems('_folders_');
const items: any[] = [];//this.getItems('_folders_');
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
@ -113,7 +113,7 @@ export default class FolderService extends AbstractService {
process = await this.completeFolder(process);
// Update cache
this.setItem('_folders_', process);
//this.setItem('_folders_', process);
items.push(process);
}
@ -126,7 +126,7 @@ export default class FolderService extends AbstractService {
// Check if we have valid cache
const item: any = this.getItem('_folders_', uid);
if (item) {
return Promise.resolve(item);
//return Promise.resolve(item);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
@ -145,7 +145,7 @@ export default class FolderService extends AbstractService {
process = await this.completeFolder(process);
// Update cache
this.setItem('_folders_', process);
//this.setItem('_folders_', process);
resolve(process);
}
@ -160,9 +160,9 @@ export default class FolderService extends AbstractService {
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
const folderUid: string = process.processData.uid;
this.removeItem('_folders_', folderUid);
//this.removeItem('_folders_', folderUid);
this.getFolderByUid(folderUid).then(resolve).catch(reject);
//this.getFolderByUid(folderUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);

View File

@ -257,7 +257,7 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
const date: Date = new Date();
const strDate: string = `${date.getDate().toString().padStart(2, '0')}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getFullYear()}`;
const fileName: string = `aplc-${file.name.split('.')[0]}-${strDate}.${file.name.split('.').pop()}`;
const fileName: string = `${file.name.split('.')[0]}-${strDate}.${file.name.split('.').pop()}`;
const arrayBuffer: ArrayBuffer = event.target.result as ArrayBuffer;
const uint8Array: Uint8Array = new Uint8Array(arrayBuffer);

View File

@ -48,7 +48,7 @@ export default function DepositDocumentComponent(props: IProps) {
const date: Date = new Date();
const strDate: string = `${date.getDate().toString().padStart(2, '0')}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getFullYear()}`;
const fileName: string = `aplc-${document.document_type.name}-${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const fileName: string = `${document.document_type.name}-${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const arrayBuffer: ArrayBuffer = event.target.result as ArrayBuffer;
const uint8Array: Uint8Array = new Uint8Array(arrayBuffer);
@ -100,7 +100,7 @@ export default function DepositDocumentComponent(props: IProps) {
const date: Date = new Date();
const strDate: string = `${date.getDate().toString().padStart(2, '0')}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getFullYear()}`;
const fileName: string = `aplc-${document.document_type.name}-${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const fileName: string = `${document.document_type.name}-${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const arrayBuffer: ArrayBuffer = event.target.result as ArrayBuffer;
const uint8Array: Uint8Array = new Uint8Array(arrayBuffer);

View File

@ -83,7 +83,7 @@ export default function SendDocuments() {
const date: Date = new Date();
const strDate: string = `${date.getDate().toString().padStart(2, '0')}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getFullYear()}`;
const fileName: string = `aplc-${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const fileName: string = `${customer.contact.last_name}-${strDate}.${file.name.split('.').pop()}`;
const arrayBuffer: ArrayBuffer = event.target.result as ArrayBuffer;
const uint8Array: Uint8Array = new Uint8Array(arrayBuffer);

View File

@ -17,9 +17,10 @@ import classes from "./classes.module.scss";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import MessageBox from "@Front/Components/Elements/MessageBox";
import { FileBlob } from "@Front/Api/Entities/types";
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
import { FileBlob } from "@Front/Api/Entities/types";
type IProps = {};
type IPropsClass = {
@ -35,7 +36,7 @@ type IState = {
selectedFileIndex: number;
selectedFile: { uid: string; file_name: string; file_blob: FileBlob } | null;
validatedPercentage: number;
document: Document | null;
document: any | null;
fileBlob: Blob | null;
isLoading: boolean;
};
@ -239,7 +240,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
private async getFilePreview(): Promise<void> {
try {
if (!this.state.selectedFile) return;
const fileBlob: Blob = new Blob([this.state.selectedFile.file_blob.data], { type: this.state.selectedFile.file_blob.type });
this.setState({
fileBlob,
@ -342,8 +343,34 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
private async validateDocument() {
try {
DocumentService.getDocumentByUid(this.props.documentUid).then((process: any) => {
DocumentService.getDocumentByUid(this.props.documentUid).then(async (process: any) => {
if (process) {
await new Promise<void>((resolve: () => void) => {
FileService.getFileByUid(process.processData.files[0].uid).then((p) => {
if (p) {
alert(`aplc-${p.processData.file_name}`)
FileService.updateFile(p, { file_name: `aplc-${p.processData.file_name}` }).then(resolve);
}
});
});
FileService.getFileByUid(process.processData.files[0].uid).then((process) => {
if (process) {
console.log(process.processData);
}
});
/*
this.props.router.push(
Module.getInstance()
.get()
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid) +
"?customerUid=" +
this.state.document?.depositor?.uid,
);
*/
/*
DocumentService.updateDocument(process, { document_status: EDocumentStatus.VALIDATED }).then(() => {
this.props.router.push(
Module.getInstance()
@ -353,6 +380,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
this.state.document?.depositor?.uid,
);
});
*/
}
});
} catch (e) {

View File

@ -25,6 +25,7 @@ type IProps = {
export default function StepEmail(props: IProps) {
const { onSubmit, validationErrors } = props;
const [isErrorModalOpen, setIsErrorModalOpen] = useState(0);
/* const router = useRouter();
const redirectCustomerOnConnection = useCallback(() => {
async function getCustomer() {
@ -99,14 +100,14 @@ export default function StepEmail(props: IProps) {
Pour les clients :
</Typography>
<Form className={classes["form"]} onSubmit={onSubmit}>
{/*
<TextField
placeholder="Renseigner votre email"
label="E-mail"
name="email"
validationError={validationErrors.find((err) => err.property === "email")}
/>
*/}
{
<TextField
placeholder="Renseigner votre email"
label="E-mail"
name="email"
validationError={validationErrors.find((err) => err.property === "email")}
/>
}
<Button type="submit">Se connecter</Button>
</Form>
</div>

View File

@ -16,6 +16,12 @@ import Module from "@Front/Config/Module";
import { TotpCodesReasons } from "le-coffre-resources/dist/Customer/TotpCodes";
import PasswordForgotten from "./PasswordForgotten";
import backgroundImage from "@Assets/images/background_refonte.svg";
import UserStore from "@Front/Stores/UserStore";
import AuthModal from "src/sdk/AuthModal";
import CustomerService from "src/common/Api/LeCoffreApi/sdk/CustomerService";
export enum LoginStep {
EMAIL,
TOTP,
@ -23,6 +29,7 @@ export enum LoginStep {
NEW_PASSWORD,
PASSWORD_FORGOTTEN,
}
export default function Login() {
const router = useRouter();
// const error = router.query["error"];
@ -35,6 +42,7 @@ export default function Login() {
const [email, setEmail] = useState<string>("");
const [partialPhoneNumber, setPartialPhoneNumber] = useState<string>("");
const [validationErrors, setValidationErrors] = useState<ValidationError[]>([]);
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
// const openErrorModal = useCallback(() => {
// setIsErrorModalOpen(true);
@ -50,9 +58,10 @@ export default function Login() {
const onEmailFormSubmit = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
try {
/* TODO: review
if (!values["email"]) return;
setEmail(values["email"]);
/* TODO: review
const res = await Auth.getInstance().mailVerifySms({ email: values["email"] });
setPartialPhoneNumber(res.partialPhoneNumber);
setTotpCodeUid(res.totpCodeUid);
@ -76,19 +85,34 @@ export default function Login() {
const onSmsCodeSubmit = useCallback(
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
try {
console.log(values);
console.log(email);
if (!values["totpCode"]) return;
/*
const res = await Auth.getInstance().verifyTotpCode({ totpCode: values["totpCode"], email });
// If the code is valid setting it in state
if (res.validCode) setTotpCode(values["totpCode"]);
if (res.validCode) {
setTotpCode(values["totpCode"]);
}
*/
if ('1234' === values["totpCode"]) {
setTotpCode(values["totpCode"]);
}
setValidationErrors([]);
/*
// If it's first connection, show the form for first connection
if (res.reason === TotpCodesReasons.FIRST_LOGIN) setStep(LoginStep.NEW_PASSWORD);
// If it's password forgotten, show the form for password forgotten
else if (res.reason === TotpCodesReasons.RESET_PASSWORD) setStep(LoginStep.PASSWORD_FORGOTTEN);
// Else just login normally
else setStep(LoginStep.PASSWORD);
*/
setIsAuthModalOpen(true);
} catch (error: any) {
setValidationErrors([
{
@ -133,7 +157,10 @@ export default function Login() {
return;
}
const token = await Auth.getInstance().setPassword({ totpCode, email, password: values["password"] });
CustomerStore.instance.connect(token.accessToken, token.refreshToken);
// TODO: review
//CustomerStore.instance.connect(token.accessToken, token.refreshToken);
setValidationErrors([]);
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
// If set password worked, setting the token and redirecting
@ -157,7 +184,10 @@ export default function Login() {
try {
if (!values["password"]) return;
const token = await Auth.getInstance().login({ totpCode, email, password: values["password"] });
CustomerStore.instance.connect(token.accessToken, token.refreshToken);
// TODO: review
//CustomerStore.instance.connect(token.accessToken, token.refreshToken);
setValidationErrors([]);
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
} catch (error: any) {
@ -234,6 +264,23 @@ export default function Login() {
{step === LoginStep.PASSWORD_FORGOTTEN && (
<PasswordForgotten onSubmit={onNewPasswordSubmit} validationErrors={validationErrors} />
)}
{isAuthModalOpen && <AuthModal
isOpen={isAuthModalOpen}
onClose={() => {
CustomerService.getCustomers().then((processes: any[]) => {
if (processes.length > 0) {
const customers: any[] = processes.map((process: any) => process.processData);
const customer: any = customers.find((customer: any) => customer.contact.email === email);
if (customer) {
UserStore.instance.connect(customer);
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
}
}
setIsAuthModalOpen(false);
});
}}
/>}
</div>
{/* <Confirm
isOpen={isErrorModalOpen}

View File

@ -1,11 +1,9 @@
import backgroundImage from "@Assets/images/background_refonte.svg";
import LogoIcon from "@Assets/logo_small_blue.svg";
import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders";
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import JwtService from "@Front/Services/JwtService/JwtService";
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
import Image from "next/image";
import { useRouter } from "next/router";
@ -14,37 +12,38 @@ import { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
import Module from "@Front/Config/Module";
import UserStore from "@Front/Stores/UserStore";
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
export default function SelectFolder() {
const router = useRouter();
const [customer, setCustomer] = useState<any>(null);
const [folders, setFolders] = useState<OfficeFolder[]>([]);
useEffect(() => {
const jwt = JwtService.getInstance().decodeCustomerJwt();
if (!jwt) return;
const customer: any = UserStore.instance.getUser();
if (!customer) {
return;
}
setCustomer(customer);
Folders.getInstance()
.get({
q: {
where: {
customers: {
some: {
contact: {
email: jwt.email,
},
},
},
},
orderBy: [
{
created_at: "desc",
},
],
include: {
customers: true,
},
},
})
.then((folders) => setFolders(folders));
LoaderService.getInstance().show();
FolderService.getFolders().then((processes: any[]) => {
if (processes.length > 0) {
let folders: any[] = processes.map((process: any) => process.processData);
// FilterBy customer.uid
folders = folders.filter((folder: any) => folder.customers && folder.customers.length > 0 && folder.customers.some((customer: any) => customer.uid === customer.uid));
// OrderBy created_at desc
folders = folders.sort((a: any, b: any) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
setFolders(folders);
LoaderService.getInstance().hide();
}
});
}, []);
const handleSelectBlock = useCallback(
@ -52,7 +51,7 @@ export default function SelectFolder() {
router.push(
Module.getInstance()
.get()
.modules.pages.ClientDashboard.props.path.replace("[folderUid]", folder.id ?? ""),
.modules.pages.ClientDashboard.props.path.replace("[folderUid]", folder.id ?? "").replace("[profileUid]", customer.uid ?? ""),
);
},
[router],

View File

@ -9,27 +9,18 @@ import User from "src/sdk/User";
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;
return !!CookieService.getInstance().getCookie("leCoffreAccessToken");
}
public getRole(): string | undefined {
const decodedPayload = JwtService.getInstance().decodeJwt();
return decodedPayload?.role;
}
public async connect(accessToken: string, refreshToken: string) {
public async connect(user: any) {
try {
//Save tokens in cookies
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
this.event.emit("connection", this.accessToken);
CookieService.getInstance().setCookie("leCoffreAccessToken", JSON.stringify(user));
this.event.emit("connection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
} catch (error) {
console.error(error);
return false;
@ -39,13 +30,11 @@ export default class UserStore {
public async disconnect() {
try {
//Remove tokens from cookies
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
User.getInstance().clear();
this.event.emit("disconnection", this.accessToken);
//Remove tokens from cookies
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
this.event.emit("disconnection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
} catch (error) {
console.error(error);
}
@ -60,4 +49,8 @@ export default class UserStore {
this.event.on("connection", callback);
return () => this.event.off("connection", callback);
}
public getUser(): any {
return JSON.parse(CookieService.getInstance().getCookie("leCoffreAccessToken") || "");
}
}