feat(01-04): ClientDashboard wrapper con header, progress bar globale, layout sezioni

- Header sticky: logo iamcavalli (xs, angolo sinistro) + brand_name cliente (prominente, centrato)
- Progress bar globale con percentuale visibile
- Brief cliente con accent bar sinistra
- Sezioni: PhaseTimeline, PaymentStatus (sempre), Documents/Notes (condizionali)
- Footer con avviso link privato
- Server Component puro, nessun 'use client' necessario
This commit is contained in:
Simone Cavalli
2026-05-14 22:13:11 +02:00
parent 4e703d7068
commit debd3916db
+99
View File
@@ -0,0 +1,99 @@
import type { ClientView } from '@/lib/client-view';
import { Progress } from '@/components/ui/progress';
import { PhaseTimeline } from './phase-timeline';
import { PaymentStatus } from './payment-status';
import { DocumentsSection } from './documents-section';
import { NotesSection } from './notes-section';
interface ClientDashboardProps {
view: ClientView;
}
export function ClientDashboard({ view }: ClientDashboardProps) {
return (
<div className="min-h-screen bg-white">
{/* Header: logo iamcavalli (piccolo) + brand_name cliente (prominente) */}
<header className="bg-white border-b border-[#e5e5e5] sticky top-0 z-10">
<div className="max-w-4xl mx-auto px-4 sm:px-6 py-5">
<div className="flex items-center">
{/* iamcavalli — piccolo, angolo sinistro */}
<span className="text-xs font-semibold tracking-widest text-[#999999] uppercase w-28 shrink-0">
iamcavalli
</span>
{/* Brand name cliente — prominente, centrato */}
<h1 className="flex-1 text-center text-2xl sm:text-3xl font-bold text-[#1a1a1a] tracking-tight">
{view.client.brand_name}
</h1>
{/* Spacer bilanciatore */}
<div className="w-28 shrink-0" />
</div>
</div>
</header>
{/* Barra progresso globale */}
<section className="bg-[#f9f9f9] border-b border-[#e5e5e5]">
<div className="max-w-4xl mx-auto px-4 sm:px-6 py-5">
<div className="flex items-center justify-between mb-2">
<p className="text-sm font-semibold text-[#1a1a1a]">Avanzamento Progetto</p>
<p className="text-sm font-bold text-[#1a1a1a]">{view.global_progress_pct}%</p>
</div>
<Progress value={view.global_progress_pct} className="h-2" />
</div>
</section>
{/* Contenuto principale */}
<main className="max-w-4xl mx-auto px-4 sm:px-6 py-10 space-y-14">
{/* Brief progetto */}
{view.client.brief && (
<section>
<p className="text-base text-[#666666] italic leading-relaxed border-l-4 border-[#0066cc] pl-4">
{view.client.brief}
</p>
</section>
)}
{/* Timeline fasi */}
<section>
<h2 className="text-xl font-bold text-[#1a1a1a] mb-6">Fasi del Progetto</h2>
<PhaseTimeline phases={view.phases} />
</section>
{/* Stato pagamenti — sempre visibile (D-10) */}
<section>
<h2 className="text-xl font-bold text-[#1a1a1a] mb-6">Pagamenti</h2>
<PaymentStatus
accepted_total={view.client.accepted_total}
payments={view.payments}
/>
</section>
{/* Documenti — solo se presenti */}
{view.documents.length > 0 && (
<section>
<h2 className="text-xl font-bold text-[#1a1a1a] mb-6">Documenti & File</h2>
<DocumentsSection documents={view.documents} />
</section>
)}
{/* Note / Log decisioni — solo se presenti */}
{view.notes.length > 0 && (
<section>
<h2 className="text-xl font-bold text-[#1a1a1a] mb-6">Note & Decisioni</h2>
<NotesSection notes={view.notes} />
</section>
)}
</main>
{/* Footer */}
<footer className="border-t border-[#e5e5e5] bg-[#f9f9f9] mt-10">
<div className="max-w-4xl mx-auto px-4 sm:px-6 py-6">
<p className="text-xs text-[#999999] text-center">
Questa e&apos; la tua dashboard privata non condividere il link.
</p>
</div>
</footer>
</div>
);
}