Skip to content
Open
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Game } from '@/src/components/game'
import { getGame } from '@/src/lib/game.service.server'
import { GameProvider } from '@/src/providers/game.provider'
import { LangProvider } from '@/src/providers/lang.provider'

export default async function Home({
params,
searchParams
}: {
params: { gameId: string }
params: { gameId: string; lang: string }
searchParams: { playerId: string }
}) {
const game = await getGame(params.gameId, searchParams.playerId)
Expand All @@ -17,8 +18,10 @@ export default async function Home({
}

return (
<GameProvider gameId={params.gameId} game={game}>
<Game game={game} />
</GameProvider>
<LangProvider>
<GameProvider gameId={params.gameId} game={game}>
<Game game={game} />
</GameProvider>
</LangProvider>
)
}
14 changes: 8 additions & 6 deletions app/games/create/page.tsx → app/[lang]/games/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { createGame } from '@/src/lib/game.service.client'
import { useRouter } from 'next/navigation'
import { FormEvent, useState } from 'react'
import LoadingSpinner from '@/src/components/loading'
import { useTranslationClient } from '@/src/i18n/i18n.client'

export default function Home() {
export default function Home({ params: { lang } }: { params: { lang: string } }) {
const { t } = useTranslationClient(lang)
const router = useRouter()
const [isLoading, setIsLoading] = useState<boolean>(false)

Expand All @@ -15,7 +17,7 @@ export default function Home() {
const playerName = String(event.currentTarget.playerName.value)
try {
const { gameId, playerId } = await createGame({ nbOfPlayers, playerName })
router.push(`/games/${gameId}?playerId=${playerId}`)
router.push(`/${lang}/games/${gameId}?playerId=${playerId}`)
} catch (e) {
console.error(e)
} finally {
Expand All @@ -27,11 +29,11 @@ export default function Home() {
<div className="flex flex-col h-screen justify-center items-center">
<form onSubmit={onSubmit} className="flex flex-col gap-4 justify-center">
<div className="flex flex-row gap-4 text-xl justify-between">
<label htmlFor="playerName">Your name:</label>
<label htmlFor="playerName">{t('your-name')}</label>
<input type="text" name="playerName" className="text-black w-40" />
</div>
<div className="flex flex-row gap-4 text-xl justify-between">
<label htmlFor="nbPlayers">Number of players:</label>
<label htmlFor="nbPlayers">{t('number-of-players')}</label>
<input
type="number"
name="nbPlayers"
Expand All @@ -46,10 +48,10 @@ export default function Home() {
type="submit"
className="w-96 text-center px-4 py-1 text-4xl text-zinc-300 font-semibold rounded-lg border-4 border-zinc-300 hover:text-slate-950 hover:bg-zinc-300 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-zinc-300 focus:ring-offset-2 basis-1/4 shrink"
>
New game
{t('new-game')}
</button>
</form>
{isLoading && <LoadingSpinner label="Creating game..." />}
{isLoading && <LoadingSpinner label={t('creating-game')} />}
</div>
)
}
12 changes: 7 additions & 5 deletions app/games/join/page.tsx → app/[lang]/games/join/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { joinGame } from '@/src/lib/game.service.client'
import { useRouter } from 'next/navigation'
import { FormEvent, useState } from 'react'
import LoadingSpinner from '@/src/components/loading'
import { useTranslationClient } from '@/src/i18n/i18n.client'

export default function Home() {
export default function Home({ params: { lang } }: { params: { lang: string } }) {
const { t } = useTranslationClient(lang)
const router = useRouter()
const [isLoading, setIsLoading] = useState<boolean>(false)

Expand All @@ -27,21 +29,21 @@ export default function Home() {
<div className="flex flex-col h-screen justify-center items-center">
<form onSubmit={onSubmit} className="flex flex-col gap-4 justify-center">
<div className="flex flex-row gap-4 text-xl justify-between">
<label htmlFor="playerName">Your name:</label>
<label htmlFor="playerName">{t('your-name')}</label>
<input type="text" name="playerName" className="text-black w-48" />
</div>
<div className="flex flex-row gap-4 text-xl justify-between">
<label htmlFor="gameId">Game code:</label>
<label htmlFor="gameId">{t('game-code')}</label>
<input type="text" name="gameId" className="text-black w-48" />
</div>
<button
type="submit"
className="w-96 text-center px-4 py-1 text-4xl text-zinc-300 font-semibold rounded-lg border-4 border-zinc-300 hover:text-slate-950 hover:bg-zinc-300 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-zinc-300 focus:ring-offset-2 basis-1/4 shrink"
>
Join game
{t('join-game')}
</button>
</form>
{isLoading && <LoadingSpinner label="Joining game..." />}
{isLoading && <LoadingSpinner label={t('joining-game')} />}
</div>
)
}
2 changes: 1 addition & 1 deletion app/globals.css → app/[lang]/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

:root {
--main-font-color: white;
--background-image: url('../src/assets/images/background.jpg');
--background-image: url('../../src/assets/images/background.jpg');
}

body {
Expand Down
10 changes: 8 additions & 2 deletions app/layout.tsx → app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
import { dir } from 'i18next'
import { languages } from '@/src/i18n/settings'

export async function generateStaticParams() {
return languages.map((lng) => ({ lng }))
}

const inter = Inter({ subsets: ['latin'] })

Expand All @@ -9,9 +15,9 @@ export const metadata: Metadata = {
description: 'Generated by create next app'
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
export default function RootLayout({ children, params }: { children: React.ReactNode; params: { lang: string } }) {
return (
<html lang="en">
<html lang={params.lang} dir={dir(params.lang)}>
<body className={inter.className}>{children}</body>
</html>
)
Expand Down
12 changes: 7 additions & 5 deletions app/page.tsx → app/[lang]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import Link from 'next/link'
import { useTranslationServer } from '@/src/i18n/i18n.server'

const linkClasses =
'w-96 text-center px-4 py-1 text-4xl text-zinc-300 font-semibold rounded-lg border-4 border-zinc-300 hover:text-slate-950 hover:bg-zinc-300 hover:border-transparent focus:outline-none focus:ring-2 focus:ring-zinc-300 focus:ring-offset-2 basis-1/4 shrink'

export default function Home() {
export default async function Home({ params }: { params: { lang: string } }) {
const { t } = await useTranslationServer(params.lang)
return (
<div className="flex flex-col h-screen justify-center">
<div className="flex flex-col gap-4 items-center">
<Link href="/games/create" className={linkClasses}>
Create a game
<Link href={`/${params.lang}/games/create`} className={linkClasses}>
{t('create-a-game')}
</Link>
<Link href="/games/join" className={linkClasses}>
Join a game
<Link href={`/${params.lang}/games/join`} className={linkClasses}>
{t('join-a-game')}
</Link>
</div>
</div>
Expand Down
47 changes: 47 additions & 0 deletions middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { NextRequest } from 'next/server.js'
import { cookieName, languages } from '@/src/i18n/settings'
import acceptLanguage from 'accept-language'
import { NextResponse } from 'next/server'

export function middleware(request: NextRequest) {
// Check if there is any supported locale in the pathname
const { pathname } = request.nextUrl
const pathnameHasLocale = languages.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
)

const referer = request.headers.get('referer')
if (referer) {
const refererUrl = new URL(referer)
const lngInReferer = languages.find((lang) => refererUrl.pathname.startsWith(`/${lang}`))
const response = NextResponse.next()
if (lngInReferer) {
response.cookies.set(cookieName, lngInReferer)
}
return response
}

if (pathnameHasLocale) {
return
}

let locale = 'en'
if (request.cookies.has(cookieName)) {
const newLocale =acceptLanguage.get(request.cookies.get(cookieName)?.value)
locale = newLocale ?? locale
}
if (!locale){
const newLocale = acceptLanguage.get(request.headers.get('Accept-Language'))
locale = newLocale ?? locale
}

request.nextUrl.pathname = `/${locale}${pathname}`
return Response.redirect(request.nextUrl)
}

export const config = {
matcher: [
// Skip all internal paths (_next)
'/((?!api|_next/static|_next/image|favicon.ico).*)'
],
}
Loading