feat: restructure routes under [locale], add LanguageSwitcher
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
import type { Metadata } from 'next'
|
||||||
|
import { NextIntlClientProvider } from 'next-intl'
|
||||||
|
import { getTranslations, getMessages } from 'next-intl/server'
|
||||||
|
import { notFound } from 'next/navigation'
|
||||||
|
import { routing } from '@/i18n/routing'
|
||||||
|
import { LanguageSwitcher } from '@/components/LanguageSwitcher'
|
||||||
|
|
||||||
|
export async function generateMetadata({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ locale: string }>
|
||||||
|
}): Promise<Metadata> {
|
||||||
|
const { locale } = await params
|
||||||
|
const t = await getTranslations({ locale, namespace: 'meta' })
|
||||||
|
return { title: t('title') }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function LocaleLayout({
|
||||||
|
children,
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
params: Promise<{ locale: string }>
|
||||||
|
}) {
|
||||||
|
const { locale } = await params
|
||||||
|
|
||||||
|
if (!(routing.locales as readonly string[]).includes(locale)) {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const messages = await getMessages()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<html lang={locale}>
|
||||||
|
<body>
|
||||||
|
<NextIntlClientProvider messages={messages}>
|
||||||
|
<LanguageSwitcher />
|
||||||
|
{children}
|
||||||
|
</NextIntlClientProvider>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { getTranslations } from 'next-intl/server'
|
||||||
|
import { SubmitForm } from '@/components/SubmitForm'
|
||||||
|
|
||||||
|
export default async function Home({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ locale: string }>
|
||||||
|
}) {
|
||||||
|
const { locale } = await params
|
||||||
|
const t = await getTranslations({ locale, namespace: 'home' })
|
||||||
|
return (
|
||||||
|
<main style={{ padding: '2rem' }}>
|
||||||
|
<h1>{t('heading')}</h1>
|
||||||
|
<SubmitForm />
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { getTranslations } from 'next-intl/server'
|
||||||
|
import { StatusView } from '@/components/StatusView'
|
||||||
|
|
||||||
|
export default async function StatusPage({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: Promise<{ locale: string; uuid: string }>
|
||||||
|
}) {
|
||||||
|
const { locale, uuid } = await params
|
||||||
|
const t = await getTranslations({ locale, namespace: 'status' })
|
||||||
|
return (
|
||||||
|
<main style={{ padding: '2rem' }}>
|
||||||
|
<h1>{t('heading')}</h1>
|
||||||
|
<StatusView uuid={uuid} />
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
+1
-11
@@ -1,13 +1,3 @@
|
|||||||
import type { Metadata } from 'next'
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: 'Ombrora — Telechargeur de videos',
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return children
|
||||||
<html lang="fr">
|
|
||||||
<body>{children}</body>
|
|
||||||
</html>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
import { SubmitForm } from '@/components/SubmitForm'
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
return (
|
|
||||||
<main style={{ padding: '2rem' }}>
|
|
||||||
<h1>Ombrora</h1>
|
|
||||||
<SubmitForm />
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { StatusView } from '@/components/StatusView'
|
|
||||||
|
|
||||||
export default async function StatusPage({
|
|
||||||
params,
|
|
||||||
}: {
|
|
||||||
params: Promise<{ uuid: string }>
|
|
||||||
}) {
|
|
||||||
const { uuid } = await params
|
|
||||||
return (
|
|
||||||
<main style={{ padding: '2rem' }}>
|
|
||||||
<h1>Statut du telechargement</h1>
|
|
||||||
<StatusView uuid={uuid} />
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useLocale } from 'next-intl'
|
||||||
|
import { useRouter, usePathname } from '@/navigation'
|
||||||
|
import { routing } from '@/i18n/routing'
|
||||||
|
|
||||||
|
const FLAGS: Record<string, string> = {
|
||||||
|
en: '🇺🇸',
|
||||||
|
fr: '🇫🇷',
|
||||||
|
es: '🇪🇸',
|
||||||
|
it: '🇮🇹',
|
||||||
|
}
|
||||||
|
|
||||||
|
export function LanguageSwitcher() {
|
||||||
|
const locale = useLocale()
|
||||||
|
const router = useRouter()
|
||||||
|
const pathname = usePathname()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: 'flex', gap: '0.5rem', padding: '0.5rem 2rem' }}>
|
||||||
|
{routing.locales.map((loc) => (
|
||||||
|
<button
|
||||||
|
key={loc}
|
||||||
|
onClick={() => router.replace(pathname, { locale: loc })}
|
||||||
|
aria-label={loc}
|
||||||
|
style={{
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
background: 'none',
|
||||||
|
border: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
opacity: loc === locale ? 1 : 0.4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{FLAGS[loc]}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user