From bd75de8fdabc4b17e00bbcecdc92cc87daf1b1fa Mon Sep 17 00:00:00 2001 From: jongomez Date: Thu, 26 Oct 2023 12:33:50 +0100 Subject: [PATCH] feat: implement subscribe button and dialogue --- src/components/NavBar/NavBar.tsx | 4 +- .../SubscribeButton/SubscribeButton.tsx | 52 ++++ src/components/SubscribeButton/index.ts | 1 + .../SubscribeDialogue/SubscribeDialogue.tsx | 225 ++++++++++++++++++ src/components/SubscribeDialogue/index.ts | 1 + 5 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 src/components/SubscribeButton/SubscribeButton.tsx create mode 100644 src/components/SubscribeButton/index.ts create mode 100644 src/components/SubscribeDialogue/SubscribeDialogue.tsx create mode 100644 src/components/SubscribeDialogue/index.ts diff --git a/src/components/NavBar/NavBar.tsx b/src/components/NavBar/NavBar.tsx index 85e7f0ab..60da92ec 100644 --- a/src/components/NavBar/NavBar.tsx +++ b/src/components/NavBar/NavBar.tsx @@ -20,6 +20,7 @@ import { useEffect, useState } from 'react' import { NavbarState, useNavbarState } from '../../states/navbarState' import { lsdUtils } from '../../utils/lsd.utils' import { LogosIcon } from '../Icons/LogosIcon' +import { SubscribeButton } from '../SubscribeButton' export interface NavBarProps { defaultState?: Partial @@ -62,6 +63,7 @@ export default function NavBar({ defaultState }: NavBarProps) { const buttons = ( <> + ` +export const PressLogoType = styled(Typography)<{ display: boolean }>` text-transform: uppercase; ${(props) => !props.display && diff --git a/src/components/SubscribeButton/SubscribeButton.tsx b/src/components/SubscribeButton/SubscribeButton.tsx new file mode 100644 index 00000000..8ff2553b --- /dev/null +++ b/src/components/SubscribeButton/SubscribeButton.tsx @@ -0,0 +1,52 @@ +import { Tag, Typography } from '@acid-info/lsd-react' +import styled from '@emotion/styled' +import { useState } from 'react' +import { SubscribeDialogue } from '../SubscribeDialogue' + +const mockOnSubmit = (data: any) => { + return new Promise((resolve, reject) => { + setTimeout(() => { + console.log('Form data submitted:', data) + resolve(true) + }, 3000) + }) +} + +export default function SubscribeButton() { + const [showDialogue, setShowDialogue] = useState(false) + + const handleClick = () => { + setShowDialogue(!showDialogue) + } + + return ( + <> + + + Subscribe + + + setShowDialogue(false)} + /> + + ) +} + +const CustomTag = styled(Tag)` + gap: 0 8px; + padding: 4px 12px; + background-color: rgb(var(--lsd-surface-secondary)); + + .subscribe-button-text { + color: rgb(var(--lsd-text-secondary)); + } + + &:hover { + .subscribe-button-text { + text-decoration: underline; + } + } +` diff --git a/src/components/SubscribeButton/index.ts b/src/components/SubscribeButton/index.ts new file mode 100644 index 00000000..1ffa047b --- /dev/null +++ b/src/components/SubscribeButton/index.ts @@ -0,0 +1 @@ +export { default as SubscribeButton } from './SubscribeButton' diff --git a/src/components/SubscribeDialogue/SubscribeDialogue.tsx b/src/components/SubscribeDialogue/SubscribeDialogue.tsx new file mode 100644 index 00000000..5893410f --- /dev/null +++ b/src/components/SubscribeDialogue/SubscribeDialogue.tsx @@ -0,0 +1,225 @@ +import { copyConfigs } from '@/configs/copy.configs' +import { Button, CloseIcon, IconButton, Typography } from '@acid-info/lsd-react' +import styled from '@emotion/styled' +import { useEffect, useState } from 'react' +import { LogosIcon } from '../Icons/LogosIcon' +import { PressLogoType } from '../NavBar/NavBar' + +type EmailSubscribeProps = React.HTMLAttributes & { + onSubmit: (formData: SubscribeFormData) => void + isOpen: boolean + onClose: () => void +} + +type SubscribeFormData = { + email: string + firstName: string + lastName: string +} + +export default function SubscribeDialogue({ + onSubmit, + isOpen, + onClose, + ...props +}: EmailSubscribeProps) { + const [isSubmitting, setIsSubmitting] = useState(false) + const [isSuccess, setIsSuccess] = useState(false) + const [errorMessage, setErrorMessage] = useState('') + + // Reset states when the dialog is closed. + useEffect(() => { + if (!isOpen) { + if (isSuccess) { + setIsSuccess(false) + } + + if (errorMessage) { + setErrorMessage('') + } + } + }, [isOpen, isSuccess, errorMessage]) + + if (!isOpen) { + return null + } + + const handleFormSubmit = async (e: React.FormEvent) => { + e.preventDefault() + setIsSubmitting(true) + + try { + await onSubmit({ + email: e.currentTarget.email.value, + firstName: e.currentTarget.firstName.value, + lastName: e.currentTarget.lastName.value, + }) + + setErrorMessage('') + setIsSuccess(true) + } catch (error) { + setIsSuccess(false) + setErrorMessage( + 'There was an error submitting the form. Please try again.', + ) + } finally { + setIsSubmitting(false) + } + } + + return ( + + + onClose()} + > + + + + + + + {copyConfigs.navbar.title} + + + + Subscribe for updates + + + + + + + + + + Subscribe + + + + {isSubmitting && ( + + Submitting... + + )} + {isSuccess && ( + + Submitted successfully! + + )} + {errorMessage && ( + + {errorMessage} + + )} + + + ) +} + +const SubmitionInfoMessage = styled(Typography)` + margin: 16px 0px; +` + +const LogosIconAndTitleContainer = styled.div` + display: flex; + align-items: center; + gap: 16px; + margin-bottom: 16px; +` + +const MainContentContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; + + padding: 24px 0; + width: 518px; + max-width: 90%; + + .subscribe-dialogue__close-button { + position: absolute; + top: 16px; + right: 32px; + } +` + +const SubscribeDialogueContainer = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + + background: rgb(var(--lsd-surface-primary)); + + display: flex; + align-items: center; + justify-content: center; +` + +const EmailSubscribeForm = styled.form` + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + gap: 16px; + width: 100%; + margin-top: 50px; +` + +const StyledInput = styled.input` + padding: 0; + padding-left: 18px; + box-sizing: border-box; + + outline: none; + border: none; + border-bottom: 1px solid rgb(var(--lsd-border-primary)); + + height: 40px; + width: 100%; + &:focus { + outline: none; + } +` + +const SubscribeButton = styled(Button)` + margin-top: 30px; + height: 40px; + width: 162px; + flex-shrink: 0; +` diff --git a/src/components/SubscribeDialogue/index.ts b/src/components/SubscribeDialogue/index.ts new file mode 100644 index 00000000..f4cef2f1 --- /dev/null +++ b/src/components/SubscribeDialogue/index.ts @@ -0,0 +1 @@ +export { default as SubscribeDialogue } from './SubscribeDialogue'