feat: implement subscribe button and dialogue

This commit is contained in:
jongomez 2023-10-26 12:33:50 +01:00 committed by Jon
parent 50e222fd2a
commit 2461659b5d
5 changed files with 282 additions and 1 deletions

View File

@ -20,6 +20,7 @@ import { useEffect, useState } from 'react'
import { NavbarState, useNavbarState } from '../../states/navbarState' import { NavbarState, useNavbarState } from '../../states/navbarState'
import { lsdUtils } from '../../utils/lsd.utils' import { lsdUtils } from '../../utils/lsd.utils'
import { LogosIcon } from '../Icons/LogosIcon' import { LogosIcon } from '../Icons/LogosIcon'
import { SubscribeButton } from '../SubscribeButton'
export interface NavBarProps { export interface NavBarProps {
defaultState?: Partial<NavbarState> defaultState?: Partial<NavbarState>
@ -62,6 +63,7 @@ export default function NavBar({ defaultState }: NavBarProps) {
const buttons = ( const buttons = (
<> <>
<SubscribeButton />
<Buttons> <Buttons>
<ThemeSwitch <ThemeSwitch
toggle={themeState.toggleMode} toggle={themeState.toggleMode}
@ -111,7 +113,7 @@ export default function NavBar({ defaultState }: NavBarProps) {
) )
} }
const PressLogoType = styled(Typography)<{ display: boolean }>` export const PressLogoType = styled(Typography)<{ display: boolean }>`
text-transform: uppercase; text-transform: uppercase;
${(props) => ${(props) =>
!props.display && !props.display &&

View File

@ -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 (
<>
<CustomTag onClick={handleClick} iconDirection="left">
<Typography variant="body3" className="subscribe-button-text">
Subscribe
</Typography>
</CustomTag>
<SubscribeDialogue
onSubmit={mockOnSubmit}
isOpen={showDialogue}
onClose={() => 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;
}
}
`

View File

@ -0,0 +1 @@
export { default as SubscribeButton } from './SubscribeButton'

View File

@ -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<HTMLDivElement> & {
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<HTMLFormElement>) => {
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 (
<SubscribeDialogueContainer {...props}>
<MainContentContainer>
<IconButton
className="subscribe-dialogue__close-button"
size="small"
onClick={() => onClose()}
>
<CloseIcon color="primary" />
</IconButton>
<LogosIconAndTitleContainer>
<LogosIcon color="primary" width="44px" height="44px" />
<PressLogoType variant={'h2'} genericFontFamily={'serif'} display>
{copyConfigs.navbar.title}
</PressLogoType>
</LogosIconAndTitleContainer>
<Typography
variant="body1"
style={{
marginBottom: '24px',
}}
>
Subscribe for updates
</Typography>
<EmailSubscribeForm onSubmit={handleFormSubmit}>
<StyledInput
type="text"
id="firstName"
name="firstName"
placeholder="First Name"
disabled={isSubmitting}
required
/>
<StyledInput
type="text"
id="lastName"
name="lastName"
placeholder="Last Name"
disabled={isSubmitting}
required
/>
<StyledInput
type="email"
id="email"
name="email"
placeholder="Email address"
disabled={isSubmitting}
required
/>
<SubscribeButton
variant="filled"
type="submit"
disabled={isSubmitting}
>
Subscribe
</SubscribeButton>
</EmailSubscribeForm>
{isSubmitting && (
<SubmitionInfoMessage variant="body1">
Submitting...
</SubmitionInfoMessage>
)}
{isSuccess && (
<SubmitionInfoMessage variant="body1">
Submitted successfully!
</SubmitionInfoMessage>
)}
{errorMessage && (
<SubmitionInfoMessage variant="body1">
{errorMessage}
</SubmitionInfoMessage>
)}
</MainContentContainer>
</SubscribeDialogueContainer>
)
}
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;
`

View File

@ -0,0 +1 @@
export { default as SubscribeDialogue } from './SubscribeDialogue'