Merge branch 'dev' into staging

This commit is contained in:
Maxime Lalo 2024-04-05 12:07:50 +02:00
commit a272a9ad2a
24 changed files with 188 additions and 122 deletions

View File

@ -19,7 +19,7 @@ export default class Auth extends BaseApiService {
try { try {
return await fetch(url); return await fetch(url);
} catch (err) { } catch (err) {
console.log(err); console.error(err);
this.onError(err); this.onError(err);
return Promise.reject(err); return Promise.reject(err);
} }
@ -27,7 +27,11 @@ export default class Auth extends BaseApiService {
public async loginWithIdNot() { public async loginWithIdNot() {
const variables = FrontendVariables.getInstance(); const variables = FrontendVariables.getInstance();
const url = new URL(`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${variables.FRONT_APP_HOST}/authorized-client&scope=openid,profile&response_type=code`); const url = new URL(
`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${
variables.FRONT_APP_HOST
}/authorized-client&scope=openid,profile&response_type=code`,
);
try { try {
return await this.getRequest(url); return await this.getRequest(url);
} catch (err) { } catch (err) {
@ -36,16 +40,15 @@ export default class Auth extends BaseApiService {
} }
} }
public async getIdnotJwt(autorizationCode: string | string[]): Promise<{accessToken: string, refreshToken: string}> { public async getIdnotJwt(autorizationCode: string | string[]): Promise<{ accessToken: string; refreshToken: string }> {
const variables = FrontendVariables.getInstance(); const variables = FrontendVariables.getInstance();
const baseBackUrl = variables.BACK_API_PROTOCOL + variables.BACK_API_HOST; const baseBackUrl = variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`); const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
try { try {
return await this.postRequest<{accessToken: string, refreshToken: string}>(url); return await this.postRequest<{ accessToken: string; refreshToken: string }>(url);
} catch (err) { } catch (err) {
this.onError(err); this.onError(err);
return Promise.reject(err); return Promise.reject(err);
} }
} }
} }

View File

@ -14,6 +14,11 @@ export type IGetClientPortalSessionResponse = {
url: string; url: string;
}; };
export interface IGetCustomerBySubscriptionIdParams {
email: string;
name: string;
}
export default class Stripe extends BaseAdmin { export default class Stripe extends BaseAdmin {
private static instance: Stripe; private static instance: Stripe;
private readonly baseURl = this.namespaceUrl.concat("/stripe"); private readonly baseURl = this.namespaceUrl.concat("/stripe");
@ -53,4 +58,14 @@ export default class Stripe extends BaseAdmin {
return Promise.reject(err); return Promise.reject(err);
} }
} }
public async getCustomerBySubscriptionId(subscriptionId: string) {
const url = new URL(this.baseURl.concat(`/${subscriptionId}/customer`));
try {
return await this.getRequest<IGetCustomerBySubscriptionIdParams>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
} }

View File

@ -4,6 +4,9 @@
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
&.disabled {
cursor: not-allowed;
}
input[type="checkbox"] { input[type="checkbox"] {
appearance: none; appearance: none;
@ -15,6 +18,10 @@
margin-right: 16px; margin-right: 16px;
display: grid; display: grid;
place-content: center; place-content: center;
&:disabled {
cursor: not-allowed;
}
} }
input[type="checkbox"]::before { input[type="checkbox"]::before {

View File

@ -4,6 +4,7 @@ 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";
import classNames from "classnames";
type IProps = { type IProps = {
name?: string; name?: string;
@ -11,6 +12,7 @@ type IProps = {
toolTip?: string; toolTip?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void; onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
checked: boolean; checked: boolean;
disabled?: boolean;
}; };
type IState = { type IState = {
@ -21,6 +23,7 @@ export default class CheckBox extends React.Component<IProps, IState> {
static defaultProps = { static defaultProps = {
toolTip: "", toolTip: "",
checked: false, checked: false,
disabled: false,
}; };
constructor(props: IProps) { constructor(props: IProps) {
@ -35,13 +38,14 @@ export default class CheckBox extends React.Component<IProps, IState> {
public override render(): JSX.Element { public override render(): JSX.Element {
return ( return (
<Typography typo={ITypo.P_ERR_16} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_ERR_16} color={ITypoColor.BLACK}>
<label className={classes["root"]}> <label className={classNames(classes["root"], this.props.disabled && classes["disabled"])}>
<input <input
type="checkbox" type="checkbox"
name={this.props.name ?? (this.props.option.value as string)} name={this.props.name ?? (this.props.option.value as string)}
value={this.props.option.value as string} value={this.props.option.value as string}
onChange={this.onChange} onChange={this.onChange}
checked={this.state.checked} checked={this.state.checked}
disabled={this.props.disabled}
/> />
{this.props.option.label} {this.props.option.label}
{this.props.toolTip && <Tooltip className={classes["tooltip"]} text={this.props.toolTip} />} {this.props.toolTip && <Tooltip className={classes["tooltip"]} text={this.props.toolTip} />}

View File

@ -421,7 +421,6 @@ export default class DepositDocument extends React.Component<IProps, IState> {
} }
} catch (e) { } catch (e) {
this.setState({ loading: false }); this.setState({ loading: false });
console.log(e);
} }
} }

View File

@ -85,14 +85,12 @@ export default class DepositRib extends React.Component<IProps, IState> {
// formData.append("file", this.state.documents[0]!, this.state.documents[0]!.name); // formData.append("file", this.state.documents[0]!, this.state.documents[0]!.name);
// const sentFile = await Bucket.getInstance().post(formData); // const sentFile = await Bucket.getInstance().post(formData);
// console.log("Sent file:", sentFile);
// // Reset documents state // // Reset documents state
// this.setState({ documents: [] }); // this.setState({ documents: [] });
// }; // };
// handleCancel = () => { // handleCancel = () => {
// console.log("Cancel:", this.state.documents);
// // Reset documents state // // Reset documents state
// this.setState({ documents: [] }); // this.setState({ documents: [] });
// }; // };

View File

@ -29,7 +29,7 @@ export default function Navigation() {
await OfficeFolderAnchors.getInstance().getByUid(anchor.folder?.uid as string); await OfficeFolderAnchors.getInstance().getByUid(anchor.folder?.uid as string);
} }
} catch (e) { } catch (e) {
console.log(e); console.error(e);
} }
}, []); }, []);

View File

@ -38,7 +38,6 @@ class ToastElementClass extends React.Component<IPropsClass, IState> {
} }
public override render(): JSX.Element { public override render(): JSX.Element {
console.log(this.props);
const toast = this.props.toast; const toast = this.props.toast;
const style = { const style = {
"--data-duration": `${toast.time}ms`, "--data-duration": `${toast.time}ms`,

View File

@ -33,7 +33,6 @@ export default function DocumentTypeListContainer(props: IProps) {
const onSelectedBlock = useCallback( const onSelectedBlock = useCallback(
(block: IBlock) => { (block: IBlock) => {
props.onCloseLeftSide && props.onCloseLeftSide(); props.onCloseLeftSide && props.onCloseLeftSide();
console.log("Block selected :", block);
const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path; const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path;
router.push(redirectPath.replace("[uid]", block.id)); router.push(redirectPath.replace("[uid]", block.id));
}, },

View File

@ -36,7 +36,6 @@ export default function DeedTypesCreate(props: IProps) {
try { try {
await validateOrReject(deedType, { groups: ["createDeedType"], forbidUnknownValues: true }); await validateOrReject(deedType, { groups: ["createDeedType"], forbidUnknownValues: true });
} catch (validationErrors: Array<ValidationError> | any) { } catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
setValidationError(validationErrors as ValidationError[]); setValidationError(validationErrors as ValidationError[]);
return; return;
} }
@ -57,12 +56,11 @@ export default function DeedTypesCreate(props: IProps) {
.modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeCreated.uid!), .modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeCreated.uid!),
); );
} catch (validationErrors: Array<ValidationError> | any) { } catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
setValidationError(validationErrors as ValidationError[]); setValidationError(validationErrors as ValidationError[]);
return; return;
} }
}, },
[router, validationError], [router],
); );
const closeConfirmModal = useCallback(() => { const closeConfirmModal = useCallback(() => {

View File

@ -42,7 +42,6 @@ export default function DocumentTypesEdit() {
try { try {
await validateOrReject(documentToUpdate, { groups: ["updateDocumentType"] }); await validateOrReject(documentToUpdate, { groups: ["updateDocumentType"] });
} catch (validationErrors: Array<ValidationError> | any) { } catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
if (!Array.isArray(validationErrors)) return; if (!Array.isArray(validationErrors)) return;
setValidationError(validationErrors as ValidationError[]); setValidationError(validationErrors as ValidationError[]);
return; return;
@ -63,7 +62,7 @@ export default function DocumentTypesEdit() {
return; return;
} }
}, },
[documentTypeUid, router, validationError], [documentTypeUid, router],
); );
return ( return (

View File

@ -242,7 +242,6 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
const contactToCreate = Contact.hydrate<Customer>(values); const contactToCreate = Contact.hydrate<Customer>(values);
await contactToCreate.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false }); await contactToCreate.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false });
} catch (validationErrors) { } catch (validationErrors) {
console.log(validationErrors);
this.setState({ this.setState({
validationError: validationErrors as ValidationError[], validationError: validationErrors as ValidationError[],
}); });

View File

@ -200,7 +200,6 @@ class UpdateClientClass extends BasePage<IPropsClass, IState> {
try { try {
await contact.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false }); await contact.validateOrReject?.({ groups: ["createCustomer"], forbidUnknownValues: false });
} catch (validationErrors) { } catch (validationErrors) {
console.log(validationErrors);
this.setState({ this.setState({
validationError: validationErrors as ValidationError[], validationError: validationErrors as ValidationError[],
}); });

View File

@ -200,7 +200,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
fileBlob, fileBlob,
}); });
} catch (e) { } catch (e) {
console.log(e); console.error(e);
} }
} }

View File

@ -28,7 +28,6 @@ export default function LoginCallBack() {
await UserStore.instance.connect(token.accessToken, token.refreshToken); await UserStore.instance.connect(token.accessToken, token.refreshToken);
return router.push(Module.getInstance().get().modules.pages.Folder.props.path); return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
} catch (e: any) { } catch (e: any) {
console.log("Log error : ", e);
if (e.http_status === 401 && e.message === "Email not found") { if (e.http_status === 401 && e.message === "Email not found") {
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3"); return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3");
} }

View File

@ -26,7 +26,7 @@ export default function LoginCallBackCustomer() {
try { try {
token = await Customers.getInstance().loginCallback(tokenid360); token = await Customers.getInstance().loginCallback(tokenid360);
} catch (e) { } catch (e) {
console.log(e); console.error(e);
router.push(Module.getInstance().get().modules.pages.CustomersLogin.props.path + "?error=1"); router.push(Module.getInstance().get().modules.pages.CustomersLogin.props.path + "?error=1");
return; return;
} }
@ -34,7 +34,7 @@ export default function LoginCallBackCustomer() {
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
} }
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken"); const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if(!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1"); if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken); const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken);
if (isTokenRefreshed) { if (isTokenRefreshed) {
return router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); return router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);

View File

@ -35,7 +35,6 @@ export default function RolesCreate(props: IProps) {
try { try {
await officeRole.validateOrReject?.({ groups: ["createOfficeRole"], forbidUnknownValues: true }); await officeRole.validateOrReject?.({ groups: ["createOfficeRole"], forbidUnknownValues: true });
} catch (validationErrors: Array<ValidationError> | any) { } catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
if (!Array.isArray(validationErrors)) return; if (!Array.isArray(validationErrors)) return;
setValidationError(validationErrors as ValidationError[]); setValidationError(validationErrors as ValidationError[]);
return; return;
@ -52,13 +51,12 @@ export default function RolesCreate(props: IProps) {
router.push(Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path.replace("[uid]", role.uid!)); router.push(Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path.replace("[uid]", role.uid!));
} catch (validationErrors: Array<ValidationError> | any) { } catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
if (!Array.isArray(validationErrors)) return; if (!Array.isArray(validationErrors)) return;
setValidationError(validationErrors as ValidationError[]); setValidationError(validationErrors as ValidationError[]);
return; return;
} }
}, },
[router, validationError], [router],
); );
const closeConfirmModal = useCallback(() => { const closeConfirmModal = useCallback(() => {
@ -96,7 +94,11 @@ export default function RolesCreate(props: IProps) {
<Typography typo={ITypo.H1Bis}>Créer un rôle</Typography> <Typography typo={ITypo.H1Bis}>Créer un rôle</Typography>
</div> </div>
<Form onSubmit={onSubmitHandler} className={classes["form-container"]} onFieldChange={onFieldChange}> <Form onSubmit={onSubmitHandler} className={classes["form-container"]} onFieldChange={onFieldChange}>
<TextField name="name" placeholder="Nom du rôle" validationError={validationError.find((error) => error.property === "name")}/> <TextField
name="name"
placeholder="Nom du rôle"
validationError={validationError.find((error) => error.property === "name")}
/>
<div className={classes["buttons-container"]}> <div className={classes["buttons-container"]}>
<Button variant={EButtonVariant.GHOST} onClick={onCancel}> <Button variant={EButtonVariant.GHOST} onClick={onCancel}>
Annuler Annuler

View File

@ -18,7 +18,6 @@ export default function SelectFolder() {
async function getFolders() { async function getFolders() {
const jwt = JwtService.getInstance().decodeCustomerJwt(); const jwt = JwtService.getInstance().decodeCustomerJwt();
if (!jwt) return; if (!jwt) return;
console.log(jwt)
const folders = await Folders.getInstance().get({ const folders = await Folders.getInstance().get({
q: { q: {
@ -37,8 +36,8 @@ export default function SelectFolder() {
}, },
], ],
include: { include: {
customers: true customers: true,
} },
}, },
}); });
setFolders(folders); setFolders(folders);

View File

@ -1,24 +1,30 @@
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import { IGetCustomerBySubscriptionIdParams } from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe";
export default function SubscriptionClientInfos() { type IProps = {
customer: IGetCustomerBySubscriptionIdParams;
};
export default function SubscriptionClientInfos(props: IProps) {
const { customer } = props;
return ( return (
<div className={classes["root"]}> <div className={classes["root"]}>
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
Informations client Informations client
</Typography> </Typography>
<Typography typo={ITypo.P_18} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_18} color={ITypoColor.BLACK}>
john.doe@contact.fr {customer.email}
</Typography> </Typography>
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}> {/* <Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
Adresse de facturation Adresse de facturation
</Typography> </Typography> */}
<Typography typo={ITypo.P_18} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_18} color={ITypoColor.BLACK}>
John Doe <br /> {customer.name} <br />
23 rue taitbout, {/* 23 rue taitbout,
<br /> <br />
75009 Paris 75009 Paris
<br /> <br /> */}
France France
</Typography> </Typography>
</div> </div>

View File

@ -4,22 +4,106 @@ import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import Form from "@Front/Components/DesignSystem/Form"; import Form from "@Front/Components/DesignSystem/Form";
import CheckBox from "@Front/Components/DesignSystem/CheckBox"; import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import { Subscription } from "le-coffre-resources/dist/Admin"; import User, { Subscription } from "le-coffre-resources/dist/Admin";
import JwtService from "@Front/Services/JwtService/JwtService"; import JwtService from "@Front/Services/JwtService/JwtService";
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions"; import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
export default function SubscriptionManageCollaborators() { export default function SubscriptionManageCollaborators() {
const [subscription, setSubscription] = useState<Subscription | null>(null); const [subscription, setSubscription] = useState<Subscription | null>(null);
const [availableCollaborators, setAvailableCollaborators] = useState<User[]>([
{
created_at: new Date("2021-09-29T14:00:00.000Z"),
uid: "1",
idNot: "1",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
contact: {
civility: "M",
created_at: new Date("2021-09-29T14:00:00.000Z"),
email: "jean.dupont@gmail.com",
first_name: "Jean",
last_name: "Dupont",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
},
},
{
created_at: new Date("2021-09-29T14:00:00.000Z"),
uid: "2",
idNot: "1",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
contact: {
civility: "M",
created_at: new Date("2021-09-29T14:00:00.000Z"),
email: "jean.dupont@gmail.com",
first_name: "Jean",
last_name: "Dupont",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
},
},
{
created_at: new Date("2021-09-29T14:00:00.000Z"),
uid: "3",
idNot: "1",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
contact: {
civility: "M",
created_at: new Date("2021-09-29T14:00:00.000Z"),
email: "jean.dupont@gmail.com",
first_name: "Jean",
last_name: "Dupont",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
},
},
{
created_at: new Date("2021-09-29T14:00:00.000Z"),
uid: "4",
idNot: "1",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
contact: {
civility: "M",
created_at: new Date("2021-09-29T14:00:00.000Z"),
email: "jean.dupont@gmail.com",
first_name: "Jean",
last_name: "Dupont",
updated_at: new Date("2021-09-29T14:00:00.000Z"),
},
},
]);
const [selectedCollaborators, setSelectedCollaborators] = useState<string[]>([]);
const loadSubscription = useCallback(async () => { const loadSubscription = useCallback(async () => {
const jwt = JwtService.getInstance().decodeJwt(); const jwt = JwtService.getInstance().decodeJwt();
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } }); const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
console.log(subscription);
if (!subscription[0]) return; if (!subscription[0]) return;
subscription[0].seats?.forEach((seat) => setSelectedCollaborators((prev) => [...prev, seat.user.uid!]));
setSubscription(subscription[0]); setSubscription(subscription[0]);
}, []); }, []);
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
if (!subscription) return;
const value = event.target.value;
if (selectedCollaborators.includes(value)) {
setSelectedCollaborators((prev) => prev.filter((collaborator) => collaborator !== value));
} else {
if (selectedCollaborators.length < subscription.nb_seats!) {
setSelectedCollaborators((prev) => [...prev, value]);
}
}
},
[selectedCollaborators, subscription],
);
const cancelAll = () => {
setSelectedCollaborators([]);
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
if (!e) return;
e.preventDefault();
};
useEffect(() => { useEffect(() => {
loadSubscription(); loadSubscription();
}, [loadSubscription]); }, [loadSubscription]);
@ -34,76 +118,33 @@ export default function SubscriptionManageCollaborators() {
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
{subscription.nb_seats} sièges disponibles {subscription.nb_seats} sièges disponibles
</Typography> </Typography>
<Form> <Form onSubmit={handleSubmit}>
<div className={classes["collaborators-container"]}> <div className={classes["collaborators-container"]}>
{availableCollaborators.map((collaborator) => (
<CheckBox <CheckBox
key={collaborator.uid}
option={{ option={{
label: "Jean Dupont", label: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
value: "Jean Dupont", value: collaborator.uid,
}}
name="collaborators"
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
checked
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
checked
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
checked
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}}
name="collaborators"
/>
<CheckBox
option={{
label: "Jean Dupont",
value: "Jean Dupont",
}} }}
checked={selectedCollaborators.includes(collaborator.uid!)}
onChange={handleChange}
disabled={
selectedCollaborators.length >= subscription.nb_seats! &&
!selectedCollaborators.includes(collaborator.uid!)
}
name="collaborators" name="collaborators"
/> />
))}
</div> </div>
<Typography typo={ITypo.CAPTION_14} color={ITypoColor.BLACK}> <Typography typo={ITypo.CAPTION_14} color={ITypoColor.BLACK}>
7 collaborateurs sélectionnés {selectedCollaborators.length} collaborateurs sélectionnés
</Typography> </Typography>
<div className={classes["buttons-container"]}> <div className={classes["buttons-container"]}>
<Button variant={EButtonVariant.PRIMARY} fullwidth> <Button variant={EButtonVariant.PRIMARY} fullwidth>
Enregistrer Enregistrer
</Button> </Button>
<Button variant={EButtonVariant.GHOST} fullwidth> <Button variant={EButtonVariant.GHOST} fullwidth onClick={cancelAll} type="button">
Annuler Annuler
</Button> </Button>
</div> </div>

View File

@ -17,7 +17,6 @@ export default function SubscriptionError() {
const loadSubscription = useCallback(async () => { const loadSubscription = useCallback(async () => {
const jwt = JwtService.getInstance().decodeJwt(); const jwt = JwtService.getInstance().decodeJwt();
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } }); const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
console.log(subscription);
if (!subscription[0]) return; if (!subscription[0]) return;
setSubscription(subscription[0]); setSubscription(subscription[0]);
}, []); }, []);

View File

@ -44,7 +44,6 @@ export default function SubscriptionFacturation() {
const loadSubscription = useCallback(async () => { const loadSubscription = useCallback(async () => {
const jwt = JwtService.getInstance().decodeJwt(); const jwt = JwtService.getInstance().decodeJwt();
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } }); const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
console.log(subscription);
if (!subscription[0]) { if (!subscription[0]) {
router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path); router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
} else { } else {

View File

@ -12,16 +12,19 @@ import { useCallback, useEffect, useState } from "react";
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions"; import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
import JwtService from "@Front/Services/JwtService/JwtService"; import JwtService from "@Front/Services/JwtService/JwtService";
import { Subscription } from "le-coffre-resources/dist/Admin"; import { Subscription } from "le-coffre-resources/dist/Admin";
import Stripe from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe";
export default function SubscriptionSuccess() { export default function SubscriptionSuccess() {
const [subscription, setSubscription] = useState<Subscription | null>(null); const [subscription, setSubscription] = useState<Subscription | null>(null);
const [customer, setCustomer] = useState<any | null>(null);
const loadSubscription = useCallback(async () => { const loadSubscription = useCallback(async () => {
const jwt = JwtService.getInstance().decodeJwt(); const jwt = JwtService.getInstance().decodeJwt();
const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } }); const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } });
console.log(subscription);
if (!subscription[0]) return; if (!subscription[0]) return;
setSubscription(subscription[0]); setSubscription(subscription[0]);
const customer = await Stripe.getInstance().getCustomerBySubscriptionId(subscription[0].stripe_subscription_id!);
setCustomer(customer);
}, []); }, []);
const getFrequency = useCallback(() => { const getFrequency = useCallback(() => {
@ -40,7 +43,7 @@ export default function SubscriptionSuccess() {
return ( return (
<DefaultTemplate title="Abonnement réussi"> <DefaultTemplate title="Abonnement réussi">
{subscription && ( {subscription && customer && (
<div className={classes["root"]}> <div className={classes["root"]}>
<div className={classes["left"]}> <div className={classes["left"]}>
<div className={classes["title"]}> <div className={classes["title"]}>
@ -58,7 +61,7 @@ export default function SubscriptionSuccess() {
</div> </div>
<div className={classes["separator"]} /> <div className={classes["separator"]} />
<div className={classes["client-infos"]}> <div className={classes["client-infos"]}>
<SubscriptionClientInfos /> <SubscriptionClientInfos customer={customer} />
</div> </div>
<div className={classes["separator"]} /> <div className={classes["separator"]} />
{subscription.type === "STANDARD" && ( {subscription.type === "STANDARD" && (

View File

@ -47,7 +47,6 @@ export default class JwtService {
return jwt_decode(accessToken); return jwt_decode(accessToken);
} }
public decodeJwt(): IUserJwtPayload | undefined { public decodeJwt(): IUserJwtPayload | undefined {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return; if (!accessToken) return;
@ -78,7 +77,7 @@ export default class JwtService {
`${ `${
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/idnot/user/auth/refresh-token`, }/idnot/user/auth/refresh-token`,
{ method: 'POST', headers: headers }, { method: "POST", headers: headers },
); );
const newAccessToken: { accessToken: string } = await response.json(); const newAccessToken: { accessToken: string } = await response.json();
if (newAccessToken) { if (newAccessToken) {
@ -86,7 +85,7 @@ export default class JwtService {
return true; return true;
} }
} catch (err) { } catch (err) {
console.log(err); console.error(err);
return false; return false;
} }
} else if (customerToken?.customerId) { } else if (customerToken?.customerId) {
@ -97,7 +96,7 @@ export default class JwtService {
`${ `${
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/id360/customers/refresh-token`, }/id360/customers/refresh-token`,
{ method: 'POST', headers: headers }, { method: "POST", headers: headers },
); );
const newAccessToken: { accessToken: string } = await response.json(); const newAccessToken: { accessToken: string } = await response.json();
if (newAccessToken) { if (newAccessToken) {
@ -105,7 +104,7 @@ export default class JwtService {
return true; return true;
} }
} catch (err) { } catch (err) {
console.log(err); console.error(err);
return false; return false;
} }
} }