85 lines
3.8 KiB
TypeScript
85 lines
3.8 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
import { useQuery } from '@tanstack/react-query';
|
|
import { apiFetch } from '../../../../lib/api';
|
|
import type { Decision } from '../../../../lib/api';
|
|
import { useSession } from '../../../../components/session-provider';
|
|
|
|
function fmtDate(s: string | null) {
|
|
if (!s) return '—';
|
|
return new Date(s).toLocaleDateString('ro-RO', { day: 'numeric', month: 'short', year: 'numeric' });
|
|
}
|
|
|
|
export default function DecisionRegisterPage() {
|
|
const { activeTenant } = useSession();
|
|
const tenantId = activeTenant?.tenantId ?? '';
|
|
|
|
const { data: decisions = [], isLoading } = useQuery({
|
|
queryKey: ['decisions-all', tenantId],
|
|
queryFn: () => apiFetch<Decision[]>('/v1/decisions?limit=200', { tenantId }),
|
|
enabled: Boolean(tenantId),
|
|
});
|
|
|
|
return (
|
|
<div className="max-w-5xl space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="font-display text-2xl font-semibold text-ink">Registru Decizii</h1>
|
|
<p className="mt-1 text-sm text-ink-faint">
|
|
{decisions.length} decizii înregistrate • istoric complet
|
|
</p>
|
|
</div>
|
|
<Link href="/dashboard/decisions" className="text-sm text-bronze-deep hover:underline">← Dashboard</Link>
|
|
</div>
|
|
|
|
{isLoading ? (
|
|
<p className="text-sm text-ink-faint">Se încarcă…</p>
|
|
) : decisions.length === 0 ? (
|
|
<div className="card p-12 text-center">
|
|
<p className="text-sm text-ink-faint">Niciun registru de decizii. Adaugă prima decizie din <Link href="/dashboard/decisions" className="text-bronze-deep hover:underline">Decision Dashboard</Link>.</p>
|
|
</div>
|
|
) : (
|
|
<div className="overflow-x-auto">
|
|
<table className="w-full text-sm">
|
|
<thead>
|
|
<tr className="border-b border-paper-border">
|
|
{['Context', 'Opțiuni', 'Selectat', 'Review due', 'Outcome', 'Data'].map((h) => (
|
|
<th key={h} className="py-3 px-3 text-left text-xs font-semibold uppercase tracking-wider text-ink-faint first:pl-0">{h}</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-paper-border">
|
|
{decisions.map((d) => (
|
|
<tr key={d.id} className="hover:bg-paper-sunken/50">
|
|
<td className="py-3 px-3 first:pl-0">
|
|
<p className="max-w-xs truncate font-medium text-ink">{d.context}</p>
|
|
</td>
|
|
<td className="py-3 px-3">
|
|
<span className="text-ink-faint">{d.options.length}</span>
|
|
</td>
|
|
<td className="py-3 px-3">
|
|
<span className="max-w-32 truncate block text-ink-faint">{d.selectedOption ?? '—'}</span>
|
|
</td>
|
|
<td className="py-3 px-3">
|
|
<span className={`text-ink-faint ${d.reviewDueAt && !d.outcomeReview && new Date(d.reviewDueAt) < new Date() ? 'text-signal-danger' : ''}`}>
|
|
{fmtDate(d.reviewDueAt)}
|
|
</span>
|
|
</td>
|
|
<td className="py-3 px-3">
|
|
<span className={`rounded-full px-2 py-0.5 text-[10px] font-medium ${d.outcomeReview ? 'bg-signal-ok/10 text-signal-ok' : d.selectedOption ? 'bg-bronze-wash text-bronze-deep' : 'bg-signal-warn/10 text-signal-warn'}`}>
|
|
{d.outcomeReview ? 'revizuit' : d.selectedOption ? 'decis' : 'deschis'}
|
|
</span>
|
|
</td>
|
|
<td className="py-3 px-3 font-mono text-xs text-ink-line">
|
|
{fmtDate(d.createdAt)}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|