Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 3 additions & 24 deletions app/(auth)/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
import type { Metadata } from 'next'
import { SITE_NAME } from '@/lib/consts'
import { ForgotPasswordForm } from '@/components/forgot-password-form'
import { Route } from 'next'
import { redirect } from 'next/navigation'

export const metadata: Metadata = {
title: `Forgot Password · ${SITE_NAME}`,
}

export default async function Page({
searchParams,
}: {
searchParams: Promise<{
email?: string
from?: Route
}>
}) {
const { email, from = '/' } = await searchParams
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<div className="w-full max-w-sm">
<ForgotPasswordForm email={email} from={from} />
</div>
</div>
)
export default function ForgotPasswordRedirect() {
redirect('/en/forgot-password')
}
28 changes: 3 additions & 25 deletions app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
import { LoginForm } from '@/components/login-form'
import type { Metadata, Route } from 'next'
import { SITE_NAME } from '@/lib/consts'
import { AnimatedBooksBackground } from '@/components/ui/animated-books-background'
import { redirect } from 'next/navigation'

export const metadata: Metadata = {
title: `Login · ${SITE_NAME}`,
}

export default async function Page({
searchParams,
}: {
searchParams: Promise<{
email?: string
from?: Route
}>
}) {
const { email, from = '/' } = await searchParams
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<AnimatedBooksBackground />
<div className="relative w-full max-w-sm">
<LoginForm email={email} from={from} />
</div>
</div>
)
export default function LoginRedirect() {
redirect('/en/login')
}
20 changes: 3 additions & 17 deletions app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
import { SignUpForm } from '@/components/signup-form'
import type { Metadata } from 'next'
import { SITE_NAME } from '@/lib/consts'
import { AnimatedBooksBackground } from '@/components/ui/animated-books-background'
import { redirect } from 'next/navigation'

export const metadata: Metadata = {
title: `Signup · ${SITE_NAME}`,
}

export default async function Page() {
return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<AnimatedBooksBackground />
<div className="relative w-full max-w-sm">
<SignUpForm />
</div>
</div>
)
export default function SignupRedirect() {
redirect('/en/signup')
}
69 changes: 69 additions & 0 deletions app/[locale]/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { Metadata } from 'next'
import Link from 'next/link'
import { ArrowLeft } from 'lucide-react'
import { notFound } from 'next/navigation'
import { Button } from '@/components/ui/button'
import {
getDictionary,
getMetadataForPage,
isLocale,
localizePath,
type Locale,
} from '@/lib/i18n'

type Props = {
params: Promise<{
locale: string
}>
}

async function getPageLocale(params: Props['params']): Promise<Locale> {
const { locale } = await params

if (!isLocale(locale)) {
notFound()
}

return locale
}

export async function generateMetadata({
params,
}: Props): Promise<Metadata> {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)

return getMetadataForPage(locale, '/about', dictionary.meta.about)
}

export default async function AboutPage({ params }: Props) {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)

return (
<div>
<div className="container mx-auto px-4 py-12 max-w-3xl">
<div className="mb-10">
<Button variant="ghost" asChild className="mb-4 -ml-4">
<Link href={localizePath(locale, '/')}>
<ArrowLeft className="mr-2 h-4 w-4" />
{dictionary.about.backToHome}
</Link>
</Button>

<div className="flex items-center gap-3 mb-4">
<h1 className="text-3xl font-bold leading-tight bg-gradient-to-r from-foreground via-foreground to-foreground/80 bg-clip-text text-transparent">
{dictionary.about.title}
</h1>
</div>
</div>

{dictionary.about.paragraphs.map((paragraph) => (
<p key={paragraph} className="text-lg text-foreground/80 mb-6">
{paragraph}
</p>
))}
</div>
</div>
)
}
62 changes: 62 additions & 0 deletions app/[locale]/forgot-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { Metadata, Route } from 'next'
import { notFound } from 'next/navigation'
import { ForgotPasswordForm } from '@/components/forgot-password-form'
import {
getDictionary,
getMetadataForPage,
isLocale,
type Locale,
} from '@/lib/i18n'

type Props = {
params: Promise<{ locale: string }>
searchParams: Promise<{
email?: string
from?: Route
}>
}

async function getPageLocale(params: Props['params']): Promise<Locale> {
const { locale } = await params

if (!isLocale(locale)) {
notFound()
}

return locale
}

export async function generateMetadata({
params,
}: Props): Promise<Metadata> {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)

return getMetadataForPage(
locale,
'/forgot-password',
dictionary.meta.forgotPassword
)
}

export default async function ForgotPasswordPage({
params,
searchParams,
}: Props) {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)
const { email, from = '/' } = await searchParams

return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<div className="w-full max-w-sm">
<ForgotPasswordForm
email={email}
from={from}
locale={locale}
copy={dictionary.auth.forgotPassword}
/>
</div>
</div>
)
}
25 changes: 25 additions & 0 deletions app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { notFound } from 'next/navigation'
import { isLocale, locales } from '@/lib/i18n'

type Props = {
children: React.ReactNode
params: Promise<{
locale: string
}>
}

export const dynamicParams = false

export function generateStaticParams() {
return locales.map((locale) => ({ locale }))
}

export default async function LocaleLayout({ children, params }: Props) {
const { locale } = await params

if (!isLocale(locale)) {
notFound()
}

return children
}
57 changes: 57 additions & 0 deletions app/[locale]/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { Metadata, Route } from 'next'
import { notFound } from 'next/navigation'
import { AnimatedBooksBackground } from '@/components/ui/animated-books-background'
import { LoginForm } from '@/components/login-form'
import {
getDictionary,
getMetadataForPage,
isLocale,
type Locale,
} from '@/lib/i18n'

type Props = {
params: Promise<{ locale: string }>
searchParams: Promise<{
email?: string
from?: Route
}>
}

async function getPageLocale(params: Props['params']): Promise<Locale> {
const { locale } = await params

if (!isLocale(locale)) {
notFound()
}

return locale
}

export async function generateMetadata({
params,
}: Props): Promise<Metadata> {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)

return getMetadataForPage(locale, '/login', dictionary.meta.login)
}

export default async function LoginPage({ params, searchParams }: Props) {
const locale = await getPageLocale(params)
const dictionary = await getDictionary(locale)
const { email, from = '/' } = await searchParams

return (
<div className="flex min-h-svh w-full items-center justify-center p-6 md:p-10">
<AnimatedBooksBackground />
<div className="relative w-full max-w-sm">
<LoginForm
email={email}
from={from}
locale={locale}
copy={dictionary.auth.login}
/>
</div>
</div>
)
}
Loading