feat(dashboard): l'inbox sale in cima e dice da quanto aspettano

Il widget dei messaggi esisteva gia', ma era il terzo riquadro della colonna
stretta: sotto la piega, cioe' invisibile. Un messaggio non letto e' la cosa
piu' urgente della giornata e ora sta in testa alla dashboard, a piena
larghezza, due colonne.

Due dati erano gia' in ConversationSummary e non venivano mostrati: da quanto
aspetta il messaggio e su cosa e' stato scritto (fase, task, deliverable o
generale). Sono esattamente i due che dicono con che fretta rispondere. Il
tempo relativo si ferma alla settimana e poi passa alla data: oltre, "23 giorni
fa" non aiuta piu' nessuno.

La fascia sparisce del tutto quando non c'e' niente da leggere, invece di
lasciare a video un riquadro vuoto che si impara a saltare — e con lui si
imparerebbe a saltare anche quello pieno.

relativeTime va in src/lib/dates.ts perche' serve anche altrove. FollowUpWidget
ha ancora la sua copia locale con il prefisso "Contattato": la si unifica
quando la si tocca, non oggi.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 22:42:52 +02:00
parent d6e95ef66a
commit 1115bb2265
4 changed files with 129 additions and 71 deletions
+7 -6
View File
@@ -1,7 +1,7 @@
import { Suspense } from "react";
import { getDashboardStats } from "@/lib/dashboard-queries";
import { FollowUpWidget } from "@/components/admin/dashboard/FollowUpWidget";
import { MessagesWidget } from "@/components/admin/dashboard/MessagesWidget";
import { InboxBand } from "@/components/admin/dashboard/InboxBand";
import {
getAnalyticsByYear,
getTotalTrackedHours,
@@ -39,6 +39,12 @@ export default async function AdminDashboard({
return (
<div className="flex flex-col gap-8">
{/* Messaggi in attesa — in cima perché è la cosa più urgente della
giornata. Non renderizza nulla quando non c'è niente da leggere. */}
<Suspense fallback={null}>
<InboxBand />
</Suspense>
{/* KPI strip */}
<section className="grid grid-cols-2 lg:grid-cols-4 gap-6">
<MetricCard
@@ -76,11 +82,6 @@ export default async function AdminDashboard({
>
<FollowUpWidget />
</Suspense>
<Suspense
fallback={<div className="animate-pulse h-40 bg-muted rounded-xl" />}
>
<MessagesWidget />
</Suspense>
<OffersSoldChart data={offersSold} />
</div>
</div>