ChargeBreakdown.tsx 1.8 KB

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