chore: heygermany customer project
This commit is contained in:
75
apps/website/context/i18n-provider.tsx
Normal file
75
apps/website/context/i18n-provider.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, { createContext, useContext, useMemo } from 'react'
|
||||
import type { I18nString } from '@pikku/react'
|
||||
import type { SupportedLocale } from '@/config'
|
||||
import { mKey } from '@/i18n/messages'
|
||||
import { setRouteLocale, supportedLocales, defaultLocale } from '@/i18n/config'
|
||||
|
||||
export type GetNamespaced = (
|
||||
key: string,
|
||||
variables?: Record<string, any>
|
||||
) => I18nString
|
||||
|
||||
export interface I18nContextType {
|
||||
locale: SupportedLocale
|
||||
get: GetNamespaced
|
||||
getEnumOptions: (
|
||||
e: Record<string, string>,
|
||||
enumName: string
|
||||
) => { value: string; label: I18nString }[]
|
||||
}
|
||||
|
||||
// Resolve any dotted i18n key through Paraglide (mKey snake_cases it and calls
|
||||
// the compiled message). Replaces the old i18next `t`.
|
||||
const get: GetNamespaced = (key, variables) => mKey(key, variables)
|
||||
|
||||
const getEnumOptions = (enumObject: Record<string, string>, enumName: string) =>
|
||||
Object.values(enumObject).map((value) => ({
|
||||
value,
|
||||
label: mKey(`enums.${enumName}.${value}`.toLowerCase()),
|
||||
}))
|
||||
|
||||
export const I18nContext = createContext<I18nContextType>({
|
||||
locale: defaultLocale as SupportedLocale,
|
||||
get,
|
||||
getEnumOptions,
|
||||
})
|
||||
|
||||
// useI18n() returns a callable `t` (Paraglide-backed) augmented with the same
|
||||
// helpers components used under i18next: `t('key')`, `t.getEnumOptions(...)`,
|
||||
// `t.locale`.
|
||||
export const useI18n = () => {
|
||||
const ctx = useContext(I18nContext)
|
||||
const t = (key: string, variables?: Record<string, any>): I18nString =>
|
||||
mKey(key, variables)
|
||||
return Object.assign(t, {
|
||||
get: ctx.get,
|
||||
getEnumOptions: ctx.getEnumOptions,
|
||||
locale: ctx.locale,
|
||||
})
|
||||
}
|
||||
|
||||
interface I18nProviderProps {
|
||||
children: React.ReactNode
|
||||
lang?: string
|
||||
}
|
||||
|
||||
const normalize = (lang: string): SupportedLocale => {
|
||||
const short = lang.slice(0, 2).toLowerCase()
|
||||
return (
|
||||
supportedLocales.includes(short as (typeof supportedLocales)[number])
|
||||
? short
|
||||
: defaultLocale
|
||||
) as SupportedLocale
|
||||
}
|
||||
|
||||
export function I18nProvider({ children, lang = 'en' }: I18nProviderProps) {
|
||||
const locale = normalize(lang)
|
||||
// Set the active Paraglide locale before children resolve messages (SSR-safe:
|
||||
// synchronous, ahead of the children's render in this pass).
|
||||
setRouteLocale(locale as (typeof supportedLocales)[number])
|
||||
const value = useMemo<I18nContextType>(
|
||||
() => ({ locale, get, getEnumOptions }),
|
||||
[locale]
|
||||
)
|
||||
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
|
||||
}
|
||||
Reference in New Issue
Block a user