"use client"; import { useState, useMemo } from "react"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, Button, FormField, FormInput, FormSelect, Icon } from "@/app/components/ui"; import { StatusMappingDto } from "@/lib/api"; import { useTranslation } from "@/lib/i18n/context"; export function StatusMappingsCard({ initialStatusMappings, initialSeriesStatuses, initialProviderStatuses }: { initialStatusMappings: Record[]; initialSeriesStatuses: string[]; initialProviderStatuses: string[] }) { const { t } = useTranslation(); const [mappings, setMappings] = useState(initialStatusMappings as unknown as StatusMappingDto[]); const [targetStatuses, setTargetStatuses] = useState(initialSeriesStatuses); const [providerStatuses] = useState(initialProviderStatuses); const [newTargetName, setNewTargetName] = useState(""); // Group mappings by target status (only those with a non-null mapped_status) const grouped = useMemo(() => { const map = new Map(); for (const m of mappings) { if (m.mapped_status) { const list = map.get(m.mapped_status) || []; list.push(m); map.set(m.mapped_status, list); } } return map; }, [mappings]); // Unmapped = mappings with null mapped_status + provider statuses not in status_mappings at all const knownProviderStatuses = useMemo( () => new Set(mappings.map((m) => m.provider_status)), [mappings], ); const unmappedMappings = useMemo( () => mappings.filter((m) => !m.mapped_status), [mappings], ); const newProviderStatuses = useMemo( () => providerStatuses.filter((ps) => !knownProviderStatuses.has(ps)), [providerStatuses, knownProviderStatuses], ); // All possible targets = existing statuses from DB + custom ones added locally const [customTargets, setCustomTargets] = useState([]); const allTargets = useMemo(() => { const set = new Set([...targetStatuses, ...customTargets]); return [...set].sort(); }, [targetStatuses, customTargets]); async function handleAssign(providerStatus: string, targetStatus: string) { if (!providerStatus || !targetStatus) return; try { const res = await fetch("/api/settings/status-mappings", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ provider_status: providerStatus, mapped_status: targetStatus }), }); if (res.ok) { const created: StatusMappingDto = await res.json(); setMappings((prev) => [...prev.filter((m) => m.provider_status !== created.provider_status), created]); } } catch { // ignore } } async function handleUnmap(id: string) { try { const res = await fetch(`/api/settings/status-mappings/${id}`, { method: "DELETE" }); if (res.ok) { const updated: StatusMappingDto = await res.json(); setMappings((prev) => prev.map((m) => (m.id === id ? updated : m))); } } catch { // ignore } } function handleCreateTarget() { const name = newTargetName.trim().toLowerCase(); if (!name || allTargets.includes(name)) return; setCustomTargets((prev) => [...prev, name]); setNewTargetName(""); } function statusLabel(status: string) { const key = `seriesStatus.${status}` as Parameters[0]; const translated = t(key); return translated !== key ? translated : status; } return ( {t("settings.statusMappings")} {t("settings.statusMappingsDesc")}
{/* Create new target status */}
setNewTargetName(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") handleCreateTarget(); }} className="max-w-[250px]" />
{/* Grouped by target status */} {allTargets.map((target) => { const items = grouped.get(target) || []; return (
{statusLabel(target)} ({target})
{items.map((m) => ( {m.provider_status} ))} {items.length === 0 && ( {t("settings.noMappings")} )}
); })} {/* Unmapped provider statuses (null mapped_status + brand new from providers) */} {(unmappedMappings.length > 0 || newProviderStatuses.length > 0) && (

{t("settings.unmappedSection")}

{unmappedMappings.map((m) => (
{m.provider_status} { if (e.target.value) handleAssign(m.provider_status, e.target.value); }} > {allTargets.map((s) => ( ))}
))} {newProviderStatuses.map((ps) => (
{ps} { if (e.target.value) handleAssign(ps, e.target.value); }} > {allTargets.map((s) => ( ))}
))}
)}
); }