format all front repo

This commit is contained in:
Hugo Lextrait 2023-04-17 11:43:18 +02:00
parent dae26fd7a0
commit f9ec6a47bd
76 changed files with 5644 additions and 5570 deletions

View File

@ -31,5 +31,8 @@
"rust-client.rustupPath": "${env:HOME}/elrondsdk/vendor-rust/bin/rustup",
"rust-client.rlsPath": "${env:HOME}/elrondsdk/vendor-rust/bin/rls",
"rust-client.disableRustup": true,
"rust-client.autoStartRls": false
"rust-client.autoStartRls": false,
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

8537
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,35 @@
{
"name": "lecoffre-front",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mui/material": "^5.11.13",
"@types/node": "18.15.1",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"class-validator": "^0.14.0",
"classnames": "^2.3.2",
"dotenv": "^16.0.3",
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.18",
"next": "13.2.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-select": "^5.7.2",
"reflect-metadata": "^0.1.13",
"sass": "^1.59.2",
"typedi": "^0.10.0",
"typescript": "4.9.5"
}
"name": "lecoffre-front",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"format": "prettier --write src"
},
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mui/material": "^5.11.13",
"@types/node": "18.15.1",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"class-validator": "^0.14.0",
"classnames": "^2.3.2",
"dotenv": "^16.0.3",
"eslint": "8.36.0",
"eslint-config-next": "13.2.4",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.18",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-select": "^5.7.2",
"reflect-metadata": "^0.1.13",
"sass": "^1.59.2",
"typedi": "^0.10.0",
"typescript": "4.9.5"
}
}

View File

