Skip to content
Cards

Cards

PriceBreakdown

Read-only price card that adds GST to a base price in rupees.

npx bezel-add add price-breakdown

About

A price summary card for React that works out GST on a base price and shows the total in Indian rupees. It formats amounts with the en-IN locale to two decimals, shows a dash when GST is zero, and renders nothing if the price is missing or invalid. Use it on checkout, quote or listing pages where tax must be spelled out.

Key props: price (base amount in rupees), gstPercent (GST rate as a percentage), priceLabel (label for the base line, default "Base Price")

packages/ui/src/cards/PriceBreakdown.tsx · 63 lines

import { IndianRupee, Receipt, Percent } from "lucide-react"

interface PriceBreakdownProps {
  price: number
  gstPercent: number
  priceLabel?: string
}

export function PriceBreakdown({
  price,
  gstPercent,
  priceLabel = "Base Price",
}: PriceBreakdownProps) {
  const validPrice = Number.isFinite(price) && price > 0 ? price : 0
  const validGst = Number.isFinite(gstPercent) && gstPercent >= 0 ? gstPercent : 0

  if (validPrice === 0) return null

  const gstAmount = validPrice * (validGst / 100)
  const totalPrice = validPrice + gstAmount

  return (
    <div className="rounded-lg border bg-muted/40 p-4 space-y-3">
      <div className="flex items-center gap-2 text-sm font-semibold text-muted-foreground uppercase tracking-wide">
        <Receipt className="h-4 w-4" />
        Price Breakdown
      </div>

      <div className="space-y-2">
        <div className="flex items-center justify-between text-sm">
          <span className="flex items-center gap-2 text-muted-foreground">
            <IndianRupee className="h-3.5 w-3.5" />
            {priceLabel}
          </span>
          <span className="font-medium">
            ₹{validPrice.toLocaleString("en-IN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
          </span>
        </div>

        <div className="flex items-center justify-between text-sm">
          <span className="flex items-center gap-2 text-muted-foreground">
            <Percent className="h-3.5 w-3.5" />
            GST ({validGst}%)
          </span>
          <span className="font-medium">
            {gstAmount > 0
              ? `₹${gstAmount.toLocaleString("en-IN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
              : "—"}
          </span>
        </div>

        <div className="border-t" />

        <div className="flex items-center justify-between">
          <span className="text-sm font-semibold">Total Price</span>
          <span className="text-lg font-bold text-primary">
            ₹{totalPrice.toLocaleString("en-IN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
          </span>
        </div>
      </div>
    </div>
  )
}