{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "checkout-summary-card", "type": "registry:block", "title": "Checkout summary card", "description": "Dark hosted-checkout product summary panel from the left checkout column.", "files": [ { "path": "components/lomi-ui/checkout-summary-card.tsx", "target": "components/lomi-ui/checkout-summary-card.tsx", "type": "registry:component", "content": "/* eslint-disable @next/next/no-img-element -- lomi. UI registry components are framework-portable copy-paste components. */\n\nimport * as React from 'react';\n\nexport interface CheckoutSummaryItem {\n name: string;\n quantity?: number;\n amount: number;\n unitAmount?: number;\n imageUrl?: string;\n}\n\nexport interface CheckoutSummaryFee {\n name: string;\n amount: number;\n label?: string;\n}\n\nexport interface CheckoutSummaryCardProps {\n /** Product or payment link title shown above the price. */\n title: string;\n items?: CheckoutSummaryItem[];\n subtotal: number;\n fees?: number | CheckoutSummaryFee[];\n discount?: number;\n total: number;\n currency: string;\n description?: string;\n productImageUrl?: string;\n className?: string;\n}\n\nfunction cn(...classes: Array) {\n return classes.filter(Boolean).join(' ');\n}\n\nfunction formatAmount(amount: number) {\n return new Intl.NumberFormat('fr-FR', {\n maximumFractionDigits: 0,\n }).format(amount);\n}\n\nfunction normalizeFees(\n fees: number | CheckoutSummaryFee[] | undefined,\n): CheckoutSummaryFee[] {\n if (!fees) return [];\n if (typeof fees === 'number') {\n return fees > 0 ? [{ name: 'Fees', amount: fees }] : [];\n }\n return fees.filter((fee) => fee.amount > 0);\n}\n\nexport function CheckoutSummaryCard({\n title,\n items = [],\n subtotal,\n fees,\n discount = 0,\n total,\n currency,\n description,\n productImageUrl,\n className,\n}: CheckoutSummaryCardProps) {\n const feeRows = normalizeFees(fees);\n const totalItems = items.reduce((sum, item) => sum + (item.quantity ?? 1), 0);\n const showCart = items.length > 1;\n\n return (\n \n {showCart ? (\n
\n
\n

Your Cart

\n \n {totalItems} {totalItems === 1 ? 'item' : 'items'}\n \n
\n
\n {items.map((item) => (\n \n
\n {item.imageUrl ? (\n \n ) : null}\n
\n
\n

\n {item.name}\n

\n {item.unitAmount ? (\n

\n {formatAmount(item.unitAmount)} {currency} each\n

\n ) : null}\n
\n \n Qty: {item.quantity ?? 1}\n \n
\n \n {formatAmount(item.amount)}\n \n \n {currency}\n \n
\n
\n
\n
\n ))}\n
\n
\n
\n Subtotal\n
\n \n {formatAmount(subtotal)}\n \n {currency}\n
\n
\n
\n \n ) : (\n
\n

{title}

\n
\n \n {formatAmount(total)}\n \n {currency}\n
\n {(description || productImageUrl || items[0]?.imageUrl) && (\n
\n {(productImageUrl || items[0]?.imageUrl) && (\n
\n \n
\n )}\n {description ? (\n
\n {description}\n
\n ) : null}\n
\n )}\n
\n )}\n\n {!showCart ? (\n
\n
\n
\n Subtotal\n
\n {formatAmount(subtotal)}\n {currency}\n
\n
\n\n {feeRows.map((fee) => (\n \n
\n {fee.name}\n {fee.label ? (\n ({fee.label})\n ) : null}\n
\n
\n \n {formatAmount(fee.amount)}\n \n {currency}\n
\n
\n ))}\n\n {discount > 0 ? (\n
\n Discount\n
\n \n -{formatAmount(discount)}\n \n {currency}\n
\n
\n ) : null}\n
\n\n
\n
\n Total due today\n
\n \n {formatAmount(total)}\n \n {currency}\n
\n
\n
\n \n ) : null}\n \n );\n}\n" }, { "path": "components/lomi-ui/demo/checkout-summary-card-demo.tsx", "target": "components/lomi-ui/demo/checkout-summary-card-demo.tsx", "type": "registry:component", "content": "import { LomiUiPreview } from '@/components/preview/lomi-ui-preview';\nimport { CheckoutSummaryCard } from '@/components/lomi-ui/checkout-summary-card';\n\nexport function CheckoutSummaryCardDemo() {\n return (\n \n \n \n );\n}\n" } ] }