From 87264a549762a6db3978fa9a2beadc5338a9d4b7 Mon Sep 17 00:00:00 2001 From: weeihan Date: Sat, 11 Jul 2026 19:01:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20i18n=20=E2=80=94=20EN/MS/ZH=20translati?= =?UTF-8?q?ons=20with=20cookie-based=20locale=20switching,=20report=20form?= =?UTF-8?q?=20translated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01FFDuBhMKvoWjrWT3ZnGmmr --- app/layout.tsx | 51 +++++++---- app/report/page.tsx | 6 +- components/incidents/report-form.tsx | 124 +++++++++++++++++++-------- components/language-switcher.tsx | 43 ++++++++++ lib/i18n/context.tsx | 24 ++++++ lib/i18n/locales.ts | 2 + lib/i18n/server.ts | 20 +++++ lib/offline/db.ts | 16 ++++ messages/en.json | 36 ++++++++ messages/ms.json | 36 ++++++++ messages/zh.json | 36 ++++++++ tests/lib/i18n/translations.test.ts | 30 +++++++ 12 files changed, 372 insertions(+), 52 deletions(-) create mode 100644 components/language-switcher.tsx create mode 100644 lib/i18n/context.tsx create mode 100644 lib/i18n/locales.ts create mode 100644 lib/i18n/server.ts create mode 100644 lib/offline/db.ts create mode 100644 messages/en.json create mode 100644 messages/ms.json create mode 100644 messages/zh.json create mode 100644 tests/lib/i18n/translations.test.ts diff --git a/app/layout.tsx b/app/layout.tsx index 81e392a..d347dfb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,33 +1,50 @@ -import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; -import "./globals.css"; +import type { Metadata } from 'next' +import { Geist, Geist_Mono } from 'next/font/google' +import './globals.css' +import { I18nProvider } from '@/lib/i18n/context' +import { getLocale, loadMessages } from '@/lib/i18n/server' const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); + variable: '--font-geist-sans', + subsets: ['latin'], +}) const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); + variable: '--font-geist-mono', + subsets: ['latin'], +}) export const metadata: Metadata = { - title: "IMS — HSE Incident Management", - description: "Setia Corporation HSE Incident Management System", -}; + title: 'IMS — HSE Incident Management', + description: 'Setia Corporation HSE Incident Management System', +} -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ - children: React.ReactNode; + children: React.ReactNode }>) { + const locale = await getLocale() + const messages = await loadMessages(locale) + return ( - {children} + + + + + + {children} + +