mirror of
https://github.com/acid-info/logos-press-engine.git
synced 2025-02-23 22:58:08 +00:00
feat: implement subscribe button and dialogue
This commit is contained in:
parent
50e222fd2a
commit
2461659b5d
@ -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<NavbarState>
|
||||
@ -62,6 +63,7 @@ export default function NavBar({ defaultState }: NavBarProps) {
|
||||
|
||||
const buttons = (
|
||||
<>
|
||||
<SubscribeButton />
|
||||
<Buttons>
|
||||
<ThemeSwitch
|
||||
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;
|
||||
${(props) =>
|
||||
!props.display &&
|
||||
|
52
src/components/SubscribeButton/SubscribeButton.tsx
Normal file
52
src/components/SubscribeButton/SubscribeButton.tsx
Normal 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;
|
||||
}
|
||||
}
|
||||
`
|
1
src/components/SubscribeButton/index.ts
Normal file
1
src/components/SubscribeButton/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as SubscribeButton } from './SubscribeButton'
|
225
src/components/SubscribeDialogue/SubscribeDialogue.tsx
Normal file
225
src/components/SubscribeDialogue/SubscribeDialogue.tsx
Normal 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;
|
||||
`
|
1
src/components/SubscribeDialogue/index.ts
Normal file
1
src/components/SubscribeDialogue/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as SubscribeDialogue } from './SubscribeDialogue'
|
Loading…
x
Reference in New Issue
Block a user