/opt/canhelp/apps/web/src/context
Edit: /opt/canhelp/apps/web/src/context/location.tsx (2533B)
'use client'
import { createContext, useContext, useState, useEffect, useCallback } from 'react'
import { getLocations } from '@/lib/api'
import type { Locale } from '@/lib/translations'
export interface LocationNode {
id: string
slug: string
names: { el: string; en: string; ru: string; uk?: string }
children?: LocationNode[]
}
interface LocationContextValue {
locationSlug: string
locationTree: LocationNode[]
locationLoading: boolean
setLocation: (slug: string) => void
getLabel: (locale: Locale) => string
}
const LocationContext = createContext
({
locationSlug: '',
locationTree: [],
locationLoading: true,
setLocation: () => {},
getLabel: () => '',
})
function readCookieLocation(): string {
if (typeof document === 'undefined') return ''
const match = document.cookie.match(/(?:^|;\s*)canhelp_location=([^;]+)/)
return match?.[1] ? decodeURIComponent(match[1]) : ''
}
export function LocationProvider({
children,
initialSlug = '',
}: {
children: React.ReactNode
initialSlug?: string
}) {
const [locationSlug, setLocationSlug] = useState(initialSlug)
const [locationTree, setLocationTree] = useState([])
const [locationLoading, setLocationLoading] = useState(true)
// Sync from cookie on client mount
useEffect(() => {
const cookieSlug = readCookieLocation()
setLocationSlug(cookieSlug)
}, [])
// Load location tree once
useEffect(() => {
getLocations()
.then((tree) => setLocationTree(tree as LocationNode[]))
.catch(() => {})
.finally(() => setLocationLoading(false))
}, [])
const setLocation = useCallback((slug: string) => {
setLocationSlug(slug)
const encoded = encodeURIComponent(slug)
document.cookie = `canhelp_location=${encoded}; path=/; max-age=31536000; SameSite=Lax`
}, [])
const getLabel = useCallback(
(locale: Locale): string => {
if (!locationSlug) return ''
for (const city of locationTree) {
if (city.slug === locationSlug) return city.names[locale] ?? city.names.el
for (const d of city.children ?? []) {
if (d.slug === locationSlug) return d.names[locale] ?? d.names.el
}
}
return locationSlug
},
[locationSlug, locationTree],
)
return (
{children}
)
}
export function useLocation() {
return useContext(LocationContext)
}