Ребренд Мониторинг Орбита -> Железный Егорин; accent green->amber #F59E0B; LoginScreen правая половина = Lightning (WebGL, hue 35 тёплый) под стеклянной формой; левая панель — тёплый градиент. Доступ агентам: репо публичный, push german-токеном. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import { create } from 'zustand';
|
|
|
|
// Отработка сработки ПЦН: стадии с таймстампами + журнал комментариев (кто/когда).
|
|
// Диспетчерский цикл: приём → взято в работу → ГБР выехал → ГБР прибыл → осмотр → закрыто.
|
|
// Хранение — localStorage (в проде — на шлюзе, привязано к сработке; вложения фото/видео в S3).
|
|
|
|
export interface StageDef {
|
|
key: string;
|
|
label: string;
|
|
short: string;
|
|
}
|
|
export const STAGES: StageDef[] = [
|
|
{ key: 'taken', label: 'Взято в работу', short: 'Взял' },
|
|
{ key: 'enroute', label: 'ГБР выехал', short: 'Выезд' },
|
|
{ key: 'onsite', label: 'ГБР прибыл', short: 'Прибытие' },
|
|
{ key: 'inspect', label: 'Осмотр объекта', short: 'Осмотр' },
|
|
{ key: 'closed', label: 'Отработано (закрыто)', short: 'Закрыть' },
|
|
];
|
|
|
|
// Типовые комментарии (без выдумываний — фиксированный справочник)
|
|
export const PRESET_COMMENTS = [
|
|
'Принял в работу',
|
|
'Оповещён владелец',
|
|
'Дозвон по списку',
|
|
'Передано ГБР',
|
|
'ГБР выехал на объект',
|
|
'ГБР прибыл на объект',
|
|
'Осмотр — нарушений нет',
|
|
'Осмотр — выявлено проникновение',
|
|
'Ложное срабатывание',
|
|
'Отработано, объект под охраной',
|
|
];
|
|
|
|
export interface HandlingComment {
|
|
ts: string;
|
|
text: string;
|
|
author: string;
|
|
}
|
|
export interface Handling {
|
|
stages: Record<string, string>; // stageKey -> ISO ts
|
|
comments: HandlingComment[];
|
|
}
|
|
|
|
const KEY = 'sm-alarm-handling';
|
|
function load(): Record<string, Handling> {
|
|
try {
|
|
return JSON.parse(localStorage.getItem(KEY) || '{}');
|
|
} catch {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
interface HState {
|
|
map: Record<string, Handling>;
|
|
stamp: (alarmId: string, stage: string, iso: string) => void;
|
|
addComment: (alarmId: string, text: string, author: string, iso: string) => void;
|
|
}
|
|
|
|
function persist(map: Record<string, Handling>) {
|
|
try {
|
|
localStorage.setItem(KEY, JSON.stringify(map));
|
|
} catch {
|
|
/* quota */
|
|
}
|
|
}
|
|
|
|
export const useAlarmHandling = create<HState>((set) => ({
|
|
map: load(),
|
|
stamp: (alarmId, stage, iso) =>
|
|
set((s) => {
|
|
const cur = s.map[alarmId] || { stages: {}, comments: [] };
|
|
const map = { ...s.map, [alarmId]: { ...cur, stages: { ...cur.stages, [stage]: iso } } };
|
|
persist(map);
|
|
return { map };
|
|
}),
|
|
addComment: (alarmId, text, author, iso) =>
|
|
set((s) => {
|
|
const cur = s.map[alarmId] || { stages: {}, comments: [] };
|
|
const map = { ...s.map, [alarmId]: { ...cur, comments: [...cur.comments, { ts: iso, text, author }] } };
|
|
persist(map);
|
|
return { map };
|
|
}),
|
|
}));
|