83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import React, {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useEffect,
|
|
useState,
|
|
} from 'react';
|
|
import type { TimeRange, TimeMode, TriggeredAlert } from './types';
|
|
import { TIME_RANGE_MS } from './types';
|
|
import { checkAlerts } from './api';
|
|
import { buildReverseMap } from './localization';
|
|
import type { LocaleMap, ReverseMap } from './localization';
|
|
|
|
interface AppContextValue {
|
|
timeRange: TimeRange;
|
|
setTimeRange: (r: TimeRange) => void;
|
|
timeMode: TimeMode;
|
|
setTimeMode: (m: TimeMode) => void;
|
|
triggeredAlerts: TriggeredAlert[];
|
|
refreshAlerts: () => Promise<void>;
|
|
getFromTo: () => { from: string; to: string };
|
|
localeMap: LocaleMap;
|
|
reverseMap: ReverseMap;
|
|
}
|
|
|
|
const AppContext = createContext<AppContextValue | null>(null);
|
|
|
|
export function AppProvider({
|
|
token: _token,
|
|
localeMap,
|
|
children,
|
|
}: {
|
|
token: string;
|
|
localeMap: LocaleMap;
|
|
children: React.ReactNode;
|
|
}) {
|
|
const [timeRange, setTimeRange] = useState<TimeRange>('6h');
|
|
const [timeMode, setTimeMode] = useState<TimeMode>('real');
|
|
const [triggeredAlerts, setTriggeredAlerts] = useState<TriggeredAlert[]>([]);
|
|
|
|
const reverseMap = buildReverseMap(localeMap);
|
|
|
|
const getFromTo = useCallback(() => {
|
|
const to = new Date();
|
|
const from = new Date(to.getTime() - TIME_RANGE_MS[timeRange]);
|
|
return { from: from.toISOString(), to: to.toISOString() };
|
|
}, [timeRange]);
|
|
|
|
const refreshAlerts = useCallback(async () => {
|
|
setTriggeredAlerts(await checkAlerts());
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
const poll = () => checkAlerts().then(a => { if (!cancelled) setTriggeredAlerts(a); });
|
|
poll();
|
|
const id = setInterval(poll, 30_000);
|
|
return () => { cancelled = true; clearInterval(id); };
|
|
}, []);
|
|
|
|
return (
|
|
<AppContext.Provider
|
|
value={{
|
|
timeRange, setTimeRange,
|
|
timeMode, setTimeMode,
|
|
triggeredAlerts, refreshAlerts,
|
|
getFromTo,
|
|
localeMap, reverseMap,
|
|
}}
|
|
>
|
|
{children}
|
|
</AppContext.Provider>
|
|
);
|
|
}
|
|
|
|
/** Must be used within {@link AppProvider}. */
|
|
export function useApp() {
|
|
const ctx = useContext(AppContext);
|
|
if (!ctx) throw new Error('useApp must be used within AppProvider');
|
|
return ctx;
|
|
} |