🎨 Refacto API + Forms
This commit is contained in:
parent
08df377c7b
commit
462b11cd88
@ -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 { 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
|
||||
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 {
|
||||
private static instance: Folders;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/folders");
|
||||
@ -88,10 +59,10 @@ export default class Folders extends BaseSuperAdmin {
|
||||
/**
|
||||
* @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);
|
||||
try {
|
||||
return await this.postRequest<OfficeFolder>(url, body);
|
||||
return await this.postRequest(url, officeFolder);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
@ -101,10 +72,10 @@ export default class Folders extends BaseSuperAdmin {
|
||||
/**
|
||||
* @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}`));
|
||||
try {
|
||||
return await this.putRequest<OfficeFolder>(url, body);
|
||||
return await this.putRequest(url, body);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
@ -119,14 +90,14 @@ export default class Folders extends BaseSuperAdmin {
|
||||
const targetedFolder = await this.getByUid(uid);
|
||||
if (targetedFolder.office_folder_has_customers) return Promise.reject(`The folder ${uid} contains customers`);
|
||||
try {
|
||||
return await this.deleteRequest<OfficeFolder>(url);
|
||||
return await this.deleteRequest(url);
|
||||
} catch (err) {
|
||||
this.onError(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;
|
||||
try {
|
||||
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;
|
||||
try {
|
||||
return await this.put(uid, body);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
import { IOption } from "../Select";
|
||||
import { IOption } from "../Form/SelectField";
|
||||
import Tooltip from "../ToolTip";
|
||||
import Typography, { ITypo, ITypoColor } from "../Typography";
|
||||
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 classNames from "classnames";
|
||||
import Confirm from "../Modal/Confirm";
|
||||
import InputField from "../Form/Elements/InputField";
|
||||
import GreenCheckIcon from "@Assets/Icons/green-check.svg";
|
||||
import Loader from "../Loader";
|
||||
import TextAreaField from "../Form/TextareaField";
|
||||
|
||||
type IProps = {
|
||||
defaultFiles?: FileCustomer[];
|
||||
@ -69,7 +69,6 @@ export default class DepositDocument extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
console.log("Loading :", this.state.loading);
|
||||
return (
|
||||
<div className={classes["container"]}>
|
||||
<div
|
||||
@ -172,7 +171,7 @@ export default class DepositDocument extends React.Component<IProps, IState> {
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Votre document a été refusé pour la raison suivante :
|
||||
</Typography>
|
||||
<InputField textarea fakeplaceholder={"Description"} defaultValue={this.state.refusedReason} readOnly />
|
||||
<TextAreaField placeholder="Description" defaultValue={this.state.refusedReason} readonly />
|
||||
</div>
|
||||
</Confirm>
|
||||
</div>
|
||||
|
78
src/front/Components/DesignSystem/Form/BaseField.tsx
Normal file
78
src/front/Components/DesignSystem/Form/BaseField.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React from "react";
|
||||
import { FormContext, IFormContext } from ".";
|
||||
import { ValidationError } from "class-validator";
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 onChange(event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||
this.context?.onFieldChange(this.props.name, this);
|
||||
this.setState({ value: event.currentTarget.value });
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(event);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
flex-direction: column;
|
||||
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"]{
|
||||
.container-label{
|
@ -1,10 +1,11 @@
|
||||
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 } from "../Typography";
|
||||
import Typography, { ITypo, ITypoColor } from "../../Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
type IProps = {
|
||||
@ -16,6 +17,7 @@ type IProps = {
|
||||
className?: string;
|
||||
name?: string;
|
||||
disabled: boolean;
|
||||
errors?: ValidationError;
|
||||
};
|
||||
|
||||
export type IOption = {
|
||||
@ -30,9 +32,10 @@ type IState = {
|
||||
listWidth: number;
|
||||
listHeight: number;
|
||||
selectedOption: IOption | null;
|
||||
errors: ValidationError | null;
|
||||
};
|
||||
|
||||
export default class Select extends React.Component<IProps, IState> {
|
||||
export default class SelectField extends React.Component<IProps, IState> {
|
||||
private contentRef = React.createRef<HTMLUListElement>();
|
||||
private rootRef = React.createRef<HTMLDivElement>();
|
||||
private removeOnresize = () => {};
|
||||
@ -48,6 +51,7 @@ export default class Select extends React.Component<IProps, IState> {
|
||||
listHeight: 0,
|
||||
listWidth: 0,
|
||||
selectedOption: null,
|
||||
errors: this.props.errors ?? null,
|
||||
};
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.onSelect = this.onSelect.bind(this);
|
||||
@ -59,7 +63,8 @@ export default class Select extends React.Component<IProps, IState> {
|
||||
<div
|
||||
className={classNames(classes["root"], this.props.className)}
|
||||
ref={this.rootRef}
|
||||
data-disabled={this.props.disabled.toString()}>
|
||||
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"])}
|
||||
@ -102,10 +107,19 @@ export default class Select extends React.Component<IProps, IState> {
|
||||
</ul>
|
||||
|
||||
{this.state.isOpen && <div className={classes["backdrop"]} onClick={this.toggle} />}
|
||||
{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 {
|
||||
@ -157,4 +171,17 @@ export default class Select extends React.Component<IProps, IState> {
|
||||
});
|
||||
this.toggle(e);
|
||||
}
|
||||
|
||||
private renderErrors(): JSX.Element[] | null {
|
||||
if (!this.state.errors || !this.state.errors.constraints) return null;
|
||||
let errors: JSX.Element[] = [];
|
||||
Object.entries(this.state.errors.constraints).forEach(([key, value]) => {
|
||||
errors.push(
|
||||
<Typography key={key} typo={ITypo.CAPTION_14} color={ITypoColor.RED_FLASH}>
|
||||
{value}
|
||||
</Typography>,
|
||||
);
|
||||
});
|
||||
return errors;
|
||||
}
|
||||
}
|
@ -3,21 +3,6 @@
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
@ -27,7 +12,7 @@
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
border: 1px solid $grey-medium;
|
||||
border: 1px solid var(--grey-medium);
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
@ -104,41 +89,14 @@
|
||||
transition: transform 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.textarea {
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
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);
|
||||
&[data-is-errored="true"] {
|
||||
.input{
|
||||
border: 1px solid var(--red-flash);
|
||||
~ .fake-placeholder{
|
||||
color: var(--red-flash);
|
||||
}
|
||||
}
|
||||
|
||||
&:not([data-value=""]) {
|
||||
~ .fake-placeholder {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
}
|
51
src/front/Components/DesignSystem/Form/TextField/index.tsx
Normal file
51
src/front/Components/DesignSystem/Form/TextField/index.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
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.state.validationError !== null).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}
|
||||
name={this.props.name}
|
||||
/>
|
||||
<div className={classes["fake-placeholder"]}>
|
||||
{this.props.placeholder} {!this.props.required && " (Facultatif)"}
|
||||
</div>
|
||||
</div>
|
||||
{this.state.validationError !== null && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
private 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;
|
||||
}
|
||||
}
|
@ -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,58 @@
|
||||
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.state.validationError !== null).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}
|
||||
/>
|
||||
<div className={classes["fake-placeholder"]}>
|
||||
{this.props.placeholder} {!this.props.required && " (Facultatif)"}
|
||||
</div>
|
||||
{this.state.validationError !== null && <div className={classes["errors-container"]}>{this.renderErrors()}</div>}
|
||||
</div>
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
public override componentDidMount() {
|
||||
this.setState({
|
||||
value: this.props.defaultValue ?? "",
|
||||
});
|
||||
}
|
||||
|
||||
private 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,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 BaseField, { IProps as IBaseFieldProps, IError } from "./Elements/BaseField";
|
||||
import BaseField, { IProps as IBaseFieldProps } from "./BaseField";
|
||||
|
||||
export type IBaseField = BaseField<IBaseFieldProps>;
|
||||
|
||||
@ -14,31 +14,14 @@ type IFields = {
|
||||
[key: string]: IBaseField;
|
||||
};
|
||||
|
||||
export type IApiFormErrors = {
|
||||
[fieldName: string]: string;
|
||||
};
|
||||
|
||||
export type IFormErrors = {
|
||||
[key: string]: {
|
||||
field: IBaseField;
|
||||
errors: IError[] | undefined;
|
||||
};
|
||||
};
|
||||
|
||||
type IState = {};
|
||||
|
||||
export type IProps = {
|
||||
onFieldChange?: (name: string, field: IBaseField, errors: IFormErrors | null) => void;
|
||||
onFieldChange?: (name: string, field: IBaseField) => void;
|
||||
onSubmit?: (
|
||||
e: React.FormEvent<HTMLFormElement> | null,
|
||||
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;
|
||||
children?: ReactNode;
|
||||
};
|
||||
@ -57,7 +40,6 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
this.unSetField = this.unSetField.bind(this);
|
||||
this.onFieldChange = this.onFieldChange.bind(this);
|
||||
this.onSubmit = this.onSubmit.bind(this);
|
||||
this.onSubmitErrorApi = this.onSubmitErrorApi.bind(this);
|
||||
this.formRef = React.createRef();
|
||||
}
|
||||
|
||||
@ -69,7 +51,7 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
unSetField: this.unSetField,
|
||||
onFieldChange: this.onFieldChange,
|
||||
}}>
|
||||
<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}
|
||||
</form>
|
||||
</FormContext.Provider>
|
||||
@ -77,20 +59,6 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
public async onSubmit(e: React.FormEvent<HTMLFormElement> | null) {
|
||||
if (!this.props.action) 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 elementsValues = allChildren
|
||||
.filter((e) => {
|
||||
@ -108,7 +76,7 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
const checkBoxesValues = checkBoxesInput.reduce((obj, element) => {
|
||||
const inputName = element.getAttribute("name") ?? "";
|
||||
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);
|
||||
return {
|
||||
...obj,
|
||||
@ -125,51 +93,12 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
// Deleting empty input
|
||||
delete (allInputs as any)[""];
|
||||
if (this.props.onSubmit) {
|
||||
this.props.onSubmit(e, allInputs, this.onSubmitErrorApi);
|
||||
this.props.onSubmit(e, allInputs);
|
||||
}
|
||||
|
||||
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) {
|
||||
this.fields[name] = field;
|
||||
}
|
||||
@ -180,8 +109,7 @@ export default class Form extends React.Component<IProps, IState> {
|
||||
|
||||
protected async onFieldChange(name: string, field: IBaseField) {
|
||||
if (this.props.onFieldChange) {
|
||||
const errors = await this.validate();
|
||||
this.props.onFieldChange(name, field, errors);
|
||||
this.props.onFieldChange(name, field);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import classNames from "classnames";
|
||||
import React from "react";
|
||||
import ReactSelect, { ActionMeta, MultiValue, Options, PropsValue } from "react-select";
|
||||
|
||||
import { IOption } from "../Select";
|
||||
import { IOption } from "../Form/SelectField";
|
||||
import Typography, { ITypo } from "../Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
import { styles } from "./styles";
|
||||
|
@ -9,11 +9,11 @@ import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import WindowStore from "@Front/Stores/WindowStore";
|
||||
import classNames from "classnames";
|
||||
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
|
||||
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||
|
||||
|
||||
type IProps = {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Documents, { IGetDocumentsparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Documents/Documents";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
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 Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
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"]}>
|
||||
Vous souhaitez envoyer un autre document à votre notaire ?
|
||||
</Typography>
|
||||
<InputField fakeplaceholder={"Nom du document"} />
|
||||
<TextField placeholder="Nom du document" />
|
||||
<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
|
||||
document correspondant.
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer";
|
||||
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
|
||||
import { EFolderStatus } from "le-coffre-resources/dist/Customer/OfficeFolder";
|
||||
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||
import {
|
||||
Address,
|
||||
Contact,
|
||||
@ -147,6 +147,8 @@ export const fileMock: File = {
|
||||
file_path:
|
||||
"https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf",
|
||||
archived_at: null,
|
||||
mimetype: "image/png",
|
||||
size: 0,
|
||||
};
|
||||
|
||||
export const fileMock2: File = {
|
||||
@ -158,6 +160,8 @@ export const fileMock2: File = {
|
||||
file_path:
|
||||
"https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19",
|
||||
archived_at: null,
|
||||
mimetype: "image/png",
|
||||
size: 0,
|
||||
};
|
||||
|
||||
export const identityFile: File = {
|
||||
@ -168,6 +172,8 @@ export const identityFile: File = {
|
||||
file_name: "file_3",
|
||||
file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png",
|
||||
archived_at: null,
|
||||
mimetype: "image/png",
|
||||
size: 0,
|
||||
};
|
||||
|
||||
export const documentIdentity: Document = {
|
||||
|
@ -1,18 +1,15 @@
|
||||
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary";
|
||||
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
|
||||
import FolderContainer from "@Front/Components/DesignSystem/FolderContainer";
|
||||
import FolderList from "@Front/Components/DesignSystem/FolderListContainer";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import HeaderLink from "@Front/Components/DesignSystem/Header/HeaderLink";
|
||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
|
||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
||||
import ToolTip from "@Front/Components/DesignSystem/ToolTip";
|
||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
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 { customer2, document, documentDeposited, documentPending, folder, folders, folderWithPendingDocument } from "./dummyData";
|
||||
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||
|
||||
type IState = {
|
||||
isModalDisplayed: boolean;
|
||||
@ -150,13 +150,13 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
||||
<Typography typo={ITypo.H3}>Input component</Typography>
|
||||
</div>
|
||||
<div className={classes["sub-section"]}>
|
||||
<InputField name="input field" fakeplaceholder="input place hodler" />
|
||||
<TextField name="input field" placeholder="input place hodler" />
|
||||
</div>
|
||||
<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 className={classes["sub-section"]}>
|
||||
<InputField name="input field" fakeplaceholder="number place hodler" type="number" />
|
||||
<TextField name="input field" placeholder="number place hodler" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -199,7 +199,7 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
||||
</div>
|
||||
<div className={classes["sub-section"]}>
|
||||
<div className={classes["folder-conatainer"]}>
|
||||
<Select
|
||||
<SelectField
|
||||
options={selectOptions}
|
||||
onChange={this.onSelectedOption}
|
||||
placeholder={"Type d'acte"}
|
||||
@ -222,7 +222,7 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
||||
<div className={classes["sub-section"]}>
|
||||
<Typography typo={ITypo.P_16}>Documents Depoited</Typography>
|
||||
<div className={classes["folder-conatainer"]}>
|
||||
<DocumentNotary document={documentPending} folderUid=""/>
|
||||
<DocumentNotary document={documentPending} folderUid="" />
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes["sub-section"]}>
|
||||
@ -239,7 +239,14 @@ export default class DesignSystem extends BasePage<IProps, IState> {
|
||||
<Typography typo={ITypo.H3}>Notary Documents</Typography>
|
||||
</div>
|
||||
<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>
|
||||
|
||||
|
@ -1,24 +1,22 @@
|
||||
|
||||
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 Form from "@Front/Components/DesignSystem/Form";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
|
||||
import { IOption } from "@Front/Components/DesignSystem/Select";
|
||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { 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 { NextRouter, useRouter } from "next/router";
|
||||
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import { TextField } from "@mui/material";
|
||||
|
||||
enum ESelectedOption {
|
||||
EXISTING_CUSTOMER = "existing_customer",
|
||||
@ -107,14 +105,12 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
|
||||
|
||||
{this.state.selectedOption === "new_customer" && (
|
||||
<div className={classes["new-client"]}>
|
||||
<InputField name="last_name" fakeplaceholder="Nom" />
|
||||
<InputField name="first_name" fakeplaceholder="Prénom" />
|
||||
<InputField name="email" fakeplaceholder="E-mail" isEmail />
|
||||
<InputField
|
||||
<TextField name="last_name" placeholder="Nom" />
|
||||
<TextField name="first_name" placeholder="Prénom" />
|
||||
<TextField name="email" placeholder="E-mail" />
|
||||
<TextField
|
||||
name="cell_phone_number"
|
||||
fakeplaceholder="Numéro de téléphone"
|
||||
numbersOnly
|
||||
maxLength={10}
|
||||
placeholder="Numéro de téléphone"
|
||||
/>
|
||||
<div className={classes["button-container"]}>
|
||||
<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
|
||||
|
||||
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 {
|
||||
customer: { uid: customer.value },
|
||||
};
|
||||
}) as IPutFoldersParams["office_folder_has_customers"];
|
||||
}) as Partial<OfficeFolderHasCustomer>[];
|
||||
|
||||
if (this.state.selectedOption === "new_customer") {
|
||||
const customer: Customer = await Customers.getInstance().post({
|
||||
contact: values,
|
||||
});
|
||||
if (!customer.uid) return;
|
||||
customersToLink?.push({ customer: { uid: customer.uid } });
|
||||
customersToLink?.push({ customer: { uid: customer.uid } } as Partial<OfficeFolderHasCustomer>);
|
||||
}
|
||||
|
||||
if (customersToLink) {
|
||||
const body = {
|
||||
office_folder_has_customers: customersToLink,
|
||||
};
|
||||
const body = OfficeFolder.hydrate<OfficeFolder>({ office_folder_has_customers: customersToLink.map((customer) => {
|
||||
return OfficeFolderHasCustomer.hydrate<OfficeFolderHasCustomer>(customer);
|
||||
}) });
|
||||
|
||||
await Folders.getInstance().put(this.props.selectedFolderUid, body);
|
||||
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 CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
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 { IOption } from "@Front/Components/DesignSystem/Select";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
@ -19,6 +17,9 @@ import React from "react";
|
||||
|
||||
import BasePage from "../../Base";
|
||||
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 IPropsClass = IProps & {
|
||||
@ -109,17 +110,14 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
|
||||
cancelText={"Annuler"}
|
||||
confirmText={"Ajouter"}>
|
||||
<div className={classes["add-document-form-container"]}>
|
||||
<InputField
|
||||
<TextField
|
||||
name="document_name"
|
||||
fakeplaceholder="Nom du document à ajouter"
|
||||
type="text"
|
||||
placeholder="Nom du document à ajouter"
|
||||
onChange={this.onDocumentNameChange}
|
||||
/>
|
||||
<InputField
|
||||
<TextAreaField
|
||||
name="description"
|
||||
fakeplaceholder="Description visible par le client"
|
||||
type="text"
|
||||
textarea
|
||||
placeholder="Description visible par le client"
|
||||
onChange={this.onVisibleDescriptionChange}
|
||||
/>
|
||||
</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({
|
||||
visibleDescription: e.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
private onDocumentNameChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
private onDocumentNameChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||
this.setState({
|
||||
documentName: e.target.value,
|
||||
});
|
||||
@ -275,7 +273,7 @@ class AskDocumentsClass extends BasePage<IPropsClass, IState> {
|
||||
) {
|
||||
try {
|
||||
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({
|
||||
folder: {
|
||||
uid: this.props.folderUid,
|
||||
|
@ -1,24 +1,27 @@
|
||||
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 Form from "@Front/Components/DesignSystem/Form";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
|
||||
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 BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||
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 { ActionMeta, MultiValue } from "react-select";
|
||||
|
||||
import BasePage from "../../Base";
|
||||
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";
|
||||
import { ValidationError } from "class-validator";
|
||||
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 IFormValues = {
|
||||
folder_number: string;
|
||||
@ -41,6 +44,7 @@ type IState = {
|
||||
deedTypesOptions: IOption[];
|
||||
collaborators: User[];
|
||||
collaboratorsOptions: IOption[];
|
||||
validationError: ValidationError[];
|
||||
};
|
||||
class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
public constructor(props: IPropsClass) {
|
||||
@ -59,6 +63,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
deedTypesOptions: [],
|
||||
collaborators: [],
|
||||
collaboratorsOptions: [],
|
||||
validationError: [],
|
||||
};
|
||||
|
||||
this.radioOnChange = this.radioOnChange.bind(this);
|
||||
@ -84,19 +89,29 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
</Typography>
|
||||
<Form onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["form-container"]}>
|
||||
<InputField
|
||||
<TextField
|
||||
name="folder_number"
|
||||
fakeplaceholder="Numéro de dossier"
|
||||
type="text"
|
||||
placeholder="Numéro de dossier"
|
||||
onChange={this.onFolderNumberChange}
|
||||
validationError={this.state.validationError.find((error) => error.property === "folder_number")}
|
||||
/>
|
||||
<InputField name="name" fakeplaceholder="Intitulé" onChange={this.onEntitleChange} />
|
||||
<Select options={this.state.deedTypesOptions} placeholder={"Type d’acte"} onChange={this.onActTypeChange} />
|
||||
<InputField
|
||||
<TextField
|
||||
name="name"
|
||||
placeholder="Intitulé"
|
||||
onChange={this.onEntitleChange}
|
||||
validationError={this.state.validationError.find((error) => error.property === "name")}
|
||||
/>
|
||||
<SelectField
|
||||
options={this.state.deedTypesOptions}
|
||||
placeholder={"Type d'acte"}
|
||||
onChange={this.onActTypeChange}
|
||||
errors={this.state.validationError.find((error) => error.property === "deed")}
|
||||
/>
|
||||
<TextAreaField
|
||||
name="description"
|
||||
fakeplaceholder="Note du dossier"
|
||||
textarea
|
||||
placeholder="Note du dossier"
|
||||
onChange={this.onPersonalNoteChange}
|
||||
validationError={this.state.validationError.find((error) => error.property === "description")}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes["access-container"]}>
|
||||
@ -122,7 +137,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
</div>
|
||||
)}
|
||||
<div className={classes["buttons-container"]}>
|
||||
<Button fullwidth disabled={!this.isFormSubmittable()} type="submit">
|
||||
<Button fullwidth type="submit">
|
||||
Créer un dossier
|
||||
</Button>
|
||||
</div>
|
||||
@ -166,7 +181,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
})) as IOption[];
|
||||
}
|
||||
|
||||
private onFolderNumberChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
private onFolderNumberChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||
this.setState({
|
||||
formValues: {
|
||||
...this.state.formValues,
|
||||
@ -175,7 +190,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
});
|
||||
}
|
||||
|
||||
private onEntitleChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
private onEntitleChange(e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||
this.setState({
|
||||
formValues: {
|
||||
...this.state.formValues,
|
||||
@ -193,7 +208,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
});
|
||||
}
|
||||
|
||||
private onPersonalNoteChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
private onPersonalNoteChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||
this.setState({
|
||||
formValues: {
|
||||
...this.state.formValues,
|
||||
@ -226,35 +241,61 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
|
||||
*/
|
||||
const usersMock = await Users.getInstance().get({ include: { office_membership: true } });
|
||||
const userMock = usersMock[0];
|
||||
// -----
|
||||
if (!selectedDeedTypeUid) return;
|
||||
if (!userMock?.office_membership?.uid) return;
|
||||
|
||||
let stakeholders = this.getStakeholders();
|
||||
let test = stakeholders.map((stakeholder) => ({
|
||||
let testUsers = stakeholders.map((stakeholder) => ({
|
||||
user_stakeholder: {
|
||||
uid: stakeholder.user_stakeholder.uid,
|
||||
},
|
||||
}));
|
||||
|
||||
const output: IPostFoldersParams = {
|
||||
const officeFolderForm = OfficeFolder.hydrate<OfficeFolder>({
|
||||
folder_number: values["folder_number"],
|
||||
name: values["name"],
|
||||
description: values["description"],
|
||||
deed: {
|
||||
deed_type: {
|
||||
uid: selectedDeedTypeUid.uid,
|
||||
},
|
||||
},
|
||||
office: {
|
||||
uid: userMock?.office_membership.uid,
|
||||
},
|
||||
office_folder_has_stakeholder: test,
|
||||
};
|
||||
deed: Deed.hydrate<Deed>({
|
||||
deed_type: DeedType.hydrate<DeedType>({
|
||||
uid: selectedDeedTypeUid?.uid,
|
||||
}),
|
||||
}),
|
||||
office: Office.hydrate<Office>({
|
||||
uid: userMock?.office_membership?.uid,
|
||||
}),
|
||||
office_folder_has_stakeholder: testUsers.map((user) => {
|
||||
return OfficeFolderHasStakeholder.hydrate<OfficeFolderHasStakeholder>({
|
||||
user_stakeholder: User.hydrate<User>({
|
||||
uid: user.user_stakeholder.uid,
|
||||
}),
|
||||
});
|
||||
}),
|
||||
});
|
||||
|
||||
const created = await Folders.getInstance().post(output);
|
||||
if (created) {
|
||||
this.props.router.push(`/folders/${created.uid}`);
|
||||
try {
|
||||
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
|
||||
} 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) {
|
||||
this.setState({
|
||||
validationError: backError as ValidationError[],
|
||||
});
|
||||
// this.setState({
|
||||
// validationError: [{
|
||||
// constraints: {
|
||||
// unique: "Le numéro de dossier est déjà utilisé"
|
||||
// },
|
||||
// property: "folder_number",
|
||||
// } as ValidationError],
|
||||
// });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
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 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 QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
@ -17,6 +16,7 @@ import { ChangeEvent } from "react";
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import ClientSection from "./ClientSection";
|
||||
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||
|
||||
type IProps = {};
|
||||
|
||||
@ -110,10 +110,9 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
||||
<div className={classes["modal-title"]}>
|
||||
<Typography typo={ITypo.P_16}>Souhaitez-vous vraiment archiver le dossier ?</Typography>
|
||||
</div>
|
||||
<InputField
|
||||
<TextAreaField
|
||||
name="archived_description"
|
||||
fakeplaceholder="Description"
|
||||
textarea
|
||||
placeholder="Description"
|
||||
onChange={this.onArchivedDescriptionInputChange}
|
||||
/>
|
||||
</Confirm>
|
||||
@ -172,15 +171,15 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
||||
this.setState({ isArchivedModalOpen: false });
|
||||
}
|
||||
|
||||
private onArchivedDescriptionInputChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
private onArchivedDescriptionInputChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
|
||||
this.setState({ inputArchivedDescripton: e.target.value });
|
||||
}
|
||||
|
||||
private async onArchivedModalAccepted() {
|
||||
if (!this.state.selectedFolder) return;
|
||||
const folder = this.state.selectedFolder;
|
||||
folder.archived_description = this.state.inputArchivedDescripton;
|
||||
await Folders.getInstance().archive(this.state.selectedFolder.uid ?? "", folder as IPutFoldersParams);
|
||||
const ressourceFolder = OfficeFolder.hydrate<OfficeFolder>(this.state.selectedFolder);
|
||||
ressourceFolder.archived_description = this.state.inputArchivedDescripton;
|
||||
await Folders.getInstance().archive(this.state.selectedFolder.uid ?? "", ressourceFolder);
|
||||
this.closeArchivedModal();
|
||||
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 Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
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 Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
@ -12,9 +14,6 @@ import Link from "next/link";
|
||||
import { NextRouter, useRouter } from "next/router";
|
||||
import { ChangeEvent } from "react";
|
||||
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
type IProps = {};
|
||||
|
||||
type IPropsClass = IProps & {
|
||||
@ -78,44 +77,40 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
||||
<Typography typo={ITypo.H1Bis}>Modifier les informations du client</Typography>
|
||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["content"]}>
|
||||
<InputField
|
||||
<TextField
|
||||
name="first_name"
|
||||
fakeplaceholder="Nom"
|
||||
placeholder="Nom"
|
||||
onChange={this.onChangeNameInput}
|
||||
defaultValue={this.state.customer?.contact?.first_name}
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="last_name"
|
||||
fakeplaceholder="Prénom"
|
||||
placeholder="Prénom"
|
||||
onChange={this.onChangeFirstNameInput}
|
||||
defaultValue={this.state.customer?.contact?.last_name}
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="email"
|
||||
fakeplaceholder="E-mail"
|
||||
isEmail
|
||||
placeholder="E-mail"
|
||||
onChange={this.onChangeEmailInput}
|
||||
defaultValue={this.state.customer?.contact?.email}
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="cell_phone_number"
|
||||
fakeplaceholder="Numéro de téléphone"
|
||||
isPositiveNumber
|
||||
placeholder="Numéro de téléphone"
|
||||
onChange={this.onChangePhoneNumberInput}
|
||||
defaultValue={this.state.customer?.contact?.cell_phone_number ?? ""}
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="birthdate"
|
||||
type="text"
|
||||
fakeplaceholder="Date de naissance"
|
||||
placeholder="Date de naissance"
|
||||
required={false}
|
||||
onChange={this.onChangeBirthDateInput}
|
||||
defaultValue={this.state.customer?.contact?.birthdate?.toString() ?? ""}
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="address"
|
||||
type="text"
|
||||
fakeplaceholder="Adresse"
|
||||
placeholder="Adresse"
|
||||
required={false}
|
||||
onChange={this.onChangeAddressInput}
|
||||
defaultValue={this.state.customer?.contact?.address?.address ?? ""}
|
||||
@ -185,11 +180,11 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
||||
},
|
||||
} as Contact;
|
||||
|
||||
try{
|
||||
await Customers.getInstance().put(this.props.customerUid, { contact })
|
||||
try {
|
||||
await Customers.getInstance().put(this.props.customerUid, { contact });
|
||||
this.props.router.push(this.backwardPath);
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,25 +200,25 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
|
||||
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) });
|
||||
}
|
||||
|
||||
private onChangeAddressInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
||||
private onChangeAddressInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||
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 });
|
||||
}
|
||||
|
||||
private onChangeFirstNameInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
||||
private onChangeFirstNameInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||
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 });
|
||||
}
|
||||
private onChangePhoneNumberInput(event: ChangeEvent<HTMLInputElement & HTMLSelectElement & HTMLTextAreaElement>) {
|
||||
private onChangePhoneNumberInput(event: ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) {
|
||||
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 Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||
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";
|
||||
|
||||
type IPropsClass = {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
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 BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
@ -11,6 +10,7 @@ import { NextRouter, useRouter } from "next/router";
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||
|
||||
type IProps = {};
|
||||
|
||||
@ -23,7 +23,9 @@ type IState = {
|
||||
folder: IDashBoardFolder | null;
|
||||
};
|
||||
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) {
|
||||
super(props);
|
||||
this.state = {
|
||||
@ -42,10 +44,9 @@ class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
||||
|
||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["content"]}>
|
||||
<InputField
|
||||
<TextAreaField
|
||||
name="description"
|
||||
fakeplaceholder="Note du dossier"
|
||||
textarea
|
||||
placeholder="Note du dossier"
|
||||
defaultValue={this.state.folder?.description ?? ""}
|
||||
/>
|
||||
</div>
|
||||
@ -72,7 +73,7 @@ class UpdateFolderDescriptionClass extends BasePage<IPropsClass, IState> {
|
||||
await Folders.getInstance().put(this.props.folderUid, values);
|
||||
this.props.router.push(this.backwardPath);
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
|
||||
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
||||
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
@ -14,7 +13,6 @@ import { NextRouter, useRouter } from "next/router";
|
||||
import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
|
||||
type IProps = {};
|
||||
|
||||
type IPropsClass = IProps & {
|
||||
@ -54,18 +52,14 @@ class UpdateFolderMetadataClass extends BasePage<IPropsClass, IState> {
|
||||
|
||||
<Form className={classes["form"]} onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["content"]}>
|
||||
<InputField name="name" fakeplaceholder="Intitulé du dossier" defaultValue={this.state.selectedFolder?.name} />
|
||||
<InputField
|
||||
<TextField name="name" placeholder="Intitulé du dossier" defaultValue={this.state.selectedFolder?.name} />
|
||||
<TextField
|
||||
name="folder_number"
|
||||
fakeplaceholder="Numéro de dossier"
|
||||
placeholder="Numéro de dossier"
|
||||
defaultValue={this.state.selectedFolder?.folder_number}
|
||||
/>
|
||||
<Select options={[]} placeholder={"Type d'acte"} selectedOption={deedOption} disabled />
|
||||
<InputField
|
||||
fakeplaceholder="Ouverture du dossier"
|
||||
defaultValue={openingDate.toLocaleDateString("fr-FR")}
|
||||
disabled
|
||||
/>
|
||||
<TextField placeholder="Ouverture du dossier" defaultValue={openingDate.toLocaleDateString("fr-FR")} disabled />
|
||||
</div>
|
||||
|
||||
<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 CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
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 Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
@ -20,6 +19,7 @@ import BasePage from "../../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import OcrResult from "./OcrResult";
|
||||
import Files from "@Front/Api/LeCoffreApi/SuperAdmin/Files/Files";
|
||||
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
|
||||
|
||||
type IProps = {};
|
||||
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
|
||||
version.
|
||||
</Typography>
|
||||
<InputField fakeplaceholder="Motif du refus" textarea onChange={this.onRefuseTextChange} />
|
||||
<TextAreaField placeholder="Motif du refus" onChange={this.onRefuseTextChange} />
|
||||
</div>
|
||||
</Confirm>
|
||||
</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({
|
||||
refuseText: e.target.value,
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
|
||||
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
|
||||
@ -117,9 +117,9 @@ class FolderInformationClass extends BasePage<IPropsClass, IState> {
|
||||
|
||||
private async restoreFolder() {
|
||||
if (!this.state.selectedFolder) return;
|
||||
const folder = this.state.selectedFolder;
|
||||
folder.archived_description = null;
|
||||
await Folders.getInstance().restore(this.state.selectedFolder.uid ?? "", folder as IPutFoldersParams);
|
||||
const ressourceFolder = OfficeFolder.hydrate<OfficeFolder>(this.state.selectedFolder);
|
||||
ressourceFolder.archived_description = null;
|
||||
await Folders.getInstance().restore(this.state.selectedFolder.uid ?? "", ressourceFolder);
|
||||
this.props.router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import Select, { IOption } from "@Front/Components/DesignSystem/Select";
|
||||
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||
import Select, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
|
||||
@ -47,15 +47,15 @@ class UpdateFolderMetadataClass extends BasePage<IProps, IState> {
|
||||
|
||||
<Form className={classes["form"]}>
|
||||
<div className={classes["content"]}>
|
||||
<InputField name="input field" fakeplaceholder="Intitulé du dossier" />
|
||||
<InputField name="input field" fakeplaceholder="Numéro de dossier" />
|
||||
<TextField name="input field" placeholder="Intitulé du dossier" />
|
||||
<TextField name="input field" placeholder="Numéro de dossier" />
|
||||
<Select
|
||||
options={selectOptions}
|
||||
onChange={this.onSelectedOption}
|
||||
placeholder={"Type d'acte"}
|
||||
selectedOption={this.state.selectedOption}
|
||||
/>
|
||||
<InputField name="input field" fakeplaceholder="Ouverture du dossier" />
|
||||
<TextField name="input field" placeholder="Ouverture du dossier" />
|
||||
</div>
|
||||
|
||||
<div className={classes["button-container"]}>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Form, { IApiFormErrors } from "@Front/Components/DesignSystem/Form";
|
||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import Base from "@Front/Components/Layouts/Base";
|
||||
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
||||
@ -25,19 +25,17 @@ export default class MyAccount extends Base<IProps, IState> {
|
||||
</Typography>
|
||||
<Form onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["form-container"]}>
|
||||
<InputField name="name" fakeplaceholder="Nom" type="text" defaultValue={"BIHR"} disabled />
|
||||
<InputField name="surname" fakeplaceholder="Prénom" type="text" defaultValue={"Nicolas"} disabled />
|
||||
<InputField
|
||||
<TextField name="name" placeholder="Nom" defaultValue={"BIHR"} disabled />
|
||||
<TextField name="surname" placeholder="Prénom" defaultValue={"Nicolas"} disabled />
|
||||
<TextField
|
||||
name="email"
|
||||
fakeplaceholder="E-mail"
|
||||
type="email"
|
||||
placeholder="E-mail"
|
||||
defaultValue={"nicolas.bihr@notaires.fr"}
|
||||
disabled
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="phone"
|
||||
fakeplaceholder="Numéro de téléphone"
|
||||
type="tel"
|
||||
placeholder="Numéro de téléphone"
|
||||
defaultValue={"06 74 83 90 23"}
|
||||
disabled
|
||||
/>
|
||||
@ -50,25 +48,22 @@ export default class MyAccount extends Base<IProps, IState> {
|
||||
</Typography>
|
||||
<Form onSubmit={this.onFormSubmit}>
|
||||
<div className={classes["form-container"]}>
|
||||
<InputField
|
||||
<TextField
|
||||
name="office_denomination"
|
||||
fakeplaceholder="Dénomination de l'office"
|
||||
type="text"
|
||||
placeholder="Dénomination de l'office"
|
||||
defaultValue="Etude Office notarial du Cormier"
|
||||
disabled
|
||||
/>
|
||||
<InputField name="crpcen" fakeplaceholder="CRPCEN" type="number" defaultValue="35137" disabled />
|
||||
<InputField
|
||||
<TextField name="crpcen" placeholder="CRPCEN" defaultValue="35137" disabled />
|
||||
<TextField
|
||||
name="cp_address"
|
||||
fakeplaceholder="Adresse CP"
|
||||
placeholder="Adresse CP"
|
||||
defaultValue="2 RUE DE RENNES"
|
||||
type="text"
|
||||
disabled
|
||||
/>
|
||||
<InputField
|
||||
<TextField
|
||||
name="city"
|
||||
fakeplaceholder="Ville"
|
||||
type="text"
|
||||
placeholder="Ville"
|
||||
defaultValue="35140 ST AUBIN DU CORMIER"
|
||||
disabled
|
||||
/>
|
||||
@ -85,7 +80,6 @@ export default class MyAccount extends Base<IProps, IState> {
|
||||
e: React.FormEvent<HTMLFormElement> | null,
|
||||
values: {
|
||||
[key: string]: string;
|
||||
},
|
||||
onApiErrors: (apiFormErrors: IApiFormErrors | null) => void,
|
||||
}
|
||||
) {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user