Merge branch 'dev' into staging
This commit is contained in:
commit
d53057ee2f
41
package-lock.json
generated
41
package-lock.json
generated
@ -162,9 +162,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
|
||||
"integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz",
|
||||
"integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.14.0"
|
||||
},
|
||||
@ -474,23 +474,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/core-downloads-tracker": {
|
||||
"version": "5.15.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.14.tgz",
|
||||
"integrity": "sha512-on75VMd0XqZfaQW+9pGjSNiqW+ghc5E2ZSLRBXwcXl/C4YzjfyjrLPhrEpKnR9Uym9KXBvxrhoHfPcczYHweyA==",
|
||||
"version": "5.15.15",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.15.tgz",
|
||||
"integrity": "sha512-aXnw29OWQ6I5A47iuWEI6qSSUfH6G/aCsW9KmW3LiFqr7uXZBK4Ks+z8G+qeIub8k0T5CMqlT2q0L+ZJTMrqpg==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui-org"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/material": {
|
||||
"version": "5.15.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.14.tgz",
|
||||
"integrity": "sha512-kEbRw6fASdQ1SQ7LVdWR5OlWV3y7Y54ZxkLzd6LV5tmz+NpO3MJKZXSfgR0LHMP7meKsPiMm4AuzV0pXDpk/BQ==",
|
||||
"version": "5.15.15",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.15.tgz",
|
||||
"integrity": "sha512-3zvWayJ+E1kzoIsvwyEvkTUKVKt1AjchFFns+JtluHCuvxgKcLSRJTADw37k0doaRtVAsyh8bz9Afqzv+KYrIA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.9",
|
||||
"@mui/base": "5.0.0-beta.40",
|
||||
"@mui/core-downloads-tracker": "^5.15.14",
|
||||
"@mui/system": "^5.15.14",
|
||||
"@mui/core-downloads-tracker": "^5.15.15",
|
||||
"@mui/system": "^5.15.15",
|
||||
"@mui/types": "^7.2.14",
|
||||
"@mui/utils": "^5.15.14",
|
||||
"@types/react-transition-group": "^4.4.10",
|
||||
@ -584,9 +584,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/system": {
|
||||
"version": "5.15.14",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.14.tgz",
|
||||
"integrity": "sha512-auXLXzUaCSSOLqJXmsAaq7P96VPRXg2Rrz6OHNV7lr+kB8lobUF+/N84Vd9C4G/wvCXYPs5TYuuGBRhcGbiBGg==",
|
||||
"version": "5.15.15",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.15.tgz",
|
||||
"integrity": "sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.9",
|
||||
"@mui/private-theming": "^5.15.14",
|
||||
@ -1391,13 +1391,12 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/bare-fs": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.2.tgz",
|
||||
"integrity": "sha512-X9IqgvyB0/VA5OZJyb5ZstoN62AzD7YxVGog13kkfYWYqJYcK0kcqLZ6TrmH5qr4/8//ejVcX4x/a0UvaogXmA==",
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.3.tgz",
|
||||
"integrity": "sha512-amG72llr9pstfXOBOHve1WjiuKKAMnebcmMbPWDZ7BCevAoJLpugjuAPRsDINEyjT0a6tbaVx3DctkXIRbLuJw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"bare-events": "^2.0.0",
|
||||
"bare-os": "^2.0.0",
|
||||
"bare-path": "^2.0.0",
|
||||
"streamx": "^2.13.0"
|
||||
}
|
||||
@ -4481,9 +4480,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.72.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.72.0.tgz",
|
||||
"integrity": "sha512-Gpczt3WA56Ly0Mn8Sl21Vj94s1axi9hDIzDFn9Ph9x3C3p4nNyvsqJoQyVXKou6cBlfFWEgRW4rT8Tb4i3XnVA==",
|
||||
"version": "1.74.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.74.1.tgz",
|
||||
"integrity": "sha512-w0Z9p/rWZWelb88ISOLyvqTWGmtmu2QJICqDBGyNnfG4OUnPX9BBjjYIXUpXCMOOg5MQWNpqzt876la1fsTvUA==",
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
|
@ -10,6 +10,10 @@ export type IPostStripeResponse = {
|
||||
url: string;
|
||||
};
|
||||
|
||||
export type IGetClientPortalSessionResponse = {
|
||||
url: string;
|
||||
};
|
||||
|
||||
export default class Stripe extends BaseAdmin {
|
||||
private static instance: Stripe;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/stripe");
|
||||
@ -37,4 +41,14 @@ export default class Stripe extends BaseAdmin {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async getClientPortalSession(stripe_subscription_id: string) {
|
||||
const url = new URL(this.baseURl.concat(`/${stripe_subscription_id}`));
|
||||
try {
|
||||
return await this.getRequest<IGetClientPortalSessionResponse>(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
import { Subscription } from "le-coffre-resources/dist/Admin";
|
||||
import BaseAdmin from "../../../../../common/Api/LeCoffreApi/Admin/BaseAdmin";
|
||||
|
||||
export interface IPostSubscriptionsParams {
|
||||
emails: string[];
|
||||
}
|
||||
|
||||
export default class Subscriptions extends BaseAdmin {
|
||||
private static instance: Subscriptions;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/subscriptions");
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance() {
|
||||
if (!this.instance) {
|
||||
return new this();
|
||||
} else {
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
public async get(q: any) {
|
||||
const url = new URL(this.baseURl);
|
||||
const query = { q };
|
||||
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
|
||||
try {
|
||||
return await this.getRequest<Subscription>(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Create a Document
|
||||
*/
|
||||
public async post(body: IPostSubscriptionsParams) {
|
||||
const url = new URL(this.baseURl.concat(`/invite`));
|
||||
try {
|
||||
return await this.postRequest(url, body as any);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
@ -40,11 +40,11 @@ export default function Navigation() {
|
||||
read: false,
|
||||
},
|
||||
include: {
|
||||
notification: true
|
||||
notification: true,
|
||||
},
|
||||
orderBy: {
|
||||
notification: { created_at: "desc" },
|
||||
}
|
||||
},
|
||||
});
|
||||
notifications.forEach((notification) => {
|
||||
Toasts.getInstance().open({
|
||||
@ -89,6 +89,19 @@ export default function Navigation() {
|
||||
routesActive={[Module.getInstance().get().modules.pages.Collaborators.props.path]}
|
||||
/>
|
||||
</Rules>
|
||||
<HeaderLink
|
||||
text={"Abonnement"}
|
||||
path={Module.getInstance().get().modules.pages.Subscription.pages.Manage.props.path}
|
||||
routesActive={[
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Manage.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Invite.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Success.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Error.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.New.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.pages.Standard.props.path,
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.pages.Illimity.props.path,
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import classNames from "classnames";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
@ -14,6 +15,8 @@ type IProps = {
|
||||
scrollTop: number | null;
|
||||
isPadding?: boolean;
|
||||
hasHeaderLinks: boolean;
|
||||
hasBackArrow?: boolean;
|
||||
backArrowUrl?: string;
|
||||
};
|
||||
type IState = {};
|
||||
|
||||
@ -28,7 +31,14 @@ export default class DefaultTemplate extends React.Component<IProps, IState> {
|
||||
return (
|
||||
<>
|
||||
<Header isUserConnected={this.props.hasHeaderLinks} />
|
||||
<div className={classNames(classes["root"], this.props.isPadding && classes["padding"])}>{this.props.children}</div>
|
||||
<div className={classNames(classes["root"], this.props.isPadding && classes["padding"])}>
|
||||
{this.props.hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
<Version />
|
||||
</>
|
||||
);
|
||||
|
@ -46,8 +46,6 @@ export default function SubscribeCheckoutTicket(props: IProps) {
|
||||
};
|
||||
|
||||
const handleSubmitPayment = async () => {
|
||||
console.log("handleSubmitPayment");
|
||||
|
||||
const stripeCheckout = {
|
||||
type: EType.Standard,
|
||||
nb_seats: numberOfCollaborators,
|
||||
|
@ -31,7 +31,7 @@ export default function SubscribeIllimity() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<DefaultTemplate title="Nouvelle souscription" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["left"]}>
|
||||
<NavTab
|
||||
|
@ -38,7 +38,7 @@ export default function SubscribeStandard() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<DefaultTemplate title="Nouvelle souscription" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["left"]}>
|
||||
<NavTab
|
||||
|
@ -8,7 +8,7 @@ import Button from "@Front/Components/DesignSystem/Button";
|
||||
|
||||
export default function SubscriptionError() {
|
||||
return (
|
||||
<DefaultTemplate title="Erreur à la souscription" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Erreur à la souscription">
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["left"]}>
|
||||
<div className={classes["title"]}>
|
||||
|
@ -33,6 +33,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
height: fit-content;
|
||||
|
||||
&[data-inactive="true"] {
|
||||
border: 1px solid #e7e7e7;
|
||||
@ -62,6 +63,12 @@
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,12 +6,19 @@ import { useCallback, useState } from "react";
|
||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||
import useOpenable from "@Front/Hooks/useOpenable";
|
||||
import MessageBox from "@Front/Components/Elements/MessageBox";
|
||||
import Link from "next/link";
|
||||
import Module from "@Front/Config/Module";
|
||||
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
import Stripe from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export enum EForfeitType {
|
||||
"standard",
|
||||
"unlimited",
|
||||
}
|
||||
export default function SubscriptionFacturation() {
|
||||
const router = useRouter();
|
||||
const [forfeitType, _setForfeitType] = useState(EForfeitType.standard);
|
||||
const { close: closeCancelSubscription, isOpen: isCancelSubscriptionOpen, open: openCancelSubscription } = useOpenable();
|
||||
const { close: closeConfirmation, isOpen: isConfirmationOpen, open: openConfirmation } = useOpenable();
|
||||
@ -22,13 +29,22 @@ export default function SubscriptionFacturation() {
|
||||
return;
|
||||
}, [closeCancelSubscription, openConfirmation]);
|
||||
|
||||
const manageBilling = async () => {
|
||||
try {
|
||||
const jwt = JwtService.getInstance().decodeJwt();
|
||||
const subscription = await Subscriptions.getInstance().get({ officeId: jwt?.office_Id });
|
||||
const stripe_client_portal = await Stripe.getInstance().getClientPortalSession(subscription.stripe_subscription_id!);
|
||||
router.push(stripe_client_portal.url);
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
return (
|
||||
<DefaultTemplate title="Nouvelle souscription" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Nouvelle souscription">
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["top-container"]}>
|
||||
<div className={classes["top-container-title"]}>
|
||||
<Typography typo={ITypo.H1} color={ITypoColor.BLACK}>
|
||||
Facturation
|
||||
Abonnement
|
||||
</Typography>
|
||||
</div>
|
||||
<div className={classes["sub-title"]}>
|
||||
@ -71,14 +87,29 @@ export default function SubscriptionFacturation() {
|
||||
</div>
|
||||
<div className={classes["button-container"]}>
|
||||
{forfeitType !== EForfeitType.standard && (
|
||||
<Link
|
||||
href={Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.pages.Standard.props.path}>
|
||||
<Button fullwidth variant={EButtonVariant.GHOST}>
|
||||
Rétrograder mon abonnement
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
{forfeitType === EForfeitType.standard && (
|
||||
<>
|
||||
<Link
|
||||
href={
|
||||
Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.pages.Standard.props.path
|
||||
}>
|
||||
<Button fullwidth variant={EButtonVariant.PRIMARY}>
|
||||
Gérer mes collaborateurs
|
||||
Gérer mon abonnement
|
||||
</Button>
|
||||
</Link>
|
||||
<Link href={Module.getInstance().get().modules.pages.Subscription.pages.ManageCollaborators.props.path}>
|
||||
<Button fullwidth variant={EButtonVariant.GHOST}>
|
||||
Ajouter des collaborateurs
|
||||
</Button>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -120,9 +151,12 @@ export default function SubscriptionFacturation() {
|
||||
</Button>
|
||||
)}
|
||||
{forfeitType === EForfeitType.standard && (
|
||||
<Link
|
||||
href={Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.pages.Illimity.props.path}>
|
||||
<Button fullwidth variant={EButtonVariant.GHOST}>
|
||||
Améliorer mon abonnement
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -133,7 +167,7 @@ export default function SubscriptionFacturation() {
|
||||
Arrêter l'abonnement
|
||||
</Typography>
|
||||
</Button>
|
||||
<Button>Gérer la facturation</Button>
|
||||
<Button onClick={manageBilling}>Gérer la facturation</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Confirm
|
||||
|
@ -0,0 +1,38 @@
|
||||
.root {
|
||||
max-width: 1400px;
|
||||
margin: auto;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
|
||||
.emails-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
|
||||
.input-container {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
> span {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.add-line-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
||||
import { useRouter } from "next/router";
|
||||
import TextField from "@Front/Components/DesignSystem/Form/TextField";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions";
|
||||
import { useCallback, useState } from "react";
|
||||
import { TrashIcon } from "@heroicons/react/24/outline";
|
||||
import PlusIcon from "@Assets/Icons/plus.svg";
|
||||
|
||||
export enum EForfeitType {
|
||||
"standard",
|
||||
"unlimited",
|
||||
}
|
||||
type EmailLine = {
|
||||
element: JSX.Element;
|
||||
id: number;
|
||||
};
|
||||
|
||||
export default function SubscriptionInvite() {
|
||||
const router = useRouter();
|
||||
const nbOfCollaborators = parseInt(router.query["nbOfCollaborators"] as string);
|
||||
const [incrementalId, setIncrementalId] = useState(isNaN(nbOfCollaborators) ? 0 : nbOfCollaborators);
|
||||
|
||||
const getInitialLines = () => {
|
||||
const linesToGet = isNaN(nbOfCollaborators) ? 1 : nbOfCollaborators;
|
||||
const lines: EmailLine[] = [];
|
||||
for (let i = 0; i < linesToGet; i++) {
|
||||
lines.push({
|
||||
element: <TextField key={i} name={`email_${i}`} placeholder="Email" className={classes["input"]} required />,
|
||||
id: i,
|
||||
});
|
||||
}
|
||||
return lines;
|
||||
};
|
||||
|
||||
const [lines, setLines] = useState<EmailLine[]>(getInitialLines());
|
||||
|
||||
const sendInvitations = async (e: React.FormEvent<HTMLFormElement> | null) => {
|
||||
if (!e) return;
|
||||
e.preventDefault();
|
||||
const form = e.target as HTMLFormElement;
|
||||
const emails: string[] = [];
|
||||
Object.keys(form.elements).forEach((key) => {
|
||||
if (isNaN(parseInt(key))) return;
|
||||
const element = form.elements[key as any] as HTMLInputElement;
|
||||
if (element.name.includes("email_")) {
|
||||
emails.push(element.value);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await Subscriptions.getInstance().post({
|
||||
emails,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const addLine = useCallback(() => {
|
||||
const newLine: EmailLine = {
|
||||
element: (
|
||||
<TextField key={lines.length} name={`email_${lines.length}`} placeholder="Email" className={classes["input"]} required />
|
||||
),
|
||||
id: incrementalId + 1,
|
||||
};
|
||||
setIncrementalId(incrementalId + 1);
|
||||
setLines((prev) => [...prev, newLine]);
|
||||
}, [incrementalId, lines]);
|
||||
|
||||
const deleteLine = (e: React.MouseEvent<SVGSVGElement>) => {
|
||||
const lineId = parseInt(e.currentTarget.getAttribute("data-line") as string);
|
||||
setLines((prev) => prev.filter((line) => line.id !== lineId));
|
||||
};
|
||||
|
||||
return (
|
||||
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["container"]}>
|
||||
<Typography typo={ITypo.H1} color={ITypoColor.BLACK}>
|
||||
Inviter vos collaborateurs
|
||||
</Typography>
|
||||
{!isNaN(nbOfCollaborators) && (
|
||||
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
|
||||
{nbOfCollaborators} collaborateurs à inviter
|
||||
</Typography>
|
||||
)}
|
||||
{isNaN(nbOfCollaborators) && (
|
||||
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
|
||||
Collaborateurs illimités
|
||||
</Typography>
|
||||
)}
|
||||
<Form className={classes["emails-form"]} onSubmit={sendInvitations}>
|
||||
{lines.map((line, index) => (
|
||||
<div key={line.id} className={classes["input-container"]}>
|
||||
{line.element}
|
||||
{!nbOfCollaborators && (
|
||||
<TrashIcon
|
||||
width="20"
|
||||
height="20"
|
||||
data-line={line.id}
|
||||
onClick={deleteLine}
|
||||
visibility={index === 0 ? "hidden" : "visible"}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{isNaN(nbOfCollaborators) && (
|
||||
<div className={classes["add-line-container"]}>
|
||||
<Button onClick={addLine} variant={EButtonVariant.LINE} icon={PlusIcon}>
|
||||
Ajouter une adresse email
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
<div className={classes["button-container"]}>
|
||||
<Button type="submit">Envoyer l'invitation</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultTemplate>
|
||||
);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
margin-top: 32px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
.collaborators-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.buttons-container {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
max-width: 400px;
|
||||
@media (max-width: $screen-s) {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import classes from "./classes.module.scss";
|
||||
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
||||
import Form from "@Front/Components/DesignSystem/Form";
|
||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
|
||||
export default function SubscriptionManageCollaborators() {
|
||||
return (
|
||||
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
|
||||
<div className={classes["root"]}>
|
||||
<Typography typo={ITypo.H2} color={ITypoColor.BLACK}>
|
||||
Choisissez les collaborateurs pour votre abonnement
|
||||
</Typography>
|
||||
<Typography typo={ITypo.P_SB_18} color={ITypoColor.BLACK}>
|
||||
7 sièges disponibles
|
||||
</Typography>
|
||||
<Form>
|
||||
<div className={classes["collaborators-container"]}>
|
||||
<CheckBox
|
||||
option={{
|
||||
label: "Jean Dupont",
|
||||
value: "Jean Dupont",
|
||||
}}
|
||||
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",
|
||||
}}
|
||||
name="collaborators"
|
||||
/>
|
||||
</div>
|
||||
<Typography typo={ITypo.CAPTION_14} color={ITypoColor.BLACK}>
|
||||
7 collaborateurs sélectionnés
|
||||
</Typography>
|
||||
<div className={classes["buttons-container"]}>
|
||||
<Button variant={EButtonVariant.PRIMARY} fullwidth>
|
||||
Enregistrer
|
||||
</Button>
|
||||
<Button variant={EButtonVariant.GHOST} fullwidth>
|
||||
Annuler
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</DefaultTemplate>
|
||||
);
|
||||
}
|
@ -8,7 +8,7 @@ import Link from "next/link";
|
||||
|
||||
export default function SubscriptionNew() {
|
||||
return (
|
||||
<DefaultTemplate title="Nouvelle souscription" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Nouvelle souscription" hasBackArrow>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["top-container"]}>
|
||||
<div className={classes["top-container-title"]}>
|
||||
|
@ -5,10 +5,12 @@ import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Ty
|
||||
import MessageBox from "@Front/Components/Elements/MessageBox";
|
||||
import SubscriptionClientInfos from "../SubscriptionClientInfos";
|
||||
import Button from "@Front/Components/DesignSystem/Button";
|
||||
import Link from "next/link";
|
||||
import Module from "@Front/Config/Module";
|
||||
|
||||
export default function SubscriptionSuccess() {
|
||||
return (
|
||||
<DefaultTemplate title="Abonnement réussi" hasHeaderLinks={false}>
|
||||
<DefaultTemplate title="Abonnement réussi">
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["left"]}>
|
||||
<div className={classes["title"]}>
|
||||
@ -29,7 +31,9 @@ export default function SubscriptionSuccess() {
|
||||
<SubscriptionClientInfos />
|
||||
</div>
|
||||
<div className={classes["separator"]} />
|
||||
<Link href={Module.getInstance().get().modules.pages.Subscription.pages.Invite.props.path}>
|
||||
<Button>Inviter vos collaborateurs</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={classes["right"]}>
|
||||
<SubscriptionTicket />
|
||||
|
@ -270,6 +270,80 @@
|
||||
"path": "/404",
|
||||
"labelKey": "not_found"
|
||||
}
|
||||
},
|
||||
"Subscription": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription",
|
||||
"labelKey": "subscription"
|
||||
},
|
||||
"pages": {
|
||||
"Invite": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/invite",
|
||||
"labelKey": "invite"
|
||||
}
|
||||
},
|
||||
"ManageCollaborators": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage-collaborators",
|
||||
"labelKey": "manage_collaborators"
|
||||
}
|
||||
},
|
||||
"Manage": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage",
|
||||
"labelKey": "manage"
|
||||
}
|
||||
},
|
||||
"New": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/new",
|
||||
"labelKey": "subscribe"
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/error",
|
||||
"labelKey": "error"
|
||||
}
|
||||
},
|
||||
"Success": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/success",
|
||||
"labelKey": "success"
|
||||
}
|
||||
},
|
||||
"Subscribe": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe",
|
||||
"labelKey": "subscribe"
|
||||
},
|
||||
"pages": {
|
||||
"Standard": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/standard",
|
||||
"labelKey": "standard"
|
||||
}
|
||||
},
|
||||
"Illimity": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/illimity",
|
||||
"labelKey": "illimity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,6 +270,80 @@
|
||||
"path": "/404",
|
||||
"labelKey": "not_found"
|
||||
}
|
||||
},
|
||||
"Subscription": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription",
|
||||
"labelKey": "subscription"
|
||||
},
|
||||
"pages": {
|
||||
"Invite": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/invite",
|
||||
"labelKey": "invite"
|
||||
}
|
||||
},
|
||||
"ManageCollaborators": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage-collaborators",
|
||||
"labelKey": "manage_collaborators"
|
||||
}
|
||||
},
|
||||
"Manage": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage",
|
||||
"labelKey": "manage"
|
||||
}
|
||||
},
|
||||
"New": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/new",
|
||||
"labelKey": "subscribe"
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/error",
|
||||
"labelKey": "error"
|
||||
}
|
||||
},
|
||||
"Success": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/success",
|
||||
"labelKey": "success"
|
||||
}
|
||||
},
|
||||
"Subscribe": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe",
|
||||
"labelKey": "subscribe"
|
||||
},
|
||||
"pages": {
|
||||
"Standard": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/standard",
|
||||
"labelKey": "standard"
|
||||
}
|
||||
},
|
||||
"Illimity": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/illimity",
|
||||
"labelKey": "illimity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,6 +270,80 @@
|
||||
"path": "/404",
|
||||
"labelKey": "not_found"
|
||||
}
|
||||
},
|
||||
"Subscription": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription",
|
||||
"labelKey": "subscription"
|
||||
},
|
||||
"pages": {
|
||||
"Invite": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/invite",
|
||||
"labelKey": "invite"
|
||||
}
|
||||
},
|
||||
"ManageCollaborators": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage-collaborators",
|
||||
"labelKey": "manage_collaborators"
|
||||
}
|
||||
},
|
||||
"Manage": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage",
|
||||
"labelKey": "manage"
|
||||
}
|
||||
},
|
||||
"New": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/new",
|
||||
"labelKey": "subscribe"
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/error",
|
||||
"labelKey": "error"
|
||||
}
|
||||
},
|
||||
"Success": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/success",
|
||||
"labelKey": "success"
|
||||
}
|
||||
},
|
||||
"Subscribe": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe",
|
||||
"labelKey": "subscribe"
|
||||
},
|
||||
"pages": {
|
||||
"Standard": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/standard",
|
||||
"labelKey": "standard"
|
||||
}
|
||||
},
|
||||
"Illimity": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/illimity",
|
||||
"labelKey": "illimity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,6 +270,80 @@
|
||||
"path": "/404",
|
||||
"labelKey": "not_found"
|
||||
}
|
||||
},
|
||||
"Subscription": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription",
|
||||
"labelKey": "subscription"
|
||||
},
|
||||
"pages": {
|
||||
"Invite": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/invite",
|
||||
"labelKey": "invite"
|
||||
}
|
||||
},
|
||||
"ManageCollaborators": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage-collaborators",
|
||||
"labelKey": "manage_collaborators"
|
||||
}
|
||||
},
|
||||
"Manage": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/manage",
|
||||
"labelKey": "manage"
|
||||
}
|
||||
},
|
||||
"New": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/new",
|
||||
"labelKey": "subscribe"
|
||||
}
|
||||
},
|
||||
"Error": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/error",
|
||||
"labelKey": "error"
|
||||
}
|
||||
},
|
||||
"Success": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/success",
|
||||
"labelKey": "success"
|
||||
}
|
||||
},
|
||||
"Subscribe": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe",
|
||||
"labelKey": "subscribe"
|
||||
},
|
||||
"pages": {
|
||||
"Standard": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/standard",
|
||||
"labelKey": "standard"
|
||||
}
|
||||
},
|
||||
"Illimity": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/subscription/subscribe/illimity",
|
||||
"labelKey": "illimity"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
src/pages/subscription/invite/index.tsx
Normal file
5
src/pages/subscription/invite/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import SubscriptionInvite from "@Front/Components/Layouts/Subscription/SubscriptionInvite";
|
||||
|
||||
export default function Route() {
|
||||
return <SubscriptionInvite />;
|
||||
}
|
5
src/pages/subscription/manage-collaborators/index.tsx
Normal file
5
src/pages/subscription/manage-collaborators/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import SubscriptionManageCollaborators from "@Front/Components/Layouts/Subscription/SubscriptionManageCollaborators";
|
||||
|
||||
export default function Route() {
|
||||
return <SubscriptionManageCollaborators />;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user