// Telegram slide-over, toast system, and shared status helpers for the orders register.
const DEMO_TODAY = { d: 31, m: 7, y: 2025 }; // "сегодня" для демо
const STATUS_META = {
draft: { label: "Черновик", cls: "muted", icon: I.Edit, dot: "var(--ink-400)" },
sent: { label: "Отправлено", cls: "tg", icon: I.Plane, dot: "#2682c0" },
accepted: { label: "Принято", cls: "accepted", icon: I.CheckCircle, dot: "#5546b0" },
in_progress: { label: "В работе", cls: "warn", icon: I.Hourglass, dot: "var(--warn)" },
overdue: { label: "Просрочено", cls: "err", icon: I.Alert, dot: "var(--err)" },
done: { label: "Выполнено", cls: "ok", icon: I.CheckCircle, dot: "var(--ok)" },
cancelled: { label: "Отменено", cls: "muted", icon: I.X, dot: "var(--ink-300)" },
};
const DEPT_COLORS = {
"Юридический отдел": "#3a5f9e",
"Бухгалтерия": "#1f7a4c",
"Отдел кадров": "#a8612e",
"Канцелярия": "#7a5aa6",
"Отдел контроля": "#b13b46",
"Руководство": "#36465e",
};
function parseRuDate(s) {
if (!s) return null;
const m = String(s).match(/(\d{1,2})\.(\d{1,2})\.(\d{4})/);
if (!m) return null;
return { d: +m[1], m: +m[2], y: +m[3] };
}
function dateValue(dt) { return dt ? dt.y * 10000 + dt.m * 100 + dt.d : 0; }
function daysBetween(a, b) {
const ms = Date.UTC(a.y, a.m - 1, a.d) - Date.UTC(b.y, b.m - 1, b.d);
return Math.round(ms / 86400000);
}
// "Today" comes from the server (window.SERVER_TODAY) when available, else the demo date.
function effToday() { return window.SERVER_TODAY || DEMO_TODAY; }
// Effective status — promotes stale open tasks to "overdue"
function effStatus(task) {
if (task.status === "done" || task.status === "draft" || task.status === "cancelled") return task.status;
const ord = parseRuDate(task.dateOrder) || parseRuDate(task.dateStart);
if (ord && daysBetween(effToday(), ord) > 25) return "overdue";
return task.status;
}
function StatusPill({ status }) {
const meta = STATUS_META[status] || STATUS_META.draft;
const Ic = meta.icon;
return (