/opt/canhelp/apps/web/src/context
Edit: /opt/canhelp/apps/web/src/context/locale.tsx (2615B)
'use client'
import { createContext, useContext, useState, useEffect, useCallback } from 'react'
import { useRouter } from 'next/navigation'
import { type Locale, getTranslations } from '@/lib/translations'
const COOKIE_KEY = 'canhelp_locale'
const DEFAULT_LOCALE: Locale = 'el'
interface LocaleContextValue {
locale: Locale
setLocale: (locale: Locale) => void
t: (key: string, fallback?: string) => string
}
const LocaleContext = createContext
({
locale: DEFAULT_LOCALE,
setLocale: () => {},
t: (key) => key,
})
function readCookieLocale(): Locale {
if (typeof document === 'undefined') return DEFAULT_LOCALE
const match = document.cookie.match(/canhelp_locale=([^;]+)/)
const val = match?.[1] as Locale | undefined
return val && ['el', 'en', 'uk', 'ru'].includes(val) ? val : DEFAULT_LOCALE
}
export function LocaleProvider({
children,
initialLocale,
}: {
children: React.ReactNode
initialLocale?: Locale
}) {
const router = useRouter()
const [locale, setLocaleState] = useState(initialLocale ?? DEFAULT_LOCALE)
// Sync from cookie on mount (client-side)
useEffect(() => {
const cookieLocale = readCookieLocale()
if (cookieLocale !== locale) setLocaleState(cookieLocale)
// Sync cookie locale to DB on first load (in case DB is out of sync)
const apiBase = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'
fetch(`${apiBase}/api/users/me`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ locale: cookieLocale }),
}).catch(() => {})
}, [])
const setLocale = useCallback((next: Locale) => {
setLocaleState(next)
document.cookie = `${COOKIE_KEY}=${next}; path=/; max-age=31536000; SameSite=Lax`
document.documentElement.lang = next
// Persist locale to user profile in DB (best-effort, non-blocking)
const apiBase = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'
fetch(`${apiBase}/api/users/me`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ locale: next }),
}).catch(() => {})
// Re-render server components with new cookie
router.refresh()
}, [router])
const t = useCallback(
(key: string, fallback?: string) => getTranslations(locale)(key, fallback),
[locale],
)
return (
{children}
)
}
export function useLocale() {
return useContext(LocaleContext)
}