init repo
This commit is contained in:
59
lib/i18n.tsx
Normal file
59
lib/i18n.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
"use client"
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from "react"
|
||||
import en from "@/locales/en.json"
|
||||
import zh from "@/locales/zh.json"
|
||||
|
||||
type Locale = "en" | "zh"
|
||||
|
||||
const messages: Record<Locale, typeof en> = { en, zh }
|
||||
|
||||
interface I18nContextType {
|
||||
locale: Locale
|
||||
setLocale: (locale: Locale) => void
|
||||
t: (key: string) => string
|
||||
}
|
||||
|
||||
const I18nContext = createContext<I18nContextType | null>(null)
|
||||
|
||||
function getNestedValue(obj: any, path: string): string {
|
||||
const value = path.split(".").reduce((acc, part) => acc?.[part], obj)
|
||||
return typeof value === "string" ? value : Array.isArray(value) ? value.join(", ") : path
|
||||
}
|
||||
|
||||
export function I18nProvider({ children }: { children: React.ReactNode }) {
|
||||
const [locale, setLocaleState] = useState<Locale>("zh")
|
||||
|
||||
useEffect(() => {
|
||||
const saved = localStorage.getItem("locale") as Locale | null
|
||||
if (saved && (saved === "en" || saved === "zh")) {
|
||||
setLocaleState(saved)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setLocale = useCallback((l: Locale) => {
|
||||
setLocaleState(l)
|
||||
localStorage.setItem("locale", l)
|
||||
}, [])
|
||||
|
||||
const t = useCallback(
|
||||
(key: string) => getNestedValue(messages[locale], key),
|
||||
[locale]
|
||||
)
|
||||
|
||||
return (
|
||||
<I18nContext.Provider value={{ locale, setLocale, t }}>
|
||||
{children}
|
||||
</I18nContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useI18n() {
|
||||
const ctx = useContext(I18nContext)
|
||||
if (!ctx) throw new Error("useI18n must be used within I18nProvider")
|
||||
return ctx
|
||||
}
|
||||
|
||||
export function useTranslation() {
|
||||
return useI18n()
|
||||
}
|
||||
6
lib/utils.ts
Normal file
6
lib/utils.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
Reference in New Issue
Block a user