import React, { useEffect, useState } from 'react';
import { cn } from '@/lib/utils';
import { ChevronDown } from 'lucide-react';
// At-a-glance health tones for the optional SectionCard status dot.
const DOT_TONES = {
green: 'bg-emerald-500',
amber: 'bg-amber-500',
red: 'bg-rose-500',
gray: 'bg-muted-foreground/40',
};
export function fmt(isoStr) {
if (!isoStr) return '—';
const d = new Date(isoStr);
return d.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })
+ ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}
export function importErrorState(err, fallback) {
const data = err?.data || {};
return {
message: err?.message || data.message || data.error || fallback,
error: data.error || fallback,
code: data.code || err?.code || null,
details: Array.isArray(data.details) ? data.details : (Array.isArray(err?.details) ? err.details : []),
error_id: data.error_id || null,
};
}
export function SectionCard({
title,
subtitle,
icon: Icon, // optional lucide icon component, shown in a soft chip
statusDot, // optional 'green' | 'amber' | 'red' | 'gray' health dot
badge, // optional node rendered next to the title (e.g. a count pill)
children,
className,
collapsible = false,
defaultOpen = true,
storageKey,
summary,
actions,
}) {
const [open, setOpen] = useState(() => {
if (!collapsible || !storageKey || typeof window === 'undefined') return defaultOpen;
const stored = window.localStorage.getItem(storageKey);
return stored === null ? defaultOpen : stored === 'true';
});
useEffect(() => {
if (!collapsible || !storageKey || typeof window === 'undefined') return;
window.localStorage.setItem(storageKey, String(open));
}, [collapsible, open, storageKey]);
const headerContent = (
<>
{Icon && (
{subtitle}
} {collapsible && !open && summary && ({summary}
)}{label}
{value ?? 0}