Skip to content

Commit

Permalink
feat: Add newsletter-form to subscribe users
Browse files Browse the repository at this point in the history
- TODO: Implement the logic to subscribe to Hashnode Newsletter API
  • Loading branch information
shricodev committed Nov 10, 2024
1 parent 6f1a261 commit 78298a0
Show file tree
Hide file tree
Showing 21 changed files with 1,781 additions and 180 deletions.
9 changes: 8 additions & 1 deletion app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import { NewsletterForm } from '@/components/newsletter-form'

export default function Page() {
return <div>About Page</div>
return (
<section>
About Page
<NewsletterForm />
</section>
)
}
2 changes: 1 addition & 1 deletion app/blogs/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default function Page({ params: { slug } }: Params) {
<div className='mt-3 flex items-center'>
<Avatar className='mr-2 size-8'>
<AvatarImage
src='https://github.com/shricodev.png'
src='/images/shricodev.jpg'
alt='Shrijal Acharya @shricodev'
/>
<AvatarFallback>SA</AvatarFallback>
Expand Down
29 changes: 29 additions & 0 deletions app/blogs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import BlogsWithSearch from '@/components/blogs-with-search'
import { AlertIcon } from '@/components/icons'
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { getBlogPostsWithContent } from '@/lib/blogs'

export default function Page() {
Expand All @@ -7,6 +9,33 @@ export default function Page() {
return (
<section className='container max-w-3xl'>
<h1 className='title'>Blogs</h1>
<Alert className='mb-4'>
<AlertIcon className='size-5' />
<AlertTitle className='text-sm font-semibold uppercase'>
Heads up!
</AlertTitle>
<AlertDescription className='text-sm text-muted-foreground'>
Check out these posts on{' '}
<a
href='https://dev.to/shricodev'
target='_blank'
rel='noreferrer noopener'
className='font-semibold text-zinc-400 underline underline-offset-4 hover:text-zinc-500'
>
DEV
</a>{' '}
and{' '}
<a
href='https://shricodev.hashnode.dev'
target='_blank'
rel='noreferrer noopener'
className='font-semibold text-zinc-400 underline underline-offset-4 hover:text-zinc-500'
>
Hashnode
</a>{' '}
for full engagement.
</AlertDescription>
</Alert>
<BlogsWithSearch blogsWithContent={blogsWithContent} />
</section>
)
Expand Down
11 changes: 11 additions & 0 deletions app/contact-me/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import { ContactMe } from '@/components/contact-me'
import { NewsletterForm } from '@/components/newsletter-form'

export default function Contact() {
return (
<section className='container max-w-3xl'>
<h2 className='title'>Get in touch</h2>
<p className='font-light text-muted-foreground'>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt
maxime neque numquam quia quis facere atque incidunt dolorem sed!
</p>
<br />
<p className='font-light text-muted-foreground'>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deserunt
maxime neque numquam quia quis facere atque incidunt dolorem sed!
</p>

<ContactMe />
<NewsletterForm />
</section>
)
}
3 changes: 3 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HeroIntro } from '@/components/hero-intro'
import { NewsletterForm } from '@/components/newsletter-form'
import RecentPosts from '@/components/recent-blogs'
import { Socials } from '@/components/socials'
import { getBlogPostsWithContent } from '@/lib/blogs'
Expand All @@ -13,6 +14,8 @@ export default function Home() {
<RecentPosts blogsWithContent={blogsWithContent} />

<Socials />

<NewsletterForm />
</section>
)
}
184 changes: 93 additions & 91 deletions components/contact-me.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,100 +55,102 @@ export const ContactMe = () => {
}

return (
<section className='relative isolate'>
<div className='relative'>
<Form {...form}>
<form
onSubmit={form.handleSubmit(handleFormSubmit)}
className='mt-16 lg:flex-auto'
noValidate
>
<div className='grid grid-cols-1 gap-6 sm:grid-cols-2'>
<div>
<FormField
control={form.control}
name='name'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Name
</FormLabel>
<FormControl>
<Input
id='name'
autoFocus
placeholder='Name'
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>

<div>
<FormField
control={form.control}
name='email'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Email
</FormLabel>
<FormControl>
<Input id='email' placeholder='Email' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<section className='relative'>
<Form {...form}>
<form
onSubmit={form.handleSubmit(handleFormSubmit)}
className='mt-16 lg:flex-auto'
noValidate
>
<div className='grid grid-cols-1 gap-6 sm:grid-cols-2'>
<div>
<FormField
control={form.control}
name='name'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Name
</FormLabel>
<FormControl>
<Input
id='name'
autoFocus
placeholder='Enter your name'
{...field}
/>
</FormControl>
<FormMessage className='text-xs text-rose-500' />
</FormItem>
)}
/>
</div>

