From a4e2de0611cefef8ab15fc589771472435733441 Mon Sep 17 00:00:00 2001 From: Simone Cavalli Date: Thu, 14 May 2026 22:13:27 +0200 Subject: [PATCH] =?UTF-8?q?feat(01-04):=20PaymentStatus=20=E2=80=94=20tota?= =?UTF-8?q?le=20accettato=20+=20righe=20stato=20pagamento=20(senza=20impor?= =?UTF-8?q?ti)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- src/components/payment-status.tsx | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/components/payment-status.tsx diff --git a/src/components/payment-status.tsx b/src/components/payment-status.tsx new file mode 100644 index 0000000..5172186 --- /dev/null +++ b/src/components/payment-status.tsx @@ -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 ( + + {/* Totale accettato — unico importo visibile al cliente (LOCKED) */} +
+

+ Totale Preventivo Accettato +

+

+ {totalFormatted} +

+
+ + {/* Righe pagamento: solo etichetta + stato, MAI importo singolo */} +
+ {payments.length === 0 ? ( +

+ Nessun piano di pagamento configurato. +

+ ) : ( + payments.map((payment) => { + const status = payment.status as PaymentStatusValue; + const config = statusConfig[status] ?? statusConfig.da_saldare; + + return ( +
+ {/* Indicatore dot + etichetta */} +
+
+ + {/* Badge stato — nessun importo */} + + {config.label} + +
+ ); + }) + )} +
+ + {/* Nota informativa */} +
+

+ Per dettagli o domande sui pagamenti, contattaci direttamente. +

+
+
+ ); +} \ No newline at end of file