feat(01-04): PaymentStatus — totale accettato + righe stato pagamento (senza importi)
- Mostra accepted_total formattato in EUR (unico importo permesso — LOCKED) - Righe pagamento: solo label + badge stato (da_saldare/inviata/saldato) - Nessun importo singolo visibile al cliente (T-04-001 mitigato) - Dot colorato + badge per ogni riga: blu=da_saldare, giallo=inviata, verde=saldato
This commit is contained in:
@@ -0,0 +1,98 @@
|
|||||||
|
import type { ClientView } from '@/lib/client-view';
|
||||||
|
import { Card } from '@/components/ui/card';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
|
||||||
|
interface PaymentStatusProps {
|
||||||
|
accepted_total: string;
|
||||||
|
payments: ClientView['payments'];
|
||||||
|
}
|
||||||
|
|
||||||
|
type PaymentStatusValue = 'da_saldare' | 'inviata' | 'saldato';
|
||||||
|
|
||||||
|
const statusConfig: Record<
|
||||||
|
PaymentStatusValue,
|
||||||
|
{ label: string; badgeClass: string; dotClass: string }
|
||||||
|
> = {
|
||||||
|
da_saldare: {
|
||||||
|
label: 'Da Saldare',
|
||||||
|
badgeClass: 'border-transparent bg-[#2563eb] text-white',
|
||||||
|
dotClass: 'bg-[#2563eb]',
|
||||||
|
},
|
||||||
|
inviata: {
|
||||||
|
label: 'Inviata',
|
||||||
|
badgeClass: 'border-transparent bg-[#ca8a04] text-white',
|
||||||
|
dotClass: 'bg-[#ca8a04]',
|
||||||
|
},
|
||||||
|
saldato: {
|
||||||
|
label: 'Saldato',
|
||||||
|
badgeClass: 'border-transparent bg-[#16a34a] text-white',
|
||||||
|
dotClass: 'bg-[#16a34a]',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function PaymentStatus({ accepted_total, payments }: PaymentStatusProps) {
|
||||||
|
const totalFormatted = parseFloat(accepted_total || '0').toLocaleString('it-IT', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'EUR',
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card className="rounded-lg border border-[#e5e5e5] bg-white shadow-none overflow-hidden">
|
||||||
|
{/* Totale accettato — unico importo visibile al cliente (LOCKED) */}
|
||||||
|
<div className="px-6 py-5 border-b border-[#e5e5e5] bg-[#f9f9f9]">
|
||||||
|
<p className="text-xs font-semibold text-[#666666] uppercase tracking-wider mb-1">
|
||||||
|
Totale Preventivo Accettato
|
||||||
|
</p>
|
||||||
|
<p className="text-3xl font-bold text-[#1a1a1a] tracking-tight">
|
||||||
|
{totalFormatted}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Righe pagamento: solo etichetta + stato, MAI importo singolo */}
|
||||||
|
<div className="px-6 py-4 space-y-3">
|
||||||
|
{payments.length === 0 ? (
|
||||||
|
<p className="text-sm text-[#999999] italic py-2">
|
||||||
|
Nessun piano di pagamento configurato.
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
payments.map((payment) => {
|
||||||
|
const status = payment.status as PaymentStatusValue;
|
||||||
|
const config = statusConfig[status] ?? statusConfig.da_saldare;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={payment.id}
|
||||||
|
className="flex items-center justify-between gap-4 py-2"
|
||||||
|
>
|
||||||
|
{/* Indicatore dot + etichetta */}
|
||||||
|
<div className="flex items-center gap-2.5">
|
||||||
|
<span
|
||||||
|
className={`w-2 h-2 rounded-full shrink-0 ${config.dotClass}`}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<p className="text-sm font-medium text-[#1a1a1a]">
|
||||||
|
{payment.label}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Badge stato — nessun importo */}
|
||||||
|
<Badge className={`text-xs shrink-0 ${config.badgeClass}`}>
|
||||||
|
{config.label}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Nota informativa */}
|
||||||
|
<div className="px-6 py-3 border-t border-[#e5e5e5] bg-[#f9f9f9]">
|
||||||
|
<p className="text-xs text-[#999999] italic">
|
||||||
|
Per dettagli o domande sui pagamenti, contattaci direttamente.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user