Init migration
This commit is contained in:
parent
b6da6db0fe
commit
65f67993ba
@ -16,6 +16,7 @@ const nextConfig = {
|
|||||||
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
||||||
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
||||||
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
||||||
|
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
|
||||||
},
|
},
|
||||||
|
|
||||||
serverRuntimeConfig: {
|
serverRuntimeConfig: {
|
||||||
@ -31,6 +32,7 @@ const nextConfig = {
|
|||||||
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
||||||
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
||||||
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
||||||
|
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
|
||||||
},
|
},
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
@ -46,6 +48,7 @@ const nextConfig = {
|
|||||||
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
NEXT_PUBLIC_DOCAPOSTE_API_URL: process.env.NEXT_PUBLIC_DOCAPOSTE_API_URL,
|
||||||
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
NEXT_PUBLIC_HOTJAR_SITE_ID: process.env.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
||||||
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
NEXT_PUBLIC_HOTJAR_VERSION: process.env.NEXT_PUBLIC_HOTJAR_VERSION,
|
||||||
|
NEXT_PUBLIC_4NK_URL: process.env.NEXT_PUBLIC_4NK_URL,
|
||||||
},
|
},
|
||||||
|
|
||||||
// webpack: config => {
|
// webpack: config => {
|
||||||
|
11503
package-lock.json
generated
11503
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
|||||||
"heroicons": "^2.1.5",
|
"heroicons": "^2.1.5",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.167",
|
"le-coffre-resources": "file:../lecoffre-ressources",
|
||||||
"next": "^14.2.3",
|
"next": "^14.2.3",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
129
src/common/Api/LeCoffreApi/sdk/FolderService.ts
Normal file
129
src/common/Api/LeCoffreApi/sdk/FolderService.ts
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
import MessageBus from 'src/sdk/MessageBus';
|
||||||
|
import User from 'src/sdk/User';
|
||||||
|
|
||||||
|
import ProfileService from './ProfileService';
|
||||||
|
|
||||||
|
export default class FolderService {
|
||||||
|
|
||||||
|
private static readonly messageBus: MessageBus = MessageBus.getInstance();
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static createFolder(folderData: any, stakeholdersId: string[], customersId: string[]): Promise<any> {
|
||||||
|
const ownerId = User.getInstance().getPairingId()!;
|
||||||
|
|
||||||
|
const processData: any = {
|
||||||
|
uid: uuidv4(),
|
||||||
|
utype: 'folder',
|
||||||
|
isArchived: 'false',
|
||||||
|
isDeleted: 'false',
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
|
updated_at: new Date().toISOString(),
|
||||||
|
...folderData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const privateFields: string[] = Object.keys(processData);
|
||||||
|
privateFields.splice(privateFields.indexOf('uid'), 1);
|
||||||
|
privateFields.splice(privateFields.indexOf('utype'), 1);
|
||||||
|
|
||||||
|
const roles: any = {
|
||||||
|
demiurge: {
|
||||||
|
members: [ownerId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
members: [ownerId],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: [...privateFields, 'roles'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
stakeholders: {
|
||||||
|
members: stakeholdersId,
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: ['documents', 'motes'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
customers: {
|
||||||
|
members: customersId,
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.0,
|
||||||
|
fields: privateFields,
|
||||||
|
min_sig_member: 0.0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
apophis: {
|
||||||
|
members: [ownerId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise<any>((resolve: (folderCreated: any) => void, reject: (error: string) => void) => {
|
||||||
|
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
|
||||||
|
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
||||||
|
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
|
resolve(processCreated);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getFolders(): Promise<any[]> {
|
||||||
|
return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'folder');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getFolderByUid(uid: string): Promise<any> {
|
||||||
|
return new Promise<any>((resolve: (folder: any) => void, reject: (error: string) => void) => {
|
||||||
|
this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'folder').then(async (folders: any[]) => {
|
||||||
|
if (folders.length === 0) {
|
||||||
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
const folder: any = folders[0];
|
||||||
|
|
||||||
|
if (folder.processData.customers && folder.processData.customers.length > 0) {
|
||||||
|
folder.processData.customers = await new Promise<any[]>(async (resolve: (profiles: any[]) => void, reject: (error: string) => void) => {
|
||||||
|
const customers: any[] = [];
|
||||||
|
for (const uid of folder.processData.customers) {
|
||||||
|
customers.push(await ProfileService.getProfileByUid(uid));
|
||||||
|
}
|
||||||
|
resolve(customers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(folder);
|
||||||
|
}
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static updateFolder(folder: any, newData: any): Promise<void> {
|
||||||
|
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
|
||||||
|
this.messageBus.updateProcess(folder.processId, folder.lastStateId, newData, [], null).then((processUpdated: any) => {
|
||||||
|
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||||
|
this.messageBus.notifyUpdate(folder.processId, newStateId).then(() => {
|
||||||
|
this.messageBus.validateState(folder.processId, newStateId).then((_stateValidated) => {
|
||||||
|
resolve();
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
95
src/common/Api/LeCoffreApi/sdk/ProfileService.ts
Normal file
95
src/common/Api/LeCoffreApi/sdk/ProfileService.ts
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
import MessageBus from 'src/sdk/MessageBus';
|
||||||
|
import User from 'src/sdk/User';
|
||||||
|
|
||||||
|
export default class ProfileService {
|
||||||
|
|
||||||
|
private static readonly messageBus: MessageBus = MessageBus.getInstance();
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static createProfile(profileData: any, validatorId: string): Promise<any> {
|
||||||
|
const ownerId = User.getInstance().getPairingId()!;
|
||||||
|
|
||||||
|
const processData: any = {
|
||||||
|
uid: uuidv4(),
|
||||||
|
utype: 'profile',
|
||||||
|
isDeleted: 'false',
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
|
updated_at: new Date().toISOString(),
|
||||||
|
...profileData,
|
||||||
|
};
|
||||||
|
|
||||||
|
const privateFields: string[] = Object.keys(processData);
|
||||||
|
privateFields.splice(privateFields.indexOf('uid'), 1);
|
||||||
|
privateFields.splice(privateFields.indexOf('utype'), 1);
|
||||||
|
|
||||||
|
const roles: any = {
|
||||||
|
demiurge: {
|
||||||
|
members: [...[ownerId], validatorId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
members: [ownerId],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: [...privateFields, 'roles'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
validator: {
|
||||||
|
members: [validatorId],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: ['idCertified', 'roles'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quorum: 0.0,
|
||||||
|
fields: [...privateFields],
|
||||||
|
min_sig_member: 0,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
apophis: {
|
||||||
|
members: [ownerId],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Promise<any>((resolve: (profileCreated: any) => void, reject: (error: string) => void) => {
|
||||||
|
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
|
||||||
|
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
||||||
|
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
|
resolve(processCreated);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getProfiles(): Promise<any[]> {
|
||||||
|
return this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['utype'] && publicValues['utype'] === 'profile');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getProfileByUid(uid: string): Promise<any> {
|
||||||
|
return new Promise<any>((resolve: (profile: any) => void, reject: (error: string) => void) => {
|
||||||
|
this.messageBus.getProcessesDecoded((publicValues: any) => publicValues['uid'] && publicValues['uid'] === uid && publicValues['utype'] && publicValues['utype'] === 'profile').then((profiles: any[]) => {
|
||||||
|
if (profiles.length === 0) {
|
||||||
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
resolve(profiles[0]);
|
||||||
|
}
|
||||||
|
}).catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,10 @@ export default class Auth extends BaseApiService {
|
|||||||
|
|
||||||
public async getIdnotJwt(autorizationCode: string | string[]): Promise<{ accessToken: string; refreshToken: string }> {
|
public async getIdnotJwt(autorizationCode: string | string[]): Promise<{ accessToken: string; refreshToken: string }> {
|
||||||
const variables = FrontendVariables.getInstance();
|
const variables = FrontendVariables.getInstance();
|
||||||
const baseBackUrl = variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
|
|
||||||
|
// TODO: review
|
||||||
|
const baseBackUrl = 'http://localhost:8080'//variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
|
||||||
|
|
||||||
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
|
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
|
||||||
try {
|
try {
|
||||||
return await this.postRequest<{ accessToken: string; refreshToken: string }>(url);
|
return await this.postRequest<{ accessToken: string; refreshToken: string }>(url);
|
||||||
|
@ -17,6 +17,7 @@ export default function Navigation() {
|
|||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
|
|
||||||
const getAnchoringStatus = useCallback(async () => {
|
const getAnchoringStatus = useCallback(async () => {
|
||||||
|
/* TODO: review
|
||||||
const anchors = await OfficeFolderAnchors.getInstance().get({
|
const anchors = await OfficeFolderAnchors.getInstance().get({
|
||||||
where: {
|
where: {
|
||||||
status: {
|
status: {
|
||||||
@ -27,6 +28,8 @@ export default function Navigation() {
|
|||||||
folder: true,
|
folder: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
const anchors = [] as any[];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const anchor of anchors) {
|
for (const anchor of anchors) {
|
||||||
@ -39,6 +42,8 @@ export default function Navigation() {
|
|||||||
|
|
||||||
const getNotifications = useCallback(async () => {
|
const getNotifications = useCallback(async () => {
|
||||||
//await getAnchoringStatus();
|
//await getAnchoringStatus();
|
||||||
|
|
||||||
|
/* TODO: review
|
||||||
const notifications = await Notifications.getInstance().get({
|
const notifications = await Notifications.getInstance().get({
|
||||||
where: {
|
where: {
|
||||||
read: false,
|
read: false,
|
||||||
@ -50,6 +55,9 @@ export default function Navigation() {
|
|||||||
notification: { created_at: "desc" },
|
notification: { created_at: "desc" },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
const notifications = [] as any[];
|
||||||
|
|
||||||
notifications.forEach((notification) => {
|
notifications.forEach((notification) => {
|
||||||
Toasts.getInstance().open({
|
Toasts.getInstance().open({
|
||||||
title: notification.notification.message,
|
title: notification.notification.message,
|
||||||
|
@ -35,6 +35,7 @@ export default function Header(props: IProps) {
|
|||||||
const [cancelAt, setCancelAt] = useState<Date | null>(null);
|
const [cancelAt, setCancelAt] = useState<Date | null>(null);
|
||||||
|
|
||||||
const loadSubscription = useCallback(async () => {
|
const loadSubscription = useCallback(async () => {
|
||||||
|
/* TODO: review
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
const jwt = JwtService.getInstance().decodeJwt();
|
||||||
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
|
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
|
||||||
if (subscription[0]) {
|
if (subscription[0]) {
|
||||||
@ -43,6 +44,7 @@ export default function Header(props: IProps) {
|
|||||||
setCancelAt(new Date(stripeSubscription.cancel_at! * 1000));
|
setCancelAt(new Date(stripeSubscription.cancel_at! * 1000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -30,7 +30,8 @@ export default function Rules(props: IProps) {
|
|||||||
}, [props.mode, props.rules]);
|
}, [props.mode, props.rules]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!JwtService.getInstance().decodeJwt()) return;
|
// TODO: review
|
||||||
|
//if (!JwtService.getInstance().decodeJwt()) return;
|
||||||
setHasJwt(true);
|
setHasJwt(true);
|
||||||
setIsShowing(getShowValue());
|
setIsShowing(getShowValue());
|
||||||
}, [getShowValue, isShowing]);
|
}, [getShowValue, isShowing]);
|
||||||
@ -40,7 +41,8 @@ export default function Rules(props: IProps) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasJwt || !isShowing) return null;
|
// TODO: review
|
||||||
|
//if (!hasJwt || !isShowing) return null;
|
||||||
|
|
||||||
return props.children;
|
return props.children;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,14 @@ export default function Tabs<T>({ onSelect, tabs: propsTabs }: IProps<T>) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
tabs.current = propsTabs;
|
tabs.current = propsTabs;
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
setTimeout(() => {
|
||||||
|
calculateVisibleElements();
|
||||||
|
if (tabs.current && tabs.current.length > 0 && tabs.current[0]) {
|
||||||
|
setSelectedTab(tabs.current[0].value);
|
||||||
|
}
|
||||||
|
}, 150);
|
||||||
}, [propsTabs]);
|
}, [propsTabs]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -15,6 +15,7 @@ export default function DefaultCollaboratorDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { collaboratorUid } = router.query;
|
const { collaboratorUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
const jwt = JwtService.getInstance().decodeJwt();
|
||||||
if (!jwt) return;
|
if (!jwt) return;
|
||||||
const query: IGetUsersparams = {
|
const query: IGetUsersparams = {
|
||||||
@ -28,10 +29,11 @@ export default function DefaultCollaboratorDashboard(props: IProps) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Users.getInstance()
|
Users.getInstance()
|
||||||
.get(query)
|
.get(query)
|
||||||
.then((users) => setCollaborators(users));
|
.then((users) => setCollaborators(users));
|
||||||
|
*/
|
||||||
|
setCollaborators([]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
|
@ -7,6 +7,8 @@ import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDas
|
|||||||
import { DeedType } from "le-coffre-resources/dist/Notary";
|
import { DeedType } from "le-coffre-resources/dist/Notary";
|
||||||
import DeedTypes, { IGetDeedTypesParams } from "@Front/Api/LeCoffreApi/Notary/DeedTypes/DeedTypes";
|
import DeedTypes, { IGetDeedTypesParams } from "@Front/Api/LeCoffreApi/Notary/DeedTypes/DeedTypes";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = IPropsDashboardWithList;
|
type IProps = IPropsDashboardWithList;
|
||||||
|
|
||||||
export default function DefaultDeedTypeDashboard(props: IProps) {
|
export default function DefaultDeedTypeDashboard(props: IProps) {
|
||||||
@ -14,6 +16,16 @@ export default function DefaultDeedTypeDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { deedTypeUid } = router.query;
|
const { deedTypeUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
MessageBus.getInstance().getDeepTypes().then((deedTypes: any) => {
|
||||||
|
setDeedTypes(deedTypes.map((deedType: any) => deedType.processData));
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const query: IGetDeedTypesParams = {
|
const query: IGetDeedTypesParams = {
|
||||||
where: {
|
where: {
|
||||||
archived_at: null,
|
archived_at: null,
|
||||||
@ -26,6 +38,7 @@ export default function DefaultDeedTypeDashboard(props: IProps) {
|
|||||||
DeedTypes.getInstance()
|
DeedTypes.getInstance()
|
||||||
.get(query)
|
.get(query)
|
||||||
.then((deedTypes) => setDeedTypes(deedTypes));
|
.then((deedTypes) => setDeedTypes(deedTypes));
|
||||||
|
*/
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
@ -39,10 +52,10 @@ export default function DefaultDeedTypeDashboard(props: IProps) {
|
|||||||
blocks={
|
blocks={
|
||||||
deedTypes
|
deedTypes
|
||||||
? deedTypes.map((deedTypes) => ({
|
? deedTypes.map((deedTypes) => ({
|
||||||
id: deedTypes.uid!,
|
id: deedTypes.uid!,
|
||||||
primaryText: deedTypes.name,
|
primaryText: deedTypes.name,
|
||||||
isActive: deedTypes.uid === deedTypeUid,
|
isActive: deedTypes.uid === deedTypeUid,
|
||||||
}))
|
}))
|
||||||
: []
|
: []
|
||||||
}
|
}
|
||||||
bottomButton={{
|
bottomButton={{
|
||||||
|
@ -8,6 +8,8 @@ import JwtService from "@Front/Services/JwtService/JwtService";
|
|||||||
import DocumentTypes from "@Front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes";
|
import DocumentTypes from "@Front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes";
|
||||||
import { DocumentType } from "le-coffre-resources/dist/Notary";
|
import { DocumentType } from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = IPropsDashboardWithList;
|
type IProps = IPropsDashboardWithList;
|
||||||
|
|
||||||
export default function DefaultDocumentTypeDashboard(props: IProps) {
|
export default function DefaultDocumentTypeDashboard(props: IProps) {
|
||||||
@ -15,6 +17,18 @@ export default function DefaultDocumentTypeDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { documentTypeUid } = router.query;
|
const { documentTypeUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// TODO: review
|
||||||
|
const officeId = 'demo_notary_office_id'; //JwtService.getInstance().decodeJwt()?.office_Id;
|
||||||
|
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
MessageBus.getInstance().getDocuments().then((documents: any) => {
|
||||||
|
setDocumentTypes(documents.map((document: any) => document.processData));
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
const jwt = JwtService.getInstance().decodeJwt();
|
||||||
if (!jwt) return;
|
if (!jwt) return;
|
||||||
DocumentTypes.getInstance()
|
DocumentTypes.getInstance()
|
||||||
@ -27,6 +41,7 @@ export default function DefaultDocumentTypeDashboard(props: IProps) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((documentTypes) => setDocumentTypes(documentTypes));
|
.then((documentTypes) => setDocumentTypes(documentTypes));
|
||||||
|
*/
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
@ -42,10 +57,10 @@ export default function DefaultDocumentTypeDashboard(props: IProps) {
|
|||||||
blocks={
|
blocks={
|
||||||
documentTypes
|
documentTypes
|
||||||
? documentTypes.map((documentType) => ({
|
? documentTypes.map((documentType) => ({
|
||||||
id: documentType.uid!,
|
id: documentType.uid!,
|
||||||
primaryText: documentType.name,
|
primaryText: documentType.name,
|
||||||
isActive: documentType.uid === documentTypeUid,
|
isActive: documentType.uid === documentTypeUid,
|
||||||
}))
|
}))
|
||||||
: []
|
: []
|
||||||
}
|
}
|
||||||
bottomButton={{
|
bottomButton={{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
||||||
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
import React, { useCallback, useEffect } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
|
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
|
||||||
|
|
||||||
import Module from "@Front/Config/Module";
|
import Module from "@Front/Config/Module";
|
||||||
@ -9,6 +9,8 @@ import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||||
|
|
||||||
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
|
||||||
type IProps = IPropsDashboardWithList & {
|
type IProps = IPropsDashboardWithList & {
|
||||||
isArchived?: boolean;
|
isArchived?: boolean;
|
||||||
};
|
};
|
||||||
@ -74,6 +76,7 @@ export default function DefaultNotaryDashboard(props: IProps) {
|
|||||||
}, [folders, getBlocks]);
|
}, [folders, getBlocks]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
let targetedStatus: EFolderStatus = EFolderStatus["LIVE" as keyof typeof EFolderStatus];
|
let targetedStatus: EFolderStatus = EFolderStatus["LIVE" as keyof typeof EFolderStatus];
|
||||||
if (isArchived) targetedStatus = EFolderStatus.ARCHIVED;
|
if (isArchived) targetedStatus = EFolderStatus.ARCHIVED;
|
||||||
const query: IGetFoldersParams = {
|
const query: IGetFoldersParams = {
|
||||||
@ -110,6 +113,13 @@ export default function DefaultNotaryDashboard(props: IProps) {
|
|||||||
Folders.getInstance()
|
Folders.getInstance()
|
||||||
.get(query)
|
.get(query)
|
||||||
.then((folders) => setFolders(folders));
|
.then((folders) => setFolders(folders));
|
||||||
|
*/
|
||||||
|
|
||||||
|
FolderService.getFolders().then((folders) => {
|
||||||
|
if (folders.length > 0) {
|
||||||
|
setFolders(folders.map((folder: any) => folder.processData).filter((folder: any) => folder.isArchived && folder.isArchived === (isArchived ? 'true' : 'false')));
|
||||||
|
}
|
||||||
|
});
|
||||||
}, [isArchived]);
|
}, [isArchived]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -14,9 +14,12 @@ export default function DefaultOfficeDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { officeUid } = router.query;
|
const { officeUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
Offices.getInstance()
|
Offices.getInstance()
|
||||||
.get()
|
.get()
|
||||||
.then((offices) => setOffices(offices));
|
.then((offices) => setOffices(offices));
|
||||||
|
*/
|
||||||
|
setOffices([]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
|
@ -14,6 +14,7 @@ export default function DefaultRoleDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { roleUid } = router.query;
|
const { roleUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
const query: IGetRolesParams = {
|
const query: IGetRolesParams = {
|
||||||
include: { rules: true },
|
include: { rules: true },
|
||||||
};
|
};
|
||||||
@ -21,6 +22,8 @@ export default function DefaultRoleDashboard(props: IProps) {
|
|||||||
OfficeRoles.getInstance()
|
OfficeRoles.getInstance()
|
||||||
.get(query)
|
.get(query)
|
||||||
.then((roles) => setRoles(roles));
|
.then((roles) => setRoles(roles));
|
||||||
|
*/
|
||||||
|
setRoles([]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
|
@ -14,13 +14,15 @@ export default function DefaultUserDashboard(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { userUid } = router.query;
|
const { userUid } = router.query;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
const query: IGetUsersparams = {
|
const query: IGetUsersparams = {
|
||||||
include: { contact: true, office_membership: true },
|
include: { contact: true, office_membership: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
Users.getInstance()
|
Users.getInstance()
|
||||||
.get(query)
|
.get(query)
|
||||||
.then((users) => setUsers(users));
|
.then((users) => setUsers(users));
|
||||||
|
*/
|
||||||
|
setUsers([]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onSelectedBlock = (block: IBlock) => {
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
|
@ -18,10 +18,20 @@ export default function ContactBox(props: IProps) {
|
|||||||
|
|
||||||
const [ribUrl, setRibUrl] = useState<string | null>(null);
|
const [ribUrl, setRibUrl] = useState<string | null>(null);
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
const stakeholder = {
|
||||||
|
cell_phone_number: "0606060606",
|
||||||
|
phone_number: "0606060606",
|
||||||
|
email: "test@lecoffre.fr",
|
||||||
|
};
|
||||||
|
|
||||||
const notaryContact = useMemo(
|
const notaryContact = useMemo(
|
||||||
() =>
|
() =>
|
||||||
folder?.stakeholders!.find((stakeholder) => stakeholder.office_role?.name === "Notaire")?.contact ??
|
/*folder?.stakeholders!.find((stakeholder) => stakeholder.office_role?.name === "Notaire")?.contact ??
|
||||||
folder?.stakeholders![0]!.contact,
|
folder?.stakeholders![0]!.contact*/
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
stakeholder,
|
||||||
[folder],
|
[folder],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
94
src/front/Components/Layouts/ClientDashboard/FormModal.tsx
Normal file
94
src/front/Components/Layouts/ClientDashboard/FormModal.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
|
import Modal from '@Front/Components/DesignSystem/Modal';
|
||||||
|
import Typography, { ETypo } from '@Front/Components/DesignSystem/Typography';
|
||||||
|
import Button, { EButtonstyletype, EButtonVariant } from '@Front/Components/DesignSystem/Button';
|
||||||
|
|
||||||
|
interface FormModalProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
onSubmit: (file: File) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FormModal({ isOpen, onClose, onSubmit }: FormModalProps) {
|
||||||
|
const [selectedFile, setSelectedFile] = useState<File | null>(null);
|
||||||
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) {
|
||||||
|
setSelectedFile(null);
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const files = e.target.files;
|
||||||
|
if (files && files.length > 0 && files[0] instanceof File) {
|
||||||
|
setSelectedFile(files[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleButtonClick = () => {
|
||||||
|
if (fileInputRef.current) {
|
||||||
|
fileInputRef.current.click();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
title='Ajouter un document'
|
||||||
|
>
|
||||||
|
<div style={{ padding: '20px 0' }}>
|
||||||
|
<div style={{ marginBottom: '20px' }}>
|
||||||
|
<Typography typo={ETypo.TEXT_MD_SEMIBOLD} className="mb-2">
|
||||||
|
Document
|
||||||
|
</Typography>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<input
|
||||||
|
ref={fileInputRef}
|
||||||
|
type="file"
|
||||||
|
accept="application/pdf"
|
||||||
|
onChange={handleFileChange}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant={EButtonVariant.SECONDARY}
|
||||||
|
styletype={EButtonstyletype.OUTLINED}
|
||||||
|
onClick={handleButtonClick}
|
||||||
|
>
|
||||||
|
Sélectionner un fichier PDF
|
||||||
|
</Button>
|
||||||
|
{selectedFile && (
|
||||||
|
<div className="ml-3">
|
||||||
|
<Typography typo={ETypo.TEXT_MD_REGULAR}>
|
||||||
|
{selectedFile.name}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: '12px', marginTop: '20px' }}>
|
||||||
|
<Button
|
||||||
|
variant={EButtonVariant.SECONDARY}
|
||||||
|
styletype={EButtonstyletype.OUTLINED}
|
||||||
|
onClick={onClose}
|
||||||
|
>
|
||||||
|
Annuler
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant={EButtonVariant.PRIMARY}
|
||||||
|
styletype={EButtonstyletype.CONTAINED}
|
||||||
|
onClick={() => selectedFile && onSubmit(selectedFile)}
|
||||||
|
disabled={!selectedFile}
|
||||||
|
>
|
||||||
|
Enregistrer
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@ -5,7 +5,7 @@ import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Ty
|
|||||||
|
|
||||||
import Customer, { Document, DocumentType } from "le-coffre-resources/dist/Customer";
|
import Customer, { Document, DocumentType } from "le-coffre-resources/dist/Customer";
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { DocumentNotary, type OfficeFolder as OfficeFolderNotary } from "le-coffre-resources/dist/Notary";
|
import { DocumentNotary, OfficeFolder as OfficeFolderNotary } from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
@ -25,19 +25,76 @@ import DocumentsNotary from "@Front/Api/LeCoffreApi/Customer/DocumentsNotary/Doc
|
|||||||
import { EDocumentNotaryStatus } from "le-coffre-resources/dist/Notary/DocumentNotary";
|
import { EDocumentNotaryStatus } from "le-coffre-resources/dist/Notary/DocumentNotary";
|
||||||
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";
|
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";
|
||||||
|
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
|
import MapUtils from "src/sdk/MapUtils";
|
||||||
|
import AuthModal from "src/sdk/AuthModal";
|
||||||
|
import FormModal from "./FormModal";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
export default function ClientDashboard(props: IProps) {
|
export default function ClientDashboard(props: IProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
let { folderUid } = router.query;
|
let { folderUid, profileUid } = router.query;
|
||||||
const [documents, setDocuments] = useState<Document[] | null>(null);
|
const [documents, setDocuments] = useState<Document[] | null>(null);
|
||||||
|
|
||||||
const [customer, setCustomer] = useState<Customer | null>(null);
|
const [customer, setCustomer] = useState<Customer | null>(null);
|
||||||
const [folder, setFolder] = useState<OfficeFolderNotary | null>(null);
|
const [folder, setFolder] = useState<OfficeFolderNotary | null>(null);
|
||||||
|
const [file, setFile] = useState<any | null>(null);
|
||||||
|
|
||||||
const [documentsNotary, setDocumentsNotary] = useState<DocumentNotary[]>([]);
|
const [documentsNotary, setDocumentsNotary] = useState<DocumentNotary[]>([]);
|
||||||
const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false);
|
const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
|
||||||
|
const [isFormModalOpen, setIsFormModalOpen] = useState(false);
|
||||||
|
|
||||||
const fetchFolderAndCustomer = useCallback(async () => {
|
const fetchFolderAndCustomer = useCallback(async () => {
|
||||||
|
// TODO: review
|
||||||
|
const { folder, customer, file } = await new Promise<any>((resolve) => {
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
MessageBus.getInstance().getFolders().then(async (folders) => {
|
||||||
|
const folder: any = folders.find((folder: any) => folder.processData.uid === folderUid as string);
|
||||||
|
if (folder) {
|
||||||
|
const customer = folder.processData.customers
|
||||||
|
.map((customer: any) => MapUtils.toJson(customer))
|
||||||
|
.find((customer: any) => customer.uid === profileUid as string);
|
||||||
|
|
||||||
|
const file = await new Promise<any>((resolve: (file: any) => void) => {
|
||||||
|
MessageBus.getInstance().getFiles().then((files: any) => {
|
||||||
|
if (!files || files.length === 0) {
|
||||||
|
resolve(null);
|
||||||
|
} else {
|
||||||
|
const file: any = files.find((file: any) => file.processData.folderUid === folderUid as string && file.processData.profileUid === profileUid as string);
|
||||||
|
if (file) {
|
||||||
|
resolve(file);
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(() => resolve(null));
|
||||||
|
});
|
||||||
|
|
||||||
|
resolve({ folder: folder.processData, customer, file: file ? file.processData : null });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 2500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
setCustomer(customer);
|
||||||
|
setFolder(folder);
|
||||||
|
setFile(file);
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
setIsAuthModalOpen(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { folder, customer };
|
||||||
|
|
||||||
|
/*
|
||||||
let jwt: ICustomerJwtPayload | undefined;
|
let jwt: ICustomerJwtPayload | undefined;
|
||||||
if (typeof document !== "undefined") {
|
if (typeof document !== "undefined") {
|
||||||
jwt = JwtService.getInstance().decodeCustomerJwt();
|
jwt = JwtService.getInstance().decodeCustomerJwt();
|
||||||
@ -73,6 +130,7 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
setCustomer(customer);
|
setCustomer(customer);
|
||||||
|
|
||||||
return { folder, customer };
|
return { folder, customer };
|
||||||
|
*/
|
||||||
}, [folderUid]);
|
}, [folderUid]);
|
||||||
|
|
||||||
const fetchDocuments = useCallback(
|
const fetchDocuments = useCallback(
|
||||||
@ -110,9 +168,13 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const customerUid = customer?.uid;
|
const customerUid = customer?.uid;
|
||||||
if (!folderUid || !customerUid) return;
|
if (!folderUid || !customerUid) return;
|
||||||
|
|
||||||
|
/* TODO: review
|
||||||
DocumentsNotary.getInstance()
|
DocumentsNotary.getInstance()
|
||||||
.get({ where: { folder: { uid: folderUid }, customer: { uid: customerUid } }, include: { files: true } })
|
.get({ where: { folder: { uid: folderUid }, customer: { uid: customerUid } }, include: { files: true } })
|
||||||
.then((documentsNotary) => setDocumentsNotary(documentsNotary));
|
.then((documentsNotary) => setDocumentsNotary(documentsNotary));
|
||||||
|
*/
|
||||||
|
|
||||||
}, [folderUid, customer?.uid]);
|
}, [folderUid, customer?.uid]);
|
||||||
|
|
||||||
const documentsNotaryNotRead = useMemo(
|
const documentsNotaryNotRead = useMemo(
|
||||||
@ -129,6 +191,21 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
setIsAddDocumentModalVisible(true);
|
setIsAddDocumentModalVisible(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onDownloadFile = useCallback(() => {
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const blob = new Blob([file.file.data], { type: file.file.type });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'document.pdf';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
}, [file]);
|
||||||
|
|
||||||
const renderBox = useCallback(() => {
|
const renderBox = useCallback(() => {
|
||||||
return (
|
return (
|
||||||
<DepositOtherDocument
|
<DepositOtherDocument
|
||||||
@ -157,6 +234,16 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
<Typography typo={ETypo.TITLE_H4} color={ETypoColor.TEXT_PRIMARY}>
|
<Typography typo={ETypo.TITLE_H4} color={ETypoColor.TEXT_PRIMARY}>
|
||||||
Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
|
Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
{file && (
|
||||||
|
<Button
|
||||||
|
variant={EButtonVariant.SECONDARY}
|
||||||
|
styletype={EButtonstyletype.OUTLINED}
|
||||||
|
onClick={() => onDownloadFile()}
|
||||||
|
>
|
||||||
|
Télécharger le document
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
<Tag color={ETagColor.INFO} label={folder?.deed?.deed_type?.name ?? ""} />
|
<Tag color={ETagColor.INFO} label={folder?.deed?.deed_type?.name ?? ""} />
|
||||||
<div className={classes["office-container"]}>
|
<div className={classes["office-container"]}>
|
||||||
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
|
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
|
||||||
@ -244,6 +331,56 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
Ajouter d'autres documents
|
Ajouter d'autres documents
|
||||||
</Button>
|
</Button>
|
||||||
{isAddDocumentModalVisible && renderBox()}
|
{isAddDocumentModalVisible && renderBox()}
|
||||||
|
|
||||||
|
{isAuthModalOpen && <AuthModal
|
||||||
|
isOpen={isAuthModalOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsAuthModalOpen(false);
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsFormModalOpen(true);
|
||||||
|
}, 500);
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
|
|
||||||
|
<FormModal
|
||||||
|
isOpen={isFormModalOpen}
|
||||||
|
onClose={() => setIsFormModalOpen(false)}
|
||||||
|
onSubmit={(file: any) => {
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
if (event.target?.result) {
|
||||||
|
const arrayBuffer = event.target.result as ArrayBuffer;
|
||||||
|
const uint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
|
||||||
|
const fileBlob = {
|
||||||
|
type: file.type,
|
||||||
|
data: uint8Array
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileData = {
|
||||||
|
uid: uuidv4(),
|
||||||
|
utype_ff: 'file',
|
||||||
|
folderUid: folderUid as string,
|
||||||
|
profileUid: profileUid as string,
|
||||||
|
file: fileBlob
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().createFile(fileData, [], []).then((processCreated: any) => {
|
||||||
|
MessageBus.getInstance().notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
|
setIsFormModalOpen(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</DefaultCustomerDashboard>
|
</DefaultCustomerDashboard>
|
||||||
);
|
);
|
||||||
|
@ -15,6 +15,10 @@ import { useCallback, useState } from "react";
|
|||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import { validateOrReject, ValidationError } from "class-validator";
|
import { validateOrReject, ValidationError } from "class-validator";
|
||||||
|
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function DeedTypesCreate(props: IProps) {
|
export default function DeedTypesCreate(props: IProps) {
|
||||||
const [hasChanged, setHasChanged] = useState<boolean>(false);
|
const [hasChanged, setHasChanged] = useState<boolean>(false);
|
||||||
@ -25,12 +29,14 @@ export default function DeedTypesCreate(props: IProps) {
|
|||||||
const onSubmitHandler = useCallback(
|
const onSubmitHandler = useCallback(
|
||||||
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
||||||
try {
|
try {
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
// TODO: review
|
||||||
|
const officeId = 'demo_notary_office_id'; //JwtService.getInstance().decodeJwt()?.office_Id;
|
||||||
|
|
||||||
const deedType = DeedType.hydrate<DeedType>({
|
const deedType = DeedType.hydrate<DeedType>({
|
||||||
name: values["name"],
|
name: values["name"],
|
||||||
description: values["description"],
|
description: values["description"],
|
||||||
office: Office.hydrate<Office>({
|
office: Office.hydrate<Office>({
|
||||||
uid: jwt?.office_Id,
|
uid: officeId,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -40,12 +46,27 @@ export default function DeedTypesCreate(props: IProps) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().createDeedType({ ...deedType, uid: uuidv4(), utype_dt: 'deedType', isDeleted: 'false' }, [], []).then((processCreated: any) => {
|
||||||
|
MessageBus.getInstance().notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
|
router.push(
|
||||||
|
Module.getInstance()
|
||||||
|
.get()
|
||||||
|
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const deedTypeCreated = await DeedTypes.getInstance().post(
|
const deedTypeCreated = await DeedTypes.getInstance().post(
|
||||||
DeedType.hydrate<DeedType>({
|
DeedType.hydrate<DeedType>({
|
||||||
name: values["name"],
|
name: values["name"],
|
||||||
description: values["description"],
|
description: values["description"],
|
||||||
office: Office.hydrate<Office>({
|
office: Office.hydrate<Office>({
|
||||||
uid: jwt?.office_Id,
|
uid: officeId,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -55,6 +76,7 @@ export default function DeedTypesCreate(props: IProps) {
|
|||||||
.get()
|
.get()
|
||||||
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeCreated.uid!),
|
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeCreated.uid!),
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
} catch (validationErrors: Array<ValidationError> | any) {
|
} catch (validationErrors: Array<ValidationError> | any) {
|
||||||
setValidationError(validationErrors as ValidationError[]);
|
setValidationError(validationErrors as ValidationError[]);
|
||||||
return;
|
return;
|
||||||
|
@ -20,6 +20,9 @@ import { useCallback, useEffect, useState } from "react";
|
|||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
import MapUtils from "src/sdk/MapUtils";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function DeedTypesInformations(props: IProps) {
|
export default function DeedTypesInformations(props: IProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -62,6 +65,30 @@ export default function DeedTypesInformations(props: IProps) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getDeedType() {
|
async function getDeedType() {
|
||||||
if (!deedTypeUid) return;
|
if (!deedTypeUid) return;
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getDeepTypes().then((deedTypes: any) => {
|
||||||
|
const deedType: any = deedTypes.find((deedType: any) => deedType.processData.uid === deedTypeUid);
|
||||||
|
if (deedType) {
|
||||||
|
setDeedTypeSelected(deedType.processData);
|
||||||
|
|
||||||
|
const documentsOptions: any[] = deedType.processData.document_types
|
||||||
|
?.map((documentType: any) => MapUtils.toJson(documentType))
|
||||||
|
.map((documentType: any) => {
|
||||||
|
return {
|
||||||
|
label: documentType[0].name,
|
||||||
|
id: documentType[0].uid ?? "",
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.sort((a: any, b: any) => a.label.localeCompare(b.label));
|
||||||
|
|
||||||
|
setSelectedDocuments(documentsOptions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const deedType = await DeedTypes.getInstance().getByUid(deedTypeUid as string, {
|
const deedType = await DeedTypes.getInstance().getByUid(deedTypeUid as string, {
|
||||||
q: {
|
q: {
|
||||||
document_types: true,
|
document_types: true,
|
||||||
@ -79,11 +106,23 @@ export default function DeedTypesInformations(props: IProps) {
|
|||||||
})
|
})
|
||||||
.sort((a, b) => a.label.localeCompare(b.label));
|
.sort((a, b) => a.label.localeCompare(b.label));
|
||||||
setSelectedDocuments(documentsOptions);
|
setSelectedDocuments(documentsOptions);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getDocuments() {
|
async function getDocuments() {
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
MessageBus.getInstance().getDocuments().then((documents: any) => {
|
||||||
|
setAvailableDocuments(documents.map((document: any) => document.processData));
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const documents = await DocumentTypes.getInstance().get({});
|
const documents = await DocumentTypes.getInstance().get({});
|
||||||
setAvailableDocuments(documents);
|
setAvailableDocuments(documents);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
getDocuments();
|
getDocuments();
|
||||||
@ -98,11 +137,40 @@ export default function DeedTypesInformations(props: IProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const saveDocumentTypes = useCallback(async () => {
|
const saveDocumentTypes = useCallback(async () => {
|
||||||
|
/*
|
||||||
await DeedTypes.getInstance().put(deedTypeUid as string, {
|
await DeedTypes.getInstance().put(deedTypeUid as string, {
|
||||||
uid: deedTypeUid as string,
|
uid: deedTypeUid as string,
|
||||||
document_types: selectedDocuments.map((document) => DocumentType.hydrate<DocumentType>({ uid: document.id as string })),
|
document_types: selectedDocuments.map((document) => DocumentType.hydrate<DocumentType>({ uid: document.id as string })),
|
||||||
});
|
});
|
||||||
closeSaveModal();
|
*/
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getDeepTypes().then((deedTypes: any) => {
|
||||||
|
const deedType: any = deedTypes.find((deedType: any) => deedType.processData.uid === deedTypeUid);
|
||||||
|
if (deedType) {
|
||||||
|
let document_types: any[] = deedType.processData.document_types;
|
||||||
|
if (!document_types) {
|
||||||
|
document_types = [];
|
||||||
|
}
|
||||||
|
document_types.push(selectedDocuments.map((document) => {
|
||||||
|
return {
|
||||||
|
uid: document.id,
|
||||||
|
name: document.label,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
MessageBus.getInstance().updateProcess(deedType.processId, deedType.lastStateId, { document_types: document_types }, [], null).then((processUpdated: any) => {
|
||||||
|
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||||
|
MessageBus.getInstance().notifyUpdate(deedType.processId, newStateId).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(deedType.processId, newStateId).then((_stateValidated) => {
|
||||||
|
closeSaveModal();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}, [closeSaveModal, deedTypeUid, selectedDocuments]);
|
}, [closeSaveModal, deedTypeUid, selectedDocuments]);
|
||||||
|
|
||||||
const onDocumentChangeHandler = useCallback((options: IOption[] | null) => {
|
const onDocumentChangeHandler = useCallback((options: IOption[] | null) => {
|
||||||
|
@ -14,6 +14,10 @@ import { useCallback, useState } from "react";
|
|||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
export default function DocumentTypesCreate(props: IProps) {
|
export default function DocumentTypesCreate(props: IProps) {
|
||||||
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
||||||
@ -22,6 +26,38 @@ export default function DocumentTypesCreate(props: IProps) {
|
|||||||
const onSubmitHandler = useCallback(
|
const onSubmitHandler = useCallback(
|
||||||
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
||||||
try {
|
try {
|
||||||
|
// TODO: review
|
||||||
|
const officeId = 'demo_notary_office_id'; //JwtService.getInstance().decodeJwt()?.office_Id;
|
||||||
|
|
||||||
|
const documentToCreate = DocumentType.hydrate<DocumentType>({
|
||||||
|
...values,
|
||||||
|
office: Office.hydrate<Office>({
|
||||||
|
uid: officeId,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
await validateOrReject(documentToCreate, { groups: ["createDocumentType"] });
|
||||||
|
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
const documentData: any = {
|
||||||
|
...values,
|
||||||
|
uid: uuidv4(),
|
||||||
|
utype_d: 'document',
|
||||||
|
isDeleted: 'false'
|
||||||
|
};
|
||||||
|
MessageBus.getInstance().createDocument(documentData, [], []).then((processCreated: any) => {
|
||||||
|
MessageBus.getInstance().notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
|
||||||
|
router.push(
|
||||||
|
Module.getInstance()
|
||||||
|
.get()
|
||||||
|
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", processCreated.processData.uid),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
const jwt = JwtService.getInstance().decodeJwt();
|
||||||
if (!jwt) return;
|
if (!jwt) return;
|
||||||
const office = Office.hydrate<Office>({
|
const office = Office.hydrate<Office>({
|
||||||
@ -39,6 +75,7 @@ export default function DocumentTypesCreate(props: IProps) {
|
|||||||
.get()
|
.get()
|
||||||
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", documentTypeCreated.uid!),
|
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", documentTypeCreated.uid!),
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Array) {
|
if (e instanceof Array) {
|
||||||
setValidationError(e);
|
setValidationError(e);
|
||||||
|
@ -13,6 +13,8 @@ import { useEffect, useState } from "react";
|
|||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
export default function DocumentTypesInformations() {
|
export default function DocumentTypesInformations() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
let { documentTypeUid } = router.query;
|
let { documentTypeUid } = router.query;
|
||||||
@ -22,11 +24,24 @@ export default function DocumentTypesInformations() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getDocument() {
|
async function getDocument() {
|
||||||
if (!documentTypeUid) return;
|
if (!documentTypeUid) return;
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getDocuments().then((documents: any) => {
|
||||||
|
const document: any = documents.find((document: any) => document.processData.uid === documentTypeUid as string);
|
||||||
|
if (document) {
|
||||||
|
setDocumentSelected(document.processData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const document = await DocumentTypes.getInstance().getByUid(documentTypeUid as string, {
|
const document = await DocumentTypes.getInstance().getByUid(documentTypeUid as string, {
|
||||||
_count: true,
|
_count: true,
|
||||||
});
|
});
|
||||||
if (!document) return;
|
if (!document) return;
|
||||||
setDocumentSelected(document);
|
setDocumentSelected(document);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
getDocument();
|
getDocument();
|
||||||
|
@ -19,6 +19,9 @@ import classes from "./classes.module.scss";
|
|||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||||
|
|
||||||
|
import ProfileService from "src/common/Api/LeCoffreApi/sdk/ProfileService";
|
||||||
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
|
||||||
enum ESelectedOption {
|
enum ESelectedOption {
|
||||||
EXISTING_CUSTOMER = "existing_customer",
|
EXISTING_CUSTOMER = "existing_customer",
|
||||||
NEW_CUSTOMER = "new_customer",
|
NEW_CUSTOMER = "new_customer",
|
||||||
@ -71,11 +74,33 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// TODO: review
|
||||||
|
const profile: any = {
|
||||||
|
contact: values
|
||||||
|
};
|
||||||
|
|
||||||
|
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
|
||||||
|
|
||||||
|
ProfileService.createProfile(profile, validatorId).then((profileCreated: any) => {
|
||||||
|
FolderService.getFolderByUid(folderUid as string).then((folder: any) => {
|
||||||
|
if (folder) {
|
||||||
|
const customers: any[] = folder.processData.customers;
|
||||||
|
customers.push(profileCreated.processData.uid);
|
||||||
|
|
||||||
|
FolderService.updateFolder(folder, { customers }).then(() => {
|
||||||
|
router.push(`/folders/${folderUid}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const customer: Customer = await Customers.getInstance().post({
|
const customer: Customer = await Customers.getInstance().post({
|
||||||
contact: values,
|
contact: values,
|
||||||
});
|
});
|
||||||
if (!customer.uid) return;
|
if (!customer.uid) return;
|
||||||
customersToLink?.push({ uid: customer.uid } as Partial<Customer>);
|
customersToLink?.push({ uid: customer.uid } as Partial<Customer>);
|
||||||
|
*/
|
||||||
} catch (backError) {
|
} catch (backError) {
|
||||||
if (!Array.isArray(backError)) return;
|
if (!Array.isArray(backError)) return;
|
||||||
setValidationError(backError as ValidationError[]);
|
setValidationError(backError as ValidationError[]);
|
||||||
@ -83,6 +108,7 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (customersToLink) {
|
if (customersToLink) {
|
||||||
const body = OfficeFolder.hydrate<OfficeFolder>({
|
const body = OfficeFolder.hydrate<OfficeFolder>({
|
||||||
customers: customersToLink.map((customer) => {
|
customers: customersToLink.map((customer) => {
|
||||||
@ -92,6 +118,7 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
await Folders.getInstance().put(folderUid as string, body);
|
await Folders.getInstance().put(folderUid as string, body);
|
||||||
router.push(`/folders/${folderUid}`);
|
router.push(`/folders/${folderUid}`);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
[existingCustomers, folderUid, router, selectedCustomers, selectedOption],
|
[existingCustomers, folderUid, router, selectedCustomers, selectedOption],
|
||||||
);
|
);
|
||||||
@ -126,6 +153,7 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const loadCustomers = useCallback(async () => {
|
const loadCustomers = useCallback(async () => {
|
||||||
|
/* TODO: review
|
||||||
const query = {};
|
const query = {};
|
||||||
const availableCustomers = await Customers.getInstance().get(query);
|
const availableCustomers = await Customers.getInstance().get(query);
|
||||||
let preExistingCustomers: IOption[] | undefined = await getFolderPreSelectedCustomers(folderUid as string);
|
let preExistingCustomers: IOption[] | undefined = await getFolderPreSelectedCustomers(folderUid as string);
|
||||||
@ -143,8 +171,9 @@ export default function AddClientToFolder(props: IProps) {
|
|||||||
|
|
||||||
setAvailableCustomers(availableCustomers);
|
setAvailableCustomers(availableCustomers);
|
||||||
setExistingCustomers(existingCustomers);
|
setExistingCustomers(existingCustomers);
|
||||||
|
*/
|
||||||
setIsLoaded(true);
|
setIsLoaded(true);
|
||||||
setSelectedOption(selectedOption);
|
//setSelectedOption(selectedOption);
|
||||||
}, [folderUid, getFolderPreSelectedCustomers]);
|
}, [folderUid, getFolderPreSelectedCustomers]);
|
||||||
|
|
||||||
const getSelectedOptions = useCallback((): IOption[] => {
|
const getSelectedOptions = useCallback((): IOption[] => {
|
||||||
|
@ -55,7 +55,10 @@ export default function AskDocuments() {
|
|||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
|
// TODO: review
|
||||||
const documentAsked: [] = values["document_types"] as [];
|
const documentAsked: [] = values["document_types"] as [];
|
||||||
|
|
||||||
|
/*
|
||||||
for (let i = 0; i < documentAsked.length; i++) {
|
for (let i = 0; i < documentAsked.length; i++) {
|
||||||
await Documents.getInstance().post({
|
await Documents.getInstance().post({
|
||||||
folder: {
|
folder: {
|
||||||
@ -75,6 +78,7 @@ export default function AskDocuments() {
|
|||||||
.get()
|
.get()
|
||||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folderUid as string),
|
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folderUid as string),
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,11 @@ import User from "le-coffre-resources/dist/Notary";
|
|||||||
import { DeedType } from "le-coffre-resources/dist/Notary";
|
import { DeedType } from "le-coffre-resources/dist/Notary";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
|
||||||
export default function CreateFolder(): JSX.Element {
|
export default function CreateFolder(): JSX.Element {
|
||||||
/**
|
/**
|
||||||
* State
|
* State
|
||||||
@ -48,9 +50,10 @@ export default function CreateFolder(): JSX.Element {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const officeId = JwtService.getInstance().decodeJwt()?.office_Id;
|
// TODO: review
|
||||||
|
const officeId = 'demo_notary_office_id'; //JwtService.getInstance().decodeJwt()?.office_Id;
|
||||||
|
|
||||||
const officeFolderForm = OfficeFolder.hydrate<OfficeFolder>({
|
const officeFolderModel = OfficeFolder.hydrate<OfficeFolder>({
|
||||||
folder_number: values["folder_number"],
|
folder_number: values["folder_number"],
|
||||||
name: values["name"],
|
name: values["name"],
|
||||||
description: values["description"],
|
description: values["description"],
|
||||||
@ -67,16 +70,37 @@ export default function CreateFolder(): JSX.Element {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: true });
|
await officeFolderModel.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: true });
|
||||||
} catch (validationErrors) {
|
} catch (validationErrors) {
|
||||||
setValidationError(validationErrors as ValidationError[]);
|
setValidationError(validationErrors as ValidationError[]);
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
/*
|
||||||
const newOfficeFolder = await Folders.getInstance().post(officeFolderForm);
|
const newOfficeFolder = await Folders.getInstance().post(officeFolderForm);
|
||||||
if (!newOfficeFolder) return;
|
if (!newOfficeFolder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
router.push(`/folders/${newOfficeFolder.uid}`);
|
router.push(`/folders/${newOfficeFolder.uid}`);
|
||||||
|
*/
|
||||||
|
|
||||||
|
const folderData: any = {
|
||||||
|
folder_number: officeFolderModel.folder_number,
|
||||||
|
name: officeFolderModel.name,
|
||||||
|
deed: officeFolderModel.deed,
|
||||||
|
description: officeFolderModel.description,
|
||||||
|
customers: [],
|
||||||
|
documents: [],
|
||||||
|
notes: [],
|
||||||
|
office: officeFolderModel.office,
|
||||||
|
stakeholders: officeFolderModel.stakeholders
|
||||||
|
};
|
||||||
|
|
||||||
|
FolderService.createFolder(folderData, [], []).then((folderCreated: any) => {
|
||||||
|
const folderUid: string = folderCreated.processData.uid;
|
||||||
|
router.push(`/folders/${folderUid}`);
|
||||||
|
});
|
||||||
} catch (backError) {
|
} catch (backError) {
|
||||||
if (!Array.isArray(backError)) return;
|
if (!Array.isArray(backError)) return;
|
||||||
setValidationError(backError as ValidationError[]);
|
setValidationError(backError as ValidationError[]);
|
||||||
@ -100,9 +124,19 @@ export default function CreateFolder(): JSX.Element {
|
|||||||
* UseEffect
|
* UseEffect
|
||||||
*/
|
*/
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getDeepTypes().then((deedTypes: any) => {
|
||||||
|
console.log(deedTypes.map((deedType: any) => deedType.processData));
|
||||||
|
setAvailableDeedTypes(deedTypes.map((deedType: any) => deedType.processData));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
/*
|
||||||
DeedTypes.getInstance()
|
DeedTypes.getInstance()
|
||||||
.get({ where: { archived_at: null } })
|
.get({ where: { archived_at: null } })
|
||||||
.then((deedTypes) => setAvailableDeedTypes(deedTypes));
|
.then((deedTypes) => setAvailableDeedTypes(deedTypes));
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TODO: review
|
||||||
// no need to pass query 'where' param here, default query for notaries include only users which are in the same office as the caller
|
// 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()
|
Users.getInstance()
|
||||||
.get({
|
.get({
|
||||||
@ -110,12 +144,15 @@ export default function CreateFolder(): JSX.Element {
|
|||||||
})
|
})
|
||||||
.then((users) => {
|
.then((users) => {
|
||||||
setAvailableCollaborators(users);
|
setAvailableCollaborators(users);
|
||||||
|
/ *
|
||||||
// set default selected collaborators to the connected user
|
// set default selected collaborators to the connected user
|
||||||
const currentUser = users.find((user) => user.uid === JwtService.getInstance().decodeJwt()?.userId);
|
const currentUser = users.find((user) => user.uid === JwtService.getInstance().decodeJwt()?.userId);
|
||||||
if (currentUser) {
|
if (currentUser) {
|
||||||
setSelectedCollaborators([currentUser]);
|
setSelectedCollaborators([currentUser]);
|
||||||
}
|
}
|
||||||
|
* /
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +28,12 @@ export default function ClientBox(props: IProps) {
|
|||||||
const { isOpen: isDeleteModalOpen, open: openDeleteModal, close: closeDeleteModal } = useOpenable();
|
const { isOpen: isDeleteModalOpen, open: openDeleteModal, close: closeDeleteModal } = useOpenable();
|
||||||
const { isOpen: isErrorModalOpen, open: openErrorModal, close: closeErrorModal } = useOpenable();
|
const { isOpen: isErrorModalOpen, open: openErrorModal, close: closeErrorModal } = useOpenable();
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
const handleOpenConnectionLink = useCallback(() => {
|
||||||
|
const url = `http://localhost:3000/client-dashboard/${folderUid}/profile/${customer.uid}`;
|
||||||
|
alert(url);
|
||||||
|
}, [customer.uid, folderUid]);
|
||||||
|
|
||||||
const handleDelete = useCallback(
|
const handleDelete = useCallback(
|
||||||
async (customerUid: string) => {
|
async (customerUid: string) => {
|
||||||
console.log(customer);
|
console.log(customer);
|
||||||
@ -83,6 +89,15 @@ export default function ClientBox(props: IProps) {
|
|||||||
</Menu>
|
</Menu>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size={EButtonSize.SM}
|
||||||
|
variant={EButtonVariant.WARNING}
|
||||||
|
styletype={EButtonstyletype.TEXT}
|
||||||
|
onClick={handleOpenConnectionLink}>
|
||||||
|
Lien de connexion
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_700}>
|
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_700}>
|
||||||
Numéro de téléphone
|
Numéro de téléphone
|
||||||
|
@ -73,8 +73,10 @@ export default function DocumentTables(props: IProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
fetchDocuments();
|
fetchDocuments();
|
||||||
fetchDocumentsNotary();
|
fetchDocumentsNotary();
|
||||||
|
*/
|
||||||
}, [fetchDocuments, fetchDocumentsNotary]);
|
}, [fetchDocuments, fetchDocumentsNotary]);
|
||||||
|
|
||||||
const openDeleteAskedDocumentModal = useCallback(
|
const openDeleteAskedDocumentModal = useCallback(
|
||||||
|
@ -41,7 +41,9 @@ export default function EmailReminder(props: IProps) {
|
|||||||
}, [customer.uid, folderUid]);
|
}, [customer.uid, folderUid]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
fetchReminders();
|
fetchReminders();
|
||||||
|
*/
|
||||||
}, [fetchReminders]);
|
}, [fetchReminders]);
|
||||||
|
|
||||||
const remindersLength = useMemo(() => {
|
const remindersLength = useMemo(() => {
|
||||||
|
@ -7,7 +7,7 @@ import Customer from "le-coffre-resources/dist/Customer";
|
|||||||
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
||||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
|
|
||||||
import { AnchorStatus } from "..";
|
import { AnchorStatus } from "..";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
@ -27,23 +27,34 @@ export default function ClientView(props: IProps) {
|
|||||||
const { folder, anchorStatus } = props;
|
const { folder, anchorStatus } = props;
|
||||||
|
|
||||||
const customers: ICustomer[] = useMemo(
|
const customers: ICustomer[] = useMemo(
|
||||||
() =>
|
() => {
|
||||||
folder?.customers
|
// TODO: review
|
||||||
?.map((customer) => ({
|
return folder?.customers?.map((customer: any) => customer.processData)
|
||||||
id: customer.uid ?? "",
|
.map((customer: any) => ({
|
||||||
|
id: customer.uid ?? '',
|
||||||
...customer,
|
...customer,
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => {
|
.sort((a: any, b: any) => {
|
||||||
return a.documents &&
|
return a.documents &&
|
||||||
a.documents.filter((document) => document.document_status === EDocumentStatus.DEPOSITED).length > 0
|
a.documents.filter((document: any) => document.document_status === EDocumentStatus.DEPOSITED).length > 0
|
||||||
? -1
|
? -1
|
||||||
: 1;
|
: 1;
|
||||||
}) ?? [],
|
}) ?? []
|
||||||
|
},
|
||||||
[folder],
|
[folder],
|
||||||
);
|
);
|
||||||
|
|
||||||
const [customer, setCustomer] = useState<(typeof customers)[number]>(customers[0]!);
|
const [customer, setCustomer] = useState<(typeof customers)[number]>(customers[0]!);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// TODO: review
|
||||||
|
setTimeout(() => {
|
||||||
|
if (customers.length > 0 && customers[0]) {
|
||||||
|
setCustomer(customers[0]);
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}, [customers]);
|
||||||
|
|
||||||
const tabs = useMemo(
|
const tabs = useMemo(
|
||||||
() =>
|
() =>
|
||||||
customers.map((customer) => ({
|
customers.map((customer) => ({
|
||||||
@ -75,7 +86,7 @@ export default function ClientView(props: IProps) {
|
|||||||
folder.uid,
|
folder.uid,
|
||||||
OfficeFolder.hydrate<OfficeFolder>({
|
OfficeFolder.hydrate<OfficeFolder>({
|
||||||
...folder,
|
...folder,
|
||||||
customers: folder.customers?.filter((customer) => customer.uid !== customerUid),
|
customers: folder.customers?.filter((customer: any) => customer.uid !== customerUid),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
@ -110,7 +121,7 @@ export default function ClientView(props: IProps) {
|
|||||||
anchorStatus={anchorStatus}
|
anchorStatus={anchorStatus}
|
||||||
folderUid={folder.uid}
|
folderUid={folder.uid}
|
||||||
onDelete={handleClientDelete}
|
onDelete={handleClientDelete}
|
||||||
customerNote={folder.notes!.find((value) => value.customer?.uid === customer.uid) ?? null}
|
customerNote={folder.notes!.find((value: any) => value.customer?.uid === customer.uid) ?? null}
|
||||||
/>
|
/>
|
||||||
<div className={classes["button-container"]}>
|
<div className={classes["button-container"]}>
|
||||||
{anchorStatus === AnchorStatus.NOT_ANCHORED && (
|
{anchorStatus === AnchorStatus.NOT_ANCHORED && (
|
||||||
|
@ -6,6 +6,8 @@ import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
@ -21,10 +23,16 @@ export default function DeleteFolderModal(props: IProps) {
|
|||||||
if ((folder?.customers?.length ?? 0) > 0 || (folder?.documents?.length ?? 0) > 0)
|
if ((folder?.customers?.length ?? 0) > 0 || (folder?.documents?.length ?? 0) > 0)
|
||||||
return console.warn("Cannot delete folder with customers or documents");
|
return console.warn("Cannot delete folder with customers or documents");
|
||||||
|
|
||||||
|
/* TODO: review
|
||||||
return Folders.getInstance()
|
return Folders.getInstance()
|
||||||
.delete(folder.uid)
|
.delete(folder.uid)
|
||||||
.then(() => router.push(Module.getInstance().get().modules.pages.Folder.props.path))
|
.then(() => router.push(Module.getInstance().get().modules.pages.Folder.props.path))
|
||||||
.then(onClose);
|
.then(onClose);
|
||||||
|
*/
|
||||||
|
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
//MessageBus.getInstance().deleteFolder(folder.uid).then(() => router.push(Module.getInstance().get().modules.pages.Folder.props.path)).then(onClose);
|
||||||
|
});
|
||||||
}, [folder, router, onClose]);
|
}, [folder, router, onClose]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -6,6 +6,7 @@ import Image from "next/image";
|
|||||||
import React, { useCallback, useState } from "react";
|
import React, { useCallback, useState } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -19,11 +20,37 @@ export default function AnchoringModal(props: IProps) {
|
|||||||
const [isAnchoring, setIsAnchoring] = useState(false);
|
const [isAnchoring, setIsAnchoring] = useState(false);
|
||||||
|
|
||||||
const anchor = useCallback(() => {
|
const anchor = useCallback(() => {
|
||||||
|
setIsAnchoring(true);
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getFolders().then((folders: any) => {
|
||||||
|
const folder = folders.find((folder: any) => folder.processData.uid === folderUid);
|
||||||
|
if (folder) {
|
||||||
|
MessageBus.getInstance().updateProcess(folder.processId, folder.lastStateId, { isArchived: 'true' }, [], null).then((processUpdated: any) => {
|
||||||
|
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||||
|
MessageBus.getInstance().notifyUpdate(folder.processId, newStateId).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(folder.processId, newStateId).then((_updatedProcess) => {
|
||||||
|
setIsAnchoring(false);
|
||||||
|
|
||||||
|
onAnchorSuccess();
|
||||||
|
if (onClose) {
|
||||||
|
onClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const timeoutDelay = 9800;
|
const timeoutDelay = 9800;
|
||||||
const timeoutPromise = new Promise((resolve) => {
|
const timeoutPromise = new Promise((resolve) => {
|
||||||
setTimeout(resolve, timeoutDelay);
|
setTimeout(resolve, timeoutDelay);
|
||||||
});
|
});
|
||||||
setIsAnchoring(true);
|
setIsAnchoring(true);
|
||||||
|
|
||||||
return OfficeFolderAnchors.getInstance()
|
return OfficeFolderAnchors.getInstance()
|
||||||
.post(folderUid)
|
.post(folderUid)
|
||||||
.then(() => timeoutPromise)
|
.then(() => timeoutPromise)
|
||||||
@ -34,6 +61,7 @@ export default function AnchoringModal(props: IProps) {
|
|||||||
console.warn(e);
|
console.warn(e);
|
||||||
setIsAnchoring(false);
|
setIsAnchoring(false);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}, [folderUid, onAnchorSuccess, onClose]);
|
}, [folderUid, onAnchorSuccess, onClose]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -21,6 +21,8 @@ import InformationSection from "./InformationSection";
|
|||||||
import NoClientView from "./NoClientView";
|
import NoClientView from "./NoClientView";
|
||||||
import AnchoringProcessingInfo from "./elements/AnchoringProcessingInfo";
|
import AnchoringProcessingInfo from "./elements/AnchoringProcessingInfo";
|
||||||
|
|
||||||
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
|
||||||
export enum AnchorStatus {
|
export enum AnchorStatus {
|
||||||
"VERIFIED_ON_CHAIN" = "VERIFIED_ON_CHAIN",
|
"VERIFIED_ON_CHAIN" = "VERIFIED_ON_CHAIN",
|
||||||
"ANCHORING" = "ANCHORING",
|
"ANCHORING" = "ANCHORING",
|
||||||
@ -59,6 +61,8 @@ export default function FolderInformation(props: IProps) {
|
|||||||
|
|
||||||
const fetchFolder = useCallback(async () => {
|
const fetchFolder = useCallback(async () => {
|
||||||
if (!folderUid) return;
|
if (!folderUid) return;
|
||||||
|
|
||||||
|
/*
|
||||||
const query = {
|
const query = {
|
||||||
q: {
|
q: {
|
||||||
deed: { include: { deed_type: true, document_types: true } },
|
deed: { include: { deed_type: true, document_types: true } },
|
||||||
@ -99,6 +103,17 @@ export default function FolderInformation(props: IProps) {
|
|||||||
return Folders.getInstance()
|
return Folders.getInstance()
|
||||||
.getByUid(folderUid, query)
|
.getByUid(folderUid, query)
|
||||||
.then((folder) => setFolder(folder));
|
.then((folder) => setFolder(folder));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: review
|
||||||
|
return new Promise<any>((resolve: (value: any) => void) => {
|
||||||
|
FolderService.getFolderByUid(folderUid).then((folder: any) => {
|
||||||
|
if (folder) {
|
||||||
|
setFolder(folder.processData);
|
||||||
|
resolve(folder.processData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}, [folderUid]);
|
}, [folderUid]);
|
||||||
|
|
||||||
const fetchAnchorStatus = useCallback(() => {
|
const fetchAnchorStatus = useCallback(() => {
|
||||||
@ -113,7 +128,10 @@ export default function FolderInformation(props: IProps) {
|
|||||||
const fetchData = useCallback(() => {
|
const fetchData = useCallback(() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
return fetchFolder()
|
return fetchFolder()
|
||||||
.then(() => fetchAnchorStatus())
|
.then((folder) => {
|
||||||
|
// TODO: review
|
||||||
|
//return fetchAnchorStatus()
|
||||||
|
})
|
||||||
.catch((e) => console.error(e))
|
.catch((e) => console.error(e))
|
||||||
.finally(() => setIsLoading(false));
|
.finally(() => setIsLoading(false));
|
||||||
}, [fetchAnchorStatus, fetchFolder]);
|
}, [fetchAnchorStatus, fetchFolder]);
|
||||||
|
@ -15,9 +15,11 @@ import { Contact, Customer } from "le-coffre-resources/dist/Notary";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
import MapUtils from "src/sdk/MapUtils";
|
||||||
|
|
||||||
export default function UpdateClient() {
|
export default function UpdateClient() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { folderUid, customerUid } = router.query;
|
const { folderUid, customerUid } = router.query;
|
||||||
@ -35,6 +37,21 @@ export default function UpdateClient() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchCustomer = async () => {
|
const fetchCustomer = async () => {
|
||||||
try {
|
try {
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getFolders().then((folders: any) => {
|
||||||
|
const folder = folders.find((folder: any) => folder.processData.uid === folderUid as string);
|
||||||
|
if (folder) {
|
||||||
|
const customers: any[] = folder.processData.customers.map((customer: any) => MapUtils.toJson(customer));
|
||||||
|
const customer: any = customers.find((customer: any) => customer.uid === customerUid as string);
|
||||||
|
if (customer) {
|
||||||
|
setCustomer(customer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
const customerData = await Customers.getInstance().getByUid(customerUid as string, {
|
const customerData = await Customers.getInstance().getByUid(customerUid as string, {
|
||||||
contact: {
|
contact: {
|
||||||
include: {
|
include: {
|
||||||
@ -45,6 +62,7 @@ export default function UpdateClient() {
|
|||||||
if (customerData) {
|
if (customerData) {
|
||||||
setCustomer(customerData);
|
setCustomer(customerData);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch customer", error);
|
console.error("Failed to fetch customer", error);
|
||||||
}
|
}
|
||||||
@ -71,9 +89,34 @@ export default function UpdateClient() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// TODO: review
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
MessageBus.getInstance().getFolders().then((folders: any) => {
|
||||||
|
const folder = folders.find((folder: any) => folder.processData.uid === folderUid as string);
|
||||||
|
if (folder) {
|
||||||
|
const customers: any[] = folder.processData.customers.map((customer: any) => MapUtils.toJson(customer));
|
||||||
|
const customer: any = customers.find((customer: any) => customer.uid === customerUid as string);
|
||||||
|
if (customer) {
|
||||||
|
customer.contact = contact; // Update the contact
|
||||||
|
|
||||||
|
MessageBus.getInstance().updateProcess(folder.processId, folder.lastStateId, { customers: customers }, [], null).then((processUpdated: any) => {
|
||||||
|
const newStateId: string = processUpdated.diffs[0]?.state_id;
|
||||||
|
MessageBus.getInstance().notifyUpdate(folder.processId, newStateId).then(() => {
|
||||||
|
MessageBus.getInstance().validateState(folder.processId, newStateId).then((_stateValidated) => {
|
||||||
|
router.push(backwardPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
await contact.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false });
|
await contact.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false });
|
||||||
await Customers.getInstance().put(customerUid as string, { contact });
|
await Customers.getInstance().put(customerUid as string, { contact });
|
||||||
router.push(backwardPath);
|
router.push(backwardPath);
|
||||||
|
*/
|
||||||
} catch (validationErrors) {
|
} catch (validationErrors) {
|
||||||
if (Array.isArray(validationErrors)) {
|
if (Array.isArray(validationErrors)) {
|
||||||
setValidationError(validationErrors as ValidationError[]);
|
setValidationError(validationErrors as ValidationError[]);
|
||||||
|
@ -13,9 +13,10 @@ import Image from "next/image";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
|
||||||
|
|
||||||
export default function Folder() {
|
export default function Folder() {
|
||||||
const [_isArchivedModalOpen, _setIsArchivedModalOpen] = useState(true);
|
const [_isArchivedModalOpen, _setIsArchivedModalOpen] = useState(true);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -23,6 +24,19 @@ export default function Folder() {
|
|||||||
const { user: activeUser } = useUser();
|
const { user: activeUser } = useUser();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// TODO: review
|
||||||
|
FolderService.getFolders().then((folders: any) => {
|
||||||
|
const foldersLive = folders.filter((folder: any) => folder.processData.isArchived === 'false');
|
||||||
|
if (foldersLive.length !== 0) {
|
||||||
|
router.push(
|
||||||
|
Module.getInstance()
|
||||||
|
.get()
|
||||||
|
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", foldersLive[foldersLive.length - 1].processData.uid)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
Folders.getInstance()
|
Folders.getInstance()
|
||||||
.get({
|
.get({
|
||||||
q: {
|
q: {
|
||||||
@ -38,6 +52,7 @@ export default function Folder() {
|
|||||||
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folders[0]?.uid ?? ""),
|
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folders[0]?.uid ?? ""),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}, [router]);
|
}, [router]);
|
||||||
return (
|
return (
|
||||||
<DefaultNotaryDashboard title={"Dossier"} mobileBackText={"Liste des dossiers"}>
|
<DefaultNotaryDashboard title={"Dossier"} mobileBackText={"Liste des dossiers"}>
|
||||||
|
@ -41,12 +41,17 @@ export default function StepEmail(props: IProps) {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const error = router.query["error"];
|
const error = router.query["error"];
|
||||||
const redirectUserOnConnection = useCallback(() => {
|
const redirectUserOnConnection = useCallback(() => {
|
||||||
|
/* TODO: review
|
||||||
const variables = FrontendVariables.getInstance();
|
const variables = FrontendVariables.getInstance();
|
||||||
router.push(
|
router.push(
|
||||||
`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${
|
`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${
|
||||||
variables.FRONT_APP_HOST
|
variables.FRONT_APP_HOST
|
||||||
}/authorized-client&scope=openid,profile&response_type=code`,
|
}/authorized-client&scope=openid,profile&response_type=code`,
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
router.push(
|
||||||
|
`https://qual-connexion.idnot.fr/user/IdPOAuth2/authorize/idnot_idp_v1?client_id=B3CE56353EDB15A9&redirect_uri=http://local.lecoffreio.4nkweb:3000/authorized-client&scope=openid,profile&response_type=code`,
|
||||||
|
);
|
||||||
}, [router]);
|
}, [router]);
|
||||||
|
|
||||||
const openErrorModal = useCallback((index: number) => {
|
const openErrorModal = useCallback((index: number) => {
|
||||||
@ -94,12 +99,14 @@ export default function StepEmail(props: IProps) {
|
|||||||
Pour les clients :
|
Pour les clients :
|
||||||
</Typography>
|
</Typography>
|
||||||
<Form className={classes["form"]} onSubmit={onSubmit}>
|
<Form className={classes["form"]} onSubmit={onSubmit}>
|
||||||
|
{/*
|
||||||
<TextField
|
<TextField
|
||||||
placeholder="Renseigner votre email"
|
placeholder="Renseigner votre email"
|
||||||
label="E-mail"
|
label="E-mail"
|
||||||
name="email"
|
name="email"
|
||||||
validationError={validationErrors.find((err) => err.property === "email")}
|
validationError={validationErrors.find((err) => err.property === "email")}
|
||||||
/>
|
/>
|
||||||
|
*/}
|
||||||
<Button type="submit">Se connecter</Button>
|
<Button type="submit">Se connecter</Button>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,11 +50,14 @@ export default function Login() {
|
|||||||
|
|
||||||
const onEmailFormSubmit = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
const onEmailFormSubmit = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
|
||||||
try {
|
try {
|
||||||
|
/* TODO: review
|
||||||
if (!values["email"]) return;
|
if (!values["email"]) return;
|
||||||
setEmail(values["email"]);
|
setEmail(values["email"]);
|
||||||
const res = await Auth.getInstance().mailVerifySms({ email: values["email"] });
|
const res = await Auth.getInstance().mailVerifySms({ email: values["email"] });
|
||||||
setPartialPhoneNumber(res.partialPhoneNumber);
|
setPartialPhoneNumber(res.partialPhoneNumber);
|
||||||
setTotpCodeUid(res.totpCodeUid);
|
setTotpCodeUid(res.totpCodeUid);
|
||||||
|
*/
|
||||||
|
|
||||||
setStep(LoginStep.TOTP);
|
setStep(LoginStep.TOTP);
|
||||||
setValidationErrors([]);
|
setValidationErrors([]);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
@ -11,15 +11,25 @@ import JwtService from "@Front/Services/JwtService/JwtService";
|
|||||||
import UserStore from "@Front/Stores/UserStore";
|
import UserStore from "@Front/Stores/UserStore";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
import AuthModal from "src/sdk/AuthModal";
|
||||||
|
|
||||||
export default function LoginCallBack() {
|
export default function LoginCallBack() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getUser() {
|
async function getUser() {
|
||||||
|
// TODO: review
|
||||||
|
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
|
||||||
|
// Replace with http://localhost:3000/authorized-client
|
||||||
|
if (window.location.href.startsWith('http://local.lecoffreio.4nkweb:3000/authorized-client')) {
|
||||||
|
window.location.href = window.location.href.replace('http://local.lecoffreio.4nkweb:3000/authorized-client', 'http://localhost:3000/authorized-client');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const code = router.query["code"];
|
const code = router.query["code"];
|
||||||
if (code) {
|
if (code) {
|
||||||
try {
|
try {
|
||||||
@ -28,10 +38,12 @@ export default function LoginCallBack() {
|
|||||||
await UserStore.instance.connect(token.accessToken, token.refreshToken);
|
await UserStore.instance.connect(token.accessToken, token.refreshToken);
|
||||||
const jwt = JwtService.getInstance().decodeJwt();
|
const jwt = JwtService.getInstance().decodeJwt();
|
||||||
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||||
if (!jwt.rules.includes("GET folders")) {
|
if (jwt.rules && !jwt.rules.includes("GET folders")) {
|
||||||
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
||||||
}
|
}
|
||||||
return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
setIsAuthModalOpen(true);
|
||||||
|
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||||
|
return;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (e.http_status === 401 && e.message === "Email not found") {
|
if (e.http_status === 401 && e.message === "Email not found") {
|
||||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3");
|
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3");
|
||||||
@ -42,6 +54,7 @@ export default function LoginCallBack() {
|
|||||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
||||||
if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||||
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken);
|
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken);
|
||||||
@ -51,7 +64,9 @@ export default function LoginCallBack() {
|
|||||||
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
|
||||||
}
|
}
|
||||||
if (isTokenRefreshed) {
|
if (isTokenRefreshed) {
|
||||||
return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
setIsAuthModalOpen(true);
|
||||||
|
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=2");
|
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=2");
|
||||||
}
|
}
|
||||||
@ -76,6 +91,13 @@ export default function LoginCallBack() {
|
|||||||
description="Notre équipe de support est là pour vous aider."
|
description="Notre équipe de support est là pour vous aider."
|
||||||
button={{ text: "Contacter l'administrateur", link: "mailto:support@lecoffre.io" }}
|
button={{ text: "Contacter l'administrateur", link: "mailto:support@lecoffre.io" }}
|
||||||
/>
|
/>
|
||||||
|
{isAuthModalOpen && <AuthModal
|
||||||
|
isOpen={isAuthModalOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setIsAuthModalOpen(false);
|
||||||
|
router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
</div>
|
</div>
|
||||||
</DefaultDoubleSidePage>
|
</DefaultDoubleSidePage>
|
||||||
);
|
);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"ClientDashboard": {
|
"ClientDashboard": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
"path": "/client-dashboard/[folderUid]",
|
"path": "/client-dashboard/[folderUid]/profile/[profileUid]",
|
||||||
"labelKey": "client-dashboard"
|
"labelKey": "client-dashboard"
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"ClientDashboard": {
|
"ClientDashboard": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
"path": "/client-dashboard/[folderUid]",
|
"path": "/client-dashboard/[folderUid]/profile/[profileUid]",
|
||||||
"labelKey": "client-dashboard"
|
"labelKey": "client-dashboard"
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"ClientDashboard": {
|
"ClientDashboard": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
"path": "/client-dashboard/[folderUid]",
|
"path": "/client-dashboard/[folderUid]/profile/[profileUid]",
|
||||||
"labelKey": "client-dashboard"
|
"labelKey": "client-dashboard"
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
"ClientDashboard": {
|
"ClientDashboard": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
"path": "/client-dashboard/[folderUid]",
|
"path": "/client-dashboard/[folderUid]/profile/[profileUid]",
|
||||||
"labelKey": "client-dashboard"
|
"labelKey": "client-dashboard"
|
||||||
},
|
},
|
||||||
"pages": {
|
"pages": {
|
||||||
|
@ -27,7 +27,9 @@ export class FrontendVariables {
|
|||||||
|
|
||||||
public HOTJAR_SITE_ID!: number;
|
public HOTJAR_SITE_ID!: number;
|
||||||
|
|
||||||
public HOJAR_VERSION!: number;
|
public HOTJAR_VERSION!: number;
|
||||||
|
|
||||||
|
public _4NK_URL!: string;
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ export default function useUser() {
|
|||||||
const [user, setUser] = useState<User | null>();
|
const [user, setUser] = useState<User | null>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
/* TODO: review
|
||||||
const decodedJwt = JwtService.getInstance().decodeJwt();
|
const decodedJwt = JwtService.getInstance().decodeJwt();
|
||||||
if (!decodedJwt) return;
|
if (!decodedJwt) return;
|
||||||
Users.getInstance()
|
Users.getInstance()
|
||||||
@ -18,6 +19,7 @@ export default function useUser() {
|
|||||||
.then((user) => {
|
.then((user) => {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -4,13 +4,15 @@ import CookieService from "@Front/Services/CookieService/CookieService";
|
|||||||
import EventEmitter from "@Front/Services/EventEmitter";
|
import EventEmitter from "@Front/Services/EventEmitter";
|
||||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||||
|
|
||||||
|
import User from "src/sdk/User";
|
||||||
|
|
||||||
export default class UserStore {
|
export default class UserStore {
|
||||||
public static readonly instance = new this();
|
public static readonly instance = new this();
|
||||||
protected readonly event = new EventEmitter();
|
protected readonly event = new EventEmitter();
|
||||||
public accessToken: string | null = null;
|
public accessToken: string | null = null;
|
||||||
public refreshToken: string | null = null;
|
public refreshToken: string | null = null;
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() { }
|
||||||
|
|
||||||
public isConnected(): boolean {
|
public isConnected(): boolean {
|
||||||
return !!this.accessToken;
|
return !!this.accessToken;
|
||||||
@ -41,6 +43,8 @@ export default class UserStore {
|
|||||||
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
|
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
|
||||||
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
|
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
|
||||||
|
|
||||||
|
User.getInstance().clear();
|
||||||
|
|
||||||
this.event.emit("disconnection", this.accessToken);
|
this.event.emit("disconnection", this.accessToken);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -4,16 +4,16 @@ import CookieService from "@Front/Services/CookieService/CookieService";
|
|||||||
import EventEmitter from "@Front/Services/EventEmitter";
|
import EventEmitter from "@Front/Services/EventEmitter";
|
||||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||||
|
|
||||||
|
import User from "src/sdk/User";
|
||||||
|
|
||||||
export default class UserStore {
|
export default class UserStore {
|
||||||
public static readonly instance = new this();
|
public static readonly instance = new this();
|
||||||
protected readonly event = new EventEmitter();
|
protected readonly event = new EventEmitter();
|
||||||
public accessToken: string | null = null;
|
|
||||||
public refreshToken: string | null = null;
|
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
public isConnected(): boolean {
|
public isConnected(): boolean {
|
||||||
return !!this.accessToken;
|
return !!CookieService.getInstance().getCookie("leCoffreAccessToken");
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRole(): string | undefined {
|
public getRole(): string | undefined {
|
||||||
@ -27,7 +27,7 @@ export default class UserStore {
|
|||||||
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
|
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
|
||||||
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
|
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
|
||||||
|
|
||||||
this.event.emit("connection", this.accessToken);
|
this.event.emit("connection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return false;
|
return false;
|
||||||
@ -41,7 +41,9 @@ export default class UserStore {
|
|||||||
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
|
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
|
||||||
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
|
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
|
||||||
|
|
||||||
this.event.emit("disconnection", this.accessToken);
|
User.getInstance().clear();
|
||||||
|
|
||||||
|
this.event.emit("disconnection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@ -56,4 +58,12 @@ export default class UserStore {
|
|||||||
this.event.on("connection", callback);
|
this.event.on("connection", callback);
|
||||||
return () => this.event.off("connection", callback);
|
return () => this.event.off("connection", callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAccessToken(): string {
|
||||||
|
return CookieService.getInstance().getCookie("leCoffreAccessToken") || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRefreshToken(): string {
|
||||||
|
return CookieService.getInstance().getCookie("leCoffreRefreshToken") || "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,17 @@ import { DefaultLayout } from "@Front/Components/LayoutTemplates/DefaultLayout";
|
|||||||
import { FrontendVariables } from "@Front/Config/VariablesFront";
|
import { FrontendVariables } from "@Front/Config/VariablesFront";
|
||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
import type { AppType, AppProps } from "next/app";
|
import type { AppType, AppProps } from "next/app";
|
||||||
import { useEffect, type ReactElement, type ReactNode } from "react";
|
import { useEffect, useState, type ReactElement, type ReactNode } from "react";
|
||||||
import getConfig from "next/config";
|
import getConfig from "next/config";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
import { GoogleTagManager } from "@next/third-parties/google";
|
import { GoogleTagManager } from "@next/third-parties/google";
|
||||||
import { hotjar } from "react-hotjar";
|
import { hotjar } from "react-hotjar";
|
||||||
|
|
||||||
|
import IframeReference from "src/sdk/IframeReference";
|
||||||
|
import Iframe from "src/sdk/Iframe";
|
||||||
|
import MessageBus from "src/sdk/MessageBus";
|
||||||
|
import User from "src/sdk/User";
|
||||||
|
|
||||||
export type NextPageWithLayout<TProps = Record<string, unknown>, TInitialProps = TProps> = NextPage<TProps, TInitialProps> & {
|
export type NextPageWithLayout<TProps = Record<string, unknown>, TInitialProps = TProps> = NextPage<TProps, TInitialProps> & {
|
||||||
getLayout?: (page: ReactElement) => ReactNode;
|
getLayout?: (page: ReactElement) => ReactNode;
|
||||||
};
|
};
|
||||||
@ -28,6 +34,7 @@ type AppPropsWithLayout = AppProps & {
|
|||||||
docaposteApiUrl: string;
|
docaposteApiUrl: string;
|
||||||
hotjarSiteId: number;
|
hotjarSiteId: number;
|
||||||
hotjarVersion: number;
|
hotjarVersion: number;
|
||||||
|
_4nkUrl: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
const { publicRuntimeConfig } = getConfig();
|
||||||
@ -48,6 +55,7 @@ const MyApp = (({
|
|||||||
docaposteApiUrl,
|
docaposteApiUrl,
|
||||||
hotjarSiteId,
|
hotjarSiteId,
|
||||||
hotjarVersion,
|
hotjarVersion,
|
||||||
|
_4nkUrl,
|
||||||
}: AppPropsWithLayout) => {
|
}: AppPropsWithLayout) => {
|
||||||
const getLayout = Component.getLayout ?? ((page) => <DefaultLayout children={page}></DefaultLayout>);
|
const getLayout = Component.getLayout ?? ((page) => <DefaultLayout children={page}></DefaultLayout>);
|
||||||
|
|
||||||
@ -64,7 +72,39 @@ const MyApp = (({
|
|||||||
instance.FC_CLIENT_ID = fcClientId;
|
instance.FC_CLIENT_ID = fcClientId;
|
||||||
instance.DOCAPOST_API_URL = docaposteApiUrl;
|
instance.DOCAPOST_API_URL = docaposteApiUrl;
|
||||||
instance.HOTJAR_SITE_ID = hotjarSiteId;
|
instance.HOTJAR_SITE_ID = hotjarSiteId;
|
||||||
instance.HOJAR_VERSION = hotjarVersion;
|
instance.HOTJAR_VERSION = hotjarVersion;
|
||||||
|
instance._4NK_URL = _4nkUrl;
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const [isConnected, setIsConnected] = useState(false);
|
||||||
|
const [isReady, setIsReady] = useState(false);
|
||||||
|
|
||||||
|
IframeReference.setTargetOrigin(_4nkUrl);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isAuthenticated = User.getInstance().isAuthenticated();
|
||||||
|
setIsConnected(isAuthenticated);
|
||||||
|
if (isAuthenticated) {
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsReady(true);
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const isAuthenticated = User.getInstance().isAuthenticated();
|
||||||
|
setIsConnected(isAuthenticated);
|
||||||
|
if (isAuthenticated) {
|
||||||
|
MessageBus.getInstance().isReady().then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setIsReady(true);
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hotjarSiteId || !hotjarVersion) {
|
if (!hotjarSiteId || !hotjarVersion) {
|
||||||
console.warn("No hotjar site id or version provided");
|
console.warn("No hotjar site id or version provided");
|
||||||
@ -78,9 +118,14 @@ const MyApp = (({
|
|||||||
}, [hotjarSiteId, hotjarVersion]);
|
}, [hotjarSiteId, hotjarVersion]);
|
||||||
|
|
||||||
return getLayout(
|
return getLayout(
|
||||||
<Component {...pageProps}>
|
<>
|
||||||
<GoogleTagManager gtmId="GTM-5GLJN86P" />
|
{((isConnected && isReady) || !isConnected) &&
|
||||||
</Component>,
|
<Component {...pageProps}>
|
||||||
|
<GoogleTagManager gtmId="GTM-5GLJN86P" />
|
||||||
|
</Component>
|
||||||
|
}
|
||||||
|
{isConnected && <Iframe />}
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}) as AppType;
|
}) as AppType;
|
||||||
|
|
||||||
@ -100,6 +145,7 @@ MyApp.getInitialProps = async () => {
|
|||||||
docaposteApiUrl: publicRuntimeConfig.NEXT_PUBLIC_DOCAPOST_API_URL,
|
docaposteApiUrl: publicRuntimeConfig.NEXT_PUBLIC_DOCAPOST_API_URL,
|
||||||
hotjarSiteId: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
hotjarSiteId: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_SITE_ID,
|
||||||
hotjarVersion: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_VERSION,
|
hotjarVersion: publicRuntimeConfig.NEXT_PUBLIC_HOTJAR_VERSION,
|
||||||
|
_4nkUrl: publicRuntimeConfig.NEXT_PUBLIC_4NK_URL,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
import ClientDashboard from "@Front/Components/Layouts/ClientDashboard/index";
|
||||||
|
|
||||||
|
export default function Route() {
|
||||||
|
return <ClientDashboard />;
|
||||||
|
}
|
150
src/sdk/AuthModal.tsx
Normal file
150
src/sdk/AuthModal.tsx
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import Modal from '@Front/Components/DesignSystem/Modal';
|
||||||
|
import Loader from '@Front/Components/DesignSystem/Loader';
|
||||||
|
import Typography, { ETypo, ETypoColor } from '@Front/Components/DesignSystem/Typography';
|
||||||
|
|
||||||
|
import IframeReference from './IframeReference';
|
||||||
|
import User from './User';
|
||||||
|
|
||||||
|
interface AuthModalProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
onClose: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
|
||||||
|
const [isIframeReady, setIsIframeReady] = useState(false);
|
||||||
|
const [showIframe, setShowIframe] = useState(false);
|
||||||
|
const [authSuccess, setAuthSuccess] = useState(false);
|
||||||
|
|
||||||
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleMessage = (event: MessageEvent) => {
|
||||||
|
if (!event.data || event.data.type === 'PassClientScriptReady') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iframeRef.current) {
|
||||||
|
console.error('[AuthModal] handleMessage: iframeRef.current is null');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.source !== iframeRef.current.contentWindow) {
|
||||||
|
console.error('[AuthModal] handleMessage: source not match');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetOrigin = IframeReference.getTargetOrigin();
|
||||||
|
if (!targetOrigin) {
|
||||||
|
console.error('[AuthModal] handleMessage: targetOrigin not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.origin !== targetOrigin) {
|
||||||
|
console.error('[AuthModal] handleMessage: origin not match');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event.data || typeof event.data !== 'object') {
|
||||||
|
console.error('[AuthModal] handleMessage: data not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = event.data;
|
||||||
|
console.log('[AuthModal] handleMessage:', message);
|
||||||
|
|
||||||
|
switch (message.type) {
|
||||||
|
case 'LISTENING':
|
||||||
|
iframeRef.current.contentWindow!.postMessage({ type: 'REQUEST_LINK' }, targetOrigin);
|
||||||
|
setIsIframeReady(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'LINK_ACCEPTED':
|
||||||
|
setShowIframe(false);
|
||||||
|
|
||||||
|
User.getInstance().setTokens(message.accessToken, message.refreshToken);
|
||||||
|
iframeRef.current.contentWindow!.postMessage({ type: 'GET_PAIRING_ID', accessToken: message.accessToken }, targetOrigin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'GET_PAIRING_ID':
|
||||||
|
User.getInstance().setPairingId(message.userPairingId);
|
||||||
|
setAuthSuccess(true);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowIframe(false);
|
||||||
|
setIsIframeReady(false);
|
||||||
|
setAuthSuccess(false);
|
||||||
|
onClose();
|
||||||
|
}, 500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener('message', handleMessage);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('message', handleMessage);
|
||||||
|
};
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isIframeReady && !showIframe) {
|
||||||
|
setShowIframe(true);
|
||||||
|
}
|
||||||
|
}, [isIframeReady, showIframe]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
isOpen={isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
title='Authentification 4nk'
|
||||||
|
>
|
||||||
|
{!isIframeReady && (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: '400px',
|
||||||
|
gap: 'var(--spacing-md, 16px)'
|
||||||
|
}}>
|
||||||
|
<Loader width={40} />
|
||||||
|
<Typography typo={ETypo.TEXT_MD_SEMIBOLD}>Chargement de l'authentification...</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{authSuccess ? (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: '400px',
|
||||||
|
gap: '20px'
|
||||||
|
}}>
|
||||||
|
<Typography typo={ETypo.TEXT_MD_SEMIBOLD} color={ETypoColor.COLOR_SUCCESS_500}>
|
||||||
|
Authentification réussie ! Redirection en cours...
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div style={{
|
||||||
|
display: showIframe ? 'flex' : 'none',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%'
|
||||||
|
}}>
|
||||||
|
<iframe
|
||||||
|
ref={iframeRef}
|
||||||
|
src={IframeReference.getTargetOrigin()}
|
||||||
|
style={{
|
||||||
|
display: showIframe ? 'block' : 'none',
|
||||||
|
width: '400px',
|
||||||
|
height: '400px',
|
||||||
|
border: 'none',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
33
src/sdk/EventBus.ts
Normal file
33
src/sdk/EventBus.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
export default class EventBus {
|
||||||
|
private static instance: EventBus;
|
||||||
|
private listeners: Record<string, Array<(...args: any[]) => void>> = {};
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static getInstance(): EventBus {
|
||||||
|
if (!EventBus.instance) {
|
||||||
|
EventBus.instance = new EventBus();
|
||||||
|
}
|
||||||
|
return EventBus.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public on(event: string, callback: (...args: any[]) => void): () => void {
|
||||||
|
if (!this.listeners[event]) {
|
||||||
|
this.listeners[event] = [];
|
||||||
|
}
|
||||||
|
this.listeners[event].push(callback);
|
||||||
|
return () => {
|
||||||
|
if (this.listeners[event]) {
|
||||||
|
this.listeners[event] = this.listeners[event].filter(cb => cb !== callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public emit(event: string, ...args: any[]): void {
|
||||||
|
if (this.listeners[event]) {
|
||||||
|
this.listeners[event].forEach(callback => {
|
||||||
|
callback(...args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/sdk/Iframe.tsx
Normal file
36
src/sdk/Iframe.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { useRef, useEffect, memo } from 'react';
|
||||||
|
import IframeReference from './IframeReference';
|
||||||
|
|
||||||
|
interface IframeProps {
|
||||||
|
showIframe?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Iframe({ showIframe = false }: IframeProps) {
|
||||||
|
const iframeRef = useRef<HTMLIFrameElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (iframeRef.current) {
|
||||||
|
IframeReference.setIframe(iframeRef.current);
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
IframeReference.setIframe(null);
|
||||||
|
};
|
||||||
|
}, [iframeRef.current]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<iframe
|
||||||
|
ref={iframeRef}
|
||||||
|
src={IframeReference.getTargetOrigin()}
|
||||||
|
style={{
|
||||||
|
display: showIframe ? 'block' : 'none',
|
||||||
|
width: '400px',
|
||||||
|
height: '400px',
|
||||||
|
border: 'none',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iframe.displayName = 'Iframe';
|
||||||
|
export default memo(Iframe);
|
36
src/sdk/IframeReference.ts
Normal file
36
src/sdk/IframeReference.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
export default class IframeReference {
|
||||||
|
private static targetOrigin: string | null = null;
|
||||||
|
private static iframe: HTMLIFrameElement | null = null;
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static setTargetOrigin(targetOrigin: string): void {
|
||||||
|
try {
|
||||||
|
new URL(targetOrigin);
|
||||||
|
this.targetOrigin = targetOrigin;
|
||||||
|
} catch {
|
||||||
|
throw new Error(`Invalid targetOrigin: ${targetOrigin}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getTargetOrigin(): string {
|
||||||
|
if (!this.targetOrigin) {
|
||||||
|
throw new Error("targetOrigin is not set");
|
||||||
|
}
|
||||||
|
return this.targetOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static setIframe(iframe: HTMLIFrameElement | null): void {
|
||||||
|
if (iframe !== null && !(iframe instanceof HTMLIFrameElement)) {
|
||||||
|
throw new Error("setIframe expects an HTMLIFrameElement or null");
|
||||||
|
}
|
||||||
|
this.iframe = iframe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getIframe(): HTMLIFrameElement {
|
||||||
|
if (!this.iframe) {
|
||||||
|
throw new Error("iframe is not set");
|
||||||
|
}
|
||||||
|
return this.iframe;
|
||||||
|
}
|
||||||
|
}
|
25
src/sdk/MapUtils.ts
Normal file
25
src/sdk/MapUtils.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
export default class MapUtils {
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static toJson(input: any): any {
|
||||||
|
if (input instanceof Map) {
|
||||||
|
const obj: Record<string, any> = {};
|
||||||
|
for (const [key, value] of input.entries()) {
|
||||||
|
obj[key] = MapUtils.toJson(value);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
} else if (Array.isArray(input)) {
|
||||||
|
return input.map((item) => MapUtils.toJson(item));
|
||||||
|
} else if (input !== null && typeof input === 'object') {
|
||||||
|
const obj: Record<string, any> = {};
|
||||||
|
for (const key in input) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(input, key)) {
|
||||||
|
obj[key] = MapUtils.toJson(input[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
1174
src/sdk/MessageBus.ts
Normal file
1174
src/sdk/MessageBus.ts
Normal file
File diff suppressed because it is too large
Load Diff
125
src/sdk/RolesBuilder.ts
Normal file
125
src/sdk/RolesBuilder.ts
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
type Member = string;
|
||||||
|
|
||||||
|
interface ValidationRule {
|
||||||
|
quorum: number;
|
||||||
|
fields: string[];
|
||||||
|
min_sig_member: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Storage {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
params?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoleDefinition {
|
||||||
|
members: Member[];
|
||||||
|
validation_rules: ValidationRule[];
|
||||||
|
storages: Storage[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RolesStructure {
|
||||||
|
demiurge: RoleDefinition;
|
||||||
|
owner: RoleDefinition;
|
||||||
|
validator: RoleDefinition;
|
||||||
|
collaborator: RoleDefinition;
|
||||||
|
client: RoleDefinition;
|
||||||
|
[key: string]: RoleDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class RolesBuilder {
|
||||||
|
private static instance: RolesBuilder;
|
||||||
|
private roles: RolesStructure;
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
this.roles = {
|
||||||
|
demiurge: {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
owner: {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: ['roles'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
validator: {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [
|
||||||
|
{
|
||||||
|
quorum: 0.5,
|
||||||
|
fields: ['idCertified', 'roles'],
|
||||||
|
min_sig_member: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
collaborator: {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
},
|
||||||
|
client: {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getInstance(): RolesBuilder {
|
||||||
|
if (!RolesBuilder.instance) {
|
||||||
|
RolesBuilder.instance = new RolesBuilder();
|
||||||
|
}
|
||||||
|
return RolesBuilder.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addMember(role: string, memberId: string): RolesBuilder {
|
||||||
|
if (this.roles[role]) {
|
||||||
|
if (!this.roles[role].members.includes(memberId)) {
|
||||||
|
this.roles[role].members.push(memberId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addMembers(role: string, memberIds: string[]): RolesBuilder {
|
||||||
|
memberIds.forEach(id => this.addMember(role, id));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addValidationRule(role: string, rule: ValidationRule): RolesBuilder {
|
||||||
|
if (this.roles[role]) {
|
||||||
|
this.roles[role].validation_rules.push(rule);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addStorage(role: string, storage: Storage): RolesBuilder {
|
||||||
|
if (this.roles[role]) {
|
||||||
|
this.roles[role].storages.push(storage);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public createRole(roleId: string): RolesBuilder {
|
||||||
|
if (!this.roles[roleId]) {
|
||||||
|
this.roles[roleId] = {
|
||||||
|
members: [],
|
||||||
|
validation_rules: [],
|
||||||
|
storages: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public build(): RolesStructure {
|
||||||
|
return { ...this.roles };
|
||||||
|
}
|
||||||
|
}
|
43
src/sdk/User.ts
Normal file
43
src/sdk/User.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
export default class User {
|
||||||
|
private static instance: User;
|
||||||
|
|
||||||
|
private constructor() { }
|
||||||
|
|
||||||
|
public static getInstance(): User {
|
||||||
|
if (!User.instance) {
|
||||||
|
User.instance = new User();
|
||||||
|
}
|
||||||
|
return User.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setTokens(access: string, refresh: string): void {
|
||||||
|
sessionStorage.setItem('accessToken', access);
|
||||||
|
sessionStorage.setItem('refreshToken', refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAccessToken(): string | null {
|
||||||
|
return sessionStorage.getItem('accessToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRefreshToken(): string | null {
|
||||||
|
return sessionStorage.getItem('refreshToken');
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPairingId(pairingId: string): void {
|
||||||
|
sessionStorage.setItem('pairingId', pairingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPairingId(): string | null {
|
||||||
|
return sessionStorage.getItem('pairingId');
|
||||||
|
}
|
||||||
|
|
||||||
|
public isAuthenticated(): boolean {
|
||||||
|
return this.getAccessToken() !== null && this.getRefreshToken() !== null && this.getPairingId() !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear(): void {
|
||||||
|
sessionStorage.removeItem('accessToken');
|
||||||
|
sessionStorage.removeItem('refreshToken');
|
||||||
|
sessionStorage.removeItem('pairingId');
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user