Merge branch 'dev' of https://github.com/smart-chain-fr/leCoffre-front into dev
This commit is contained in:
commit
be23295fe7
@ -13,6 +13,16 @@ const nextConfig = {
|
|||||||
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT,
|
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT,
|
||||||
NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID,
|
NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID,
|
||||||
},
|
},
|
||||||
|
webpack: config => {
|
||||||
|
config.node = {
|
||||||
|
fs: 'empty',
|
||||||
|
child_process: 'empty',
|
||||||
|
net: 'empty',
|
||||||
|
dns: 'empty',
|
||||||
|
tls: 'empty',
|
||||||
|
};
|
||||||
|
return config;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = nextConfig;
|
module.exports = nextConfig;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"eslint": "8.36.0",
|
"eslint": "8.36.0",
|
||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.2.4",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.47",
|
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.52",
|
||||||
"next": "13.2.4",
|
"next": "13.2.4",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
@ -119,17 +119,18 @@ export default abstract class BaseApiService {
|
|||||||
responseJson = await response.json();
|
responseJson = await response.json();
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
responseJson = null;
|
responseJson = null;
|
||||||
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return Promise.reject(response);
|
return Promise.reject(responseJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseJson as T;
|
return responseJson as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onError(error: unknown) {
|
protected onError(error: unknown) {
|
||||||
console.error(error);
|
//console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import User, { Customer, DeedType, Office, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
import { type OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
import BaseSuperAdmin from "../BaseSuperAdmin";
|
import BaseSuperAdmin from "../BaseSuperAdmin";
|
||||||
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
|
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||||
|
|
||||||
// TODO Type get query params -> Where + inclue + orderby
|
// TODO Type get query params -> Where + inclue + orderby
|
||||||
export interface IGetFoldersParams {
|
export interface IGetFoldersParams {
|
||||||
@ -11,36 +12,6 @@ export interface IGetFoldersParams {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPostFoldersParams {
|
|
||||||
folder_number: OfficeFolder["folder_number"];
|
|
||||||
name: OfficeFolder["name"];
|
|
||||||
description: OfficeFolder["description"];
|
|
||||||
deed: {
|
|
||||||
deed_type: {
|
|
||||||
uid: DeedType["uid"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
office: {
|
|
||||||
uid: Office["uid"];
|
|
||||||
};
|
|
||||||
office_folder_has_stakeholder: {
|
|
||||||
user_stakeholder: {
|
|
||||||
uid: User["uid"];
|
|
||||||
};
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IPutFoldersParams = {
|
|
||||||
uid?: OfficeFolder["uid"];
|
|
||||||
folder_number?: OfficeFolder["folder_number"];
|
|
||||||
name?: OfficeFolder["name"];
|
|
||||||
description?: OfficeFolder["description"];
|
|
||||||
archived_description?: OfficeFolder["archived_description"];
|
|
||||||
status?: OfficeFolder["status"];
|
|
||||||
office_folder_has_stakeholder?: OfficeFolder["office_folder_has_stakeholder"];
|
|
||||||
office_folder_has_customers?: { customer: { uid: Customer["uid"] } }[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class Folders extends BaseSuperAdmin {
|
export default class Folders extends BaseSuperAdmin {
|
||||||
private static instance: Folders;
|
private static instance: Folders;
|
||||||
private readonly baseURl = this.namespaceUrl.concat("/folders");
|
private readonly baseURl = this.namespaceUrl.concat("/folders");
|
||||||
@ -88,10 +59,10 @@ export default class Folders extends BaseSuperAdmin {
|
|||||||
/**
|
/**
|
||||||
* @description : Create a folder
|
* @description : Create a folder
|
||||||
*/
|
*/
|
||||||
public async post(body: any): Promise<OfficeFolder> {
|
public async post(officeFolder: Partial<OfficeFolder>): Promise<OfficeFolder> {
|
||||||
const url = new URL(this.baseURl);
|
const url = new URL(this.baseURl);
|
||||||
try {
|
try {
|
||||||
return await this.postRequest<OfficeFolder>(url, body);
|
return await this.postRequest(url, officeFolder);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.onError(err);
|
this.onError(err);
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
@ -101,10 +72,10 @@ export default class Folders extends BaseSuperAdmin {
|
|||||||
/**
|
/**
|
||||||
* @description : Update the folder description
|
* @description : Update the folder description
|
||||||
*/
|
*/
|
||||||
public async put(uid: string, body: IPutFoldersParams): Promise<OfficeFolder> {
|
public async put(uid: string, body: Partial<OfficeFolder>): Promise<OfficeFolder> {
|
||||||
const url = new URL(this.baseURl.concat(`/${uid}`));
|
const url = new URL(this.baseURl.concat(`/${uid}`));
|
||||||
try {
|
try {
|
||||||
return await this.putRequest<OfficeFolder>(url, body);
|
return await this.putRequest(url, body);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.onError(err);
|
this.onError(err);
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
@ -119,14 +90,14 @@ export default class Folders extends BaseSuperAdmin {
|
|||||||
const targetedFolder = await this.getByUid(uid);
|
const targetedFolder = await this.getByUid(uid);
|
||||||
if (targetedFolder.office_folder_has_customers) return Promise.reject(`The folder ${uid} contains customers`);
|
if (targetedFolder.office_folder_has_customers) return Promise.reject(`The folder ${uid} contains customers`);
|
||||||
try {
|
try {
|
||||||
return await this.deleteRequest<OfficeFolder>(url);
|
return await this.deleteRequest(url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.onError(err);
|
this.onError(err);
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async archive(uid: string, body: IPutFoldersParams): Promise<OfficeFolder> {
|
public async archive(uid: string, body: Partial<OfficeFolder>): Promise<OfficeFolder> {
|
||||||
body.status = EFolderStatus.ARCHIVED;
|
body.status = EFolderStatus.ARCHIVED;
|
||||||
try {
|
try {
|
||||||
return await this.put(uid, body);
|
return await this.put(uid, body);
|
||||||
@ -136,7 +107,7 @@ export default class Folders extends BaseSuperAdmin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async restore(uid: string, body: IPutFoldersParams): Promise<OfficeFolder> {
|
public async restore(uid: string, body: Partial<OfficeFolder>): Promise<OfficeFolder> {
|
||||||
body.status = EFolderStatus.LIVE;
|
body.status = EFolderStatus.LIVE;
|
||||||
try {
|
try {
|
||||||
return await this.put(uid, body);
|
return await this.put(uid, body);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { IOption } from "../Select";
|
import { IOption } from "../Form/SelectField";
|
||||||
import Tooltip from "../ToolTip";
|
import Tooltip from "../ToolTip";
|
||||||
import Typography, { ITypo, ITypoColor } from "../Typography";
|
import Typography, { ITypo, ITypoColor } from "../Typography";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
@ -14,9 +14,9 @@ import Files from "@Front/Api/LeCoffreApi/SuperAdmin/Files/Files";
|
|||||||
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import Confirm from "../Modal/Confirm";
|
import Confirm from "../Modal/Confirm";
|
||||||
import InputField from "../Form/Elements/InputField";
|
|
||||||
import GreenCheckIcon from "@Assets/Icons/green-check.svg";
|
import GreenCheckIcon from "@Assets/Icons/green-check.svg";
|
||||||
import Loader from "../Loader";
|
import Loader from "../Loader";
|
||||||
|
import TextAreaField from "../Form/TextareaField";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
defaultFiles?: FileCustomer[];
|
defaultFiles?: FileCustomer[];
|
||||||
@ -69,7 +69,6 @@ export default class DepositDocument extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override render(): JSX.Element {
|
public override render(): JSX.Element {
|
||||||
console.log("Loading :", this.state.loading);
|
|
||||||
return (
|
return (
|
||||||
<div className={classes["container"]}>
|
<div className={classes["container"]}>
|
||||||
<div
|
<div
|
||||||
@ -172,7 +171,7 @@ export default class DepositDocument extends React.Component<IProps, IState> {
|
|||||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||||
Votre document a été refusé pour la raison suivante :
|
Votre document a été refusé pour la raison suivante :
|
||||||
</Typography>
|
</Typography>
|
||||||
<InputField textarea fakeplaceholder={"Description"} defaultValue={this.state.refusedReason} readOnly />
|
<TextAreaField placeholder="Description" defaultValue={this.state.refusedReason} readonly />
|
||||||
</div>
|
</div>
|
||||||
</Confirm>
|
</Confirm>
|
||||||
</div>
|
</div>
|
||||||
|
111
src/front/Components/DesignSystem/Form/BaseField.tsx
Normal file
111
src/front/Components/DesignSystem/Form/BaseField.tsx
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { FormContext, IFormContext } from ".";
|
||||||
|
import { ValidationError } from "class-validator";
|
||||||
|
import Typography, { ITypo, ITypoColor } from "../Typography";
|
||||||
|
|
||||||
|
export type IProps = {
|
||||||
|
value?: string;
|
||||||
|
onChange?: (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => void;
|
||||||
|
name: string;
|
||||||
|
required?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
|
readonly?: boolean;
|
||||||
|
className?: string;
|
||||||
|
defaultValue?: string;
|
||||||
|
disableValidation?: boolean;
|
||||||
|
validationError?: ValidationError;
|
||||||
|
disabled?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
value: string;
|
||||||
|
validationError: ValidationError | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default abstract class BaseField<P extends IProps, S extends IState = IState> extends React.Component<P, S> {
|
||||||
|
public static override contextType = FormContext;
|
||||||
|
public override context: IFormContext | null = null;
|
||||||
|
public fieldRef: React.RefObject<any> = React.createRef();
|
||||||
|
|
||||||
|
static defaultProps: Partial<IProps> = {
|
||||||
|
disableValidation: false,
|
||||||
|
required: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props: P) {
|
||||||
|
super(props);
|
||||||
|
this.onChange = this.onChange.bind(this);
|
||||||
|
this.onFocus = this.onFocus.bind(this);
|
||||||
|
this.onBlur = this.onBlur.bind(this);
|
||||||
|
this.hasError = this.hasError.bind(this);
|
||||||
|
this.renderErrors = this.renderErrors.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidMount() {
|
||||||
|
this.context?.setField(this.props.name, this);
|
||||||
|
this.setState({
|
||||||
|
value: this.props.defaultValue ?? "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidUpdate(prevProps: IProps) {
|
||||||
|
if (this.props.value !== prevProps.value) {
|
||||||
|
this.setState({
|
||||||
|
value: this.props.value ?? "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.validationError !== prevProps.validationError) {
|
||||||
|
this.setState({
|
||||||
|
validationError: this.props.validationError ?? null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentWillUnmount() {
|
||||||
|
this.context?.unSetField(this.props.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getDefaultState(): IState {
|
||||||
|
return {
|
||||||
|
value: this.props.value ?? "",
|
||||||
|
validationError: this.props.validationError ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onFocus(event: React.FocusEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
|
this.context?.onFieldFocusChange(this.props.name, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onBlur(event: React.FocusEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
|
this.context?.onFieldFocusChange(this.props.name, this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onChange(event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
|
this.context?.onFieldChange(this.props.name, this);
|
||||||
|
this.setState({ value: event.currentTarget.value, validationError: null });
|
||||||
|
if (this.props.onChange) {
|
||||||
|
this.props.onChange(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected hasError(): boolean {
|
||||||
|
return this.state.validationError !== null;
|
||||||
|
// if(!this.context) return false;
|
||||||
|
// if(!this.context.hasOneFocusedInput() && this.state.validationError !== null) return true;
|
||||||
|
// return this.state.validationError !== null && this.context.isInputFocused(this.props.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected renderErrors(): JSX.Element[] | null {
|
||||||
|
if (!this.state.validationError || !this.state.validationError.constraints) return null;
|
||||||
|
let errors: JSX.Element[] = [];
|
||||||
|
Object.entries(this.state.validationError.constraints).forEach(([key, value]) => {
|
||||||
|
errors.push(
|
||||||
|
<Typography key={key} typo={ITypo.CAPTION_14} color={ITypoColor.RED_FLASH}>
|
||||||
|
{value}
|
||||||
|
</Typography>,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
@ -1,154 +0,0 @@
|
|||||||
import { ChangeEvent, Component, createRef } from "react";
|
|
||||||
|
|
||||||
import { FormContext, IFormContext } from "..";
|
|
||||||
// elements
|
|
||||||
import Validators, { IValidationTypes } from "../Validators/Validators";
|
|
||||||
|
|
||||||
export type IError = {
|
|
||||||
message: string;
|
|
||||||
validator: string;
|
|
||||||
value: string | number | readonly string[];
|
|
||||||
args: any[];
|
|
||||||
isErrored?: (hasError: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type INewBasefieldProps = {
|
|
||||||
onChange?: (event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) => void;
|
|
||||||
name: string;
|
|
||||||
regex?: RegExp;
|
|
||||||
onCancel?: () => void;
|
|
||||||
disableValidation?: boolean;
|
|
||||||
onErrors?: (errors: IError[]) => void;
|
|
||||||
fieldRef?: React.RefObject<any>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IProps = IValidationTypes & React.InputHTMLAttributes<HTMLInputElement> & INewBasefieldProps;
|
|
||||||
|
|
||||||
type IState = {
|
|
||||||
value?: string | number | readonly string[];
|
|
||||||
errors: IError[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default abstract class BaseField<P extends IProps> extends Component<P, IState> {
|
|
||||||
public static override contextType = FormContext;
|
|
||||||
public override context: IFormContext | null = null;
|
|
||||||
public fieldRef: React.RefObject<any> = createRef();
|
|
||||||
|
|
||||||
static defaultProps: Partial<IProps> = {
|
|
||||||
disableValidation: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: P) {
|
|
||||||
super(props);
|
|
||||||
this.onChange = this.onChange.bind(this);
|
|
||||||
this.validate = this.validate.bind(this);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
value: this.props.value ?? this.props.defaultValue ?? "",
|
|
||||||
errors: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentDidMount() {
|
|
||||||
this.context?.setField(this.props.name, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentDidUpdate(prevProps: P) {
|
|
||||||
if (prevProps.value !== this.props.value || prevProps.defaultValue !== this.props.defaultValue) {
|
|
||||||
this.setState({ value: this.props.value ?? this.props.defaultValue ?? "" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentWillUnmount() {
|
|
||||||
this.context?.unSetField(this.props.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async onBlur(event: React.FocusEvent<HTMLInputElement, Element>) {
|
|
||||||
// this.validate();
|
|
||||||
// if (this.props.onBlur) {
|
|
||||||
// this.props.onBlur(event);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
public async validate(isOnSubmit?: boolean) {
|
|
||||||
if (this.props.disableValidation) return;
|
|
||||||
if (this.props.readOnly) return;
|
|
||||||
|
|
||||||
const errorArray: IError[] = [];
|
|
||||||
const props: { [key: string]: any } = this.props;
|
|
||||||
const validators = Object.entries(Validators).filter(([key]) => props[key]);
|
|
||||||
|
|
||||||
const isValidable = isOnSubmit
|
|
||||||
? this.props.required || (this.state.value && this.state.value !== "")
|
|
||||||
: this.state.value && this.state.value !== "";
|
|
||||||
|
|
||||||
if (isValidable) {
|
|
||||||
const validations = await Promise.all(
|
|
||||||
validators.map(async ([key, validator]) => {
|
|
||||||
const validation = await (validator.validate as any)(this.state.value, ...(props[key].args ?? []));
|
|
||||||
if (props[key].isErrored) {
|
|
||||||
props[key].isErrored(!validation);
|
|
||||||
}
|
|
||||||
return [key, validator, validation];
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const unValidateds = validations.filter(([key, validator, validation]) => !validation);
|
|
||||||
const errors: IError[] = unValidateds.map(([key, unValidated]) => {
|
|
||||||
let message = unValidated.message;
|
|
||||||
if (typeof props[key] === "object" && props[key].message) message = props[key].message;
|
|
||||||
return { message, validator: key, value: this.state.value!, args: props[key].args ?? [] };
|
|
||||||
});
|
|
||||||
|
|
||||||
errorArray.push(...errors);
|
|
||||||
} else {
|
|
||||||
validators.forEach(async ([key]) => {
|
|
||||||
if (props[key].isErrored) {
|
|
||||||
props[key].isErrored(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({ errors: errorArray });
|
|
||||||
this.onErrors(errorArray);
|
|
||||||
return errorArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setErrors(errors: IError[]) {
|
|
||||||
this.setState({ ...this.state, errors });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* It is automatically called by the parent form when the user cancelled the
|
|
||||||
* form and all of its changes.
|
|
||||||
*
|
|
||||||
* Override the method for custom cancelling logic, or pass a custom onCancel
|
|
||||||
* callback.
|
|
||||||
*/
|
|
||||||
public cancel() {
|
|
||||||
if (this.props.onCancel) {
|
|
||||||
this.props.onCancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public onErrors(errors: IError[]) {
|
|
||||||
if (this.props.onErrors) {
|
|
||||||
this.props.onErrors(errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected onChange(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
|
||||||
if (this.props.regex) {
|
|
||||||
if (!this.props.regex.test(event.currentTarget.value)) {
|
|
||||||
event.currentTarget.value = event.currentTarget.value.substring(0, event.currentTarget.value.length - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.setState({ value: event.currentTarget.value }, () => {
|
|
||||||
this.validate();
|
|
||||||
this.context?.onFieldChange(this.props.name, this);
|
|
||||||
});
|
|
||||||
if (this.props.onChange) {
|
|
||||||
this.props.onChange(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
|
||||||
import { ReactNode } from "react";
|
|
||||||
|
|
||||||
import Validators from "../../Validators/Validators";
|
|
||||||
import BaseField, { IProps as IBaseFieldProps } from "../BaseField";
|
|
||||||
import classes from "./classes.module.scss";
|
|
||||||
|
|
||||||
export type IProps = IBaseFieldProps & {
|
|
||||||
fakeplaceholder: string;
|
|
||||||
textarea?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
// @ts-ignore TODO: typing error on IProps (validator class?? cf Massi 22/02/23)
|
|
||||||
export default class InputField extends BaseField<IProps> {
|
|
||||||
static override defaultProps: Partial<IBaseFieldProps> = {
|
|
||||||
...BaseField.defaultProps,
|
|
||||||
required: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
public override render(): ReactNode {
|
|
||||||
let pattern;
|
|
||||||
|
|
||||||
if (this.props.type === "number") {
|
|
||||||
pattern = "(^[0-9]*)(\\.{0,1})([0-9]*)$";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.pattern) {
|
|
||||||
pattern = this.props.pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.fieldRef) {
|
|
||||||
this.fieldRef = this.props.fieldRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we always need to control the input so we need to set the value as "" by default
|
|
||||||
const value = this.state.value ?? "";
|
|
||||||
|
|
||||||
if (this.props.textarea === true) {
|
|
||||||
return (
|
|
||||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
|
||||||
<div className={classes["root"]}>
|
|
||||||
<textarea
|
|
||||||
maxLength={this.props.maxLength}
|
|
||||||
name={this.props.name}
|
|
||||||
required={this.props.required}
|
|
||||||
ref={this.props.fieldRef}
|
|
||||||
rows={4}
|
|
||||||
data-value={value}
|
|
||||||
onChange={this.onChange}
|
|
||||||
data-has-validation-errors={this.state.errors.length > 0}
|
|
||||||
className={
|
|
||||||
this.props.className ? [classes["textarea"], classes[this.props.className]].join(" ") : classes["textarea"]
|
|
||||||
}
|
|
||||||
value={value}
|
|
||||||
readOnly={this.props.readOnly} />
|
|
||||||
<div className={classes["fake-placeholder"]}>
|
|
||||||
{this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
|
||||||
<div className={classes["root"]}>
|
|
||||||
<input
|
|
||||||
{...this.getHtmlAttributes()}
|
|
||||||
ref={this.props.fieldRef}
|
|
||||||
pattern={pattern}
|
|
||||||
onChange={this.onChange}
|
|
||||||
onBlur={this.onBlur}
|
|
||||||
data-value={value}
|
|
||||||
data-has-validation-errors={this.state.errors.length > 0}
|
|
||||||
className={
|
|
||||||
this.props.className ? [classes["input"], classes[this.props.className]].join(" ") : classes["input"]
|
|
||||||
}
|
|
||||||
value={value}
|
|
||||||
/>
|
|
||||||
<div className={classes["fake-placeholder"]}>
|
|
||||||
{this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Typography>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentDidMount() {
|
|
||||||
this.setState({
|
|
||||||
value: this.props.defaultValue ?? "",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// We filter the props we'll pass to the primitive input as they're useless for it
|
|
||||||
// It also avoids the console warning because of passing useless props to a primitive DOM element
|
|
||||||
private getHtmlAttributes() {
|
|
||||||
const htmlAttributes = { ...this.props };
|
|
||||||
|
|
||||||
delete htmlAttributes.disableValidation;
|
|
||||||
delete htmlAttributes.onErrors;
|
|
||||||
delete htmlAttributes.fieldRef;
|
|
||||||
delete htmlAttributes.className;
|
|
||||||
delete htmlAttributes.defaultValue;
|
|
||||||
|
|
||||||
for (const validator in Validators) {
|
|
||||||
delete (htmlAttributes as { [key: string]: any })[validator];
|
|
||||||
}
|
|
||||||
|
|
||||||
return htmlAttributes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,77 +0,0 @@
|
|||||||
import { ReactNode } from "react";
|
|
||||||
|
|
||||||
import Validators from "../Validators/Validators";
|
|
||||||
//import { IProps as IBaseFieldProps } from "../.";
|
|
||||||
import classes from "./classes.module.scss";
|
|
||||||
import BaseField, { IProps as IBaseFieldProps } from "../Elements/BaseField";
|
|
||||||
|
|
||||||
export type IProps = IBaseFieldProps & {
|
|
||||||
large?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class InputField extends BaseField<IProps> {
|
|
||||||
public override render(): ReactNode {
|
|
||||||
let pattern;
|
|
||||||
|
|
||||||
if (this.props.type === "number") {
|
|
||||||
pattern = "(^[0-9]*)(\\.{0,1})([0-9]*)$";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.pattern) {
|
|
||||||
pattern = this.props.pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.fieldRef) {
|
|
||||||
this.fieldRef = this.props.fieldRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we always need to control the input so we need to set the value as "" by default
|
|
||||||
const value = this.state.value ?? "";
|
|
||||||
|
|
||||||
if (this.props.large === true) {
|
|
||||||
return (
|
|
||||||
<textarea
|
|
||||||
maxLength={this.props.maxLength}
|
|
||||||
name={this.props.name}
|
|
||||||
required={this.props.required}
|
|
||||||
ref={this.props.fieldRef}
|
|
||||||
rows={4}
|
|
||||||
value={value}
|
|
||||||
onChange={this.onChange}
|
|
||||||
data-has-validation-errors={this.state.errors.length > 0}
|
|
||||||
className={this.props.className ? [classes["textarea"], classes[this.props.className]].join(" ") : classes["textarea"]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<input
|
|
||||||
{...this.getHtmlAttributes()}
|
|
||||||
ref={this.props.fieldRef}
|
|
||||||
pattern={pattern}
|
|
||||||
onChange={this.onChange}
|
|
||||||
value={value}
|
|
||||||
data-has-validation-errors={this.state.errors.length > 0}
|
|
||||||
className={this.props.className ? [classes["input"], classes[this.props.className]].join(" ") : classes["input"]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We filter the props we'll pass to the primitive input as they're useless for it
|
|
||||||
// It also avoids the console warning because of passing useless props to a primitive DOM element
|
|
||||||
private getHtmlAttributes() {
|
|
||||||
const htmlAttributes = { ...this.props };
|
|
||||||
|
|
||||||
delete htmlAttributes.disableValidation;
|
|
||||||
delete htmlAttributes.onErrors;
|
|
||||||
delete htmlAttributes.fieldRef;
|
|
||||||
delete htmlAttributes.className;
|
|
||||||
delete htmlAttributes.defaultValue;
|
|
||||||
|
|
||||||
for (const validator in Validators) {
|
|
||||||
delete (htmlAttributes as { [key: string]: any })[validator];
|
|
||||||
}
|
|
||||||
|
|
||||||
return htmlAttributes;
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,11 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid $grey-medium;
|
border: 1px solid var(--grey-medium);
|
||||||
|
|
||||||
|
&[data-errored="true"]{
|
||||||
|
border: 1px solid var(--red-flash);
|
||||||
|
}
|
||||||
|
|
||||||
&[data-disabled="true"]{
|
&[data-disabled="true"]{
|
||||||
.container-label{
|
.container-label{
|
188
src/front/Components/DesignSystem/Form/SelectField/index.tsx
Normal file
188
src/front/Components/DesignSystem/Form/SelectField/index.tsx
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||||
|
import WindowStore from "@Front/Stores/WindowStore";
|
||||||
|
import { ValidationError } from "class-validator";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import Image from "next/image";
|
||||||
|
import React, { FormEvent, ReactNode } from "react";
|
||||||
|
|
||||||
|
import Typography, { ITypo, ITypoColor } from "../../Typography";
|
||||||
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
selectedOption?: IOption;
|
||||||
|
onChange?: (selectedOption: IOption) => void;
|
||||||
|
options: IOption[];
|
||||||
|
hasBorderRightCollapsed?: boolean;
|
||||||
|
placeholder?: string;
|
||||||
|
className?: string;
|
||||||
|
name: string;
|
||||||
|
disabled: boolean;
|
||||||
|
errors?: ValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IOption = {
|
||||||
|
value: unknown;
|
||||||
|
label: string;
|
||||||
|
icon?: ReactNode;
|
||||||
|
description?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
isOpen: boolean;
|
||||||
|
listWidth: number;
|
||||||
|
listHeight: number;
|
||||||
|
selectedOption: IOption | null;
|
||||||
|
errors: ValidationError | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class SelectField extends React.Component<IProps, IState> {
|
||||||
|
private contentRef = React.createRef<HTMLUListElement>();
|
||||||
|
private rootRef = React.createRef<HTMLDivElement>();
|
||||||
|
private removeOnresize = () => {};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isOpen: false,
|
||||||
|
listHeight: 0,
|
||||||
|
listWidth: 0,
|
||||||
|
selectedOption: null,
|
||||||
|
errors: this.props.errors ?? null,
|
||||||
|
};
|
||||||
|
this.toggle = this.toggle.bind(this);
|
||||||
|
this.onSelect = this.onSelect.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override render(): JSX.Element {
|
||||||
|
const selectedOption = this.state.selectedOption ?? this.props.selectedOption;
|
||||||
|
return (
|
||||||
|
<div className={classes["container"]}>
|
||||||
|
<div
|
||||||
|
className={classNames(classes["root"], this.props.className)}
|
||||||
|
ref={this.rootRef}
|
||||||
|
data-disabled={this.props.disabled.toString()}
|
||||||
|
data-errored={(this.state.errors !== null).toString()}>
|
||||||
|
{selectedOption && <input type="text" defaultValue={selectedOption.value as string} name={this.props.name} hidden />}
|
||||||
|
<label
|
||||||
|
className={classNames(classes["container-label"])}
|
||||||
|
data-open={this.state.isOpen}
|
||||||
|
onClick={this.toggle}
|
||||||
|
data-border-right-collapsed={this.props.hasBorderRightCollapsed}>
|
||||||
|
<div className={classNames(classes["container-input"])}>
|
||||||
|
{selectedOption && (
|
||||||
|
<>
|
||||||
|
<span className={classNames(classes["icon"], classes["token-icon"])}>{selectedOption?.icon}</span>
|
||||||
|
<Typography typo={ITypo.P_18}>
|
||||||
|
<span className={classes["text"]}>{selectedOption?.label}</span>
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{!selectedOption && (
|
||||||
|
<div className={classes["placeholder"]} data-open={(selectedOption ? true : false).toString()}>
|
||||||
|
<Typography typo={ITypo.NAV_INPUT_16}>
|
||||||
|
<span className={classes["text"]}>{this.props.placeholder ?? ""}</span>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<Image className={classes["chevron-icon"]} data-open={this.state.isOpen} src={ChevronIcon} alt="chevron icon" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<ul
|
||||||
|
className={classes["container-ul"]}
|
||||||
|
data-open={this.state.isOpen}
|
||||||
|
ref={this.contentRef}
|
||||||
|
style={{
|
||||||
|
height: this.state.listHeight + "px",
|
||||||
|
}}>
|
||||||
|
{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>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{this.state.isOpen && <div className={classes["backdrop"]} onClick={this.toggle} />}
|
||||||
|
</div>
|
||||||
|
{this.state.errors !== null && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidUpdate(prevProps: IProps) {
|
||||||
|
if (this.props.errors !== prevProps.errors) {
|
||||||
|
this.setState({
|
||||||
|
errors: this.props.errors ?? null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props: IProps, state: IState) {
|
||||||
|
if (props.selectedOption?.value) {
|
||||||
|
return {
|
||||||
|
value: props.selectedOption?.value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidMount(): void {
|
||||||
|
this.onResize();
|
||||||
|
this.removeOnresize = WindowStore.getInstance().onResize(() => this.onResize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentWillUnmount() {
|
||||||
|
this.removeOnresize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onResize() {
|
||||||
|
let listHeight = 0;
|
||||||
|
let listWidth = 0;
|
||||||
|
listWidth = this.rootRef.current?.scrollWidth ?? 0;
|
||||||
|
if (this.state.listHeight) {
|
||||||
|
listHeight = this.contentRef.current?.scrollHeight ?? 0;
|
||||||
|
}
|
||||||
|
this.setState({ listHeight, listWidth });
|
||||||
|
}
|
||||||
|
|
||||||
|
private toggle(e: FormEvent) {
|
||||||
|
if (this.props.disabled) return;
|
||||||
|
e.preventDefault();
|
||||||
|
let listHeight = 0;
|
||||||
|
let listWidth = this.rootRef.current?.scrollWidth ?? 0;
|
||||||
|
|
||||||
|
if (!this.state.listHeight) {
|
||||||
|
listHeight = this.contentRef.current?.scrollHeight ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState((state) => {
|
||||||
|
return { isOpen: !state.isOpen, listHeight, listWidth };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onSelect(option: IOption, e: React.MouseEvent<HTMLLIElement, MouseEvent>) {
|
||||||
|
if (this.props.disabled) return;
|
||||||
|
this.props.onChange && this.props.onChange(option);
|
||||||
|
this.setState({
|
||||||
|
selectedOption: option,
|
||||||
|
});
|
||||||
|
this.toggle(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderErrors(): JSX.Element | null {
|
||||||
|
if (!this.state.errors) return null;
|
||||||
|
return (
|
||||||
|
<Typography typo={ITypo.CAPTION_14} color={ITypoColor.RED_FLASH}>
|
||||||
|
{this.props.placeholder} est requis
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -3,21 +3,6 @@
|
|||||||
.root {
|
.root {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: none;
|
|
||||||
height: auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-family: "Inter";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 22px;
|
|
||||||
|
|
||||||
&:read-only{
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -27,7 +12,7 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
border: 1px solid $grey-medium;
|
border: 1px solid var(--grey-medium);
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
@ -104,41 +89,14 @@
|
|||||||
transition: transform 0.3s ease-in-out;
|
transition: transform 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.textarea {
|
&[data-is-errored="true"] {
|
||||||
z-index: 1;
|
.input{
|
||||||
display: flex;
|
border: 1px solid var(--red-flash);
|
||||||
flex-direction: row;
|
~ .fake-placeholder{
|
||||||
align-items: center;
|
color: var(--red-flash);
|
||||||
padding: 24px;
|
}
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 70px;
|
|
||||||
border: 1px solid $grey-medium;
|
|
||||||
|
|
||||||
~ .fake-placeholder {
|
|
||||||
z-index: 2;
|
|
||||||
top: -12px;
|
|
||||||
margin-left: 8px;
|
|
||||||
padding: 0 16px;
|
|
||||||
pointer-events: none;
|
|
||||||
position: absolute;
|
|
||||||
background: $white;
|
|
||||||
transform: translateY(35px);
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
~ .fake-placeholder {
|
|
||||||
transform: translateY(0px);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
&:not([data-value=""]) {
|
|
||||||
~ .fake-placeholder {
|
|
||||||
transform: translateY(0px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
40
src/front/Components/DesignSystem/Form/TextField/index.tsx
Normal file
40
src/front/Components/DesignSystem/Form/TextField/index.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import React from "react";
|
||||||
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import BaseField, { IProps as IBaseFieldProps } from "../BaseField";
|
||||||
|
import classes from "./classes.module.scss";
|
||||||
|
import classnames from "classnames";
|
||||||
|
|
||||||
|
export type IProps = IBaseFieldProps & {};
|
||||||
|
|
||||||
|
export default class TextField extends BaseField<IProps> {
|
||||||
|
constructor(props: IProps){
|
||||||
|
super(props);
|
||||||
|
this.state = this.getDefaultState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override render(): ReactNode {
|
||||||
|
const value = this.state.value ?? "";
|
||||||
|
return (
|
||||||
|
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||||
|
<div className={classes["root"]} data-is-errored={this.hasError().toString()}>
|
||||||
|
<input
|
||||||
|
onChange={this.onChange}
|
||||||
|
data-value={value}
|
||||||
|
data-has-validation-errors={(this.state.validationError === null).toString()}
|
||||||
|
className={classnames(classes["input"], this.props.className)}
|
||||||
|
value={value}
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
onBlur={this.onBlur}
|
||||||
|
name={this.props.name}
|
||||||
|
/>
|
||||||
|
<div className={classes["fake-placeholder"]}>
|
||||||
|
{this.props.placeholder} {!this.props.required && " (Facultatif)"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{this.hasError() && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
@import "@Themes/constants.scss";
|
||||||
|
|
||||||
|
.root {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.textarea {
|
||||||
|
resize: none;
|
||||||
|
height: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: "Inter";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
&:read-only{
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
z-index: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24px;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid var(--grey-medium);
|
||||||
|
|
||||||
|
~ .fake-placeholder {
|
||||||
|
z-index: 2;
|
||||||
|
top: -12px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 0 16px;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
background: $white;
|
||||||
|
transform: translateY(35px);
|
||||||
|
transition: transform 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
~ .fake-placeholder {
|
||||||
|
transform: translateY(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([data-value=""]) {
|
||||||
|
~ .fake-placeholder {
|
||||||
|
transform: translateY(0px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-is-errored="true"] {
|
||||||
|
.textarea {
|
||||||
|
border: 1px solid var(--red-flash);
|
||||||
|
~ .fake-placeholder {
|
||||||
|
color: var(--red-flash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
import BaseField, { IProps as IBaseFieldProps } from "../BaseField";
|
||||||
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
|
import React from "react";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
import classes from "./classes.module.scss";
|
||||||
|
import classnames from "classnames";
|
||||||
|
|
||||||
|
export type IProps = IBaseFieldProps & {};
|
||||||
|
|
||||||
|
export default class TextAreaField extends BaseField<IProps> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
this.state = this.getDefaultState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override render(): ReactNode {
|
||||||
|
const value = this.state.value ?? "";
|
||||||
|
return (
|
||||||
|
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||||
|
<div className={classes["root"]} data-is-errored={this.hasError().toString()}>
|
||||||
|
<textarea
|
||||||
|
name={this.props.name}
|
||||||
|
rows={4}
|
||||||
|
data-value={value}
|
||||||
|
onChange={this.onChange}
|
||||||
|
className={classnames(classes["textarea"], this.props.className)}
|
||||||
|
value={value}
|
||||||
|
readOnly={this.props.readonly}
|
||||||
|
onFocus={this.onFocus}
|
||||||
|
onBlur={this.onBlur}
|
||||||
|
/>
|
||||||
|
<div className={classes["fake-placeholder"]}>
|
||||||
|
{this.props.placeholder} {!this.props.required && " (Facultatif)"}
|
||||||
|
</div>
|
||||||
|
{this.hasError() && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||||
|
</div>
|
||||||
|
</Typography>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidMount() {
|
||||||
|
this.setState({
|
||||||
|
value: this.props.defaultValue ?? "",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,180 +0,0 @@
|
|||||||
import { isEmail, isNotEmpty, isNumberString, isString, max, maxLength, min, minLength } from "class-validator";
|
|
||||||
|
|
||||||
const Validators = {
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the value is not empty
|
|
||||||
*/
|
|
||||||
required: { validate: isNotEmpty, message: "validation_messages.field_required" },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the value is a number
|
|
||||||
*/
|
|
||||||
numbersOnly: { validate: isNumberString, message: "validation_messages.only_numbers" },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the value is a number
|
|
||||||
*/
|
|
||||||
intOnly: {
|
|
||||||
validate: function (value: string) {
|
|
||||||
const regex = /^[0-9]*$/;
|
|
||||||
return regex.test(value);
|
|
||||||
},
|
|
||||||
message: "validation_messages.only_integers",
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : number
|
|
||||||
*
|
|
||||||
* This validator verifies the number is not below the parameter
|
|
||||||
*/
|
|
||||||
minNumber: { validate: (value: string, minVal: number) => min(Number(value), minVal), message: "validation_messages.below_min" },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : number
|
|
||||||
*
|
|
||||||
* This validator verifies the number is not above the parameter
|
|
||||||
*/
|
|
||||||
maxNumber: { validate: (value: string, maxVal: number) => max(Number(value), maxVal), message: "validation_messages.above_max" },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : number
|
|
||||||
*
|
|
||||||
* This validator verifies the string minimum length is conform to the parameter
|
|
||||||
*/
|
|
||||||
minLength: {
|
|
||||||
validate: minLength,
|
|
||||||
message: "validation_messages.min_string_length",
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : number
|
|
||||||
*
|
|
||||||
* This validator verifies the string maximum length is conform to the parameter
|
|
||||||
*/
|
|
||||||
maxLength: {
|
|
||||||
validate: maxLength,
|
|
||||||
message: "validation_messages.max_string_length",
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the input's value is a string.
|
|
||||||
*/
|
|
||||||
isString: { validate: (value: string) => isString(value), message: "validation_messages.only_letters" },
|
|
||||||
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the input's value is conform to the tag regex.
|
|
||||||
*/
|
|
||||||
isTag: {
|
|
||||||
validate: function (value: string) {
|
|
||||||
const regex = /^[a-zA-Z0-9][a-zA-Z0-9 ]*(,[a-zA-Z0-9][a-zA-Z0-9 ]*)*$/;
|
|
||||||
const isValid = regex.test(value);
|
|
||||||
if (!isValid) return false;
|
|
||||||
|
|
||||||
const splittedTag = value.split(",");
|
|
||||||
if (splittedTag.length !== new Set(splittedTag).size) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
message: "validation_messages.not_valid_tag",
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* **Parameters** : boolean
|
|
||||||
*
|
|
||||||
* This validator verifies the input's value is a valid email.
|
|
||||||
*
|
|
||||||
* If the **input is empty, it is considered valid**. If you do not wish this
|
|
||||||
* to happen please refer to the `required` validator.
|
|
||||||
*/
|
|
||||||
isEmail: {
|
|
||||||
validate: (value: string) => (Boolean(value) ? isEmail(value) : true),
|
|
||||||
message: "validation_messages.invalid_email",
|
|
||||||
},
|
|
||||||
|
|
||||||
isPseudo: {
|
|
||||||
validate: (value: string) => {
|
|
||||||
const pseudoRegex = /^[a-zA-Z][a-zA-Z0-9_-]{2,19}$/;
|
|
||||||
return pseudoRegex.test(value);
|
|
||||||
},
|
|
||||||
message: "validation_messages.is_pseudo",
|
|
||||||
},
|
|
||||||
|
|
||||||
noSpaceInString: {
|
|
||||||
validate: (value: string) => {
|
|
||||||
const regex = /^\S*$/;
|
|
||||||
return regex.test(value);
|
|
||||||
},
|
|
||||||
message: "validation_messages.no_space_in_string",
|
|
||||||
},
|
|
||||||
|
|
||||||
isPositiveNumber: {
|
|
||||||
validate: (value: string) => {
|
|
||||||
let nbr = parseFloat(value);
|
|
||||||
return !(isNaN(nbr) || nbr <= 0);
|
|
||||||
},
|
|
||||||
message: "validation_messages.positive_number",
|
|
||||||
},
|
|
||||||
|
|
||||||
floatPrecision: {
|
|
||||||
validate: (value: string, precision: number) => {
|
|
||||||
// If value is not a float
|
|
||||||
if (isNaN(parseFloat(value))) return false;
|
|
||||||
let splittedValue = value.split(".");
|
|
||||||
// If there is no decimals
|
|
||||||
if (!splittedValue[1]) return true;
|
|
||||||
// If there is more decimals than the required precision
|
|
||||||
if (splittedValue[1].length > precision) return false;
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
message: "validation_messages.float_precision",
|
|
||||||
},
|
|
||||||
|
|
||||||
isUrl: {
|
|
||||||
validate: (value: string, root: string | string[]) => {
|
|
||||||
try {
|
|
||||||
const url = new URL(value);
|
|
||||||
if (root) {
|
|
||||||
if (typeof root === "string") {
|
|
||||||
return url.hostname === root || url.hostname === `www.${root}`;
|
|
||||||
} else {
|
|
||||||
return root.some((r) => url.hostname === r || url.hostname === `www.${r}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
message: "validation_messages.invalid_url",
|
|
||||||
},
|
|
||||||
|
|
||||||
// isUniqueEmail: { TODO : uncomment and implement DB request
|
|
||||||
// validate: async (value: string, actual: string) => {
|
|
||||||
// try {
|
|
||||||
// const users = await AppUser.getInstance().getUsers({email: value});
|
|
||||||
// if (!users.metadata.count) return true;
|
|
||||||
// if (users.data.length > 1) return false;
|
|
||||||
// if (users.data[0]?.email === actual) return true;
|
|
||||||
// return false;
|
|
||||||
// } catch {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// message: "validation_messages.unique_email",
|
|
||||||
// },
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Validators;
|
|
||||||
export type IValidationTypes = Partial<
|
|
||||||
Record<keyof typeof Validators, boolean | Partial<{ message: string; args: any[]; isErrored: (errored: boolean) => void }>>
|
|
||||||
>;
|
|
@ -1,6 +1,6 @@
|
|||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode } from "react";
|
||||||
|
|
||||||
import BaseField, { IProps as IBaseFieldProps, IError } from "./Elements/BaseField";
|
import BaseField, { IProps as IBaseFieldProps } from "./BaseField";
|
||||||
|
|
||||||
export type IBaseField = BaseField<IBaseFieldProps>;
|
export type IBaseField = BaseField<IBaseFieldProps>;
|
||||||
|
|
||||||
@ -8,42 +8,39 @@ export type IFormContext = {
|
|||||||
setField: (name: string, field: IBaseField) => void;
|
setField: (name: string, field: IBaseField) => void;
|
||||||
unSetField: (name: string) => void;
|
unSetField: (name: string) => void;
|
||||||
onFieldChange: (name: string, field: IBaseField) => void;
|
onFieldChange: (name: string, field: IBaseField) => void;
|
||||||
|
onFieldFocusChange: (name: string, field: IBaseField, focused: boolean) => void;
|
||||||
|
isInputFocused: (name: string) => boolean;
|
||||||
|
hasOneFocusedInput: () => boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type IFields = {
|
type IFields = {
|
||||||
[key: string]: IBaseField;
|
[key: string]: IBaseField;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IApiFormErrors = {
|
type IState = {
|
||||||
[fieldName: string]: string;
|
inputFocused: {
|
||||||
};
|
name: string;
|
||||||
|
|
||||||
export type IFormErrors = {
|
|
||||||
[key: string]: {
|
|
||||||
field: IBaseField;
|
field: IBaseField;
|
||||||
errors: IError[] | undefined;
|
focused: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type IState = {};
|
|
||||||
export type IProps = {
|
export type IProps = {
|
||||||
onFieldChange?: (name: string, field: IBaseField, errors: IFormErrors | null) => void;
|
onFieldFocusChange?: (name: string, field: IBaseField, focused: boolean) => void;
|
||||||
onSubmit?: (
|
onFieldChange?: (name: string, field: IBaseField) => void;
|
||||||
e: React.FormEvent<HTMLFormElement> | null,
|
onSubmit?: (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => void;
|
||||||
values: { [key: string]: string },
|
|
||||||
onApiErrors: (apiFormErrors: IApiFormErrors | null) => void,
|
|
||||||
) => void;
|
|
||||||
onValidated?: () => void;
|
|
||||||
onErrors?: (errors: IFormErrors) => void;
|
|
||||||
/**
|
|
||||||
* @description Url, No redirection without action
|
|
||||||
*/
|
|
||||||
action?: string;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FormContext = React.createContext<IFormContext>({ setField: () => {}, unSetField: () => {}, onFieldChange: () => {} });
|
export const FormContext = React.createContext<IFormContext>({
|
||||||
|
setField: () => {},
|
||||||
|
unSetField: () => {},
|
||||||
|
onFieldChange: () => {},
|
||||||
|
onFieldFocusChange: () => {},
|
||||||
|
isInputFocused: () => false,
|
||||||
|
hasOneFocusedInput: () => false,
|
||||||
|
});
|
||||||
|
|
||||||
export default class Form extends React.Component<IProps, IState> {
|
export default class Form extends React.Component<IProps, IState> {
|
||||||
protected fields: IFields = {};
|
protected fields: IFields = {};
|
||||||
@ -52,13 +49,22 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {};
|
this.state = {
|
||||||
|
inputFocused: {
|
||||||
|
name: "",
|
||||||
|
field: {} as IBaseField,
|
||||||
|
focused: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
this.setField = this.setField.bind(this);
|
this.setField = this.setField.bind(this);
|
||||||
this.unSetField = this.unSetField.bind(this);
|
this.unSetField = this.unSetField.bind(this);
|
||||||
this.onFieldChange = this.onFieldChange.bind(this);
|
this.onFieldChange = this.onFieldChange.bind(this);
|
||||||
this.onSubmit = this.onSubmit.bind(this);
|
this.onSubmit = this.onSubmit.bind(this);
|
||||||
this.onSubmitErrorApi = this.onSubmitErrorApi.bind(this);
|
|
||||||
this.formRef = React.createRef();
|
this.formRef = React.createRef();
|
||||||
|
this.onFieldFocusChange = this.onFieldFocusChange.bind(this);
|
||||||
|
this.isInputFocused = this.isInputFocused.bind(this);
|
||||||
|
this.hasOneFocusedInput = this.hasOneFocusedInput.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override render() {
|
public override render() {
|
||||||
@ -68,8 +74,11 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
setField: this.setField,
|
setField: this.setField,
|
||||||
unSetField: this.unSetField,
|
unSetField: this.unSetField,
|
||||||
onFieldChange: this.onFieldChange,
|
onFieldChange: this.onFieldChange,
|
||||||
|
onFieldFocusChange: this.onFieldFocusChange,
|
||||||
|
isInputFocused: this.isInputFocused,
|
||||||
|
hasOneFocusedInput: this.hasOneFocusedInput,
|
||||||
}}>
|
}}>
|
||||||
<form className={this.props.className} ref={this.formRef} onSubmit={this.onSubmit} action={this.props.action ?? ""}>
|
<form className={this.props.className} ref={this.formRef} onSubmit={this.onSubmit}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</form>
|
</form>
|
||||||
</FormContext.Provider>
|
</FormContext.Provider>
|
||||||
@ -77,20 +86,7 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async onSubmit(e: React.FormEvent<HTMLFormElement> | null) {
|
public async onSubmit(e: React.FormEvent<HTMLFormElement> | null) {
|
||||||
if (!this.props.action) e?.preventDefault();
|
e?.preventDefault();
|
||||||
|
|
||||||
const errors = await this.validate();
|
|
||||||
|
|
||||||
if (errors) {
|
|
||||||
e?.preventDefault();
|
|
||||||
|
|
||||||
this.onErrors(errors);
|
|
||||||
|
|
||||||
return { errors };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.onValidated) this.props.onValidated();
|
|
||||||
|
|
||||||
const allChildren = this.getAllChildrenFields(e);
|
const allChildren = this.getAllChildrenFields(e);
|
||||||
const elementsValues = allChildren
|
const elementsValues = allChildren
|
||||||
.filter((e) => {
|
.filter((e) => {
|
||||||
@ -108,7 +104,7 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
const checkBoxesValues = checkBoxesInput.reduce((obj, element) => {
|
const checkBoxesValues = checkBoxesInput.reduce((obj, element) => {
|
||||||
const inputName = element.getAttribute("name") ?? "";
|
const inputName = element.getAttribute("name") ?? "";
|
||||||
const inputValue = (element as any).value as string;
|
const inputValue = (element as any).value as string;
|
||||||
const newValue = (obj as any)[inputName] as string[] ?? [];
|
const newValue = ((obj as any)[inputName] as string[]) ?? [];
|
||||||
newValue.push(inputValue);
|
newValue.push(inputValue);
|
||||||
return {
|
return {
|
||||||
...obj,
|
...obj,
|
||||||
@ -125,51 +121,12 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
// Deleting empty input
|
// Deleting empty input
|
||||||
delete (allInputs as any)[""];
|
delete (allInputs as any)[""];
|
||||||
if (this.props.onSubmit) {
|
if (this.props.onSubmit) {
|
||||||
this.props.onSubmit(e, allInputs, this.onSubmitErrorApi);
|
this.props.onSubmit(e, allInputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { values: elementsValues };
|
return { values: elementsValues };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected onSubmitErrorApi(apiFormErrors: IApiFormErrors | null) {
|
|
||||||
if (!apiFormErrors) return;
|
|
||||||
const errors: IFormErrors = {};
|
|
||||||
for (const [key, message] of Object.entries(apiFormErrors)) {
|
|
||||||
if (!this.fields[key]) continue;
|
|
||||||
this.fields[key]?.setErrors([
|
|
||||||
{
|
|
||||||
message,
|
|
||||||
validator: "",
|
|
||||||
value: this.fields[key]?.state.value ?? "",
|
|
||||||
args: [],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
this.onErrors(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async validate() {
|
|
||||||
const errors = (
|
|
||||||
await Promise.all(
|
|
||||||
Object.entries(this.fields).map(async ([name, field]) => {
|
|
||||||
return { name, validation: await field.validate(true), field };
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
).filter(({ validation }) => validation?.length);
|
|
||||||
|
|
||||||
if (!errors.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const errorsObject: IFormErrors = {};
|
|
||||||
errors.forEach(({ name, validation, field }) => (errorsObject[name] = { errors: validation, field }));
|
|
||||||
return errorsObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected onErrors(errors: IFormErrors) {
|
|
||||||
if (this.props.onErrors) this.props.onErrors(errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected setField(name: string, field: IBaseField) {
|
protected setField(name: string, field: IBaseField) {
|
||||||
this.fields[name] = field;
|
this.fields[name] = field;
|
||||||
}
|
}
|
||||||
@ -178,10 +135,31 @@ export default class Form extends React.Component<IProps, IState> {
|
|||||||
delete this.fields[name];
|
delete this.fields[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async onFieldChange(name: string, field: IBaseField) {
|
protected hasOneFocusedInput() {
|
||||||
|
return this.state.inputFocused.focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isInputFocused(name: string) {
|
||||||
|
return this.state.inputFocused.name === name && this.state.inputFocused.focused;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onFieldFocusChange(name: string, field: IBaseField, focused: boolean) {
|
||||||
|
this.setState({
|
||||||
|
inputFocused: {
|
||||||
|
name,
|
||||||
|
field,
|
||||||
|
focused,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.props.onFieldFocusChange) {
|
||||||
|
this.props.onFieldFocusChange(name, field, focused);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onFieldChange(name: string, field: IBaseField) {
|
||||||
if (this.props.onFieldChange) {
|
if (this.props.onFieldChange) {
|
||||||
const errors = await this.validate();
|
this.props.onFieldChange(name, field);
|
||||||
this.props.onFieldChange(name, field, errors);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import classNames from "classnames";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
|
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
|
||||||
|
|
||||||
import { IOption } from "../Select";
|
import { IOption } from "../Form/SelectField";
|
||||||
import Typography, { ITypo } from "../Typography";
|
import Typography, { ITypo } from "../Typography";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import { styles } from "./styles";
|
import { styles } from "./styles";
|
||||||
|
@ -1,160 +0,0 @@
|
|||||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
|
||||||
import WindowStore from "@Front/Stores/WindowStore";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import Image from "next/image";
|
|
||||||
import React, { FormEvent, ReactNode } from "react";
|
|
||||||
|
|
||||||
import Typography, { ITypo } from "../Typography";
|
|
||||||
import classes from "./classes.module.scss";
|
|
||||||
|
|
||||||
type IProps = {
|
|
||||||
selectedOption?: IOption;
|
|
||||||
onChange?: (selectedOption: IOption) => void;
|
|
||||||
options: IOption[];
|
|
||||||
hasBorderRightCollapsed?: boolean;
|
|
||||||
placeholder?: string;
|
|
||||||
className?: string;
|
|
||||||
name?: string;
|
|
||||||
disabled: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type IOption = {
|
|
||||||
value: unknown;
|
|
||||||
label: string;
|
|
||||||
icon?: ReactNode;
|
|
||||||
description?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type IState = {
|
|
||||||
isOpen: boolean;
|
|
||||||
listWidth: number;
|
|
||||||
listHeight: number;
|
|
||||||
selectedOption: IOption | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class Select extends React.Component<IProps, IState> {
|
|
||||||
private contentRef = React.createRef<HTMLUListElement>();
|
|
||||||
private rootRef = React.createRef<HTMLDivElement>();
|
|
||||||
private removeOnresize = () => {};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
disabled: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: IProps) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
isOpen: false,
|
|
||||||
listHeight: 0,
|
|
||||||
listWidth: 0,
|
|
||||||
selectedOption: null,
|
|
||||||
};
|
|
||||||
this.toggle = this.toggle.bind(this);
|
|
||||||
this.onSelect = this.onSelect.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override render(): JSX.Element {
|
|
||||||
const selectedOption = this.state.selectedOption ?? this.props.selectedOption;
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames(classes["root"], this.props.className)}
|
|
||||||
ref={this.rootRef}
|
|
||||||
data-disabled={this.props.disabled.toString()}>
|
|
||||||
{selectedOption && <input type="text" defaultValue={selectedOption.value as string} name={this.props.name} hidden />}
|
|
||||||
<label
|
|
||||||
className={classNames(classes["container-label"])}
|
|
||||||
data-open={this.state.isOpen}
|
|
||||||
onClick={this.toggle}
|
|
||||||
data-border-right-collapsed={this.props.hasBorderRightCollapsed}>
|
|
||||||
<div className={classNames(classes["container-input"])}>
|
|
||||||
{selectedOption && (
|
|
||||||
<>
|
|
||||||
<span className={classNames(classes["icon"], classes["token-icon"])}>{selectedOption?.icon}</span>
|
|
||||||
<Typography typo={ITypo.P_18}>
|
|
||||||
<span className={classes["text"]}>{selectedOption?.label}</span>
|
|
||||||
</Typography>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{!selectedOption && (
|
|
||||||
<div className={classes["placeholder"]} data-open={(selectedOption ? true : false).toString()}>
|
|
||||||
<Typography typo={ITypo.NAV_INPUT_16}>
|
|
||||||
<span className={classes["text"]}>{this.props.placeholder ?? ""}</span>
|
|
||||||
</Typography>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<Image className={classes["chevron-icon"]} data-open={this.state.isOpen} src={ChevronIcon} alt="chevron icon" />
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<ul
|
|
||||||
className={classes["container-ul"]}
|
|
||||||
data-open={this.state.isOpen}
|
|
||||||
ref={this.contentRef}
|
|
||||||
style={{
|
|
||||||
height: this.state.listHeight + "px",
|
|
||||||
}}>
|
|
||||||
{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>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{this.state.isOpen && <div className={classes["backdrop"]} onClick={this.toggle} />}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDerivedStateFromProps(props: IProps, state: IState) {
|
|
||||||
if (props.selectedOption?.value) {
|
|
||||||
return {
|
|
||||||
value: props.selectedOption?.value,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentDidMount(): void {
|
|
||||||
this.onResize();
|
|
||||||
this.removeOnresize = WindowStore.getInstance().onResize(() => this.onResize());
|
|
||||||
}
|
|
||||||
|
|
||||||
public override componentWillUnmount() {
|
|
||||||
this.removeOnresize();
|
|
||||||
}
|
|
||||||
|
|
||||||
private onResize() {
|
|
||||||
let listHeight = 0;
|
|
||||||
let listWidth = 0;
|
|
||||||
listWidth = this.rootRef.current?.scrollWidth ?? 0;
|
|
||||||
if (this.state.listHeight) {
|
|
||||||
listHeight = this.contentRef.current?.scrollHeight ?? 0;
|
|
||||||
}
|
|
||||||
this.setState({ listHeight, listWidth });
|
|
||||||
}
|
|
||||||
|
|
||||||
private toggle(e: FormEvent) {
|
|
||||||
if (this.props.disabled) return;
|
|
||||||
e.preventDefault();
|
|
||||||
let listHeight = 0;
|
|
||||||
let listWidth = this.rootRef.current?.scrollWidth ?? 0;
|
|
||||||
|
|
||||||
if (!this.state.listHeight) {
|
|
||||||
listHeight = this.contentRef.current?.scrollHeight ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState((state) => {
|
|
||||||
return { isOpen: !state.isOpen, listHeight, listWidth };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private onSelect(option: IOption, e: React.MouseEvent<HTMLLIElement, MouseEvent>) {
|
|
||||||
if (this.props.disabled) return;
|
|
||||||
this.props.onChange && this.props.onChange(option);
|
|
||||||
this.setState({
|
|
||||||
selectedOption: option,
|
|
||||||
});
|
|
||||||
this.toggle(e);
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,11 +9,11 @@ import BackArrow from "@Front/Components/Elements/BackArrow";
|
|||||||
import WindowStore from "@Front/Stores/WindowStore";
|
import WindowStore from "@Front/Stores/WindowStore";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
|
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
|
||||||
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import React, { ReactNode } from "react";
|
import React, { ReactNode } from "react";
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||||
|
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Documents, { IGetDocumentsparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Documents/Documents";
|
import Documents, { IGetDocumentsparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Documents/Documents";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import DepositDocument from "@Front/Components/DesignSystem/DepositDocument";
|
import DepositDocument from "@Front/Components/DesignSystem/DepositDocument";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import Base from "@Front/Components/Layouts/Base";
|
import Base from "@Front/Components/Layouts/Base";
|
||||||
@ -64,7 +64,7 @@ export default class ClientDashboard extends Base<IProps, IState> {
|
|||||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||||
Vous souhaitez envoyer un autre document à votre notaire ?
|
Vous souhaitez envoyer un autre document à votre notaire ?
|
||||||
</Typography>
|
</Typography>
|
||||||
<InputField fakeplaceholder={"Nom du document"} />
|
<TextField placeholder="Nom du document" />
|
||||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||||
Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
||||||
document correspondant.
|
document correspondant.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer";
|
import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer";
|
||||||
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
||||||
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
|
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||||
import {
|
import {
|
||||||
Address,
|
Address,
|
||||||
Contact,
|
Contact,
|
||||||
@ -147,6 +147,8 @@ export const fileMock: File = {
|
|||||||
file_path:
|
file_path:
|
||||||
"https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf",
|
"https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf",
|
||||||
archived_at: null,
|
archived_at: null,
|
||||||
|
mimetype: "image/png",
|
||||||
|
size: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fileMock2: File = {
|
export const fileMock2: File = {
|
||||||
@ -158,6 +160,8 @@ export const fileMock2: File = {
|
|||||||
file_path:
|
file_path:
|
||||||
"https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19",
|
"https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19",
|
||||||
archived_at: null,
|
archived_at: null,
|
||||||
|
mimetype: "image/png",
|
||||||
|
size: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const identityFile: File = {
|
export const identityFile: File = {
|
||||||
@ -168,6 +172,8 @@ export const identityFile: File = {
|
|||||||
file_name: "file_3",
|
file_name: "file_3",
|
||||||
file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png",
|
file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png",
|
||||||
archived_at: null,
|
archived_at: null,
|
||||||
|
mimetype: "image/png",
|
||||||
|
size: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const documentIdentity: Document = {
|
export const documentIdentity: Document = {
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
|
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||||
import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary";
|
import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary";
|
||||||
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
|
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
|
||||||
import FolderContainer from "@Front/Components/DesignSystem/FolderContainer";
|
import FolderContainer from "@Front/Components/DesignSystem/FolderContainer";
|
||||||
import FolderList from "@Front/Components/DesignSystem/FolderListContainer";
|
import FolderList from "@Front/Components/DesignSystem/FolderListContainer";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import HeaderLink from "@Front/Components/DesignSystem/Header/HeaderLink";
|
import HeaderLink from "@Front/Components/DesignSystem/Header/HeaderLink";
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||||
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||||
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
|
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
|
||||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
|
||||||
import ToolTip from "@Front/Components/DesignSystem/ToolTip";
|
import ToolTip from "@Front/Components/DesignSystem/ToolTip";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import UserFolder from "@Front/Components/DesignSystem/UserFolder";
|
import UserFolder from "@Front/Components/DesignSystem/UserFolder";
|
||||||
@ -23,6 +20,9 @@ import Toasts, { IToast } from "@Front/Stores/Toasts";
|
|||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import { customer2, document, documentDeposited, documentPending, folder, folders, folderWithPendingDocument } from "./dummyData";
|
import { customer2, document, documentDeposited, documentPending, folder, folders, folderWithPendingDocument } from "./dummyData";
|
||||||
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
|
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
|
||||||
type IState = {
|
type IState = {
|
||||||
isModalDisplayed: boolean;
|
isModalDisplayed: boolean;
|
||||||
@ -150,13 +150,13 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
|||||||
<Typography typo={ITypo.H3}>Input component</Typography>
|
<Typography typo={ITypo.H3}>Input component</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<InputField name="input field" fakeplaceholder="input place hodler" />
|
<TextField name="input field" placeholder="input place hodler" />
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<InputField name="input field" fakeplaceholder="text area place hodler" textarea />
|
<TextAreaField name="input field" placeholder="text area place hodler" />
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<InputField name="input field" fakeplaceholder="number place hodler" type="number" />
|
<TextField name="input field" placeholder="number place hodler" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -199,7 +199,8 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
|||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<div className={classes["folder-conatainer"]}>
|
<div className={classes["folder-conatainer"]}>
|
||||||
<Select
|
<SelectField
|
||||||
|
name="select"
|
||||||
options={selectOptions}
|
options={selectOptions}
|
||||||
onChange={this.onSelectedOption}
|
onChange={this.onSelectedOption}
|
||||||
placeholder={"Type d'acte"}
|
placeholder={"Type d'acte"}
|
||||||
@ -222,7 +223,7 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
|||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<Typography typo={ITypo.P_16}>Documents Depoited</Typography>
|
<Typography typo={ITypo.P_16}>Documents Depoited</Typography>
|
||||||
<div className={classes["folder-conatainer"]}>
|
<div className={classes["folder-conatainer"]}>
|
||||||
<DocumentNotary document={documentPending} folderUid=""/>
|
<DocumentNotary document={documentPending} folderUid="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
@ -239,7 +240,14 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
|||||||
<Typography typo={ITypo.H3}>Notary Documents</Typography>
|
<Typography typo={ITypo.H3}>Notary Documents</Typography>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["sub-section"]}>
|
<div className={classes["sub-section"]}>
|
||||||
<UserFolder customer={customer2} folder={folder as IDashBoardFolder} isOpened={true} onChange={() => {return}}/>
|
<UserFolder
|
||||||
|
customer={customer2}
|
||||||
|
folder={folder as IDashBoardFolder}
|
||||||
|
isOpened={true}
|
||||||
|
onChange={() => {
|
||||||
|
return;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
|
|
||||||
import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
|
import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
|
||||||
import Folders, { IPutFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||||
import { IOption } from "@Front/Components/DesignSystem/Select";
|
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
import Module from "@Front/Config/Module";
|
import Module from "@Front/Config/Module";
|
||||||
import { ECivility } from "le-coffre-resources/dist/Customer/Contact";
|
import { ECivility } from "le-coffre-resources/dist/Customer/Contact";
|
||||||
import { Customer } from "le-coffre-resources/dist/Notary";
|
import { Customer, OfficeFolder, OfficeFolderHasCustomer } from "le-coffre-resources/dist/Notary";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { NextRouter, useRouter } from "next/router";
|
import { NextRouter, useRouter } from "next/router";
|
||||||
|
|
||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
|
import { TextField } from "@mui/material";
|
||||||
|
|
||||||
enum ESelectedOption {
|
enum ESelectedOption {
|
||||||
EXISTING_CUSTOMER = "existing_customer",
|
EXISTING_CUSTOMER = "existing_customer",
|
||||||
@ -107,14 +105,12 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
|
|
||||||
{this.state.selectedOption === "new_customer" && (
|
{this.state.selectedOption === "new_customer" && (
|
||||||
<div className={classes["new-client"]}>
|
<div className={classes["new-client"]}>
|
||||||
<InputField name="last_name" fakeplaceholder="Nom" />
|
<TextField name="last_name" placeholder="Nom" />
|
||||||
<InputField name="first_name" fakeplaceholder="Prénom" />
|
<TextField name="first_name" placeholder="Prénom" />
|
||||||
<InputField name="email" fakeplaceholder="E-mail" isEmail />
|
<TextField name="email" placeholder="E-mail" />
|
||||||
<InputField
|
<TextField
|
||||||
name="cell_phone_number"
|
name="cell_phone_number"
|
||||||
fakeplaceholder="Numéro de téléphone"
|
placeholder="Numéro de téléphone"
|
||||||
numbersOnly
|
|
||||||
maxLength={10}
|
|
||||||
/>
|
/>
|
||||||
<div className={classes["button-container"]}>
|
<div className={classes["button-container"]}>
|
||||||
<Link href={backwardPath} className={classes["cancel-button"]}>
|
<Link href={backwardPath} className={classes["cancel-button"]}>
|
||||||
@ -213,24 +209,24 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
values["civility"] = ECivility.MALE; // TODO: should maybe be deleted later or added to the form
|
values["civility"] = ECivility.MALE; // TODO: should maybe be deleted later or added to the form
|
||||||
|
|
||||||
const allCustomersToLink = this.state.selectedCustomers.concat(this.state.existingCustomers);
|
const allCustomersToLink = this.state.selectedCustomers.concat(this.state.existingCustomers);
|
||||||
let customersToLink: IPutFoldersParams["office_folder_has_customers"] = allCustomersToLink.map((customer) => {
|
let customersToLink: Partial<OfficeFolderHasCustomer>[] = allCustomersToLink.map((customer) => {
|
||||||
return {
|
return {
|
||||||
customer: { uid: customer.value },
|
customer: { uid: customer.value },
|
||||||
};
|
};
|
||||||
}) as IPutFoldersParams["office_folder_has_customers"];
|
}) as Partial<OfficeFolderHasCustomer>[];
|
||||||
|
|
||||||
if (this.state.selectedOption === "new_customer") {
|
if (this.state.selectedOption === "new_customer") {
|
||||||
const customer: Customer = await Customers.getInstance().post({
|
const customer: Customer = await Customers.getInstance().post({
|
||||||
contact: values,
|
contact: values,
|
||||||
});
|
});
|
||||||
if (!customer.uid) return;
|
if (!customer.uid) return;
|
||||||
customersToLink?.push({ customer: { uid: customer.uid } });
|
customersToLink?.push({ customer: { uid: customer.uid } } as Partial<OfficeFolderHasCustomer>);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customersToLink) {
|
if (customersToLink) {
|
||||||
const body = {
|
const body = OfficeFolder.hydrate<OfficeFolder>({ office_folder_has_customers: customersToLink.map((customer) => {
|
||||||
office_folder_has_customers: customersToLink,
|
return OfficeFolderHasCustomer.hydrate<OfficeFolderHasCustomer>(customer);
|
||||||
};
|
}) });
|
||||||
|
|
||||||
await Folders.getInstance().put(this.props.selectedFolderUid, body);
|
await Folders.getInstance().put(this.props.selectedFolderUid, body);
|
||||||
this.props.router.push(`/folders/${this.props.selectedFolderUid}`);
|
this.props.router.push(`/folders/${this.props.selectedFolderUid}`);
|
||||||
|
@ -6,9 +6,7 @@ import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
|||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import { IOption } from "@Front/Components/DesignSystem/Select";
|
|
||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
@ -19,6 +17,9 @@ import React from "react";
|
|||||||
|
|
||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
type IPropsClass = IProps & {
|
type IPropsClass = IProps & {
|
||||||
@ -109,17 +110,14 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
cancelText={"Annuler"}
|
cancelText={"Annuler"}
|
||||||
confirmText={"Ajouter"}>
|
confirmText={"Ajouter"}>
|
||||||
<div className={classes["add-document-form-container"]}>
|
<div className={classes["add-document-form-container"]}>
|
||||||
<InputField
|
<TextField
|
||||||
name="document_name"
|
name="document_name"
|
||||||
fakeplaceholder="Nom du document à ajouter"
|
placeholder="Nom du document à ajouter"
|
||||||
type="text"
|
|
||||||
onChange={this.onDocumentNameChange}
|
onChange={this.onDocumentNameChange}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextAreaField
|
||||||
name="description"
|
name="description"
|
||||||
fakeplaceholder="Description visible par le client"
|
placeholder="Description visible par le client"
|
||||||
type="text"
|
|
||||||
textarea
|
|
||||||
onChange={this.onVisibleDescriptionChange}
|
onChange={this.onVisibleDescriptionChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -232,13 +230,13 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onVisibleDescriptionChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onVisibleDescriptionChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
visibleDescription: e.target.value,
|
visibleDescription: e.target.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onDocumentNameChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onDocumentNameChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
documentName: e.target.value,
|
documentName: e.target.value,
|
||||||
});
|
});
|
||||||
@ -275,7 +273,7 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const documentAsked: [] = values["document_types"] as [];
|
const documentAsked: [] = values["document_types"] as [];
|
||||||
for(let i = 0; i < documentAsked.length; i++){
|
for (let i = 0; i < documentAsked.length; i++) {
|
||||||
await Documents.getInstance().post({
|
await Documents.getInstance().post({
|
||||||
folder: {
|
folder: {
|
||||||
uid: this.props.folderUid,
|
uid: this.props.folderUid,
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
|
import backgroundImage from "@Assets/images/404-background-image.jpeg";
|
||||||
|
import DeedTypes from "@Front/Api/LeCoffreApi/SuperAdmin/DeedTypes/DeedTypes";
|
||||||
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
|
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||||
import Button from "@Front/Components/DesignSystem/Button";
|
import Button from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
|
||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||||
|
import { ValidationError } from "class-validator";
|
||||||
|
import { Deed, DeedType, Office, OfficeFolder, OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Notary";
|
||||||
|
import User from "le-coffre-resources/dist/Notary";
|
||||||
|
import { NextRouter, useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { ActionMeta, MultiValue } from "react-select";
|
import { ActionMeta, MultiValue } from "react-select";
|
||||||
|
|
||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import { DeedType, OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Notary";
|
|
||||||
import DeedTypes from "@Front/Api/LeCoffreApi/SuperAdmin/DeedTypes/DeedTypes";
|
|
||||||
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
|
||||||
import User from "le-coffre-resources/dist/Notary";
|
|
||||||
import Folders, { IPostFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
|
||||||
import { NextRouter, useRouter } from "next/router";
|
|
||||||
import backgroundImage from "@Assets/images/404-background-image.jpeg";
|
|
||||||
|
|
||||||
type IFormValues = {
|
type IFormValues = {
|
||||||
folder_number: string;
|
folder_number: string;
|
||||||
@ -41,6 +43,7 @@ type IState = {
|
|||||||
deedTypesOptions: IOption[];
|
deedTypesOptions: IOption[];
|
||||||
collaborators: User[];
|
collaborators: User[];
|
||||||
collaboratorsOptions: IOption[];
|
collaboratorsOptions: IOption[];
|
||||||
|
validationError: ValidationError[];
|
||||||
};
|
};
|
||||||
class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||||
public constructor(props: IPropsClass) {
|
public constructor(props: IPropsClass) {
|
||||||
@ -59,6 +62,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
deedTypesOptions: [],
|
deedTypesOptions: [],
|
||||||
collaborators: [],
|
collaborators: [],
|
||||||
collaboratorsOptions: [],
|
collaboratorsOptions: [],
|
||||||
|
validationError: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
this.radioOnChange = this.radioOnChange.bind(this);
|
this.radioOnChange = this.radioOnChange.bind(this);
|
||||||
@ -84,19 +88,31 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Form onSubmit={this.onFormSubmit}>
|
<Form onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["form-container"]}>
|
<div className={classes["form-container"]}>
|
||||||
<InputField
|
<TextField
|
||||||
name="folder_number"
|
name="folder_number"
|
||||||
fakeplaceholder="Numéro de dossier"
|
placeholder="Numéro de dossier"
|
||||||
type="text"
|
|
||||||
onChange={this.onFolderNumberChange}
|
onChange={this.onFolderNumberChange}
|
||||||
|
validationError={this.state.validationError.find((error) => error.property === "folder_number")}
|
||||||
/>
|
/>
|
||||||
<InputField name="name" fakeplaceholder="Intitulé" onChange={this.onEntitleChange} />
|
<TextField
|
||||||
<Select options={this.state.deedTypesOptions} placeholder={"Type d’acte"} onChange={this.onActTypeChange} />
|
name="name"
|
||||||
<InputField
|
placeholder="Intitulé"
|
||||||
|
onChange={this.onEntitleChange}
|
||||||
|
validationError={this.state.validationError.find((error) => error.property === "name")}
|
||||||
|
/>
|
||||||
|
<SelectField
|
||||||
|
options={this.state.deedTypesOptions}
|
||||||
|
name="deed"
|
||||||
|
placeholder={"Type d'acte"}
|
||||||
|
onChange={this.onActTypeChange}
|
||||||
|
errors={this.state.validationError.find((error) => error.property === "deed")}
|
||||||
|
/>
|
||||||
|
<TextAreaField
|
||||||
name="description"
|
name="description"
|
||||||
fakeplaceholder="Note du dossier"
|
placeholder="Note du dossier"
|
||||||
textarea
|
|
||||||
onChange={this.onPersonalNoteChange}
|
onChange={this.onPersonalNoteChange}
|
||||||
|
validationError={this.state.validationError.find((error) => error.property === "description")}
|
||||||
|
required={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={classes["access-container"]}>
|
<div className={classes["access-container"]}>
|
||||||
@ -122,7 +138,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className={classes["buttons-container"]}>
|
<div className={classes["buttons-container"]}>
|
||||||
<Button fullwidth disabled={!this.isFormSubmittable()} type="submit">
|
<Button fullwidth type="submit">
|
||||||
Créer un dossier
|
Créer un dossier
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -166,7 +182,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
})) as IOption[];
|
})) as IOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
private onFolderNumberChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onFolderNumberChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
formValues: {
|
formValues: {
|
||||||
...this.state.formValues,
|
...this.state.formValues,
|
||||||
@ -175,7 +191,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onEntitleChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onEntitleChange(e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
formValues: {
|
formValues: {
|
||||||
...this.state.formValues,
|
...this.state.formValues,
|
||||||
@ -193,7 +209,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onPersonalNoteChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onPersonalNoteChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
formValues: {
|
formValues: {
|
||||||
...this.state.formValues,
|
...this.state.formValues,
|
||||||
@ -226,35 +242,52 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
|||||||
*/
|
*/
|
||||||
const usersMock = await Users.getInstance().get({ include: { office_membership: true } });
|
const usersMock = await Users.getInstance().get({ include: { office_membership: true } });
|
||||||
const userMock = usersMock[0];
|
const userMock = usersMock[0];
|
||||||
// -----
|
|
||||||
if (!selectedDeedTypeUid) return;
|
|
||||||
if (!userMock?.office_membership?.uid) return;
|
|
||||||
|
|
||||||
let stakeholders = this.getStakeholders();
|
let stakeholders = this.getStakeholders();
|
||||||
let test = stakeholders.map((stakeholder) => ({
|
let testUsers = stakeholders.map((stakeholder) => ({
|
||||||
user_stakeholder: {
|
user_stakeholder: {
|
||||||
uid: stakeholder.user_stakeholder.uid,
|
uid: stakeholder.user_stakeholder.uid,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const output: IPostFoldersParams = {
|
const officeFolderForm = OfficeFolder.hydrate<OfficeFolder>({
|
||||||
folder_number: values["folder_number"],
|
folder_number: values["folder_number"],
|
||||||
name: values["name"],
|
name: values["name"],
|
||||||
description: values["description"],
|
description: values["description"],
|
||||||
deed: {
|
deed: Deed.hydrate<Deed>({
|
||||||
deed_type: {
|
deed_type: DeedType.hydrate<DeedType>({
|
||||||
uid: selectedDeedTypeUid.uid,
|
uid: selectedDeedTypeUid?.uid,
|
||||||
},
|
}),
|
||||||
},
|
}),
|
||||||
office: {
|
office: Office.hydrate<Office>({
|
||||||
uid: userMock?.office_membership.uid,
|
uid: userMock?.office_membership?.uid,
|
||||||
},
|
}),
|
||||||
office_folder_has_stakeholder: test,
|
office_folder_has_stakeholder: testUsers.map((user) => {
|
||||||
};
|
return OfficeFolderHasStakeholder.hydrate<OfficeFolderHasStakeholder>({
|
||||||
|
user_stakeholder: User.hydrate<User>({
|
||||||
|
uid: user.user_stakeholder.uid,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
const created = await Folders.getInstance().post(output);
|
try {
|
||||||
if (created) {
|
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
|
||||||
this.props.router.push(`/folders/${created.uid}`);
|
} catch (validationErrors) {
|
||||||
|
this.setState({
|
||||||
|
validationError: validationErrors as ValidationError[],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const newOfficeFolder = await Folders.getInstance().post(officeFolderForm);
|
||||||
|
if (!newOfficeFolder) return;
|
||||||
|
this.props.router.push(`/folders/${newOfficeFolder.uid}`);
|
||||||
|
} catch (backError: any) {
|
||||||
|
this.setState({
|
||||||
|
validationError: backError as ValidationError[],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||||
import Folders, { IPutFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
|
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
@ -17,6 +16,7 @@ import { ChangeEvent } from "react";
|
|||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import ClientSection from "./ClientSection";
|
import ClientSection from "./ClientSection";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
@ -110,10 +110,9 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
|||||||
<div className={classes["modal-title"]}>
|
<div className={classes["modal-title"]}>
|
||||||
<Typography typo={ITypo.P_16}>Souhaitez-vous vraiment archiver le dossier ?</Typography>
|
<Typography typo={ITypo.P_16}>Souhaitez-vous vraiment archiver le dossier ?</Typography>
|
||||||
</div>
|
</div>
|
||||||
<InputField
|
<TextAreaField
|
||||||
name="archived_description"
|
name="archived_description"
|
||||||
fakeplaceholder="Description"
|
placeholder="Description"
|
||||||
textarea
|
|
||||||
onChange={this.onArchivedDescriptionInputChange}
|
onChange={this.onArchivedDescriptionInputChange}
|
||||||
/>
|
/>
|
||||||
</Confirm>
|
</Confirm>
|
||||||
@ -172,15 +171,15 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
|||||||
this.setState({ isArchivedModalOpen: false });
|
this.setState({ isArchivedModalOpen: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
private onArchivedDescriptionInputChange(e: ChangeEvent<HTMLInputElement>) {
|
private onArchivedDescriptionInputChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({ inputArchivedDescripton: e.target.value });
|
this.setState({ inputArchivedDescripton: e.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onArchivedModalAccepted() {
|
private async onArchivedModalAccepted() {
|
||||||
if (!this.state.selectedFolder) return;
|
if (!this.state.selectedFolder) return;
|
||||||
const folder = this.state.selectedFolder;
|
const ressourceFolder = OfficeFolder.hydrate<OfficeFolder>(this.state.selectedFolder);
|
||||||
folder.archived_description = this.state.inputArchivedDescripton;
|
ressourceFolder.archived_description = this.state.inputArchivedDescripton;
|
||||||
await Folders.getInstance().archive(this.state.selectedFolder.uid ?? "", folder as IPutFoldersParams);
|
await Folders.getInstance().archive(this.state.selectedFolder.uid ?? "", ressourceFolder);
|
||||||
this.closeArchivedModal();
|
this.closeArchivedModal();
|
||||||
this.props.router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
this.props.router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import BasePage from "../../Base";
|
||||||
|
import classes from "./classes.module.scss";
|
||||||
import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
|
import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
@ -12,9 +14,6 @@ import Link from "next/link";
|
|||||||
import { NextRouter, useRouter } from "next/router";
|
import { NextRouter, useRouter } from "next/router";
|
||||||
import { ChangeEvent } from "react";
|
import { ChangeEvent } from "react";
|
||||||
|
|
||||||
import BasePage from "../../Base";
|
|
||||||
import classes from "./classes.module.scss";
|
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
type IPropsClass = IProps & {
|
type IPropsClass = IProps & {
|
||||||
@ -78,44 +77,40 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
|||||||
<Typography typo={ITypo.H1Bis}>Modifier les informations du client</Typography>
|
<Typography typo={ITypo.H1Bis}>Modifier les informations du client</Typography>
|
||||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
<InputField
|
<TextField
|
||||||
name="first_name"
|
name="first_name"
|
||||||
fakeplaceholder="Nom"
|
placeholder="Nom"
|
||||||
onChange={this.onChangeNameInput}
|
onChange={this.onChangeNameInput}
|
||||||
defaultValue={this.state.customer?.contact?.first_name}
|
defaultValue={this.state.customer?.contact?.first_name}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="last_name"
|
name="last_name"
|
||||||
fakeplaceholder="Prénom"
|
placeholder="Prénom"
|
||||||
onChange={this.onChangeFirstNameInput}
|
onChange={this.onChangeFirstNameInput}
|
||||||
defaultValue={this.state.customer?.contact?.last_name}
|
defaultValue={this.state.customer?.contact?.last_name}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="email"
|
name="email"
|
||||||
fakeplaceholder="E-mail"
|
placeholder="E-mail"
|
||||||
isEmail
|
|
||||||
onChange={this.onChangeEmailInput}
|
onChange={this.onChangeEmailInput}
|
||||||
defaultValue={this.state.customer?.contact?.email}
|
defaultValue={this.state.customer?.contact?.email}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="cell_phone_number"
|
name="cell_phone_number"
|
||||||
fakeplaceholder="Numéro de téléphone"
|
placeholder="Numéro de téléphone"
|
||||||
isPositiveNumber
|
|
||||||
onChange={this.onChangePhoneNumberInput}
|
onChange={this.onChangePhoneNumberInput}
|
||||||
defaultValue={this.state.customer?.contact?.cell_phone_number ?? ""}
|
defaultValue={this.state.customer?.contact?.cell_phone_number ?? ""}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="birthdate"
|
name="birthdate"
|
||||||
type="text"
|
placeholder="Date de naissance"
|
||||||
fakeplaceholder="Date de naissance"
|
|
||||||
required={false}
|
required={false}
|
||||||
onChange={this.onChangeBirthDateInput}
|
onChange={this.onChangeBirthDateInput}
|
||||||
defaultValue={this.state.customer?.contact?.birthdate?.toString() ?? ""}
|
defaultValue={this.state.customer?.contact?.birthdate?.toString() ?? ""}
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="address"
|
name="address"
|
||||||
type="text"
|
placeholder="Adresse"
|
||||||
fakeplaceholder="Adresse"
|
|
||||||
required={false}
|
required={false}
|
||||||
onChange={this.onChangeAddressInput}
|
onChange={this.onChangeAddressInput}
|
||||||
defaultValue={this.state.customer?.contact?.address?.address ?? ""}
|
defaultValue={this.state.customer?.contact?.address?.address ?? ""}
|
||||||
@ -185,11 +180,11 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
|||||||
},
|
},
|
||||||
} as Contact;
|
} as Contact;
|
||||||
|
|
||||||
try{
|
try {
|
||||||
await Customers.getInstance().put(this.props.customerUid, { contact })
|
await Customers.getInstance().put(this.props.customerUid, { contact });
|
||||||
this.props.router.push(this.backwardPath);
|
this.props.router.push(this.backwardPath);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,25 +200,25 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
|||||||
this.setState({ isOpenLeavingModal: false });
|
this.setState({ isOpenLeavingModal: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
private onChangeBirthDateInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangeBirthDateInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputBirthdate: new Date(event.target.value) });
|
this.setState({ inputBirthdate: new Date(event.target.value) });
|
||||||
}
|
}
|
||||||
|
|
||||||
private onChangeAddressInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangeAddressInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputAddress: event.target.value });
|
this.setState({ inputAddress: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
private onChangeNameInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangeNameInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputNameValue: event.target.value });
|
this.setState({ inputNameValue: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
private onChangeFirstNameInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangeFirstNameInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputFirstNameValue: event.target.value });
|
this.setState({ inputFirstNameValue: event.target.value });
|
||||||
}
|
}
|
||||||
private onChangeEmailInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangeEmailInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputEmailValue: event.target.value });
|
this.setState({ inputEmailValue: event.target.value });
|
||||||
}
|
}
|
||||||
private onChangePhoneNumberInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
private onChangePhoneNumberInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||||
this.setState({ inputPhoneNumberValue: event.target.value });
|
this.setState({ inputPhoneNumberValue: event.target.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import Module from "@Front/Config/Module";
|
|||||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||||
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
import { OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Customer";
|
import { OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Customer";
|
||||||
import { IOption } from "@Front/Components/DesignSystem/Select";
|
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
import User from "le-coffre-resources/dist/Notary";
|
import User from "le-coffre-resources/dist/Notary";
|
||||||
|
|
||||||
type IPropsClass = {
|
type IPropsClass = {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
@ -11,6 +10,7 @@ import { NextRouter, useRouter } from "next/router";
|
|||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
@ -23,7 +23,9 @@ type IState = {
|
|||||||
folder: IDashBoardFolder | null;
|
folder: IDashBoardFolder | null;
|
||||||
};
|
};
|
||||||
class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
||||||
private backwardPath = Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid);
|
private backwardPath = Module.getInstance()
|
||||||
|
.get()
|
||||||
|
.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid);
|
||||||
constructor(props: IPropsClass) {
|
constructor(props: IPropsClass) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
@ -42,10 +44,9 @@ class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
|||||||
|
|
||||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
<InputField
|
<TextAreaField
|
||||||
name="description"
|
name="description"
|
||||||
fakeplaceholder="Note du dossier"
|
placeholder="Note du dossier"
|
||||||
textarea
|
|
||||||
defaultValue={this.state.folder?.description ?? ""}
|
defaultValue={this.state.folder?.description ?? ""}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -72,7 +73,7 @@ class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
|||||||
await Folders.getInstance().put(this.props.folderUid, values);
|
await Folders.getInstance().put(this.props.folderUid, values);
|
||||||
this.props.router.push(this.backwardPath);
|
this.props.router.push(this.backwardPath);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
|
|
||||||
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
@ -14,7 +13,6 @@ import { NextRouter, useRouter } from "next/router";
|
|||||||
import BasePage from "../../Base";
|
import BasePage from "../../Base";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
type IPropsClass = IProps & {
|
type IPropsClass = IProps & {
|
||||||
@ -54,18 +52,14 @@ class UpdateFolderMetadataClass extends BasePage<IPropsClass, IState> {
|
|||||||
|
|
||||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
<InputField name="name" fakeplaceholder="Intitulé du dossier" defaultValue={this.state.selectedFolder?.name} />
|
<TextField name="name" placeholder="Intitulé du dossier" defaultValue={this.state.selectedFolder?.name} />
|
||||||
<InputField
|
<TextField
|
||||||
name="folder_number"
|
name="folder_number"
|
||||||
fakeplaceholder="Numéro de dossier"
|
placeholder="Numéro de dossier"
|
||||||
defaultValue={this.state.selectedFolder?.folder_number}
|
defaultValue={this.state.selectedFolder?.folder_number}
|
||||||
/>
|
/>
|
||||||
<Select options={[]} placeholder={"Type d'acte"} selectedOption={deedOption} disabled />
|
<Select name="deed" options={[]} placeholder={"Type d'acte"} selectedOption={deedOption} disabled />
|
||||||
<InputField
|
<TextField placeholder="Ouverture du dossier" defaultValue={openingDate.toLocaleDateString("fr-FR")} disabled />
|
||||||
fakeplaceholder="Ouverture du dossier"
|
|
||||||
defaultValue={openingDate.toLocaleDateString("fr-FR")}
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classes["button-container"]}>
|
<div className={classes["button-container"]}>
|
||||||
|
@ -5,7 +5,6 @@ import ValidateAnchoringGif from "@Front/Assets/images/validate_anchoring.gif";
|
|||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||||
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
|
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
@ -20,6 +19,7 @@ import BasePage from "../../Base";
|
|||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import OcrResult from "./OcrResult";
|
import OcrResult from "./OcrResult";
|
||||||
import Files from "@Front/Api/LeCoffreApi/SuperAdmin/Files/Files";
|
import Files from "@Front/Api/LeCoffreApi/SuperAdmin/Files/Files";
|
||||||
|
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
type IPropsClass = {
|
type IPropsClass = {
|
||||||
@ -168,7 +168,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
Veuillez indiquer au client le motif du refus de son document afin qu'il puisse vous renvoyer une bonne
|
Veuillez indiquer au client le motif du refus de son document afin qu'il puisse vous renvoyer une bonne
|
||||||
version.
|
version.
|
||||||
</Typography>
|
</Typography>
|
||||||
<InputField fakeplaceholder="Motif du refus" textarea onChange={this.onRefuseTextChange} />
|
<TextAreaField placeholder="Motif du refus" onChange={this.onRefuseTextChange} />
|
||||||
</div>
|
</div>
|
||||||
</Confirm>
|
</Confirm>
|
||||||
</div>
|
</div>
|
||||||
@ -322,7 +322,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRefuseTextChange(e: React.ChangeEvent<HTMLInputElement>) {
|
private onRefuseTextChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||||
this.setState({
|
this.setState({
|
||||||
refuseText: e.target.value,
|
refuseText: e.target.value,
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||||
import Folders, { IPutFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
|
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
|
||||||
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||||
@ -117,9 +117,9 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
|||||||
|
|
||||||
private async restoreFolder() {
|
private async restoreFolder() {
|
||||||
if (!this.state.selectedFolder) return;
|
if (!this.state.selectedFolder) return;
|
||||||
const folder = this.state.selectedFolder;
|
const ressourceFolder = OfficeFolder.hydrate<OfficeFolder>(this.state.selectedFolder);
|
||||||
folder.archived_description = null;
|
ressourceFolder.archived_description = null;
|
||||||
await Folders.getInstance().restore(this.state.selectedFolder.uid ?? "", folder as IPutFoldersParams);
|
await Folders.getInstance().restore(this.state.selectedFolder.uid ?? "", ressourceFolder);
|
||||||
this.props.router.push(
|
this.props.router.push(
|
||||||
Module.getInstance()
|
Module.getInstance()
|
||||||
.get()
|
.get()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import Form from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||||
@ -47,15 +47,16 @@ class UpdateFolderMetadataClass extends BasePage<IProps, IState> {
|
|||||||
|
|
||||||
<Form className={classes["form"]}>
|
<Form className={classes["form"]}>
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
<InputField name="input field" fakeplaceholder="Intitulé du dossier" />
|
<TextField name="input field" placeholder="Intitulé du dossier" />
|
||||||
<InputField name="input field" fakeplaceholder="Numéro de dossier" />
|
<TextField name="input field" placeholder="Numéro de dossier" />
|
||||||
<Select
|
<Select
|
||||||
|
name="deed"
|
||||||
options={selectOptions}
|
options={selectOptions}
|
||||||
onChange={this.onSelectedOption}
|
onChange={this.onSelectedOption}
|
||||||
placeholder={"Type d'acte"}
|
placeholder={"Type d'acte"}
|
||||||
selectedOption={this.state.selectedOption}
|
selectedOption={this.state.selectedOption}
|
||||||
/>
|
/>
|
||||||
<InputField name="input field" fakeplaceholder="Ouverture du dossier" />
|
<TextField name="input field" placeholder="Ouverture du dossier" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classes["button-container"]}>
|
<div className={classes["button-container"]}>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Form, { IApiFormErrors } from "@Front/Components/DesignSystem/Form";
|
import Form from "@Front/Components/DesignSystem/Form";
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||||
import Base from "@Front/Components/Layouts/Base";
|
import Base from "@Front/Components/Layouts/Base";
|
||||||
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
||||||
@ -25,19 +25,17 @@ export default class MyAccount extends Base<IProps, IState> {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Form onSubmit={this.onFormSubmit}>
|
<Form onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["form-container"]}>
|
<div className={classes["form-container"]}>
|
||||||
<InputField name="name" fakeplaceholder="Nom" type="text" defaultValue={"BIHR"} disabled />
|
<TextField name="name" placeholder="Nom" defaultValue={"BIHR"} disabled />
|
||||||
<InputField name="surname" fakeplaceholder="Prénom" type="text" defaultValue={"Nicolas"} disabled />
|
<TextField name="surname" placeholder="Prénom" defaultValue={"Nicolas"} disabled />
|
||||||
<InputField
|
<TextField
|
||||||
name="email"
|
name="email"
|
||||||
fakeplaceholder="E-mail"
|
placeholder="E-mail"
|
||||||
type="email"
|
|
||||||
defaultValue={"nicolas.bihr@notaires.fr"}
|
defaultValue={"nicolas.bihr@notaires.fr"}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="phone"
|
name="phone"
|
||||||
fakeplaceholder="Numéro de téléphone"
|
placeholder="Numéro de téléphone"
|
||||||
type="tel"
|
|
||||||
defaultValue={"06 74 83 90 23"}
|
defaultValue={"06 74 83 90 23"}
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
@ -50,25 +48,22 @@ export default class MyAccount extends Base<IProps, IState> {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Form onSubmit={this.onFormSubmit}>
|
<Form onSubmit={this.onFormSubmit}>
|
||||||
<div className={classes["form-container"]}>
|
<div className={classes["form-container"]}>
|
||||||
<InputField
|
<TextField
|
||||||
name="office_denomination"
|
name="office_denomination"
|
||||||
fakeplaceholder="Dénomination de l'office"
|
placeholder="Dénomination de l'office"
|
||||||
type="text"
|
|
||||||
defaultValue="Etude Office notarial du Cormier"
|
defaultValue="Etude Office notarial du Cormier"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<InputField name="crpcen" fakeplaceholder="CRPCEN" type="number" defaultValue="35137" disabled />
|
<TextField name="crpcen" placeholder="CRPCEN" defaultValue="35137" disabled />
|
||||||
<InputField
|
<TextField
|
||||||
name="cp_address"
|
name="cp_address"
|
||||||
fakeplaceholder="Adresse CP"
|
placeholder="Adresse CP"
|
||||||
defaultValue="2 RUE DE RENNES"
|
defaultValue="2 RUE DE RENNES"
|
||||||
type="text"
|
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
<InputField
|
<TextField
|
||||||
name="city"
|
name="city"
|
||||||
fakeplaceholder="Ville"
|
placeholder="Ville"
|
||||||
type="text"
|
|
||||||
defaultValue="35140 ST AUBIN DU CORMIER"
|
defaultValue="35140 ST AUBIN DU CORMIER"
|
||||||
disabled
|
disabled
|
||||||
/>
|
/>
|
||||||
@ -85,7 +80,6 @@ export default class MyAccount extends Base<IProps, IState> {
|
|||||||
e: React.FormEvent<HTMLFormElement> | null,
|
e: React.FormEvent<HTMLFormElement> | null,
|
||||||
values: {
|
values: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
},
|
}
|
||||||
onApiErrors: (apiFormErrors: IApiFormErrors | null) => void,
|
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user