From 41578b8b65171104fc81109ab64ad9d31c3a1e64 Mon Sep 17 00:00:00 2001 From: gbuomprisco Date: Sat, 20 Jul 2024 09:06:20 +0200 Subject: [PATCH] Add newsletter signup components This commit introduces two new components for handling newsletter signups. 'NewsletterSignup' captures the form elements for newsletter subscriptions, and 'NewsletterSignupContainer' wraps the form and handles the subscription flow, including loading, success, and error states. These components have been exposed in the marketing module's index file. --- packages/ui/src/makerkit/marketing/index.tsx | 2 + .../marketing/newsletter-signup-container.tsx | 86 +++++++++++++++++++ .../makerkit/marketing/newsletter-signup.tsx | 71 +++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 packages/ui/src/makerkit/marketing/newsletter-signup-container.tsx create mode 100644 packages/ui/src/makerkit/marketing/newsletter-signup.tsx diff --git a/packages/ui/src/makerkit/marketing/index.tsx b/packages/ui/src/makerkit/marketing/index.tsx index 7a648f031..476d4abcb 100644 --- a/packages/ui/src/makerkit/marketing/index.tsx +++ b/packages/ui/src/makerkit/marketing/index.tsx @@ -10,3 +10,5 @@ export * from './footer'; export * from './feature-showcase'; export * from './feature-grid'; export * from './feature-card'; +export * from './newsletter-signup'; +export * from './newsletter-signup-container'; \ No newline at end of file diff --git a/packages/ui/src/makerkit/marketing/newsletter-signup-container.tsx b/packages/ui/src/makerkit/marketing/newsletter-signup-container.tsx new file mode 100644 index 000000000..5bb565c4a --- /dev/null +++ b/packages/ui/src/makerkit/marketing/newsletter-signup-container.tsx @@ -0,0 +1,86 @@ +'use client'; + +import { useCallback, useState } from 'react'; + +import { Alert, AlertDescription, AlertTitle } from '../../shadcn/alert'; +import { Heading } from '../../shadcn/heading'; +import { cn } from '../../utils'; +import { Spinner } from '../spinner'; +import { NewsletterSignup } from './newsletter-signup'; + +interface NewsletterSignupContainerProps + extends React.HTMLAttributes { + onSignup: (email: string) => Promise; + heading?: string; + description?: string; + successMessage?: string; + errorMessage?: string; +} + +export function NewsletterSignupContainer({ + onSignup, + heading = 'Subscribe to our newsletter', + description = 'Get the latest updates and offers directly to your inbox.', + successMessage = 'Thank you for subscribing!', + errorMessage = 'An error occurred. Please try again.', + className, + ...props +}: NewsletterSignupContainerProps) { + const [status, setStatus] = useState< + 'idle' | 'loading' | 'success' | 'error' + >('idle'); + + const handleSubmit = useCallback( + async (data: { email: string }) => { + setStatus('loading'); + + try { + await onSignup(data.email); + + setStatus('success'); + } catch (error) { + console.error('Newsletter signup error:', error); + setStatus('error'); + } + }, + [onSignup], + ); + + return ( +
+
+ {heading} +

{description}

+
+ + {status === 'idle' && } + + {status === 'loading' && ( +
+ +
+ )} + + {status === 'success' && ( +
+ + Success! + {successMessage} + +
+ )} + + {status === 'error' && ( +
+ + Error + {errorMessage} + +
+ )} +
+ ); +} diff --git a/packages/ui/src/makerkit/marketing/newsletter-signup.tsx b/packages/ui/src/makerkit/marketing/newsletter-signup.tsx new file mode 100644 index 000000000..9791eb8a1 --- /dev/null +++ b/packages/ui/src/makerkit/marketing/newsletter-signup.tsx @@ -0,0 +1,71 @@ +'use client'; + +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; + +import { Button } from '../../shadcn/button'; +import { + Form, + FormControl, + FormField, + FormItem, + FormMessage, +} from '../../shadcn/form'; +import { Input } from '../../shadcn/input'; +import { cn } from '../../utils'; + +const NewsletterFormSchema = z.object({ + email: z.string().email('Please enter a valid email address'), +}); + +type NewsletterFormValues = z.infer; + +interface NewsletterSignupProps extends React.HTMLAttributes { + onSignup: (data: NewsletterFormValues) => void; + buttonText?: string; + placeholder?: string; +} + +export function NewsletterSignup({ + onSignup, + buttonText = 'Subscribe', + placeholder = 'Enter your email', + className, + ...props +}: NewsletterSignupProps) { + const form = useForm({ + resolver: zodResolver(NewsletterFormSchema), + defaultValues: { + email: '', + }, + }); + + return ( +
+
+ + ( + + + + + + + )} + /> + + + + +
+ ); +}