@ -4,28 +4,26 @@ import { FrontendVariables } from "@Front/Config/VariablesFront";
@Service()
export default class Auth extends BaseApiService {
private static instance: Auth;
private static instance: Auth;
private constructor() {
super();
}
private constructor() {
super();
}
public static getInstance(): Auth {
return (this.instance = this.instance ?? new this());
}
public static getInstance(): Auth {
return (this.instance = this.instance ?? new this());
}
public async getIdnotJwt(autorizationCode: string | string[]): Promise<any> {
const variables = FrontendVariables.getInstance();
const baseBackUrl =
variables.BACK_API_PROTOCOL +
variables.BACK_API_HOST +
(variables.BACK_API_PORT ? ":" + variables.BACK_API_PORT : "");
const url = new URL(`${baseBackUrl}/api/v1/idnot-user/${autorizationCode}`);
try {
return await this.postRequest<any>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getIdnotJwt(autorizationCode: string | string[]): Promise<any> {
const variables = FrontendVariables.getInstance();
const baseBackUrl =
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + (variables.BACK_API_PORT ? ":" + variables.BACK_API_PORT : "");
const url = new URL(`${baseBackUrl}/api/v1/idnot-user/${autorizationCode}`);
try {
return await this.postRequest<any>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -1,145 +1,128 @@
import { FrontendVariables } from "@Front/Config/VariablesFront";
export enum ContentType {
JSON = "application/json",
FORM_DATA = "multipart/form-data;",
JSON = "application/json",
FORM_DATA = "multipart/form-data;",
}
export default abstract class BaseApiService {
private static baseUrl: string;
protected readonly variables = FrontendVariables.getInstance();
private static baseUrl: string;
protected readonly variables = FrontendVariables.getInstance();
protected constructor() {
BaseApiService.baseUrl ??=
FrontendVariables.getInstance().BACK_API_PROTOCOL +
FrontendVariables.getInstance().BACK_API_HOST +
(FrontendVariables.getInstance().BACK_API_PORT
? ":" + FrontendVariables.getInstance().BACK_API_PORT
: "") +
FrontendVariables.getInstance().BACK_API_ROOT_URL +
FrontendVariables.getInstance().BACK_API_VERSION;
}
protected constructor() {
BaseApiService.baseUrl ??=
FrontendVariables.getInstance().BACK_API_PROTOCOL +
FrontendVariables.getInstance().BACK_API_HOST +
(FrontendVariables.getInstance().BACK_API_PORT ? ":" + FrontendVariables.getInstance().BACK_API_PORT : "") +
FrontendVariables.getInstance().BACK_API_ROOT_URL +
FrontendVariables.getInstance().BACK_API_VERSION;
}
protected getBaseUrl() {
return BaseApiService.baseUrl;
}
protected getBaseUrl() {
return BaseApiService.baseUrl;
}
protected buildHeaders(contentType: ContentType) {
const headers = new Headers();
protected buildHeaders(contentType: ContentType) {
const headers = new Headers();
if (contentType === ContentType.JSON) {
headers.set("Content-Type", contentType);
}
return headers;
}
if (contentType === ContentType.JSON) {
headers.set("Content-Type", contentType);
}
return headers;
}
protected buildBody(body: { [key: string]: unknown }): string {
return JSON.stringify(body);
}
protected buildBody(body: { [key: string]: unknown }): string {
return JSON.stringify(body);
}
protected async getRequest<T>(url: URL) {
const request = async () =>
await fetch(url, {
method: "GET",
headers: this.buildHeaders(ContentType.JSON),
});
return this.sendRequest<T>(request);
}
protected async getRequest<T>(url: URL) {
const request = async () =>
await fetch(url, {
method: "GET",
headers: this.buildHeaders(ContentType.JSON),
});
return this.sendRequest<T>(request);
}
protected async postRequest<T>(
url: URL,
body: { [key: string]: unknown } = {}
) {
return this.sendRequest<T>(
async () =>
await fetch(url, {
method: "POST",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
})
);
}
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
return this.sendRequest<T>(
async () =>
await fetch(url, {
method: "POST",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
}),
);
}
protected async putRequest<T>(
url: URL,
body: { [key: string]: unknown } = {}
) {
const request = async () =>
await fetch(url, {
method: "PUT",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
protected async putRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
const request = async () =>
await fetch(url, {
method: "PUT",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
return this.sendRequest<T>(request);
}
return this.sendRequest<T>(request);
}
protected async patchRequest<T>(
url: URL,
body: { [key: string]: unknown } = {}
) {
const request = async () =>
await fetch(url, {
method: "PATCH",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
protected async patchRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
const request = async () =>
await fetch(url, {
method: "PATCH",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
return this.sendRequest<T>(request);
}
return this.sendRequest<T>(request);
}
protected async deleteRequest<T>(
url: URL,
body: { [key: string]: unknown } = {}
) {
const request = async () =>
await fetch(url, {
method: "DELETE",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
protected async deleteRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
const request = async () =>
await fetch(url, {
method: "DELETE",
headers: this.buildHeaders(ContentType.JSON),
body: this.buildBody(body),
});
return this.sendRequest<T>(request);
}
return this.sendRequest<T>(request);
}
protected async putFormDataRequest<T>(url: URL, body: FormData) {
const request = async () =>
await fetch(url, {
method: "PUT",
headers: this.buildHeaders(ContentType.FORM_DATA),
body,
});
protected async putFormDataRequest<T>(url: URL, body: FormData) {
const request = async () =>
await fetch(url, {
method: "PUT",
headers: this.buildHeaders(ContentType.FORM_DATA),
body,
});
return this.sendRequest<T>(request);
}
return this.sendRequest<T>(request);
}
private async sendRequest<T>(request: () => Promise<Response>): Promise<T> {
const response = await request();
return this.processResponse<T>(response, request);
}
private async sendRequest<T>(request: () => Promise<Response>): Promise<T> {
const response = await request();
return this.processResponse<T>(response, request);
}
protected async processResponse<T>(
response: Response,
request: () => Promise<Response>
): Promise<T> {
let responseJson: any | null;
try {
responseJson = await response.json();
} catch (err: unknown) {
responseJson = null;
}
protected async processResponse<T>(response: Response, request: () => Promise<Response>): Promise<T> {
let responseJson: any | null;
try {
responseJson = await response.json();
} catch (err: unknown) {
responseJson = null;
}
if (!response.ok) {
return Promise.reject(response);
}
if (!response.ok) {
return Promise.reject(response);
}
return responseJson as T;
}
return responseJson as T;
}
protected onError(error: unknown) {
console.error(error);
}
protected onError(error: unknown) {
console.error(error);
}
}
export interface IResponse {
http_status: number;
http_status: number;
}

View File

@ -4,64 +4,63 @@ import User from "le-coffre-resources/dist/Notary";
@Service()
export default class Users extends BaseNotary {
private static instance: Users;
private readonly baseURl = this.namespaceUrl.concat("/Users");
private static instance: Users;
private readonly baseURl = this.namespaceUrl.concat("/Users");
private constructor() {
super();
}
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new Users();
} else {
return this.instance;
}
}
public static getInstance() {
if (!this.instance) {
return new Users();
} else {
return this.instance;
}
}
public async get(): Promise<User[]> {
const url = new URL(this.baseURl);
try {
return await this.getRequest<User[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async get(): Promise<User[]> {
const url = new URL(this.baseURl);
try {
return await this.getRequest<User[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getAuthorizationCode(): Promise<any> {
try {
const url =
new URL(`https://qual-connexion.idnot.fr/IdPOAuth2/authorize/idnot_idp_v1?
public async getAuthorizationCode(): Promise<any> {
try {
const url = new URL(`https://qual-connexion.idnot.fr/IdPOAuth2/authorize/idnot_idp_v1?
client_id=4501646203F3EF67
&redirect_uri=https://app.stg.lecoffre.smart-chain.fr/
&scope=openid,profile,offline_access
&response_type=code`);
// const url = new URL("https://jsonplaceholder.typicode.com/todos/1");
await this.getRequest(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
// const url = new URL("https://jsonplaceholder.typicode.com/todos/1");
await this.getRequest(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string): Promise<User> {
const url = new URL(this.baseURl.concat("/").concat(uid));
try {
return await this.getRequest<User>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string): Promise<User> {
const url = new URL(this.baseURl.concat("/").concat(uid));
try {
return await this.getRequest<User>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
// public async post(params: User): Promise<User> {
// const url = new URL(this.baseURl);
// try {
// return await this.postRequest<User>(url, params);
// } catch (err) {
// this.onError(err);
// return Promise.reject(err);
// }
// }
// public async post(params: User): Promise<User> {
// const url = new URL(this.baseURl);
// try {
// return await this.postRequest<User>(url, params);
// } catch (err) {
// this.onError(err);
// return Promise.reject(err);
// }
// }
}

View File

@ -4,38 +4,38 @@ import BaseSuperAdmin from "../BaseSuperAdmin";
@Service()
export default class Users extends BaseSuperAdmin {
private static instance: Users;
private readonly baseURl = this.namespaceUrl.concat("/Users");
private static instance: Users;
private readonly baseURl = this.namespaceUrl.concat("/Users");
private constructor() {
super();
}
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new this();
} else {
return this.instance;
}
}
public static getInstance() {
if (!this.instance) {
return new this();
} else {
return this.instance;
}
}
public async get(): Promise<User[]> {
const url = new URL(this.baseURl);
try {
return await this.getRequest<User[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async get(): Promise<User[]> {
const url = new URL(this.baseURl);
try {
return await this.getRequest<User[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string): Promise<User> {
const url = new URL(this.baseURl.concat("/").concat(uid));
try {
return await this.getRequest<User>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string): Promise<User> {
const url = new URL(this.baseURl.concat("/").concat(uid));
try {
return await this.getRequest<User>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -7,9 +7,7 @@ Then, add the tezoslink.net RPC endpoint to your prefered Tezos JS library.
> i.e with [Sotez](https://github.com/AndrewKishino/sotez) :
>
> ```js
> const sotez = new Sotez(
> "https://<NETWORK>.tezoslink.net/v1/<YOUR_PROJECT_ID>"
> );
> const sotez = new Sotez("https://<NETWORK>.tezoslink.net/v1/<YOUR_PROJECT_ID>");
> ```
## Networks
@ -42,14 +40,14 @@ All requests of type `/chains/main/blocks(.*?)` are accepted.
> Example of valid paths:
>
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/balance`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/delegate`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/manager_key`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/counter`
> - `/chains/main/blocks/head/context/delegates/<ADDRESS>`
> - `/chains/main/blocks/head/header`
> - `/chains/main/blocks/head/votes/proposals`
> - `/chains/main/blocks/head/votes/current_quorum`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/balance`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/delegate`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/manager_key`
> - `/chains/main/blocks/head/context/contracts/<ADDRESS>/counter`
> - `/chains/main/blocks/head/context/delegates/<ADDRESS>`
> - `/chains/main/blocks/head/header`
> - `/chains/main/blocks/head/votes/proposals`
> - `/chains/main/blocks/head/votes/current_quorum`
[More about the Tezos `JSON/RPC` endpoints](https://tezos.gitlab.io/api/rpc.html)
@ -57,13 +55,13 @@ All requests of type `/chains/main/blocks(.*?)` are accepted.
Tezos has three types of nodes:
- Full mode (default mode)
- **Rolling mode**
- **Archive mode**
- Full mode (default mode)
- **Rolling mode**
- **Archive mode**
We use two types of mode:
- **Archive** to store the whole blockchain. Archive is the heaviest mode as it keeps the whole chain data to be able to query any information stored on the chain since the genesis. It is particularly suitable for indexers or block explorer, that is why we use archive nodes.
- **Rolling** to store last blocks (and scale them faster)
- **Archive** to store the whole blockchain. Archive is the heaviest mode as it keeps the whole chain data to be able to query any information stored on the chain since the genesis. It is particularly suitable for indexers or block explorer, that is why we use archive nodes.
- **Rolling** to store last blocks (and scale them faster)
> [More about history modes](https://blog.nomadic-labs.com/introducing-snapshots-and-history-modes-for-the-tezos-node.html)

View File

@ -1,6 +1,6 @@
- [Usage](##usage)
- [Networks](#networks)
- [Make Requests](#make-requests)
- [Security](##security)
- [RPC Endpoints](#rpc-endpoints)
- [Nodes](#nodes)
- [Usage](##usage)
- [Networks](#networks)
- [Make Requests](#make-requests)
- [Security](##security)
- [RPC Endpoints](#rpc-endpoints)
- [Nodes](#nodes)

View File

@ -109,4 +109,4 @@
line-height: 22px;
text-decoration-line: underline;
}
}
}

View File

@ -31,7 +31,7 @@ export default function Button(props: IProps) {
onClick,
children,
icon,
iconStyle
iconStyle,
} = props;
const attributes = { ...props, variant, disabled, type, isloading, fullwidth };

View File

@ -1,25 +1,23 @@
@import "@Themes/constants.scss";
.root {
border: 1px solid $grey-medium;
padding: 16px;
display: flex;
justify-content: space-between;
align-items: center;
&.PENDING{
border-color: $orange-soft;
}
&.VALIDATED{
border-color: $green-soft;
}
.valid-radius{
background-color: $green-flash;
padding: 6px;
border-radius: 20px;
}
.trash{
cursor: pointer;
}
border: 1px solid $grey-medium;
padding: 16px;
display: flex;
justify-content: space-between;
align-items: center;
&.PENDING {
border-color: $orange-soft;
}
&.VALIDATED {
border-color: $green-soft;
}
.valid-radius {
background-color: $green-flash;
padding: 6px;
border-radius: 20px;
}
.trash {
cursor: pointer;
}
}

View File

@ -13,8 +13,7 @@ type IProps = {
uid: Document["uid"];
document_type: Document["document_type"];
document_status: Document["document_status"];
}
};
openDeletionModal?: (uid: Document["uid"]) => void;
};
type IState = {};
@ -25,30 +24,34 @@ export default class DocumentNotary extends React.Component<IProps, IState> {
this.onOpenDeletionModal = this.onOpenDeletionModal.bind(this);
}
public override render(): JSX.Element {
return <div className={classNames(classes["root"], classes[this.props.document.document_status])}>
<div>
<Typography typo={ITypo.P_SB_16}>{this.props.document?.document_type?.name}</Typography>
<Typography typo={ITypo.CAPTION_14}>Aucun document déposé</Typography>
return (
<div className={classNames(classes["root"], classes[this.props.document.document_status])}>
<div>
<Typography typo={ITypo.P_SB_16}>{this.props.document?.document_type?.name}</Typography>
<Typography typo={ITypo.CAPTION_14}>Aucun document déposé</Typography>
</div>
{this.renderIcon()}
</div>
{this.renderIcon()}
</div>;
);
}
private renderIcon(): JSX.Element {
switch (this.props.document.document_status) {
case "VALIDATED":
return <div className={classes["valid-radius"]}>
<Image src={ValidIcon} alt="valid icon" />
</div>
return (
<div className={classes["valid-radius"]}>
<Image src={ValidIcon} alt="valid icon" />
</div>
);
case "PENDING":
return <WarningBadge />
return <WarningBadge />;
default:
return <Image src={TrashIcon} alt="trash icon" className={classes["trash"]} onClick={this.onOpenDeletionModal}/>;
return <Image src={TrashIcon} alt="trash icon" className={classes["trash"]} onClick={this.onOpenDeletionModal} />;
}
}
private onOpenDeletionModal(): void {
if(!this.props.openDeletionModal) return;
if (!this.props.openDeletionModal) return;
this.props.openDeletionModal(this.props.document.uid);
}
}

View File

@ -1,31 +1,29 @@
@import "@Themes/constants.scss";
.root {
background-color: $grey-soft;
padding: 24px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
background-color: $grey-soft;
padding: 24px;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
.content {
display:grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 32px;
@media (max-width: $screen-l) {
grid-template-columns: 1fr 1fr;
.content {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 32px;
@media (max-width: $screen-l) {
grid-template-columns: 1fr 1fr;
}
@media (max-width: $screen-s) {
grid-template-columns: 1fr;
}
}
@media (max-width: $screen-s) {
grid-template-columns: 1fr;
}
&.isSignleDescription {
grid-template-columns: 1fr;
}
}
.edit-icon{
margin-left: 48px;
}
}
&.isSignleDescription {
grid-template-columns: 1fr;
}
}
.edit-icon {
margin-left: 48px;
}
}

View File

@ -14,36 +14,38 @@ type IProps = {
export default function FolderBoxInformation(props: IProps) {
const { isDescription = false } = props;
return <div className={classNames(classes["root"], isDescription && classes["isSignleDescription"])}>
<div className={classes["content"]}>
{isDescription ?
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Note dossier :</Typography>
<Typography typo={ITypo.P_18}>{props.folder.description ?? "..."}</Typography>
</div>
:
<>
return (
<div className={classNames(classes["root"], isDescription && classes["isSignleDescription"])}>
<div className={classes["content"]}>
{isDescription ? (
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Intitulé du dossier</Typography>
<Typography typo={ITypo.P_18}>{props.folder.name ?? "..."}</Typography>
<Typography typo={ITypo.NAV_INPUT_16}>Note dossier :</Typography>
<Typography typo={ITypo.P_18}>{props.folder.description ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Numéro de dossier</Typography>
<Typography typo={ITypo.P_18}>{props.folder.folder_number ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Type dacte</Typography>
<Typography typo={ITypo.P_18}>{props.folder.deed.deed_type.name ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Ouverture du dossier</Typography>
<Typography typo={ITypo.P_18}>{formatDate(props.folder.created_at)}</Typography>
</div>
</>
}
) : (
<>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Intitulé du dossier</Typography>
<Typography typo={ITypo.P_18}>{props.folder.name ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Numéro de dossier</Typography>
<Typography typo={ITypo.P_18}>{props.folder.folder_number ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Type dacte</Typography>
<Typography typo={ITypo.P_18}>{props.folder.deed.deed_type.name ?? "..."}</Typography>
</div>
<div className={classes["text-container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Ouverture du dossier</Typography>
<Typography typo={ITypo.P_18}>{formatDate(props.folder.created_at)}</Typography>
</div>
</>
)}
</div>
<Image src={PenICon} alt="edit informations" className={classes["edit-icon"]} />
</div>
<Image src={PenICon} alt="edit informations" className={classes["edit-icon"]} />
</div>;
);
}
function formatDate(date: Date | null): string {
@ -53,4 +55,4 @@ function formatDate(date: Date | null): string {
month: "long",
day: "numeric",
});
}
}

View File

@ -1,25 +1,25 @@
@import "@Themes/constants.scss";
.root {
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 24px;
border: 1px solid $grey-medium;
cursor: pointer;
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 24px;
border: 1px solid $grey-medium;
cursor: pointer;
&:hover{
background-color: $grey-medium;
}
&:hover {
background-color: $grey-medium;
}
.left-side {
display: inline-flex;
justify-content: space-between;
align-items: center;
.left-side {
display: inline-flex;
justify-content: space-between;
align-items: center;
.warning{
margin-left: 32px;
}
}
}
.warning {
margin-left: 32px;
}
}
}

View File

@ -9,7 +9,7 @@ import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotar
type IProps = {
folder: IDashBoardFolder;
onSelectedFolder?: (folder: IDashBoardFolder) => void;
}
};
type IState = {};
export default class FolderContainer extends React.Component<IProps, IState> {
@ -19,13 +19,19 @@ export default class FolderContainer extends React.Component<IProps, IState> {
}
public override render(): JSX.Element {
return <div className={classes["root"]} onClick={this.onSelectedFolder}>
<div className={classes["left-side"]}>
<Typography typo={ITypo.P_16}>{"Dossier ".concat(this.props.folder.folder_number)}</Typography>
{this.countPendingDocuments() > 0 && <div className={classes["warning"]}><WarningBadge /></div>}
return (
<div className={classes["root"]} onClick={this.onSelectedFolder}>
<div className={classes["left-side"]}>
<Typography typo={ITypo.P_16}>{"Dossier ".concat(this.props.folder.folder_number)}</Typography>
{this.countPendingDocuments() > 0 && (
<div className={classes["warning"]}>
<WarningBadge />
</div>
)}
</div>
<Image alt="chevron" src={ChevronIcon} />
</div>
<Image alt="chevron" src={ChevronIcon} />
</div>;
);
}
private countPendingDocuments(): number {

View File

@ -14,14 +14,19 @@ type IState = {};
export default class FolderList extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
{this.props.folders.map((folder) => {
return <div onClick={this.props.onCloseLeftSide} key={folder.uid}>
<Link href={"/dossier/".concat(folder.uid)}>
<FolderContainer folder={folder} onSelectedFolder={this.props.onSelectedFolder} />;
</Link>
</div>
})};
</div>;
return (
<div className={classes["root"]}>
{this.props.folders.map((folder) => {
return (
<div onClick={this.props.onCloseLeftSide} key={folder.uid}>
<Link href={"/dossier/".concat(folder.uid)}>
<FolderContainer folder={folder} onSelectedFolder={this.props.onSelectedFolder} />;
</Link>
</div>
);
})}
;
</div>
);
}
}

View File

@ -1,13 +1,13 @@
@import "@Themes/constants.scss";
.root {
min-height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
.searchbar {
padding: 40px 24px 24px 24px;
}
}
.searchbar {
padding: 40px 24px 24px 24px;
}
}

View File

@ -24,22 +24,27 @@ export default class FolderListContainer extends React.Component<IProps, IState>
}
public override render(): JSX.Element {
return <div className={classes["root"]}>
<div>
<div className={classes["searchbar"]}>
<SearchBar folders={this.props.folders} onChange={this.filterFolders} />
return (
<div className={classes["root"]}>
<div>
<div className={classes["searchbar"]}>
<SearchBar folders={this.props.folders} onChange={this.filterFolders} />
</div>
<FolderList
folders={this.state.filteredFolders}
onSelectedFolder={this.props.onSelectedFolder && this.props.onSelectedFolder}
onCloseLeftSide={this.props.onCloseLeftSide}
/>
</div>
<div>
<Button fullwidth={"true"}>Créer un dossier</Button>
</div>
<FolderList folders={this.state.filteredFolders} onSelectedFolder={this.props.onSelectedFolder && this.props.onSelectedFolder} onCloseLeftSide={this.props.onCloseLeftSide}/>
</div>
<div>
<Button fullwidth={"true"}>Créer un dossier</Button>
</div>
</div>;
);
}
private filterFolders(folders: IDashBoardFolder[]): IDashBoardFolder[] {
this.setState({ filteredFolders: folders })
this.setState({ filteredFolders: folders });
return folders;
}
}

View File

@ -2,11 +2,11 @@
.root {
position: relative;
textarea{
textarea {
resize: none;
height: auto;
box-sizing: border-box;
font-family: 'Inter';
font-family: "Inter";
font-style: normal;
font-weight: 400;
font-size: 18px;

View File

@ -17,7 +17,7 @@ type IState = {
};
export default class Notifications extends React.Component<IProps, IState> {
private removeOnToastChange: () => void = () => { };
private removeOnToastChange: () => void = () => {};
constructor(props: IProps) {
super(props);
@ -38,7 +38,9 @@ export default class Notifications extends React.Component<IProps, IState> {
)}
</div>
{this.props.isModalOpen && <NotificationModal isOpen={this.props.isModalOpen} closeModal={this.props.closeNotificationModal} />}
{this.props.isModalOpen && (
<NotificationModal isOpen={this.props.isModalOpen} closeModal={this.props.closeNotificationModal} />
)}
</div>
);
}

View File

@ -9,8 +9,7 @@ type IProps = {
openProfileModal: () => void;
closeProfileModal: () => void;
};
type IState = {
};
type IState = {};
export default class Profile extends React.Component<IProps, IState> {
constructor(props: IProps) {

View File

@ -60,4 +60,4 @@
}
}
}
}
}

View File

@ -26,7 +26,7 @@ type IState = {
};
export default class Header extends React.Component<IProps, IState> {
private onWindowResize = () => { };
private onWindowResize = () => {};
private headerBreakpoint = 1300;
constructor(props: IProps) {
@ -53,31 +53,40 @@ export default class Header extends React.Component<IProps, IState> {
<Image src={LogoIcon} alt="logo" className={classes["logo"]} />
</Link>
</div>
{this.props.isUserConnected &&
{this.props.isUserConnected && (
<>
<Navigation />
<div className={classes["right-section"]}>
<div className={classes["notification-section"]}>
<Notifications isModalOpen={this.state.isNotificationMenuOpen} openNotificationModal={this.openNotificationMenu} closeNotificationModal={this.closeNotificationMenu} />
<Notifications
isModalOpen={this.state.isNotificationMenuOpen}
openNotificationModal={this.openNotificationMenu}
closeNotificationModal={this.closeNotificationMenu}
/>
</div>
<div className={classes["profile-section"]}>
<Profile isModalOpen={this.state.isProfileMenuOpen} closeProfileModal={this.closeProfileMenu} openProfileModal={this.openProfileMenu} />
<Profile
isModalOpen={this.state.isProfileMenuOpen}
closeProfileModal={this.closeProfileMenu}
openProfileModal={this.openProfileMenu}
/>
</div>
<div className={classes["burger-menu"]}>
<BurgerMenu isModalOpen={this.state.isBurgerMenuOpen} closeBurgerMenu={this.closeBurgerMenu} openBurgerMenu={this.openBurgerMenu} />
<BurgerMenu
isModalOpen={this.state.isBurgerMenuOpen}
closeBurgerMenu={this.closeBurgerMenu}
openBurgerMenu={this.openBurgerMenu}
/>
</div>
</div>
</>
}
)}
</div>
);
}
public override componentDidMount() {
this.onWindowResize = WindowStore.getInstance().onResize((window) =>
this.onResize(window)
);
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
}
public override componentWillUnmount() {

View File

@ -9,19 +9,20 @@ type IState = {};
type IFolderInformation = {
label: string;
value: string;
}
};
export default class InformationBox extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
{/* {this.props.informations.map((information, key) => {
return (
<div className={classes["root"]}>
{/* {this.props.informations.map((information, key) => {
const output = <div className={classes["information"] } key={key}>
<span className={classes["label"]}>{information.label}</span>
<span className={classes["value"]}>{information.value}</span>
</div>;
return output;
})}; */}
</div>;
</div>
);
}
}

View File

@ -19,6 +19,5 @@ export default class LogOutButton extends React.Component<IProps, IState> {
);
}
private disconnect() {
}
private disconnect() {}
}

View File

@ -13,14 +13,14 @@ type IState = {
export default class Alert extends React.Component<IProps, IState> {
static defaultProps = {
closeText: "Ok",
...Modal.defaultProps
...Modal.defaultProps,
};
constructor(props: IProps) {
super(props);
this.state = {
isOpen: this.props.isOpen ?? true,
}
};
this.onClose = this.onClose.bind(this);
}

View File

@ -19,7 +19,7 @@ export default class Confirm extends React.Component<IProps, IState> {
cancelText: "Cancel",
confirmText: "Confirm",
isConfirmButtonDisabled: false,
...Modal.defaultProps
...Modal.defaultProps,
};
public override render(): JSX.Element | null {
@ -30,8 +30,7 @@ export default class Confirm extends React.Component<IProps, IState> {
onClose={this.props.onClose}
header={this.props.header}
footer={this.footer()}
animationDelay={this.props.animationDelay}
>
animationDelay={this.props.animationDelay}>
{this.props.children}
</Modal>
);
@ -40,7 +39,6 @@ export default class Confirm extends React.Component<IProps, IState> {
private footer(): JSX.Element {
return (
<div className={classes["buttons-container"]}>
{this.props.showCancelButton && (
<Button variant={EButtonVariant.GHOST} onClick={this.props.onClose}>
{this.props.cancelText}

View File

@ -121,4 +121,4 @@
}
}
}
}
}

View File

@ -28,7 +28,7 @@ type IState = {
export default class Modal extends React.Component<IProps, IState> {
static defaultProps = {
animationDelay: 250
animationDelay: 250,
};
public rootRefElement = React.createRef<HTMLDivElement>();
constructor(props: IProps) {
@ -36,19 +36,23 @@ export default class Modal extends React.Component<IProps, IState> {
this.close = this.close.bind(this);
this.state = {
willClose: false
willClose: false,
};
}
public override render(): JSX.Element | null {
if (!this.props.isOpen) return null;
const onClick = (this.props.hasContainerClosable && this.close) || (() => { });
const onClick = (this.props.hasContainerClosable && this.close) || (() => {});
return (
<div ref={this.rootRefElement} className={classes["root"]} data-side-background={this.props.withSideBackground} data-will-close={this.state.willClose.toString()}>
<div
ref={this.rootRefElement}
className={classes["root"]}
data-side-background={this.props.withSideBackground}
data-will-close={this.state.willClose.toString()}>
<div className={classes["background"]} onClick={this.close} />
<div
className={[classes["container"], this.props.hasTransparentBackground && classes["transparant-background"]].join(" ")}
onClick={onClick} >
onClick={onClick}>
{this.props.closeBtn && (
<div className={classes["cross"]}>
<Image alt="Unplugged" src={CrossIcon} className={classes["close-icon"]} onClick={this.close} />
@ -73,12 +77,12 @@ export default class Modal extends React.Component<IProps, IState> {
protected close() {
if (this.state.willClose) return;
this.setState({ willClose: true })
this.setState({ willClose: true });
window.setTimeout(() => {
this.setState({
willClose: false
})
this.props.onClose()
}, this.props.animationDelay)
willClose: false,
});
this.props.onClose();
}, this.props.animationDelay);
}
}

View File

@ -11,9 +11,8 @@
border: 1px solid $grey-medium;
background-color: transparent;
&.active{
&.active {
padding: 16px 24px;
}
.label {
font-family: var(--font-primary);
@ -32,7 +31,7 @@
border: none;
width: 100%;
>div {
> div {
width: 100%;
}
}
@ -46,4 +45,4 @@
padding: 0 16px;
}
}
}
}

View File

@ -1,79 +1,77 @@
import React from "react";
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
import { styles } from "./styles";
import classes from "./classes.module.scss";
import { IOption } from "../Select";
import Typography, { ITypo } from "../Typography";
import classNames from "classnames";
type IProps = {
options: IOption[];
label?: string | JSX.Element;
placeholder?: string;
onChange?: (newValue: MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void;
defaultValue?: PropsValue<IOption>;
value?: PropsValue<IOption>;
isMulti?: boolean;
shouldCloseMenuOnSelect?: boolean;
isOptionDisabled?: (option: IOption, selectValue: Options<IOption>) => boolean;
};
type IState = {
isSelectedOption: boolean;
};
export default class MultiSelect extends React.Component<IProps, IState> {
public static defaultProps: Partial<IProps> = {
placeholder: "Sélectionner une option...",
}
constructor(props: IProps) {
super(props);
this.state = {
isSelectedOption: this.props.defaultValue ? true : false
}
this.onChange = this.onChange.bind(this);
this.onEmptyResearch = this.onEmptyResearch.bind(this);
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<div className={classNames(classes["label-container"], this.state.isSelectedOption && classes["active"])}>
{this.props.label && <div className={classes["label"]}>{this.props.label}</div>}
{this.state.isSelectedOption &&
<>
< Typography typo={ITypo.NAV_INPUT_16}>
<div className={classes["is-active-placeholder"]}>{this.props.placeholder}</div>
</Typography>
</>
}
<div className={classes["input-container"]}>
<ReactSelect
placeholder={this.props.placeholder}
options={this.props.options}
styles={styles}
onChange={this.onChange}
value={this.props.value}
defaultValue={this.props.defaultValue}
closeMenuOnSelect={this.props.shouldCloseMenuOnSelect}
isMulti
isOptionDisabled={this.props.isOptionDisabled}
noOptionsMessage={this.onEmptyResearch}
/>
</div>
</div>
</div >
);
}
private onChange(newValue: MultiValue<IOption>, actionMeta: ActionMeta<IOption>) {
this.props.onChange && this.props.onChange(newValue, actionMeta);
this.setState({ isSelectedOption: newValue.length > 0 });
}
private onEmptyResearch(){
return "Aucune option correspondante"
}
}
import React from "react";
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
import { styles } from "./styles";
import classes from "./classes.module.scss";
import { IOption } from "../Select";
import Typography, { ITypo } from "../Typography";
import classNames from "classnames";
type IProps = {
options: IOption[];
label?: string | JSX.Element;
placeholder?: string;
onChange?: (newValue: MultiValue<IOption>, actionMeta: ActionMeta<IOption>) => void;
defaultValue?: PropsValue<IOption>;
value?: PropsValue<IOption>;
isMulti?: boolean;
shouldCloseMenuOnSelect?: boolean;
isOptionDisabled?: (option: IOption, selectValue: Options<IOption>) => boolean;
};
type IState = {
isSelectedOption: boolean;
};
export default class MultiSelect extends React.Component<IProps, IState> {
public static defaultProps: Partial<IProps> = {
placeholder: "Sélectionner une option...",
};
constructor(props: IProps) {
super(props);
this.state = {
isSelectedOption: this.props.defaultValue ? true : false,
};
this.onChange = this.onChange.bind(this);
this.onEmptyResearch = this.onEmptyResearch.bind(this);
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<div className={classNames(classes["label-container"], this.state.isSelectedOption && classes["active"])}>
{this.props.label && <div className={classes["label"]}>{this.props.label}</div>}
{this.state.isSelectedOption && (
<>
<Typography typo={ITypo.NAV_INPUT_16}>
<div className={classes["is-active-placeholder"]}>{this.props.placeholder}</div>
</Typography>
</>
)}
<div className={classes["input-container"]}>
<ReactSelect
placeholder={this.props.placeholder}
options={this.props.options}
styles={styles}
onChange={this.onChange}
value={this.props.value}
defaultValue={this.props.defaultValue}
closeMenuOnSelect={this.props.shouldCloseMenuOnSelect}
isMulti
isOptionDisabled={this.props.isOptionDisabled}
noOptionsMessage={this.onEmptyResearch}
/>
</div>
</div>
</div>
);
}
private onChange(newValue: MultiValue<IOption>, actionMeta: ActionMeta<IOption>) {
this.props.onChange && this.props.onChange(newValue, actionMeta);
this.setState({ isSelectedOption: newValue.length > 0 });
}
private onEmptyResearch() {
return "Aucune option correspondante";
}
}

View File

@ -31,7 +31,7 @@ export const styles = {
fontSize: "16px",
lineHeight: "22px",
color: "#939393",
letter: "0.5 px"
letter: "0.5 px",
}),
multiValue: (provided: any) => ({
...provided,
@ -65,13 +65,12 @@ export const styles = {
}),
indicatorSeparator: () => ({
display: "none",
}),
menu: (provided: any) => ({
...provided,
position: "static",
border: "0",
boxShadow: "none"
boxShadow: "none",
}),
menuList: (provided: any) => ({
...provided,
@ -87,7 +86,7 @@ export const styles = {
">svg": {
width: "16px",
height: "16px",
}
},
}),
indicatorsContainer: (provided: any) => ({
...provided,
@ -99,4 +98,3 @@ export const styles = {
fontSize: "16px",
}),
};

View File

@ -24,4 +24,4 @@
left: 50%;
transform: translate(-50%);
}
}
}

View File

@ -6,12 +6,11 @@ type IProps = {
percentage: number;
};
export default class ProgressBar extends React.Component<IProps> {
public override render(): JSX.Element {
const quantity = (this.props.percentage.toFixed(2)).toString().concat("%")
const quantity = this.props.percentage.toFixed(2).toString().concat("%");
return (
<div className={classes["root"]}>
<div className={classes["progress"]} style={{ width: quantity }} >
<div className={classes["progress"]} style={{ width: quantity }}>
<Typography typo={ITypo.P_16}>
<div className={classes["percentage"]}>{quantity}</div>
</Typography>

View File

@ -5,8 +5,8 @@
font-size: 14px;
line-height: 20px;
font-feature-settings: "salt" on;
height: 70px;
height: 70px;
.title {
margin-bottom: 8px;
}

View File

@ -11,7 +11,9 @@ type IProps = {
export default class QuantityProgressBar extends React.Component<IProps> {
public override render(): JSX.Element {
let numerator: number = this.props.currentNumber;
if (this.props.currentNumber > this.props.total) { numerator = this.props.total }
if (this.props.currentNumber > this.props.total) {
numerator = this.props.total;
}
const percentage = (numerator / this.props.total) * 100;
return (

View File

@ -1,31 +1,31 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
padding-left: 24px;
background-color: $white;
border: 1px solid $grey-medium;
position: relative;
display: flex;
align-items: center;
padding-left: 24px;
background-color: $white;
border: 1px solid $grey-medium;
position: relative;
.fake-placeholder {
position: absolute;
left: 47px;
top: 24px;
color: $grey;
pointer-events: none;
}
.fake-placeholder {
position: absolute;
left: 47px;
top: 24px;
color: $grey;
pointer-events: none;
}
.input {
border: 0;
margin-left: 8px;
padding: 24px 0;
width: 100%;
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 18px;
line-height: 22px;
color: $grey;
}
}
.input {
border: 0;
margin-left: 8px;
padding: 24px 0;
width: 100%;
font-family: "Inter";
font-style: normal;
font-weight: 400;
font-size: 18px;
line-height: 22px;
color: $grey;
}
}

View File

@ -13,7 +13,6 @@ type IState = {
hasValue: boolean;
};
export default class SearchBar extends React.Component<IProps, IState> {
public constructor(props: IProps) {
super(props);
@ -24,15 +23,21 @@ export default class SearchBar extends React.Component<IProps, IState> {
this.onChange = this.onChange.bind(this);
}
public override render(): JSX.Element {
return <div className={classes["root"]}>
<Image src={LoopIcon} alt="Loop icon" />
{!this.state.hasValue && <Typography typo={ITypo.P_ERR_18}><div className={classes["fake-placeholder"]}>Select</div></Typography>}
<input type="text" placeholder="" className={classes["input"]} onChange={this.onChange} />
</div>;
return (
<div className={classes["root"]}>
<Image src={LoopIcon} alt="Loop icon" />
{!this.state.hasValue && (
<Typography typo={ITypo.P_ERR_18}>
<div className={classes["fake-placeholder"]}>Select</div>
</Typography>
)}
<input type="text" placeholder="" className={classes["input"]} onChange={this.onChange} />
</div>
);
}
private onChange(event: React.ChangeEvent<HTMLInputElement>) {
const hasValue = event.target.value.length > 0
const hasValue = event.target.value.length > 0;
this.doesInputHaveValue(hasValue);
if (!this.props.onChange) return;
this.props.onChange(this.filterFolders(event));
@ -43,7 +48,9 @@ export default class SearchBar extends React.Component<IProps, IState> {
}
private filterFolders(event: React.ChangeEvent<HTMLInputElement>) {
const filteredFolders: IDashBoardFolder[] = this.props.folders.filter((folder) => folder.folder_number.includes(event.target.value));
const filteredFolders: IDashBoardFolder[] = this.props.folders.filter((folder) =>
folder.folder_number.includes(event.target.value),
);
return filteredFolders;
}
}

View File

@ -21,7 +21,7 @@
border-radius: 8px 0 0 8px;
}
.container-input chevron-icon{
.container-input chevron-icon {
display: flex;
align-items: center;
@ -113,12 +113,12 @@
align-items: center;
margin-right: 11px;
>svg {
> svg {
height: 20px;
margin-right: 11px;
}
>img {
> img {
height: 20px;
width: 20px;
}
@ -129,4 +129,4 @@
z-index: 1;
inset: 0;
}
}
}

View File

@ -31,7 +31,7 @@ type IState = {
export default class Select extends React.Component<IProps, IState> {
private contentRef = React.createRef<HTMLUListElement>();
private rootRef = React.createRef<HTMLDivElement>();
private removeOnresize = () => { };
private removeOnresize = () => {};
constructor(props: IProps) {
super(props);
@ -67,7 +67,6 @@ export default class Select extends React.Component<IProps, IState> {
</Typography>
</div>
</>
</div>
<Image className={classes["chevron-icon"]} data-open={this.state.isOpen} src={ChevronIcon} alt="chevron icon" />
</label>
@ -82,14 +81,11 @@ export default class Select extends React.Component<IProps, IState> {
{this.props.options.map((option, index) => (
<li key={`${index}-${option.value}`} className={classes["container-li"]} onClick={(e) => this.onSelect(option, e)}>
<div className={classes["token-icon"]}>{option.icon}</div>
<Typography typo={ITypo.P_18}>
{option.label}
</Typography>
<Typography typo={ITypo.P_18}>{option.label}</Typography>
</li>
))}
</ul>
{this.state.isOpen && <div className={classes["backdrop"]} onClick={this.toggle} />}
</div>
);

View File

@ -16,18 +16,19 @@ type IState = {
event: React.MouseEvent<HTMLElement> | null;
};
const LightTooltip = styled(({ className, ...props }: TooltipProps) => (
<TooltipMUI {...props} classes={{ popper: className }} />
))(({ theme }) => ({
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: "var(--colormerdum)",
color: "var(--colormerdum)",
//boxShadow: theme.shadows[1],
fontSize: 11,
},[`& .${tooltipClasses.arrow}`]: {
// color: theme.palette.common.black,
},
}));
const LightTooltip = styled(({ className, ...props }: TooltipProps) => <TooltipMUI {...props} classes={{ popper: className }} />)(
({ theme }) => ({
[`& .${tooltipClasses.tooltip}`]: {
backgroundColor: "var(--colormerdum)",
color: "var(--colormerdum)",
//boxShadow: theme.shadows[1],
fontSize: 11,
},
[`& .${tooltipClasses.arrow}`]: {
// color: theme.palette.common.black,
},
}),
);
export default class Tooltip extends React.Component<IProps, IState> {
static defaultProps: Partial<IProps> = {
@ -41,9 +42,7 @@ export default class Tooltip extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return (
<LightTooltip title={this.props.text} placement="top" arrow>
<span
className={this.props.className}
style={!this.props.isNotFlex ? { display: "flex" } : {}}>
<span className={this.props.className} style={!this.props.isNotFlex ? { display: "flex" } : {}}>
<Image src={ToolTipIcon} alt="toolTip icon" />
</span>
</LightTooltip>

View File

@ -1,13 +1,13 @@
@import "@Themes/constants.scss";
.root {
width: 100%;
.title{
margin-bottom: 8px;
}
.content{
display: grid;
gap: 16px;
margin-top: 32px;
}
width: 100%;
.title {
margin-bottom: 8px;
}
.content {
display: grid;
gap: 16px;
margin-top: 32px;
}
}

View File

@ -7,28 +7,34 @@ import DocumentNotary from "../../Document/DocumentNotary";
type IProps = {
title: string;
subtitle?: string;
documents: {
uid: Document["uid"];
document_type: Document["document_type"];
document_status: Document["document_status"];
}[] | null;
documents:
| {
uid: Document["uid"];
document_type: Document["document_type"];
document_status: Document["document_status"];
}[]
| null;
openDeletionModal: (uid: Document["uid"]) => void;
};
type IState = {};
export default class DocumentList extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
<div className={classes["title"]}>
<Typography typo={ITypo.P_SB_18}>{this.props.title}</Typography>
return (
<div className={classes["root"]}>
<div className={classes["title"]}>
<Typography typo={ITypo.P_SB_18}>{this.props.title}</Typography>
</div>
<Typography typo={ITypo.P_16}>{this.props.subtitle}</Typography>
<div className={classes["content"]}>
{this.props.documents &&
this.props.documents.map((document) => {
return (
<DocumentNotary document={document} key={document.uid} openDeletionModal={this.props.openDeletionModal} />
);
})}
</div>
</div>
<Typography typo={ITypo.P_16}>{this.props.subtitle}</Typography>
<div className={classes["content"]}>
{this.props.documents && this.props.documents.map((document) => {
return <DocumentNotary document={document} key={document.uid} openDeletionModal={this.props.openDeletionModal}/>
})}
</div>
</div>;
);
}
}

View File

@ -1,28 +1,27 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24px;
background-color: $grey-soft;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 24px;
background-color: $grey-soft;
width: 100%;
.content {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
.content {
width: 100%;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
@media (max-width: $screen-ls) {
grid-template-columns: 1fr 1fr;
gap: 32px;
}
@media (max-width: $screen-ls) {
grid-template-columns: 1fr 1fr;
gap: 32px;
}
}
}
.icons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}
}
.icons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}
}

View File

@ -8,50 +8,55 @@ import WarningBadge from "../../WarningBadge";
type IProps = {
contact: {
first_name: Contact["first_name"],
last_name: Contact["last_name"],
phone_number: Contact["phone_number"],
cell_phone_number: Contact["cell_phone_number"],
email: Contact["email"],
}
first_name: Contact["first_name"];
last_name: Contact["last_name"];
phone_number: Contact["phone_number"];
cell_phone_number: Contact["cell_phone_number"];
email: Contact["email"];
};
};
type IState = {};
export default class UserFolderHeader extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
<div className={classes["content"]}>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Nom</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.last_name}</Typography>
</div>
return (
<div className={classes["root"]}>
<div className={classes["content"]}>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Nom</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.last_name}</Typography>
</div>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Prénom</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.first_name}</Typography>
</div>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Prénom</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.first_name}</Typography>
</div>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Numéro de téléphone</Typography>
<Typography typo={ITypo.P_18}>{this.formatPhoneNumber(this.props.contact.phone_number) ?? this.formatPhoneNumber(this.props.contact.cell_phone_number)}</Typography>
</div>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>Numéro de téléphone</Typography>
<Typography typo={ITypo.P_18}>
{this.formatPhoneNumber(this.props.contact.phone_number) ??
this.formatPhoneNumber(this.props.contact.cell_phone_number)}
</Typography>
</div>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>E-mail</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.email}</Typography>
<div className={classes["container"]}>
<Typography typo={ITypo.NAV_INPUT_16}>E-mail</Typography>
<Typography typo={ITypo.P_18}>{this.props.contact.email}</Typography>
</div>
</div>
<div className={classes["icons"]}>
<WarningBadge />
<Image src={PenIcon} alt="edit" className={classes["edit-icon"]} onClick={this.onEditClick} />
</div>
</div>
<div className={classes["icons"]}>
<WarningBadge />
<Image src={PenIcon} alt="edit" className={classes["edit-icon"]} onClick={this.onEditClick}/>
</div>
</div>;
);
}
private formatPhoneNumber(phoneNumber: string): string {
if (!phoneNumber) return "";
const output = phoneNumber.split('').map((char, index) => {
if(index%2) return char + " ";
const output = phoneNumber.split("").map((char, index) => {
if (index % 2) return char + " ";
return char;
});
return output.join("");

View File

@ -21,47 +21,47 @@
}
.root {
border: 1px solid $grey;
padding: 16px;
transition: all 350ms $custom-easing;
border: 1px solid $grey;
padding: 16px;
transition: all 350ms $custom-easing;
.header {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.header {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.chevron-icon {
margin-left: 16px;
transform: rotate(90deg);
transition: all 350ms $custom-easing;
cursor: pointer;
&.open {
transform: rotate(-90deg);
}
}
}
.chevron-icon {
margin-left: 16px;
transform: rotate(90deg);
transition: all 350ms $custom-easing;
cursor: pointer;
&.open {
transform: rotate(-90deg);
}
}
}
.container {
margin-top: 32px;
--animation-delay: 1ms;
animation: smooth-appear var(--animation-delay) $custom-easing;
&[data-will-close="true"] {
animation: smooth-disappear var(--animation-delay) $custom-easing;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
margin-top: 32px;
}
.container {
margin-top: 32px;
--animation-delay: 1ms;
animation: smooth-appear var(--animation-delay) $custom-easing;
.button-container {
display: inline-grid;
justify-items: start;
gap: 32px;
}
}
}
&[data-will-close="true"] {
animation: smooth-disappear var(--animation-delay) $custom-easing;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
margin-top: 32px;
}
.button-container {
display: inline-grid;
justify-items: start;
gap: 32px;
}
}
}

View File

@ -8,12 +8,12 @@ import QuantityProgressBar from "../QuantityProgressBar";
import classNames from "classnames";
import DocumentList from "./DocumentList";
import Button, { EButtonVariant } from "../Button";
import PlusIcon from "@Assets/Icons/plus.svg"
import PlusIcon from "@Assets/Icons/plus.svg";
import Confirm from "../Modal/Confirm";
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
type IProps = {
customer: Customer
customer: Customer;
animationDelay?: number;
folder: IDashBoardFolder;
};
@ -25,7 +25,7 @@ type IState = {
export default class UserFolder extends React.Component<IProps, IState> {
static defaultProps = {
animationDelay: 300
animationDelay: 300,
};
public rootRefElement = React.createRef<HTMLDivElement>();
@ -34,51 +34,70 @@ export default class UserFolder extends React.Component<IProps, IState> {
this.state = {
isOpen: false,
isOpenDeletionModal: false,
willClose: false
willClose: false,
};
this.toggleOpen = this.toggleOpen.bind(this);
this.closeDeletionModal = this.closeDeletionModal.bind(this);
this.openDeletionModal = this.openDeletionModal.bind(this);
this.openComponent = this.openComponent.bind(this);
this.closeComponent = this.closeComponent.bind(this);
}
public override render(): JSX.Element {
const documentsAsked: Document[] | null = this.getDocumentsByStatus("ASKED");
const otherDocuments: Document[] | null = this.getValidatedAndPendindDocuments();
return <div className={classes["root"]}>
<Confirm
isOpen={this.state.isOpenDeletionModal}
onClose={this.closeDeletionModal}
closeBtn
header={"Supprimer la demande de document ?"}
cancelText={"Cancel"}
confirmText={"Confirmer"}>
Êtes-vous vous de vouloir supprimer la demande de document ?
</Confirm>
return (
<div className={classes["root"]}>
<Confirm
isOpen={this.state.isOpenDeletionModal}
onClose={this.closeDeletionModal}
closeBtn
header={"Supprimer la demande de document ?"}
cancelText={"Cancel"}
confirmText={"Confirmer"}>
Êtes-vous vous de vouloir supprimer la demande de document ?
</Confirm>
<div className={classes["header"]} onClick={this.toggleOpen}>
<UserFolderHeader contact={this.props.
customer.contact} />
<Image src={ChevronIcon} alt="chevron open close" className={classNames(classes["chevron-icon"], this.state.isOpen && classes["open"])} onClick={this.toggleOpen} />
</div>
{this.state.isOpen &&
<div className={classes["container"]} data-will-close={this.state.willClose.toString()} ref={this.rootRefElement}>
<QuantityProgressBar title="Complétion du dossier" total={100} currentNumber={this.calculateDocumentsPercentageProgress()} />
<div className={classes["content"]}>
<DocumentList documents={documentsAsked} title="Documents demandés" openDeletionModal={this.openDeletionModal} />
<DocumentList documents={otherDocuments} title="Documents à valider / validés" subtitle="Vous avez des documents à valider." openDeletionModal={this.openDeletionModal} />
</div>
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.LINE} icon={PlusIcon}>Demander un autre document </Button>
<Button>Envoyer un mail de demande de documents</Button>
</div>
<div className={classes["header"]} onClick={this.toggleOpen}>
<UserFolderHeader contact={this.props.customer.contact} />
<Image
src={ChevronIcon}
alt="chevron open close"
className={classNames(classes["chevron-icon"], this.state.isOpen && classes["open"])}
onClick={this.toggleOpen}
/>
</div>
}
</div>;
{this.state.isOpen && (
<div className={classes["container"]} data-will-close={this.state.willClose.toString()} ref={this.rootRefElement}>
<QuantityProgressBar
title="Complétion du dossier"
total={100}
currentNumber={this.calculateDocumentsPercentageProgress()}
/>
<div className={classes["content"]}>
<DocumentList
documents={documentsAsked}
title="Documents demandés"
openDeletionModal={this.openDeletionModal}
/>
<DocumentList
documents={otherDocuments}
title="Documents à valider / validés"
subtitle="Vous avez des documents à valider."
openDeletionModal={this.openDeletionModal}
/>
</div>
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.LINE} icon={PlusIcon}>
Demander un autre document{" "}
</Button>
<Button>Envoyer un mail de demande de documents</Button>
</div>
</div>
)}
</div>
);
}
public override componentDidUpdate(): void {
@ -94,10 +113,11 @@ export default class UserFolder extends React.Component<IProps, IState> {
private getDocumentsByStatus(status: string): Document[] | null {
if (!this.props.customer.documents) return null;
return this.props.customer.documents.filter((document) => document.document_status === status && document.folder.uid === this.props.folder.uid);
return this.props.customer.documents.filter(
(document) => document.document_status === status && document.folder.uid === this.props.folder.uid,
);
}
// Get all documents Validated, pending
private getValidatedAndPendindDocuments(): Document[] | null {
const pendingDocuments = this.getDocumentsByStatus("PENDING");
@ -117,40 +137,37 @@ export default class UserFolder extends React.Component<IProps, IState> {
private toggleOpen(): void {
if (this.state.isOpen) {
this.closeComponent();
}
else {
} else {
this.openComponent();
}
}
private openComponent(): void {
this.setState({
isOpen: true
isOpen: true,
});
}
private closeComponent(): void {
if (this.state.willClose) return;
this.setState({ willClose: true })
this.setState({ willClose: true });
window.setTimeout(() => {
this.setState({
isOpen: false,
willClose: false
willClose: false,
});
}, this.props.animationDelay)
}, this.props.animationDelay);
}
private openDeletionModal(uid: string): void {
// TODO: call API to delete document
this.setState({
isOpenDeletionModal: true
isOpenDeletionModal: true,
});
}
private closeDeletionModal(): void {
this.setState({
isOpenDeletionModal: false
})
isOpenDeletionModal: false,
});
}
}

View File

@ -1,7 +1,7 @@
@import "@Themes/constants.scss";
.root {
background-color: $orange-flash;
padding: 6px;
border-radius: 20px;
}
background-color: $orange-flash;
padding: 6px;
border-radius: 20px;
}

View File

@ -8,8 +8,10 @@ type IState = {};
export default class WarningBadge extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
<Image src={WarningIcon} alt="warning icon" />
</div>;
return (
<div className={classes["root"]}>
<Image src={WarningIcon} alt="warning icon" />
</div>
);
}
}

View File

@ -42,7 +42,6 @@ export default class InputField extends React.Component<IProps> {
{this.props.inputStatus === "success" && <Image alt="success icon" src={SuccessIcon} />}
{this.props.inputStatus === "error" && <Image alt="error icon" src={ErrorIcon} />}
</div>
</div>
{this.props.errorMsg && <div className={classes["errorMsg"]}>{this.props.errorMsg}</div>}
</>

View File

@ -27,9 +27,7 @@ export default class DefaultDoubleSidePage extends React.Component<IProps, IStat
<Header isUserConnected={false} />
<div className={classes["content"]}>
<div className={classes["sides"]}>
<div className={classes["side-content"]}>
{this.props.children}
</div>
<div className={classes["side-content"]}>{this.props.children}</div>
</div>
<div className={classNames(classes["sides"], classes["image-container"])}>
<Image alt={"right side image"} src={this.props.image} className={classes["image"]} />
@ -46,4 +44,4 @@ export default class DefaultDoubleSidePage extends React.Component<IProps, IStat
window.scrollTo(0, this.props.scrollTop);
}
}
}
}

View File

@ -26,7 +26,6 @@
min-width: 389px;
}
}
}
.closable-left-side {
@ -44,7 +43,6 @@
display: none;
}
.chevron-icon {
margin-top: 21px;
transform: rotate(180deg);
@ -58,4 +56,4 @@
overflow-y: auto;
}
}
}
}

View File

@ -1,15 +1,15 @@
import 'reflect-metadata';
import "reflect-metadata";
import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import FolderListContainer from "@Front/Components/DesignSystem/FolderListContainer";
import Header from "@Front/Components/DesignSystem/Header";
import Version from "@Front/Components/DesignSystem/Version";
import { folders } from "@Front/Components/Layouts/DesignSystem/dummyData"
import { OfficeFolder } from 'le-coffre-resources/dist/Customer';
import { folders } from "@Front/Components/Layouts/DesignSystem/dummyData";
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
import chevronIcon from "@Assets/Icons/chevron.svg";
import Image from 'next/image';
import classNames from 'classnames';
import WindowStore from '@Front/Stores/WindowStore';
import Image from "next/image";
import classNames from "classnames";
import WindowStore from "@Front/Stores/WindowStore";
type IProps = {
title: string;
children?: ReactNode;
@ -25,14 +25,14 @@ export type IDashBoardFolder = {
uid: OfficeFolder["uid"];
name: OfficeFolder["name"];
folder_number: OfficeFolder["folder_number"];
documents?: OfficeFolder["documents"]
documents?: OfficeFolder["documents"];
description: OfficeFolder["description"];
deed: OfficeFolder["deed"];
created_at: OfficeFolder["created_at"];
office_folder_has_customers?: OfficeFolder["office_folder_has_customers"];
};
export default class DefaultNotaryDashboard extends React.Component<IProps, IState> {
private onWindowResize = () => { };
private onWindowResize = () => {};
public static defaultProps = {
scrollTop: 0,
};
@ -49,16 +49,19 @@ export default class DefaultNotaryDashboard extends React.Component<IProps, ISta
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<Header isUserConnected={true} />
<div className={classes["content"]}>
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
<FolderListContainer folders={this.state.folders} onSelectedFolder={this.props.onSelectedFolder} onCloseLeftSide={this.onCloseLeftSide} />
<FolderListContainer
folders={this.state.folders}
onSelectedFolder={this.props.onSelectedFolder}
onCloseLeftSide={this.onCloseLeftSide}
/>
</div>
<div className={classNames(classes["closable-left-side"])}>
<Image alt='open side menu' src={chevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
<Image alt="open side menu" src={chevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
</div>
<div className={classes["right-side"]}>{this.props.children}</div>
</div>
@ -68,9 +71,7 @@ export default class DefaultNotaryDashboard extends React.Component<IProps, ISta
}
public override componentDidMount(): void {
this.onWindowResize = WindowStore.getInstance().onResize((window) =>
this.onResize(window)
);
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
}
public override componentWillUnmount() {
this.onWindowResize();

View File

@ -2,7 +2,7 @@ import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import Header from "@Front/Components/DesignSystem/Header";
import Version from "@Front/Components/DesignSystem/Version";
import 'reflect-metadata';
import "reflect-metadata";
type IProps = {
title: string;

View File

@ -1,22 +1,26 @@
@import "@Themes/constants.scss";
.root {
display: flex;
flex-direction: column;
min-height: 100%;
display: flex;
flex-direction: column;
min-height: 100%;
align-items: flex-start;
.radiobox-container{
margin: 32px 0;
}
.button-container{
margin-top: 24px;
:first-child{
margin-right: 32px;
}
}
.new-client{
>:not(:last-child){
margin-bottom: 24px;
}
}
}
.radiobox-container {
margin: 32px 0;
}
.button-container {
margin-top: 24px;
:first-child {
margin-right: 32px;
}
}
.new-client {
> :not(:last-child) {
margin-bottom: 24px;
}
}
}

View File

@ -9,6 +9,7 @@ import { ActionMeta, MultiValue } from "react-select";
import { IOption } from "@Front/Components/DesignSystem/Select";
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
import Form from "@Front/Components/DesignSystem/Form";
import ChevonIcon from "@Assets/icons/chevron.svg";
type IProps = {};
type IState = {
@ -17,7 +18,7 @@ type IState = {
isNewClientSelected: boolean;
hasNewClientSelected: boolean;
};
export default class AddClientToFolder extends BasePage<IProps, IState>{
export default class AddClientToFolder extends BasePage<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
@ -41,10 +42,16 @@ export default class AddClientToFolder extends BasePage<IProps, IState>{
return (
<DefaultNotaryDashboard title={"Ajouter client(s)"} onSelectedFolder={this.onSelectedFolder}>
<div className={classes["root"]}>
<Button icon={ChevonIcon} variant={EButtonVariant.LINE}>
Retour
</Button>
<Typography typo={ITypo.H1Bis}>Associer un ou plusieurs client(s)</Typography>
<Form>
<div className={classes["radiobox-container"]}>
<RadioBox name="client" onChange={this.onExistingClientSelected} defaultChecked={this.state.isExistingClientSelected}>
<RadioBox
name="client"
onChange={this.onExistingClientSelected}
defaultChecked={this.state.isExistingClientSelected}>
<Typography typo={ITypo.P_ERR_18}>Client existant</Typography>
</RadioBox>
<RadioBox name="client" onChange={this.onNewClientSelected} defaultChecked={this.state.isNewClientSelected}>
@ -52,26 +59,30 @@ export default class AddClientToFolder extends BasePage<IProps, IState>{
</RadioBox>
</div>
{this.state.isExistingClientSelected && <div className={classes["existing-client"]}>
<MultiSelect options={selectOptions} placeholder="Client" onChange={this.onMutiSelectChange} />
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button disabled={!this.state.hasNewClientSelected ? true : false} type="submit">Associer au dossier</Button>
{this.state.isExistingClientSelected && (
<div className={classes["existing-client"]}>
<MultiSelect options={selectOptions} placeholder="Client" onChange={this.onMutiSelectChange} />
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button disabled={!this.state.hasNewClientSelected ? true : false} type="submit">
Associer au dossier
</Button>
</div>
</div>
</div>
}
)}
{this.state.isNewClientSelected && <div className={classes["new-client"]}>
<InputField name="input field" fakeplaceholder="Nom" />
<InputField name="input field" fakeplaceholder="Prénom" />
<InputField name="input field" fakeplaceholder="E-mail" isEmail />
<InputField name="input field" fakeplaceholder="Numéro de téléphone" numbersOnly maxLength={10} />
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button type="submit">Associer au dossier</Button>
{this.state.isNewClientSelected && (
<div className={classes["new-client"]}>
<InputField name="input field" fakeplaceholder="Nom" />
<InputField name="input field" fakeplaceholder="Prénom" />
<InputField name="input field" fakeplaceholder="E-mail" isEmail />
<InputField name="input field" fakeplaceholder="Numéro de téléphone" numbersOnly maxLength={10} />
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button type="submit">Associer au dossier</Button>
</div>
</div>
</div>}
)}
</Form>
</div>
</DefaultNotaryDashboard>

View File

@ -12,7 +12,7 @@
display: inline-flex;
}
.folder-conatainer{
width: 389px ;
.folder-conatainer {
width: 389px;
}
}

View File

@ -1,243 +1,242 @@
import {
Address,
Office,
DeedType,
Deed,
OfficeFolder,
Contact,
Customer,
DocumentType,
Document,
OfficeFolderHasCustomer,
Address,
Office,
DeedType,
Deed,
OfficeFolder,
Contact,
Customer,
DocumentType,
Document,
OfficeFolderHasCustomer,
} from "le-coffre-resources/dist/Notary";
import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer";
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
export const address: Address = {
uid: "a&2azedzaa3",
address: "123",
city: "France",
zip_code: 78140,
created_at: new Date(),
updated_at: new Date(),
uid: "a&2azedzaa3",
address: "123",
city: "France",
zip_code: 78140,
created_at: new Date(),
updated_at: new Date(),
};
export const office: Office = {
uid: "111zdazaefez213",
idNot: "12EE12",
name: "Office 1",
crpcen: "AZezdz",
address: address,
created_at: new Date(),
updated_at: new Date(),
office_status: "ACTIVATED",
uid: "111zdazaefez213",
idNot: "12EE12",
name: "Office 1",
crpcen: "AZezdz",
address: address,
created_at: new Date(),
updated_at: new Date(),
office_status: "ACTIVATED",
};
export const deedType: DeedType = {
uid: "123azefezgzeg312",
name: "Acte mariage",
description: "dzsdaf",
archived_at: new Date(),
office: office,
created_at: new Date(),
updated_at: new Date(),
uid: "123azefezgzeg312",
name: "Acte mariage",
description: "dzsdaf",
archived_at: new Date(),
office: office,
created_at: new Date(),
updated_at: new Date(),
};
export const deed: Deed = {
uid: "zegefzeferg",
deed_type: deedType,
created_at: new Date(),
updated_at: new Date(),
uid: "zegefzeferg",
deed_type: deedType,
created_at: new Date(),
updated_at: new Date(),
};
export const contact: Contact = {
uid: "g('yeh(grgrezg",
first_name: "John",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
uid: "g('yeh(grgrezg",
first_name: "John",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
};
export const contact2: Contact = {
uid: "g('yeh(grgrezg",
first_name: "Customer2",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
uid: "g('yeh(grgrezg",
first_name: "Customer2",
last_name: "Doe",
email: "johnDoe@gmail.com",
address: address,
created_at: new Date(),
updated_at: new Date(),
cell_phone_number: "0132249865",
phone_number: "0132249865",
civility: "MALE",
};
export const docType: DocumentType = {
name: "Acte de naissance",
uid: "fezezfazegezrgrezg",
created_at: new Date(),
updated_at: new Date(),
public_description: "Acte de naissance public description",
private_description: "Acte de naissance private description",
archived_at: new Date(),
name: "Acte de naissance",
uid: "fezezfazegezrgrezg",
created_at: new Date(),
updated_at: new Date(),
public_description: "Acte de naissance public description",
private_description: "Acte de naissance private description",
archived_at: new Date(),
};
export const customer: Customer = {
uid: "erhtgerfzeare",
contact: contact,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
uid: "erhtgerfzeare",
contact: contact,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
};
export const folder: OfficeFolder = {
uid: "zfaefergregrezterf",
folder_number: "12331",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
uid: "zfaefergregrezterf",
folder_number: "12331",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
};
export const document: Document = {
uid: "fzeafergreztyzgrf",
depositor: customer,
document_status: "ASKED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
uid: "fzeafergreztyzgrf",
depositor: customer,
document_status: "ASKED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const documentPending: Document = {
uid: "fzefeazdagrtetrury",
depositor: customer,
document_status: "PENDING",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
uid: "fzefeazdagrtetrury",
depositor: customer,
document_status: "PENDING",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const documentDeposited: Document = {
uid: "uè§u§htfgrthytrgr",
depositor: customer,
document_status: "VALIDATED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
uid: "uè§u§htfgrthytrgr",
depositor: customer,
document_status: "VALIDATED",
folder: folder,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const customer2: Customer = {
uid: "yregrgetergrt",
contact: contact2,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
documents: [document, documentPending, documentDeposited, ],
uid: "yregrgetergrt",
contact: contact2,
created_at: new Date(),
updated_at: new Date(),
status: ECustomerStatus.VALIDATED,
documents: [document, documentPending, documentDeposited],
};
export const folderWithPendingDocument: OfficeFolder = {
uid: "ferzferzfezeefzdd",
folder_number: "00001",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document, documentPending, documentDeposited],
uid: "ferzferzfezeefzdd",
folder_number: "00001",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document, documentPending, documentDeposited],
};
export const folderWithPendingDocument1: OfficeFolder = {
uid: "gtrtyutyhretgytu",
folder_number: "00002",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [documentDeposited],
uid: "gtrtyutyhretgytu",
folder_number: "00002",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [documentDeposited],
};
export const folderWithPendingDocument2: OfficeFolder = {
uid: "adzefzefsfrefzrtgtr",
folder_number: "00003",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document],
uid: "adzefzefsfrefzrtgtr",
folder_number: "00003",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document],
};
export const officeFolderHasCustomer1: OfficeFolderHasCustomer = {
uid: "ferzfergrzeyerezrz",
customer: customer,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
uid: "ferzfergrzeyerezrz",
customer: customer,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
};
export const officeFolderHasCustomer2: OfficeFolderHasCustomer = {
uid: "tezrfzdfgrggeerry",
customer: customer2,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
uid: "tezrfzdfgrggeerry",
customer: customer2,
office_folder: folderWithPendingDocument,
created_at: new Date(),
updated_at: new Date(),
};
export const document8: Document = {
uid: "eztreggrgbyunjukhg",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
uid: "eztreggrgbyunjukhg",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const folderWithPendingDocument3: OfficeFolder = {
uid: "mkovrijvrezviev",
folder_number: "00014",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document, documentDeposited, documentPending],
office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2],
uid: "mkovrijvrezviev",
folder_number: "00014",
name: "Mon dossier",
status: EFolderStatus.ARCHIVED,
deed: deed,
office: office,
created_at: new Date(),
updated_at: new Date(),
description: "Description",
archived_description: "Archived description",
documents: [document, documentDeposited, documentPending],
office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2],
};
export const document2: Document = {
uid: "mejfihruehfoire",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument3,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
uid: "mejfihruehfoire",
depositor: customer,
document_status: "ASKED",
folder: folderWithPendingDocument3,
document_type: docType,
updated_at: new Date(),
created_at: new Date(),
};
export const folders: OfficeFolder[] = [
folderWithPendingDocument,
folderWithPendingDocument1,
folderWithPendingDocument2,
folderWithPendingDocument3,
folderWithPendingDocument,
folderWithPendingDocument1,
folderWithPendingDocument2,
folderWithPendingDocument3,
];

View File

@ -13,7 +13,7 @@ import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField"
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
import "reflect-metadata";
import FolderContainer from "@Front/Components/DesignSystem/FolderContainer";
import { customer2, document, documentDeposited, documentPending, folder, folderWithPendingDocument, folders } from "./dummyData"
import { customer2, document, documentDeposited, documentPending, folder, folderWithPendingDocument, folders } from "./dummyData";
import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary";
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
import UserFolder from "@Front/Components/DesignSystem/UserFolder";
@ -28,7 +28,6 @@ type IState = {
type IProps = {};
export default class DesignSystem extends BasePage<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
@ -39,18 +38,15 @@ export default class DesignSystem extends BasePage<IProps, IState> {
this.onSelectedOption = this.onSelectedOption.bind(this);
}
public override render(): JSX.Element {
const selectOptions: IOption[] = [
{ value: "1", label: "Divorce" },
{ value: "2", label: "Succession" },
{ value: "3", label: "Vente immobilière" },
]
];
return (
<DefaultTemplate title={"HomePage"}>
<div className={classes["root"]}>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H1}>Website design System</Typography>
@ -174,7 +170,6 @@ export default class DesignSystem extends BasePage<IProps, IState> {
</div>
</div>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.P_16}>Folder with document waiting for being validate</Typography>
<div className={classes["folder-conatainer"]}>
<FolderContainer folder={folderWithPendingDocument} />
@ -188,7 +183,12 @@ export default class DesignSystem extends BasePage<IProps, IState> {
</div>
<div className={classes["sub-section"]}>
<div className={classes["folder-conatainer"]}>
<Select options={selectOptions} onChange={this.onSelectedOption} placeholder={"Type dacte"} selectedOption={this.state.selectedOption} />
<Select
options={selectOptions}
onChange={this.onSelectedOption}
placeholder={"Type dacte"}
selectedOption={this.state.selectedOption}
/>
</div>
</div>
</div>
@ -236,7 +236,6 @@ export default class DesignSystem extends BasePage<IProps, IState> {
</div>
</div>
<div className={classes["section"]}>
<div className={classes["sub-section"]}>
<Typography typo={ITypo.H3}>Document SearchBar</Typography>
@ -254,8 +253,6 @@ export default class DesignSystem extends BasePage<IProps, IState> {
<FolderList folders={folders} />
</div>
</div>
</div>
</DefaultTemplate>
);

View File

@ -1,72 +1,72 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
.no-folder-selected {
width: 100%;
.no-folder-selected {
width: 100%;
.choose-a-folder {
margin-top: 96px;
text-align: center;
}
}
.choose-a-folder {
margin-top: 96px;
text-align: center;
}
}
.folder-informations {
width: 100%;
min-height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
flex-grow: 1;
.folder-informations {
width: 100%;
min-height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
flex-grow: 1;
.folder-header {
width: 100%;
.folder-header {
width: 100%;
.header {
margin-bottom: 32px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
}
.header {
margin-bottom: 32px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
}
.second-box {
margin-top: 24px;
margin-bottom: 32px;
}
.second-box {
margin-top: 24px;
margin-bottom: 32px;
}
.progress-bar {
margin-bottom: 32px;
}
.progress-bar {
margin-bottom: 32px;
}
.button-container {
width: 100%;
text-align: center;
:first-child {
margin-right: 12px;
}
> * {
margin: auto;
}
@media (max-width: $screen-m) {
:first-child {
margin-right: 0;
margin-bottom: 12px;
}
> * {
width: 100%;
}
}
}
.modal-title{
margin-bottom: 24px;
}
}
}
.button-container {
width: 100%;
text-align: center;
:first-child {
margin-right: 12px;
}
> * {
margin: auto;
}
@media (max-width: $screen-m) {
:first-child {
margin-right: 0;
margin-bottom: 12px;
}
> * {
width: 100%;
}
}
}
.modal-title {
margin-bottom: 24px;
}
}
}

View File

@ -15,7 +15,7 @@ type IState = {
selectedFolder: IDashBoardFolder | null;
isArchivedModalOpen: boolean;
};
export default class Folder extends BasePage<IProps, IState>{
export default class Folder extends BasePage<IProps, IState> {
public constructor(props: IProps) {
super(props);
this.state = {
@ -70,12 +70,14 @@ export default class Folder extends BasePage<IProps, IState>{
</Confirm>
</div>
: */}
<div className={classes["no-folder-selected"]}>
<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
<div className={classes["choose-a-folder"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>Veuillez sélectionner un dossier.</Typography>
</div>
<div className={classes["no-folder-selected"]}>
<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
<div className={classes["choose-a-folder"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Veuillez sélectionner un dossier.
</Typography>
</div>
</div>
</div>
</DefaultNotaryDashboard>
);

View File

@ -1,21 +1,20 @@
@import "@Themes/constants.scss";
.root {
width: 100%;
padding-bottom: 32px;
.no-client{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 72px;
.title{
margin-bottom: 16px;
}
}
.client{
display: grid;
gap: 32px;
}
width: 100%;
padding-bottom: 32px;
.no-client {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 72px;
.title {
margin-bottom: 16px;
}
}
.client {
display: grid;
gap: 32px;
}
}

View File

@ -14,29 +14,36 @@ type IState = {};
export default class ClientSection extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return <div className={classes["root"]}>
{this.doesFolderHaveCustomer() ?
<div className={classes["client"]}>
{this.renderCustomerFolders()}
</div>
:
<div className={classes["no-client"]}>
<div className={classes["title"]}>
<Typography typo={ITypo.P_18}>Aucun client nest associé au dossier.</Typography>
return (
<div className={classes["root"]}>
{this.doesFolderHaveCustomer() ? (
<div className={classes["client"]}>{this.renderCustomerFolders()}</div>
) : (
<div className={classes["no-client"]}>
<div className={classes["title"]}>
<Typography typo={ITypo.P_18}>Aucun client nest associé au dossier.</Typography>
</div>
<Link href={"/dossier/".concat(this.props.folder.uid).concat("/ajouter-client")}>
<Button variant={EButtonVariant.LINE} icon={PlusIcon}>
Ajouter un client
</Button>
</Link>
</div>
<Link href={"/dossier/".concat(this.props.folder.uid).concat("/ajouter-client")}>
<Button variant={EButtonVariant.LINE} icon={PlusIcon}>Ajouter un client</Button>
</Link>
</div>}
</div>;
)}
</div>
);
}
private renderCustomerFolders() {
const output = this.props.folder.office_folder_has_customers?.map((folderHasCustomer, key) => {
if (!folderHasCustomer.customer) return null;
// TODO : Les documents ASKED fonctionne mais les autres documents ne doivcent etre seulement ceux qui correspondent au folder
return <div className={classes["user-folder"]} key={folderHasCustomer.customer.uid}><UserFolder folder={this.props.folder} customer={folderHasCustomer.customer} /></div>;
})
return (
<div className={classes["user-folder"]} key={folderHasCustomer.customer.uid}>
<UserFolder folder={this.props.folder} customer={folderHasCustomer.customer} />
</div>
);
});
return output ?? null;
}

View File

@ -1,72 +1,72 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
.no-folder-selected {
width: 100%;
.no-folder-selected {
width: 100%;
.choose-a-folder {
margin-top: 96px;
text-align: center;
}
}
.choose-a-folder {
margin-top: 96px;
text-align: center;
}
}
.folder-informations {
width: 100%;
min-height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
flex-grow: 1;
.folder-informations {
width: 100%;
min-height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
flex-grow: 1;
.folder-header {
width: 100%;
.folder-header {
width: 100%;
.header {
margin-bottom: 32px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
}
.header {
margin-bottom: 32px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
}
.second-box {
margin-top: 24px;
margin-bottom: 32px;
}
.second-box {
margin-top: 24px;
margin-bottom: 32px;
}
.progress-bar {
margin-bottom: 32px;
}
.progress-bar {
margin-bottom: 32px;
}
.button-container {
width: 100%;
text-align: center;
:first-child {
margin-right: 12px;
}
> * {
margin: auto;
}
@media (max-width: $screen-m) {
:first-child {
margin-right: 0;
margin-bottom: 12px;
}
> * {
width: 100%;
}
}
}
.modal-title{
margin-bottom: 24px;
}
}
}
.button-container {
width: 100%;
text-align: center;
:first-child {
margin-right: 12px;
}
> * {
margin: auto;
}
@media (max-width: $screen-m) {
:first-child {
margin-right: 0;
margin-bottom: 12px;
}
> * {
width: 100%;
}
}
}
.modal-title {
margin-bottom: 24px;
}
}
}

View File

@ -18,7 +18,7 @@ type IState = {
selectedFolder: IDashBoardFolder | null;
isArchivedModalOpen: boolean;
};
class FolderInformationClass extends BasePage<IPropsClass, IState>{
class FolderInformationClass extends BasePage<IPropsClass, IState> {
public constructor(props: IPropsClass) {
super(props);
this.state = {
@ -35,13 +35,14 @@ class FolderInformationClass extends BasePage<IPropsClass, IState>{
return (
<DefaultNotaryDashboard title={"Dossier"} onSelectedFolder={this.onSelectedFolder}>
<div className={classes["root"]}>
{this.state.selectedFolder
?
{this.state.selectedFolder ? (
<div className={classes["folder-informations"]}>
<div className={classes["folder-header"]}>
<div className={classes["header"]}>
<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
<Button variant={EButtonVariant.LINE} icon={ChevronIcon}>Modifier les collaborateurs</Button>
<Button variant={EButtonVariant.LINE} icon={ChevronIcon}>
Modifier les collaborateurs
</Button>
</div>
<FolderBoxInformation folder={this.state.selectedFolder} />
<div className={classes["second-box"]}>
@ -56,7 +57,9 @@ class FolderInformationClass extends BasePage<IPropsClass, IState>{
{!this.doesFolderHaveCustomer() && <ClientSection folder={this.state.selectedFolder} />}
<div className={classes["button-container"]}>
<Button variant={EButtonVariant.GHOST} onClick={this.openArchivedModal}>Archiver le dossier</Button>
<Button variant={EButtonVariant.GHOST} onClick={this.openArchivedModal}>
Archiver le dossier
</Button>
<Button variant={EButtonVariant.SECONDARY}>Supprimer le dossier</Button>
</div>
<Confirm
@ -72,13 +75,16 @@ class FolderInformationClass extends BasePage<IPropsClass, IState>{
<InputField name="input field" fakeplaceholder="Description" textarea />
</Confirm>
</div>
:
) : (
<div className={classes["no-folder-selected"]}>
<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
<div className={classes["choose-a-folder"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>Veuillez sélectionner un dossier.</Typography>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Veuillez sélectionner un dossier.
</Typography>
</div>
</div>}
</div>
)}
</div>
</DefaultNotaryDashboard>
);

View File

@ -1,16 +1,16 @@
.root {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.title {
margin: 32px 0;
text-align: center;
}
.title {
margin: 32px 0;
text-align: center;
}
.forget-password {
margin-top: 32px;
margin-bottom: 8px;
}
}
.forget-password {
margin-top: 32px;
margin-bottom: 8px;
}
}

View File

@ -9,41 +9,31 @@ import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoub
import { FrontendVariables } from "@Front/Config/VariablesFront";
export default class LoginClass extends BasePage {
public override render(): JSX.Element {
return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}>
<div className={classes["root"]}>
<Image alt="coffre" src={CoffreIcon} />
<Typography typo={ITypo.H1}>
<div className={classes["title"]}>
Connexion espace professionnel
</div>
</Typography>
<Button onClick={this.redirectUserOnConnection}>
Sidentifier avec ID.not
</Button>
<Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>
Vous narrivez pas à vous connecter ?
</div>
</Typography>
<Button variant={EButtonVariant.LINE}>
Contacter ladministrateur
</Button>
</div>
</DefaultDoubleSidePage>
);
}
public override render(): JSX.Element {
return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}>
<div className={classes["root"]}>
<Image alt="coffre" src={CoffreIcon} />
<Typography typo={ITypo.H1}>
<div className={classes["title"]}>Connexion espace professionnel</div>
</Typography>
<Button onClick={this.redirectUserOnConnection}>Sidentifier avec ID.not</Button>
<Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous narrivez pas à vous connecter ?</div>
</Typography>
<Button variant={EButtonVariant.LINE}>Contacter ladministrateur</Button>
</div>
</DefaultDoubleSidePage>
);
}
private redirectUserOnConnection() {
const variables = FrontendVariables.getInstance();
const baseFronturl =
variables.BACK_API_PROTOCOL +
variables.FRONT_APP_HOST +
(variables.FRONT_APP_PORT ? ":" + variables.FRONT_APP_PORT : "");
const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT;
const clientId = variables.IDNOT_CLIENT_ID;
const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`;
window.location.assign(url);
}
private redirectUserOnConnection() {
const variables = FrontendVariables.getInstance();
const baseFronturl =
variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST + (variables.FRONT_APP_PORT ? ":" + variables.FRONT_APP_PORT : "");
const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT;
const clientId = variables.IDNOT_CLIENT_ID;
const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`;
window.location.assign(url);
}
}

View File

@ -1,16 +1,16 @@
.root {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.title {
margin: 32px 0;
text-align: center;
}
.title {
margin: 32px 0;
text-align: center;
}
.forget-password {
margin-top: 32px;
margin-bottom: 8px;
}
}
.forget-password {
margin-top: 32px;
margin-bottom: 8px;
}
}

View File

@ -14,7 +14,7 @@ import Auth from "@Front/Api/Auth/IdNot";
import Folder from "../Folder";
import LoginClass from "../Login";
type IPropsClass = {};
type IPropsClass = {};
// type IStateClass = {};
@ -76,15 +76,15 @@ export default function LoginCallBack(props: IPropsClass) {
const { code } = router.query;
if (code) {
const getIdNotJwt = async () => {
try {
const authService = Auth.getInstance();
await authService.getIdnotJwt(code);
} catch (error) {
console.error(error);
}
try {
const authService = Auth.getInstance();
await authService.getIdnotJwt(code);
} catch (error) {
console.error(error);
}
};
getIdNotJwt();
return <Folder {...props} />;
return <Folder {...props} />;
}
return <LoginClass {...props}/>
}
return <LoginClass {...props} />;
}

View File

@ -1,30 +1,30 @@
export class FrontendVariables {
private static instance: FrontendVariables;
private static instance: FrontendVariables;
public BACK_API_PROTOCOL!: string;
public BACK_API_PROTOCOL!: string;
public BACK_API_HOST!: string;
public BACK_API_HOST!: string;
public BACK_API_PORT!: string;
public BACK_API_PORT!: string;
public BACK_API_ROOT_URL!: string;
public BACK_API_ROOT_URL!: string;
public BACK_API_VERSION!: string;
public BACK_API_VERSION!: string;
public FRONT_APP_HOST!: string;
public FRONT_APP_HOST!: string;
public FRONT_APP_PORT!: string;
public FRONT_APP_PORT!: string;
public IDNOT_AUTHORIZE_ENDPOINT!: string;
public IDNOT_AUTHORIZE_ENDPOINT!: string;
public IDNOT_CLIENT_ID!: string;
public IDNOT_CLIENT_ID!: string;
private constructor() {}
private constructor() {}
public static getInstance(): FrontendVariables {
if (!this.instance) {
this.instance = new this();
}
return this.instance;
}
public static getInstance(): FrontendVariables {
if (!this.instance) {
this.instance = new this();
}
return this.instance;
}
}

View File

@ -1,3 +1,3 @@
{
"version": "v0.4.1"
"version": "v0.4.1"
}

View File

@ -12,18 +12,30 @@ export type NextPageWithLayout<TProps = Record<string, unknown>, TInitialProps =
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
} & {
backApiProtocol: string,
backApiHost: string,
backApiPort: string,
backApiRootUrl: string,
backApiVersion: string,
frontAppHost: string,
frontAppPort: string,
backApiProtocol: string;
backApiHost: string;
backApiPort: string;
backApiRootUrl: string;
backApiVersion: string;
frontAppHost: string;
frontAppPort: string;
idNotAuthorizeEndpoint: string;
idNotClientId: string;
};
const MyApp = (({ Component, pageProps, backApiProtocol, backApiHost, backApiPort, backApiRootUrl, backApiVersion, frontAppHost, frontAppPort, idNotAuthorizeEndpoint, idNotClientId }: AppPropsWithLayout) => {
const MyApp = (({
Component,
pageProps,
backApiProtocol,
backApiHost,
backApiPort,
backApiRootUrl,
backApiVersion,
frontAppHost,
frontAppPort,
idNotAuthorizeEndpoint,
idNotClientId,
}: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => <DefaultLayout children={page}></DefaultLayout>);
FrontendVariables.getInstance().BACK_API_PROTOCOL = backApiProtocol;
@ -36,7 +48,6 @@ const MyApp = (({ Component, pageProps, backApiProtocol, backApiHost, backApiPor
FrontendVariables.getInstance().IDNOT_AUTHORIZE_ENDPOINT = idNotAuthorizeEndpoint;
FrontendVariables.getInstance().IDNOT_CLIENT_ID = idNotClientId;
return getLayout(<Component {...pageProps} />);
}) as AppType;
@ -52,6 +63,6 @@ MyApp.getInitialProps = async () => {
idNotAuthorizeEndpoint: process.env["IDNOT_AUTHORIZE_ENDPOINT"],
idNotClientId: process.env["IDNOT_CLIENT_ID"],
};
}
};
export default MyApp;

View File

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