ChargeBreakdown.tsx60 lines · main
1import { cn } from 'ui'
2
3import { formatCurrency } from '@/lib/helpers'
4
5export interface ChargeBreakdownProps {
6 subtotal: number
7 subtotalLabel?: string
8 total: number
9 tax?: { amount: number; percentage: number }
10 taxStatus?: 'calculated' | 'failed' | 'not_applicable'
11 isFetching: boolean
12}
13
14export const ChargeBreakdown = ({
15 subtotal,
16 subtotalLabel = 'Subtotal',
17 total,
18 tax,
19 taxStatus,
20 isFetching,
21}: ChargeBreakdownProps) => {
22 return (
23 <div
24 className={cn('text-foreground-light text-sm transition-opacity', isFetching && 'opacity-50')}
25 >
26 {total !== subtotal && (
27 <div className="flex items-center justify-between gap-2 border-b border-muted text-sm">
28 <div className="py-2">{subtotalLabel}</div>
29 <div className="py-2 text-right tabular-nums" translate="no">
30 {formatCurrency(subtotal)}
31 </div>
32 </div>
33 )}
34
35 {taxStatus === 'calculated' && tax && tax.amount > 0 && (
36 <div className="flex items-center justify-between gap-2 border-b border-muted text-sm">
37 <div className="py-2">Tax ({tax.percentage}%)</div>
38 <div className="py-2 text-right tabular-nums" translate="no">
39 {formatCurrency(tax.amount)}
40 </div>
41 </div>
42 )}
43
44 {taxStatus === 'failed' && (
45 <div className="flex items-center justify-between gap-2 border-b border-muted text-sm">
46 <div className="py-2 text-foreground-lighter">
47 Tax could not be estimated and may be applied separately
48 </div>
49 </div>
50 )}
51
52 <div className="flex items-center justify-between gap-2 text-foreground text-base">
53 <div className="py-2">Total due today</div>
54 <div className="py-2 text-right tabular-nums" translate="no">
55 {formatCurrency(total)}
56 </div>
57 </div>
58 </div>
59 )
60}