import { useEffect, useState } from "react"; import { ChevronDown, GripVertical, Pencil, Trash2 } from "lucide-react"; import { cn } from "@/lib/utils"; import { t } from "@/i18n"; import { useItemDnd, useSectionDnd } from "@/board/dnd"; import { useBoard } from "@/board/store"; import { IconImg, ItemAnchor, hostOf } from "@/board/primitives"; import { WidgetContent } from "@/widgets"; import type { BoardViewProps, ItemViewProps, RendererViews, SectionViewProps, } from "@/renderers/types"; // Index — editorial/list renderer. Serif masthead + section heads, numbered // full-width rows, stat strip. Ported from mockups/e-editorial.html. function BoardView({ children }: BoardViewProps) { const board = useBoard(); const [now, setNow] = useState(() => new Date()); useEffect(() => { const t = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(t); }, []); const services = board.sections.flatMap((s) => s.items).filter((i) => i.kind !== "widget"); const widgets = board.sections.flatMap((s) => s.items).filter((i) => i.kind === "widget"); const up = services.filter((i) => board.statuses[i.id]?.status === "up").length; const down = services.filter((i) => board.statuses[i.id]?.status === "down").length; const time = new Intl.DateTimeFormat(undefined, { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false, }).format(now); const date = new Intl.DateTimeFormat(undefined, { weekday: "long", day: "numeric", month: "long", year: "numeric", }).format(now); const cells: [string, string, string][] = [ [t("renderer.localTime"), time, date.split(",")[0] ?? ""], ["Services", String(services.length), `${board.sections.length} sections`], ["Up", String(up), "responding"], [t("renderer.down"), String(down), down === 0 ? t("renderer.allGreen") : t("renderer.offline")], ["Widgets", String(widgets.length), "registered"], ]; return (