feat(i18n): add locale dictionaries and pilot surfaces

This commit is contained in:
2026-06-11 04:55:47 +02:00
parent 2c6d6bffcd
commit ac3dfe69cd
15 changed files with 354 additions and 19 deletions
+27
View File
@@ -0,0 +1,27 @@
export const en = {
login: {
title: "Sign In",
usernameLabel: "Username",
passwordLabel: "Password",
submitLabel: "Sign In",
},
dashboardHome: {
heading: "Dashboard",
cards: {
items: {
title: "Total Items",
countLabel: "Total",
},
assets: {
title: "Total Assets",
countLabel: "Total",
},
recipients: {
title: "Total Recipients",
countLabel: "Total",
},
},
},
}
export type Dictionary = typeof en
+27
View File
@@ -0,0 +1,27 @@
import type { Dictionary } from "./en"
export const es = {
login: {
title: "Iniciar sesión",
usernameLabel: "Usuario",
passwordLabel: "Contraseña",
submitLabel: "Iniciar sesión",
},
dashboardHome: {
heading: "Panel de control",
cards: {
items: {
title: "Total de artículos",
countLabel: "Total",
},
assets: {
title: "Total de activos",
countLabel: "Total",
},
recipients: {
title: "Total de destinatarios",
countLabel: "Total",
},
},
},
} satisfies Dictionary
+15
View File
@@ -0,0 +1,15 @@
import type { Locale } from "../locales"
import { type Dictionary, en } from "./en"
import { es } from "./es"
export type { Dictionary }
export const dictionaries = {
en,
es,
} satisfies Record<Locale, Dictionary>
export function getDictionary(locale: Locale): Dictionary {
return dictionaries[locale]
}
+21
View File
@@ -0,0 +1,21 @@
export const SUPPORTED_LOCALES = ["en", "es"] as const
export type Locale = (typeof SUPPORTED_LOCALES)[number]
export const FALLBACK_LOCALE: Locale = "en"
export const DEFAULT_LOCALE_ENV_VAR = "STOCK_MANAGER_DEFAULT_LOCALE"
export const LOCALE_COOKIE_NAME = "stock-manager-locale"
export function isLocale(value: unknown): value is Locale {
return (
typeof value === "string" && SUPPORTED_LOCALES.includes(value as Locale)
)
}
export function resolveDefaultLocale(value: unknown): Locale {
return isLocale(value) ? value : FALLBACK_LOCALE
}
export function resolveLocale(value: unknown, fallback: Locale): Locale {
return isLocale(value) ? value : fallback
}
+27
View File
@@ -0,0 +1,27 @@
import "server-only"
import { cookies } from "next/headers"
import { getDictionary } from "./dictionaries"
import {
DEFAULT_LOCALE_ENV_VAR,
LOCALE_COOKIE_NAME,
resolveDefaultLocale,
resolveLocale,
} from "./locales"
export async function getI18n() {
const cookieStore = await cookies()
const defaultLocale = resolveDefaultLocale(
process.env[DEFAULT_LOCALE_ENV_VAR],
)
const locale = resolveLocale(
cookieStore.get(LOCALE_COOKIE_NAME)?.value,
defaultLocale,
)
return {
locale,
dictionary: getDictionary(locale),
}
}