88 lines
2.2 KiB
TypeScript
88 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;
|
|
}
|