/**
* PromotionSection Component
*
* Handles promotion code input, applied discounts display, and removal.
*/
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
import type { TPaymentCurrency } from '@blocklet/payment-types';
import { Close, LocalOffer } from '@mui/icons-material';
import { Box, Button, Stack, Typography } from '@mui/material';
import PromotionCode from '../../components/promotion-code';
import { formatAmount, formatCouponTerms } from '../../libs/util';
export interface DiscountInfo {
promotion_code?: string;
coupon?: string;
discount_amount?: string;
promotion_code_details?: {
code?: string;
};
coupon_details?: any;
verification_data?: {
code?: string;
};
}
export interface PromotionSectionProps {
checkoutSessionId: string;
currency: TPaymentCurrency;
currencyId: string;
discounts: DiscountInfo[];
allowPromotionCodes: boolean;
completed?: boolean;
disabled?: boolean;
onPromotionUpdate: () => void;
onRemovePromotion: (sessionId: string) => void;
// For dynamic pricing: frontend-calculated discount amount
calculatedDiscountAmount?: string | null;
isRateLoading?: boolean;
}
export default function PromotionSection({
checkoutSessionId,
currency,
currencyId,
discounts,
allowPromotionCodes,
completed = false,
disabled = false,
onPromotionUpdate,
onRemovePromotion,
calculatedDiscountAmount = null,
isRateLoading = false,
}: PromotionSectionProps) {
const { t, locale } = useLocaleContext();
const hasDiscounts = discounts?.length > 0;
const getAppliedPromotionCodes = () => {
if (!discounts?.length) return [];
return discounts
.filter((discount) => discount.promotion_code || discount.coupon)
.map((discount) => ({
id: (discount.promotion_code || discount.coupon) as string,
code: discount.verification_data?.code || 'APPLIED',
discount_amount: discount.discount_amount,
}));
};
// Only show add button if no discounts applied
if (allowPromotionCodes && !hasDiscounts) {
return (
);
}
// Show applied discounts
if (!hasDiscounts) {
return null;
}
return (
{discounts.map((discount) => {
const promotionCodeInfo = discount.promotion_code_details;
const couponInfo = discount.coupon_details;
const discountDescription = couponInfo ? formatCouponTerms(couponInfo, currency, locale) : '';
const notSupported = discountDescription === t('payment.checkout.coupon.noDiscount');
return (
{promotionCodeInfo?.code || discount.verification_data?.code || t('payment.checkout.discount')}
{!completed && (
)}
-{formatAmount(calculatedDiscountAmount || '0', currency.decimal)} {currency.symbol}
{/* Show discount description */}
{discountDescription && (
{discountDescription}
)}
);
})}
);
}