Files
mtdb_movie/common/resources/client/billing/checkout/checkout-product-summary.tsx
maher 703f50a09d
Some checks failed
Build / run (push) Has been cancelled
first commit
2025-10-29 11:42:25 +01:00

89 lines
2.4 KiB
TypeScript
Executable File

import {Trans} from '../../i18n/trans';
import {FormattedPrice} from '../../i18n/formatted-price';
import {useCheckoutProduct} from '../requests/use-checkout-product';
import {m} from 'framer-motion';
import {Skeleton} from '../../ui/skeleton/skeleton';
import {Product} from '../product';
import {Price} from '../price';
import {FormattedCurrency} from '../../i18n/formatted-currency';
import {ProductFeatureList} from '../pricing-table/product-feature-list';
import {opacityAnimation} from '../../ui/animation/opacity-animation';
interface CheckoutProductSummaryProps {
showBillingLine?: boolean;
}
export function CheckoutProductSummary({
showBillingLine = true,
}: CheckoutProductSummaryProps) {
const {status, product, price} = useCheckoutProduct();
if (status === 'error' || (status !== 'pending' && (!product || !price))) {
return null;
}
return (
<div>
<h2 className="text-2xl mb-30">
<Trans message="Summary" />
</h2>
{status === 'pending' ? (
<LoadingSkeleton key="loading-skeleton" />
) : (
<ProductSummary
product={product!}
price={price!}
showBillingLine={showBillingLine}
/>
)}
</div>
);
}
interface ProductSummaryProps {
product: Product;
price: Price;
showBillingLine: boolean;
}
function ProductSummary({
product,
price,
showBillingLine,
}: ProductSummaryProps) {
return (
<m.div>
<div className="text-xl font-semibold mb-6">{product.name}</div>
{product.description && (
<div className="text-sm text-muted">{product.description}</div>
)}
<FormattedPrice
priceClassName="font-bold text-4xl"
periodClassName="text-muted text-xs"
variant="separateLine"
price={price}
className="mt-32"
/>
<ProductFeatureList product={product} />
{showBillingLine && (
<div className="flex items-center justify-between gap-24 border-t pt-24 mt-32 font-medium">
<div>
<Trans message="Billed today" />
</div>
<div>
<FormattedCurrency value={price.amount} currency={price.currency} />
</div>
</div>
)}
</m.div>
);
}
function LoadingSkeleton() {
return (
<m.div {...opacityAnimation} className="max-w-180">
<Skeleton className="text-xl mb-6" />
<Skeleton className="text-sm" />
<Skeleton className="text-4xl mt-32" />
</m.div>
);
}