<div className='sm:col-span-2'>
<FormField
control={form.control}
name='message'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Message
</FormLabel>
<FormControl>
<Textarea
rows={8}
id='message'
placeholder='Enter your message..'
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<div>
<FormField
control={form.control}
name='email'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Email
</FormLabel>
<FormControl>
<Input
id='email'
placeholder='Enter your email'
{...field}
/>
</FormControl>
<FormMessage className='text-xs text-rose-500' />
</FormItem>
)}
/>
</div>
<div className='mt-6'>
<Button
type='submit'
disabled={form.formState.isSubmitting}
className='w-full disabled:opacity-50'
>
{form.formState.isSubmitting ? (
<Loader className='mr-2 size-5 animate-spin' />
) : null}
Contact Me
</Button>

<div className='sm:col-span-2'>
<FormField
control={form.control}
name='message'
render={({ field }) => (
<FormItem>
<FormLabel className='text-xs font-bold uppercase text-zinc-500'>
Message
</FormLabel>
<FormControl>
<Textarea
rows={8}
id='message'
placeholder='Enter your message...'
{...field}
/>
</FormControl>
<FormMessage className='text-xs text-rose-500' />
</FormItem>
)}
/>
</div>
<p className='mt-4 text-xs text-muted-foreground'>
By submitting this form, I agree to the{' '}
<Link href='/privacy' className='font-bold' target='_blank'>
privacy&nbsp;policy.
</Link>
</p>
</form>
</Form>
</div>
</div>
<div className='mt-6'>
<Button
type='submit'
disabled={form.formState.isSubmitting}
className='w-full disabled:opacity-50'
>
{form.formState.isSubmitting ? (
<Loader className='mr-2 size-5 animate-spin' />
) : null}
Contact Me
</Button>
</div>
<p className='mt-4 text-xs text-muted-foreground'>
By submitting this form, I agree to the{' '}
<Link href='/privacy' className='font-bold' target='_blank'>
privacy&nbsp;policy.
</Link>
</p>
</form>
</Form>
</section>
)
}
4 changes: 2 additions & 2 deletions components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const socials = [
},
{
name: 'Hashnode',
href: 'https://hashnode.com/@shricodev',
href: 'https://shricodev.hashnode.dev',
icon: HashnodeIcon,
},
{
Expand All @@ -36,7 +36,7 @@ const socials = [

export const Footer = () => {
return (
<footer className='container max-w-3xl px-4 py-8'>
<footer className='container max-w-3xl py-8'>
<div className='md:flex md:items-center md:justify-between'>
<div className='flex justify-center space-x-6 md:order-2'>
{socials.map(social => (
Expand Down
8 changes: 4 additions & 4 deletions components/hero-intro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export const HeroIntro = () => {
</p>
</div>
<Image
className='hidden rounded-full grayscale md:block'
src={'https://placehold.jp/175x175.png'}
className='hidden rounded-full md:block'
src={'/images/shricodev.jpg'}
alt='Shrijal Acharya'
width={175}
height={175}
Expand All @@ -34,11 +34,11 @@ export const HeroIntro = () => {
<Card className='mt-6 p-4 md:flex md:items-center'>
<div className='md:hidden md:flex-shrink-0'>
<Image
src={'https://placehold.jp/175x175.png'}
src={'/images/shricodev.jpg'}
alt='Shrijal Acharya'
width={175}
height={175}
className='rounded-full grayscale'
className='rounded-full'
/>
</div>

Expand Down
21 changes: 21 additions & 0 deletions components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,27 @@ export function CrossIcon(
)
}

export function AlertIcon(
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
) {
return (
<svg
fill='none'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 24 24'
{...props}
>
<path
stroke='currentColor'
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth='2'
d='M9 9a3 3 0 0 1 3-3m-2 15h4m0-3c0-4.1 4-4.9 4-9A6 6 0 1 0 6 9c0 4 4 5 4 9h4Z'
/>
</svg>
)
}

export function GitHubIcon(
props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>,
) {
Expand Down
Loading

0 comments on commit 78298a0

Please sign in to comment.