diff --git a/src/front/Api/LeCoffreApi/Notary/Mailchimp/Mailchimp.ts b/src/front/Api/LeCoffreApi/Notary/Mailchimp/Mailchimp.ts new file mode 100644 index 00000000..ec7a4d1b --- /dev/null +++ b/src/front/Api/LeCoffreApi/Notary/Mailchimp/Mailchimp.ts @@ -0,0 +1,35 @@ +import BaseNotary from "../BaseNotary"; + +// export interface IPostMailchimpParams { +// email: string; +// } + +export default class Mailchimp extends BaseNotary { + private static instance: Mailchimp; + private readonly baseURl = this.namespaceUrl.concat("/mailchimp"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + /** + * @description : Add to mail list + */ + public async post(body: any) { + const url = new URL(this.baseURl); + try { + return await this.postRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Assets/Icons/mail.svg b/src/front/Assets/Icons/mail.svg new file mode 100644 index 00000000..61fc88c6 --- /dev/null +++ b/src/front/Assets/Icons/mail.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/front/Components/DesignSystem/Button/classes.module.scss b/src/front/Components/DesignSystem/Button/classes.module.scss index 1b7192e5..bc86a437 100644 --- a/src/front/Components/DesignSystem/Button/classes.module.scss +++ b/src/front/Components/DesignSystem/Button/classes.module.scss @@ -91,6 +91,33 @@ } } + &[variant="white"] { + color: $pink-flash; + background-color: white; + border-color: $pink-flash; + padding: 24px 48px; + font-weight: 400; + font-size: 18px; + line-height: 22px; + + svg { + path { + stroke: $white; + } + } + + &:hover { + border-color: $pink-hover; + color: $pink-hover; + } + + &:disabled { + border-color: $pink-soft; + background-color: $pink-soft; + pointer-events: none; + } + } + &[fullwidthattr="true"] { width: 100%; flex: 1; diff --git a/src/front/Components/DesignSystem/Button/index.tsx b/src/front/Components/DesignSystem/Button/index.tsx index a9b28008..258a3d63 100644 --- a/src/front/Components/DesignSystem/Button/index.tsx +++ b/src/front/Components/DesignSystem/Button/index.tsx @@ -9,6 +9,7 @@ export enum EButtonVariant { SECONDARY = "secondary", GHOST = "ghost", LINE = "line", + WHITE = "white", } type IProps = { diff --git a/src/front/Components/DesignSystem/Newsletter/classes.module.scss b/src/front/Components/DesignSystem/Newsletter/classes.module.scss new file mode 100644 index 00000000..3800eef5 --- /dev/null +++ b/src/front/Components/DesignSystem/Newsletter/classes.module.scss @@ -0,0 +1,38 @@ +.container { + padding: 4px; + background-color: #320756; // Adjusted to match the background color in the image + border-radius: 10px; + max-width: 504px; + margin: auto; + text-align: left; + position: absolute; + bottom: 114px; + right: 48px; + + .root { + margin: 44px; + background-color: #320756; + height: fit-content; + display: flex; + flex-direction: column; + gap: 24px; + + .text { + display: flex; + flex-direction: column; + gap: 24px; + } + + .form { + display: flex; + flex-direction: column; + gap: 4px; + } + + .buttons { + display: flex; + flex-direction: column; + gap: 4px; + } + } +} diff --git a/src/front/Components/DesignSystem/Newsletter/index.tsx b/src/front/Components/DesignSystem/Newsletter/index.tsx new file mode 100644 index 00000000..9d8b4483 --- /dev/null +++ b/src/front/Components/DesignSystem/Newsletter/index.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import classes from "./classes.module.scss"; +import TextField from "../Form/TextField"; +import Button, { EButtonVariant } from "../Button"; +import Typography, { ITypo, ITypoColor } from "../Typography"; +import Mailchimp from "@Front/Api/LeCoffreApi/Notary/Mailchimp/Mailchimp"; +import Form from "../Form"; + +type IProps = {}; + +interface IState { + email: string; + errorMessage: string; + successMessage: string; +} + +export default class Newsletter extends React.Component { + constructor(props: IProps) { + super(props); + this.state = { + email: "", + errorMessage: "", + successMessage: "", + }; + } + + handleChange = (e: React.ChangeEvent) => { + this.setState({ email: e.target.value }); + }; + + handleSubmit = async (e: React.FormEvent | null, values: { [key: string]: string }) => { + if (!e) return; + e.preventDefault(); + + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + if (!emailRegex.test(this.state.email)) { + this.setState({ errorMessage: "Invalid email address", successMessage: "" }); + return; + } + + Mailchimp.getInstance().post({ email: this.state.email }); + // Clear error message + this.setState({ errorMessage: "" }); + + // Normally, form submission would happen here + // For demo purposes, we'll just show a success message + this.setState({ successMessage: "Subscription successful!", email: "" }); + }; + + public override render(): JSX.Element { + return ( +
+
+
+ + Restez Informé(e) avec notre Newsletter + + + Ne manquez aucune de nos actualités, promotions exclusives et conseils d'experts ! + + {this.state.errorMessage && ( +
+ + {this.state.errorMessage} + +
+ )} + {this.state.successMessage && ( +
+ + {this.state.successMessage} + +
+ )} +
+ +
+
+ +
+ +
+ +
+
+
+ ); + } +} diff --git a/src/front/Components/DesignSystem/Typography/classes.module.scss b/src/front/Components/DesignSystem/Typography/classes.module.scss index 35ad1b15..e3b047b2 100644 --- a/src/front/Components/DesignSystem/Typography/classes.module.scss +++ b/src/front/Components/DesignSystem/Typography/classes.module.scss @@ -159,4 +159,8 @@ &.orange-flash { color: var(--orange-flash); } + + &.white { + color: $white; + } } diff --git a/src/front/Components/DesignSystem/Typography/index.tsx b/src/front/Components/DesignSystem/Typography/index.tsx index 0e812ac4..1cc80368 100644 --- a/src/front/Components/DesignSystem/Typography/index.tsx +++ b/src/front/Components/DesignSystem/Typography/index.tsx @@ -41,6 +41,7 @@ export enum ITypoColor { GREEN_FLASH = "green-flash", ORANGE_FLASH = "orange-flash", RED_FLASH = "red-flash", + WHITE = "white", } export default class Typography extends React.Component { diff --git a/src/front/Components/Layouts/Folder/classes.module.scss b/src/front/Components/Layouts/Folder/classes.module.scss index a425a01a..25f65c9c 100644 --- a/src/front/Components/Layouts/Folder/classes.module.scss +++ b/src/front/Components/Layouts/Folder/classes.module.scss @@ -69,4 +69,24 @@ margin-bottom: 24px; } } + .newsletter { + position: absolute; + bottom: 44px; + right: 48px; + background-color: #320756; + width: 56px; + height: 56px; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + + .newsletter-icon { + width: 24px; + height: 24px; + + font-size: 24px; + } + } } diff --git a/src/front/Components/Layouts/Folder/index.tsx b/src/front/Components/Layouts/Folder/index.tsx index 6601c2e3..72f16926 100644 --- a/src/front/Components/Layouts/Folder/index.tsx +++ b/src/front/Components/Layouts/Folder/index.tsx @@ -4,11 +4,15 @@ import { OfficeFolder } from "le-coffre-resources/dist/Notary"; import BasePage from "../Base"; import classes from "./classes.module.scss"; +import Newletter from "@Front/Components/DesignSystem/Newsletter"; +import Image from "next/image"; +import Mail from "@Assets/Icons/mail.svg"; type IProps = {}; type IState = { selectedFolder: OfficeFolder | null; isArchivedModalOpen: boolean; + isNewsletterOpen: boolean; }; export default class Folder extends BasePage { public constructor(props: IProps) { @@ -16,6 +20,7 @@ export default class Folder extends BasePage { this.state = { selectedFolder: null, isArchivedModalOpen: false, + isNewsletterOpen: false, }; this.onSelectedFolder = this.onSelectedFolder.bind(this); } @@ -32,6 +37,16 @@ export default class Folder extends BasePage { Sélectionnez un dossier + {this.state.isNewsletterOpen && } + +
+ newsletter-icon this.handleNewsletterOpen(this.state.isNewsletterOpen)} + /> +
@@ -41,4 +56,8 @@ export default class Folder extends BasePage { private onSelectedFolder(folder: OfficeFolder): void { this.setState({ selectedFolder: folder }); } + + private handleNewsletterOpen(isNewsletterOpen: boolean): void { + this.setState({ isNewsletterOpen: !isNewsletterOpen }); + } }