89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useEffect,
|
|
useMemo,
|
|
useState,
|
|
type ReactNode,
|
|
} from 'react'
|
|
|
|
import { getMySites, type MeSiteRow } from '../api/backend'
|
|
|
|
export const SITE_STORAGE_KEY = 'ems.selected_site_id'
|
|
|
|
export type SiteSelectionContextValue = {
|
|
sites: MeSiteRow[]
|
|
selectedSiteId: number | null
|
|
setSelectedSiteId: (id: number) => void
|
|
ready: boolean
|
|
error: string | null
|
|
}
|
|
|
|
const SiteSelectionContext = createContext<SiteSelectionContextValue | null>(null)
|
|
|
|
export function SiteSelectionProvider({ children }: { children: ReactNode }) {
|
|
const [sites, setSites] = useState<MeSiteRow[]>([])
|
|
const [selectedSiteId, setSelectedSiteIdState] = useState<number | null>(null)
|
|
const [ready, setReady] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
let cancelled = false
|
|
;(async () => {
|
|
try {
|
|
const list = await getMySites()
|
|
if (cancelled) return
|
|
setSites(list)
|
|
if (list.length === 0) {
|
|
setError('Žádná aktivní lokalita')
|
|
setSelectedSiteIdState(null)
|
|
} else {
|
|
setError(null)
|
|
const raw = localStorage.getItem(SITE_STORAGE_KEY)
|
|
const parsed = raw != null ? Number.parseInt(raw, 10) : Number.NaN
|
|
const valid = Number.isFinite(parsed) && list.some((s) => s.id === parsed)
|
|
setSelectedSiteIdState(valid ? parsed : list[0]!.id)
|
|
}
|
|
} catch {
|
|
if (!cancelled) {
|
|
setSites([])
|
|
setSelectedSiteIdState(null)
|
|
setError('Lokality se nepodařilo načíst')
|
|
}
|
|
} finally {
|
|
if (!cancelled) setReady(true)
|
|
}
|
|
})()
|
|
return () => {
|
|
cancelled = true
|
|
}
|
|
}, [])
|
|
|
|
const setSelectedSiteId = useCallback((id: number) => {
|
|
setSelectedSiteIdState(id)
|
|
localStorage.setItem(SITE_STORAGE_KEY, String(id))
|
|
}, [])
|
|
|
|
const value = useMemo(
|
|
(): SiteSelectionContextValue => ({
|
|
sites,
|
|
selectedSiteId,
|
|
setSelectedSiteId,
|
|
ready,
|
|
error,
|
|
}),
|
|
[sites, selectedSiteId, setSelectedSiteId, ready, error],
|
|
)
|
|
|
|
return <SiteSelectionContext.Provider value={value}>{children}</SiteSelectionContext.Provider>
|
|
}
|
|
|
|
export function useSiteSelection(): SiteSelectionContextValue {
|
|
const ctx = useContext(SiteSelectionContext)
|
|
if (ctx == null) {
|
|
throw new Error('useSiteSelection must be used within SiteSelectionProvider')
|
|
}
|
|
return ctx
|
|
}
|