"use client"; import { useState } from "react"; import { useSystems } from "@/lib/useSystems"; import { c2api } from "@/lib/c2api"; import type { SystemRecord } from "@/lib/types"; // ── P25 structured config types ────────────────────────────────────────────── interface TalkgroupEntry { id: string; name: string; tag: string; } interface P25Config { nac: string; system_id: string; wacn: string; control_channels: string; voice_channels: string; talkgroups: TalkgroupEntry[]; } const DEFAULT_P25: P25Config = { nac: "", system_id: "", wacn: "", control_channels: "", voice_channels: "", talkgroups: [], }; const TG_TAGS = ["fire", "police", "ems", "transit", "public works", "other"]; function recordToP25Config(c: Record): P25Config { return { nac: String(c.nac ?? ""), system_id: String(c.system_id ?? ""), wacn: String(c.wacn ?? ""), control_channels: Array.isArray(c.control_channels) ? (c.control_channels as number[]).join(", ") : "", voice_channels: Array.isArray(c.voice_channels) ? (c.voice_channels as number[]).join(", ") : "", talkgroups: Array.isArray(c.talkgroups) ? (c.talkgroups as Array<{ id: number; name: string; tag: string }>).map((tg) => ({ id: String(tg.id), name: tg.name, tag: tg.tag ?? "other", })) : [], }; } function p25ConfigToRecord(p: P25Config): Record { const parseFreqs = (s: string) => s .split(",") .map((f) => parseFloat(f.trim())) .filter((f) => !isNaN(f)); return { nac: p.nac, system_id: p.system_id ? parseInt(p.system_id, 10) : undefined, wacn: p.wacn, control_channels: parseFreqs(p.control_channels), voice_channels: parseFreqs(p.voice_channels), talkgroups: p.talkgroups .filter((tg) => tg.id && tg.name) .map((tg) => ({ id: parseInt(tg.id, 10), name: tg.name, tag: tg.tag })), }; } // ── Talkgroup table editor ──────────────────────────────────────────────────── function TalkgroupEditor({ talkgroups, onChange, }: { talkgroups: TalkgroupEntry[]; onChange: (tgs: TalkgroupEntry[]) => void; }) { const [showPaste, setShowPaste] = useState(false); const [pasteText, setPasteText] = useState(""); function addRow() { onChange([...talkgroups, { id: "", name: "", tag: "other" }]); } function removeRow(i: number) { onChange(talkgroups.filter((_, idx) => idx !== i)); } function updateRow(i: number, field: keyof TalkgroupEntry, value: string) { const updated = [...talkgroups]; updated[i] = { ...updated[i], [field]: value }; onChange(updated); } function handlePasteImport() { const lines = pasteText.trim().split("\n"); const parsed: TalkgroupEntry[] = lines .map((line) => { const parts = line.includes("\t") ? line.split("\t") : line.split(","); const id = parts[0]?.trim() ?? ""; const name = parts[1]?.trim() ?? ""; const rawTag = parts[2]?.trim()?.toLowerCase() ?? "other"; const tag = TG_TAGS.includes(rawTag) ? rawTag : "other"; return { id, name, tag }; }) .filter((e) => e.id && e.name); onChange([...talkgroups, ...parsed]); setPasteText(""); setShowPaste(false); } return (
{showPaste && (

Paste rows from RadioReference — tab- or comma-separated: ID, Name, Tag
Tags: fire · police · ems · transit · public works · other