Skip to content

Commit

Permalink
🏀 feat: add bio feature
Browse files Browse the repository at this point in the history
  • Loading branch information
nyomansunima committed Nov 1, 2023
1 parent 45b8432 commit 0388018
Show file tree
Hide file tree
Showing 18 changed files with 567 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ NEXT_PUBLIC_HYGRAPH_URL = https://ap-southeast-2.cdn.hygraph.com/content/clo9ye1

# APP
NEXT_PUBLIC_APP_HOST = https://nyomansunima.com

NEXT_PUBLIC_BREVO_URL = https://api.brevo.com/v3
NEXT_PUBLIC_BREVO_API_KEY = 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
Binary file modified bun.lockb
Binary file not shown.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
},
"dependencies": {
"@flaticon/flaticon-uicons": "^3.0.0",
"@hookform/resolvers": "^3.3.2",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tooltip": "^1.0.7",
"@studio-freight/lenis": "^1.0.27",
Expand All @@ -26,11 +28,13 @@
"next-themes": "^0.2.1",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.47.0",
"react-markdown": "^9.0.0",
"remark-gfm": "^4.0.0",
"split-type": "^0.3.4",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zod": "^3.22.4"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.10",
Expand Down
Binary file added public/images/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions src/app/bio/components/bio-intro-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Image from 'next/image'

export default function BioIntroSection() {
return (
<section className="flex flex-col items-center">
<picture>
<Image
src={'/images/profile.png'}
height={120}
width={120}
quality={100}
alt="Nyoman Sunima Photo"
className="rounded-full overflow-hidden"
/>
</picture>

<h3 className="text-center mt-10 text-2xl">Nyoman Sunima</h3>
<p className="text-center mt-3 text-lg">
5+ years as a product designer and full stack developer. Been focusing
on crafting apps through research, design, and development. My day to
day revolves around designing and developing digital products.
</p>
</section>
)
}
27 changes: 27 additions & 0 deletions src/app/bio/components/bio-link-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Button } from '@components/ui/button'
import Link from 'next/link'
import { commonService } from '~/services/common-service'

export default async function BioLinkSection() {
const links = await commonService.getAllLinks()

return (
<section className="flex flex-col mt-10">
<div className="flex flex-wrap gap-4 justify-center">
{links.map((link, i) => (
<Button
key={i}
size={'base'}
variant={'outline'}
asChild
className="transition-all duration-700 hover:-translate-y-1"
>
<Link href={link.url} target="_blank">
{link.title}
</Link>
</Button>
))}
</div>
</section>
)
}
95 changes: 95 additions & 0 deletions src/app/bio/components/bio-newsletter-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'use client'

import {
Form,
FormControl,
FormField,
FormItem,
FormMessage,
} from '@components/ui/form'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'
import { Input } from '@components/ui/input'
import { Button } from '@components/ui/button'
import { newsletterService } from '~/services/newsletter-service'

const formSchema = z.object({
email: z
.string()
.min(1, 'Please add your email address')
.email('Opps your email looks weird.'),
})

function NewsletterForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: '',
},
})

const subscribeToNewsletter = useMutation({
mutationFn: newsletterService.subsribeToDailyUpdate,
onSuccess: () => {
form.reset()
},
onError: () => {
form.reset()
},
})

return (
<Form {...form}>
<form
onSubmit={form.handleSubmit((formData) =>
subscribeToNewsletter.mutate(formData),
)}
className="flex flex-col gap-3 mt-6"
>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormControl>
<Input placeholder="Your email address" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<div className="flex justify-end">
<Button disabled={subscribeToNewsletter.isPending} size={'base'}>
{!subscribeToNewsletter.isPending ? (
<>
<i className="fi fi-rr-paper-plane" />
Subscribe now
</>
) : (
<>
<i className="fi fi-rr-paper-plane" />
Subscribing ...
</>
)}
</Button>
</div>
</form>
</Form>
)
}

export default function BioNewsletterSection() {
return (
<section className="flex flex-col col-span-full border border-border rounded-xl p-4">
<h3 className="text-xl">Join Newsletter</h3>
<span className="opacity-75 mt-1">
Join the amazing design, development, indie hacker tips every weeek.
</span>

<NewsletterForm />
</section>
)
}
23 changes: 23 additions & 0 deletions src/app/bio/components/bio-social-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Button } from '@components/ui/button'
import Link from 'next/link'
import { socials } from '~/constants/social'

export default async function BioSocialSection() {
return (
<section className="flex flex-wrap items-center mt-16 gap-3 justify-center">
{socials.map((social, i) => (
<Button
asChild
key={i}
size={'icon'}
variant={'outline'}
className="h-14 w-14 text-lg transition-all duration-700 hover:scale-95"
>
<Link href={social.url} target="_blank">
<i className={`${social.icon}`} />
</Link>
</Button>
))}
</section>
)
}
46 changes: 46 additions & 0 deletions src/app/bio/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Metadata } from 'next'
import {
defaultOpenGraphMetadata,
defaultTwitterMetadata,
} from '~/lib/shared-metadata'
import BioIntroSection from './components/bio-intro-section'
import BioSocialSection from './components/bio-social-section'
import BioLinkSection from './components/bio-link-section'
import BioNewsletterSection from './components/bio-newsletter-section'

export const metadata: Metadata = {
title:
'Product Designer & Fullstack Developer specialized in crafting apps | Nyoman Sunima',
description:
'Product Designer & Fullstack Developer specialized in crafting apps',
openGraph: {
...defaultOpenGraphMetadata,
title:
'Product Designer & Fullstack Developer specialized in crafting apps | Nyoman Sunima',
description:
'Product Designer & Fullstack Developer specialized in crafting apps',
},
twitter: {
...defaultTwitterMetadata,
title:
'Product Designer & Fullstack Developer specialized in crafting apps | Nyoman Sunima',
description:
'Product Designer & Fullstack Developer specialized in crafting apps',
},
}

export default function BioPage() {
return (
<main className="flex flex-col laptop:py-28 py-20">
<div className="container mx-auto laptop:w-1/2 px-5">
<BioIntroSection />
<BioSocialSection />
<BioLinkSection />

<div className="grid laptop:grid-cols-9 grid-cols-1 mt-20">
<BioNewsletterSection />
</div>
</div>
</main>
)
}
2 changes: 1 addition & 1 deletion src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const buttonVariants = cva('flex justify-center items-center relative gap-3', {
secondary: 'bg-secondary text-secondary-foreground',
},
size: {
base: 'h-10 px-4 py-2',
base: 'h-12 px-6 py-2 rounded-xl text-base',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
md: 'h-16 px-10 rounded-full text-lg',
Expand Down
Loading

0 comments on commit 0388018

Please sign in to comment.