feat: dashboard box "Messaggi Clienti" — chat clienti in attesa di risposta
Nuovo MessagesWidget nella colonna 1/3 della dashboard: riusa getConversations() filtrando le conversazioni unread, mostra le prime 4 con anteprima e deep-link "Rispondi" a /admin/conversazioni?c=<clientId>. Pill emerald "N Nuovi" + pallino pulsante, empty state quando non c'è nulla in attesa. Stessa fonte di verità (clients.admin_last_read_at) del badge sidebar. Aggiornato DESIGN-SYSTEM.md (inventory + note Conversazioni/dashboard) e il mock design-reference/pagina-dashboard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { getConversations } from "@/lib/conversations-queries";
|
||||
import Link from "next/link";
|
||||
|
||||
const MAX_ROWS = 4;
|
||||
|
||||
export async function MessagesWidget() {
|
||||
const conversations = await getConversations();
|
||||
const unread = conversations.filter((c) => c.unread);
|
||||
|
||||
if (unread.length === 0) {
|
||||
return (
|
||||
<div className="bg-card rounded-xl border border-border-light shadow-card p-5">
|
||||
<h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
|
||||
Messaggi Clienti
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground mt-3">Nessun messaggio in attesa ✓</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const visible = unread.slice(0, MAX_ROWS);
|
||||
|
||||
return (
|
||||
<div className="bg-card rounded-xl border border-border-light shadow-card p-5">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
|
||||
Messaggi Clienti
|
||||
</h3>
|
||||
<span className="w-2 h-2 rounded-full bg-emerald-500 animate-pulse" />
|
||||
</div>
|
||||
<span className="text-[10px] font-bold bg-emerald-50 text-emerald-700 border border-emerald-100 px-2 py-0.5 rounded-full dark:bg-emerald-500/10 dark:text-emerald-400 dark:border-emerald-500/20">
|
||||
{unread.length} {unread.length === 1 ? "Nuovo" : "Nuovi"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
{visible.map((conv) => (
|
||||
<Link
|
||||
key={conv.clientId}
|
||||
href={`/admin/conversazioni?c=${conv.clientId}`}
|
||||
className="flex items-center justify-between gap-3 p-3 border border-border-light rounded-lg hover:border-border transition-colors group"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<h4 className="text-xs font-bold text-foreground truncate">{conv.brand_name}</h4>
|
||||
<p className="text-[10px] text-muted-foreground truncate">{conv.lastMessage}</p>
|
||||
</div>
|
||||
<span className="text-[11px] font-bold text-primary group-hover:opacity-70 transition-opacity shrink-0 inline-flex items-center gap-0.5">
|
||||
Rispondi →
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{unread.length > MAX_ROWS && (
|
||||
<Link
|
||||
href="/admin/conversazioni"
|
||||
className="block mt-3 pt-3 text-center text-xs font-medium text-muted-foreground hover:text-primary border-t border-border-light transition-colors"
|
||||
>
|
||||
Vedi tutti i messaggi
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user