'use client'; import { useState } from 'react'; import { RouteSettingsDialog } from './RouteSettingsDialog'; import { RouteRulesDialog } from './RouteRulesDialog'; type ForwardFormat = 'THREADED' | 'DIGEST' | 'SUMMARY'; type ForwardFrequency = 'INSTANT' | 'FIVE_MIN' | 'FIFTEEN_MIN' | 'ONE_HOUR' | 'ONE_DAY' | 'SEVEN_DAYS'; type ApprovalMode = 'MANUAL' | 'AUTO'; interface AssignedRule { id: string; matchType: string; matchValue: string; ruleIntent: 'POSITIVE' | 'NEGATIVE'; } interface Route { id: string; sourceGroupId: string; targetGroupId: string; sourceGroup: { name: string }; targetGroup: { name: string }; forwardFormat: ForwardFormat; withAttachment: boolean; frequency: ForwardFrequency; approvalMode: ApprovalMode; isActive: boolean; assignedRules?: Array<{ tenantRule: AssignedRule }>; } interface Group { id: string; name: string; platform: string; isActive: boolean; } const FREQ_LABELS: Record = { INSTANT: 'Instant', FIVE_MIN: '5 min', FIFTEEN_MIN: '15 min', ONE_HOUR: '1h', ONE_DAY: '1d', SEVEN_DAYS: '7d', }; const FORMAT_LABELS: Record = { THREADED: 'Threaded', DIGEST: 'Digest', SUMMARY: 'Summary', }; export function RouteManager({ groups, initialRoutes, }: { groups: Group[]; initialRoutes: Route[]; }) { const [routes, setRoutes] = useState(initialRoutes); const [sourceId, setSourceId] = useState(''); const [targetIds, setTargetIds] = useState>(new Set()); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); const [settingsRoute, setSettingsRoute] = useState(null); const [rulesRoute, setRulesRoute] = useState(null); const grouped = new Map(); for (const r of routes) { const key = r.sourceGroup.name; if (!grouped.has(key)) grouped.set(key, { sourceId: r.sourceGroupId, targets: [] }); grouped.get(key)!.targets.push(r); } function toggleTarget(id: string) { setTargetIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); setError(null); } async function addRoutes() { if (!sourceId || targetIds.size === 0) return; setBusy(true); setError(null); try { const res = await fetch('/api/routes/batch', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sourceGroupId: sourceId, targetGroupIds: [...targetIds] }), }); if (res.status === 409) { setError((await res.json()).message ?? 'Routes already exist'); return; } if (!res.ok) { setError('Failed to create routes'); return; } const created: Route[] = await res.json(); setRoutes((prev) => [...created, ...prev]); setSourceId(''); setTargetIds(new Set()); } finally { setBusy(false); } } async function deleteRoute(id: string) { const res = await fetch(`/api/routes/${id}`, { method: 'DELETE' }); if (res.ok || res.status === 204) setRoutes((prev) => prev.filter((r) => r.id !== id)); } const eligibleTargets = groups.filter((g) => g.id !== sourceId && g.platform === 'whatsapp' && g.isActive); return (

Active sync routes

{routes.length === 0 ? (

No routes configured.

) : (
{routes.map((r) => { const ruleCount = r.assignedRules?.length ?? 0; return ( ); })}
Source Target Rules Frequency Format Approval
{r.sourceGroup.name} {r.targetGroup.name} 0 ? 'bg-blue-50 text-blue-700' : 'bg-gray-100 text-gray-400'}`}> {ruleCount} rule{ruleCount !== 1 ? 's' : ''} {FREQ_LABELS[r.frequency] ?? r.frequency} {FORMAT_LABELS[r.forwardFormat] ?? r.forwardFormat} {r.withAttachment && +attach} {r.approvalMode === 'AUTO' ? 'Auto' : 'Manual'}
)}

Add routes

{targetIds.size} target{targetIds.size !== 1 ? 's' : ''} selected
{sourceId && eligibleTargets.length > 0 && (
{eligibleTargets.map((g) => ( ))}
)} {error && (

{error}

)}
{settingsRoute && ( { setRoutes((prev) => prev.map((r) => r.id === settingsRoute.id ? { ...r, ...updates } : r)); }} onClose={() => setSettingsRoute(null)} /> )} {rulesRoute && ( setRulesRoute(null)} /> )}
); }