Skip to content

Commit

Permalink
Merge pull request #22 from andostronaut/develop
Browse files Browse the repository at this point in the history
feat: translate resume and setup intl
  • Loading branch information
andostronaut authored Aug 7, 2024
2 parents ef878c6 + b5af75b commit e5828e6
Show file tree
Hide file tree
Showing 18 changed files with 475 additions and 75 deletions.
File renamed without changes.
File renamed without changes.
84 changes: 84 additions & 0 deletions app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Metadata } from 'next'

import Navbar from '@/components/navbar'
import { ThemeProvider } from '@/components/theme-provider'
import { TooltipProvider } from '@/components/ui/tooltip'

import { I18nProviderClient } from '@/locales/lib/client'

import { DATA } from '@/data/resume'

type MetadataProps = {
params: { locale: string }
}

export const generateMetadata = async ({
params,
}: MetadataProps): Promise<Metadata> => {
const locale = params.locale

return {
metadataBase: new URL(DATA.url),
title: {
default: DATA.name,
template: `%s | ${DATA.name}`,
},
description: DATA.description,
keywords: DATA.keywords,
openGraph: {
title: `${DATA.name}`,
description: DATA.description,
url: DATA.url,
siteName: `${DATA.name}`,
locale: locale,
type: 'website',
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
twitter: {
title: `${DATA.name}`,
card: 'summary_large_image',
},
verification: {
google: '',
yandex: '',
},
}
}

const SubLayout = ({
children,
params: { locale },
}: Readonly<{
children: React.ReactNode
params: { locale: string }
}>) => {
return (
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<I18nProviderClient locale={locale}>
<TooltipProvider delayDuration={0}>
<main className="max-w-2xl mx-auto py-12 sm:py-24 px-6">
{children}
</main>
<Navbar />
</TooltipProvider>
</I18nProviderClient>
</ThemeProvider>
)
}

export default SubLayout
26 changes: 14 additions & 12 deletions app/page.tsx → app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import BlurFade from '@/components/magicui/blur-fade'
import BlurFadeText from '@/components/magicui/blur-fade-text'
import { ProjectCard } from '@/components/project-card'

import { getScopedI18n } from '@/locales/lib/server'

import { DATA } from '@/data/resume'

const BLUR_FADE_DELAY = 0.04

export default function Page() {
export default async function Page() {
const translate = await getScopedI18n('global')

return (
<main className="flex flex-col min-h-[100dvh] space-y-10">
<div className="flex flex-col min-h-[100dvh] space-y-10">
<section id="hero">
<div className="mx-auto w-full max-w-2xl space-y-8">
<div className="gap-2 flex justify-between">
Expand All @@ -32,7 +36,7 @@ export default function Page() {
<section id="about">
<BlurFade delay={BLUR_FADE_DELAY * 4}>
<Markdown className="prose max-w-full text-pretty font-sans text-md text-muted-foreground dark:prose-invert">
{DATA.description}
{translate(DATA.description as keyof typeof translate)}
</Markdown>
</BlurFade>
</section>
Expand All @@ -42,12 +46,10 @@ export default function Page() {
<div className="flex flex-col items-center justify-center space-y-4">
<div className="space-y-2">
<h2 className="text-3xl font-bold tracking-tighter sm:text-5xl">
Explore my latest creations and open-source projects.
{translate('projects.intro')}
</h2>
<p className="text-muted-foreground md:text-md/relaxed lg:text-base/relaxed xl:text-md/relaxed">
I&apos;ve participated in the conception and development of a
range of projects, including libraries, npm packages, and
complex web applications. Here are a few of my favorites.
{translate('projects.about')}
</p>
</div>
</div>
Expand Down Expand Up @@ -79,22 +81,22 @@ export default function Page() {
<BlurFade delay={BLUR_FADE_DELAY * 16}>
<div className="space-y-3">
<h2 className="text-3xl font-bold tracking-tighter sm:text-5xl">
Get in Touch
{translate('contact.get_in_touch')}
</h2>
<p className="mx-auto text-muted-foreground md:text-md/relaxed lg:text-base/relaxed xl:text-md/relaxed">
Want to connect? Send me a
{translate('contact.want')}
<Link
href={DATA.contact.social.X.url}
className="text-black underline font-semibold hover:underline dark:text-white ml-1"
>
direct message on X
{translate('contact.direct_message')}
</Link>
, and I&apos;ll make sure to get back to you.
{translate('contact.back')}
</p>
</div>
</BlurFade>
</div>
</section>
</main>
</div>
)
}
71 changes: 14 additions & 57 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,34 @@
import './globals.css'
import '@/app/globals.css'

import type { Metadata } from 'next'
import { Inter as FontSans } from 'next/font/google'

import Navbar from '@/components/navbar'
import { ThemeProvider } from '@/components/theme-provider'
import { TooltipProvider } from '@/components/ui/tooltip'

import { DATA } from '@/data/resume'
import { Inter } from 'next/font/google'
import { cookies } from 'next/headers'

import { cn } from '@/lib/utils'

const fontSans = FontSans({
const inter = Inter({
subsets: ['latin'],
variable: '--font-sans',
})

export const metadata: Metadata = {
metadataBase: new URL(DATA.url),
title: {
default: DATA.name,
template: `%s | ${DATA.name}`,
},
description: DATA.description,
openGraph: {
title: `${DATA.name}`,
description: DATA.description,
url: DATA.url,
siteName: `${DATA.name}`,
locale: 'en_US',
type: 'website',
},
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
'max-video-preview': -1,
'max-image-preview': 'large',
'max-snippet': -1,
},
},
twitter: {
title: `${DATA.name}`,
card: 'summary_large_image',
},
verification: {
google: '',
yandex: '',
},
}

export default function RootLayout({
const RootLayout = ({
children,
}: Readonly<{
children: React.ReactNode
}>) {
}>) => {
const locale = cookies().get('Next-Locale')?.value || 'en'

return (
<html lang="en" suppressHydrationWarning>
<html lang={locale} suppressHydrationWarning>
<body
className={cn(
'min-h-screen bg-background font-sans antialiased max-w-2xl mx-auto py-12 sm:py-24 px-6',
fontSans.variable
'min-h-screen bg-background font-sans antialiased',
inter.variable
)}
>
<ThemeProvider attribute="class" defaultTheme="dark">
<TooltipProvider delayDuration={0}>
{children}
<Navbar />
</TooltipProvider>
</ThemeProvider>
{children}
</body>
</html>
)
}

export default RootLayout
2 changes: 1 addition & 1 deletion app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function NotFound() {
404 - Page Not Found
</h1>
<p className="text-gray-500 dark:text-gray-400">
The page you re looking for doesn t exist or has been moved.
{`The page you re looking for doesn't exist or has been moved.`}
</p>
<Button
className="inline-flex h-9 items-center justify-center rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-gray-50 shadow transition-colors hover:bg-gray-900/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-gray-950 disabled:pointer-events-none disabled:opacity-50 dark:bg-gray-50 dark:text-gray-900 dark:hover:bg-gray-50/90 dark:focus-visible:ring-gray-300"
Expand Down
Binary file modified bun.lockb
Binary file not shown.
60 changes: 60 additions & 0 deletions components/locale-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use client'

import { CheckIcon, LanguagesIcon } from 'lucide-react'

import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Button } from '@/components/ui/button'

import { useChangeLocale, useCurrentLocale } from '@/locales/lib/client'

const locales = [
{
name: 'English',
value: 'en',
},
{
name: 'French',
value: 'fr',
},
]

export const LocalToggle = () => {
const changeLocale = useChangeLocale({ preserveSearchParams: true })
const currentLocale = useCurrentLocale()

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm">
<div className="flex items-center gap-2">
<LanguagesIcon className="h-5 w-5" />
<span className="block lg:hidden">{currentLocale}</span>
</div>
<span className="sr-only">Change Locale</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{locales.map((locale) => (
<DropdownMenuItem
key={locale.value}
onClick={() => changeLocale(locale.value as typeof currentLocale)}
disabled={locale.value === currentLocale}
>
<span>{locale.name}</span>
{locale.value === currentLocale ? (
<DropdownMenuShortcut>
<CheckIcon className="h-4 w-4" />
</DropdownMenuShortcut>
) : null}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
)
}
4 changes: 2 additions & 2 deletions components/magicui/dock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const DEFAULT_MAGNIFICATION = 60
const DEFAULT_DISTANCE = 140

const dockVariants = cva(
'mx-auto w-max h-full p-2 flex items-end rounded-full border'
'mx-auto w-max h-full p-2 flex items-end rounded-xl border'
)

const Dock = React.forwardRef<HTMLDivElement, DockProps>(
Expand Down Expand Up @@ -105,7 +105,7 @@ const DockIcon = ({
ref={ref}
style={{ width }}
className={cn(
'flex aspect-square cursor-pointer items-center justify-center rounded-full',
'flex aspect-square cursor-pointer items-center justify-center rounded-xl',
className
)}
{...props}
Expand Down
12 changes: 12 additions & 0 deletions components/navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { DATA } from '@/data/resume'

import { cn } from '@/lib/utils'
import { LocalToggle } from './locale-toggle'

export default function Navbar() {
return (
Expand Down Expand Up @@ -65,6 +66,17 @@ export default function Navbar() {
</DockIcon>
))}
<Separator orientation="vertical" className="h-full py-2" />
<DockIcon>
<Tooltip>
<TooltipTrigger asChild>
<LocalToggle />
</TooltipTrigger>
<TooltipContent>
<p>Locale</p>
</TooltipContent>
</Tooltip>
</DockIcon>
<Separator orientation="vertical" className="h-full py-2" />
<DockIcon>
<Tooltip>
<TooltipTrigger asChild>
Expand Down
Loading

0 comments on commit e5828e6

Please sign in to comment.