- {/* Price breakdown */}
-
- {useCustomDays ? (
-
- Период: {customDays} дней
- {formatPrice(customDays * (selectedTariff.price_per_day_kopeks ?? 0))}
-
- ) : selectedTariffPeriod && (
-
- Период: {selectedTariffPeriod.label}
- {formatPrice(selectedTariffPeriod.price_kopeks)}
-
- )}
- {useCustomTraffic && selectedTariff.custom_traffic_enabled && (
-
- Трафик: {customTrafficGb} ГБ
- +{formatPrice(customTrafficGb * (selectedTariff.traffic_price_per_gb_kopeks ?? 0))}
-
- )}
-
-
{(() => {
- const periodPrice = useCustomDays
+ // Calculate prices with promo discount
+ const basePeriodPrice = useCustomDays
? customDays * (selectedTariff.price_per_day_kopeks ?? 0)
: (selectedTariffPeriod?.price_kopeks || 0)
+ const hasExistingPeriodDiscount = !useCustomDays && selectedTariffPeriod?.original_price_kopeks
+ ? selectedTariffPeriod.original_price_kopeks > selectedTariffPeriod.price_kopeks
+ : false
+ const promoPeriod = applyPromoDiscount(basePeriodPrice, hasExistingPeriodDiscount)
+
const trafficPrice = useCustomTraffic && selectedTariff.custom_traffic_enabled
? customTrafficGb * (selectedTariff.traffic_price_per_gb_kopeks ?? 0)
: 0
- const totalPrice = periodPrice + trafficPrice
+
+ const totalPrice = promoPeriod.price + trafficPrice
+ const originalTotal = promoPeriod.original ? promoPeriod.original + trafficPrice : null
const hasEnoughBalance = purchaseOptions && totalPrice <= purchaseOptions.balance_kopeks
return (
<>
+ {/* Price breakdown */}
+
+ {useCustomDays ? (
+
+
Период: {customDays} дней
+
+ {formatPrice(promoPeriod.price)}
+ {promoPeriod.original && (
+ {formatPrice(promoPeriod.original)}
+ )}
+
+
+ ) : selectedTariffPeriod && (
+
+
Период: {selectedTariffPeriod.label}
+
+ {formatPrice(promoPeriod.price)}
+ {(hasExistingPeriodDiscount || promoPeriod.original) && (
+
+ {formatPrice(hasExistingPeriodDiscount ? selectedTariffPeriod.original_price_kopeks! : promoPeriod.original!)}
+
+ )}
+
+
+ )}
+ {useCustomTraffic && selectedTariff.custom_traffic_enabled && (
+
+ Трафик: {customTrafficGb} ГБ
+ +{formatPrice(trafficPrice)}
+
+ )}
+
+
+ {/* Promo discount info */}
+ {promoPeriod.percent && (
+
+
+ Скидка -{promoPeriod.percent}% применена
+
+
+ )}
+
{t('subscription.total')}
-
{formatPrice(totalPrice)}
+
+
{formatPrice(totalPrice)}
+ {originalTotal && (
+
{formatPrice(originalTotal)}
+ )}
+
{purchaseOptions && !hasEnoughBalance && (
@@ -1593,93 +1696,139 @@ export default function Subscription() {
{/* Step: Period Selection */}
{currentStep === 'period' && classicOptions && (
- {classicOptions.periods.map((period) => (
-
- ))}
+ {classicOptions.periods.map((period) => {
+ const hasExistingDiscount = !!(period.discount_percent && period.discount_percent > 0)
+ const promoPeriod = applyPromoDiscount(period.price_kopeks, hasExistingDiscount)
+ const displayDiscount = hasExistingDiscount ? period.discount_percent : promoPeriod.percent
+ const displayOriginal = hasExistingDiscount ? period.original_price_kopeks : promoPeriod.original
+
+ return (
+
+ )
+ })}
)}
{/* Step: Traffic Selection */}
{currentStep === 'traffic' && selectedPeriod?.traffic.options && (
- {selectedPeriod.traffic.options.map((option) => (
-
- ))}
+ {selectedPeriod.traffic.options.map((option) => {
+ const hasExistingDiscount = !!(option.discount_percent && option.discount_percent > 0)
+ const promoTraffic = applyPromoDiscount(option.price_kopeks, hasExistingDiscount)
+
+ return (
+
+ )
+ })}
)}
{/* Step: Server Selection */}
{currentStep === 'servers' && selectedPeriod?.servers.options && (
- {selectedPeriod.servers.options.map((server) => (
-
) : preview ? (
+ {/* Active promo discount banner */}
+ {activeDiscount?.is_active && activeDiscount.discount_percent && !preview.original_price_kopeks && (
+
+
+
+ Скидка -{activeDiscount.discount_percent}% применена
+
+
+ )}
+
{preview.breakdown.map((item, idx) => (
{item.label}
@@ -1730,15 +1891,25 @@ export default function Subscription() {
))}
-
-
{t('subscription.total')}
-
-
{formatPrice(preview.total_price_kopeks)}
- {preview.original_price_kopeks && (
-
{formatPrice(preview.original_price_kopeks)}
- )}
-
-
+ {(() => {
+ // Apply promo discount if not already applied by server
+ const hasServerDiscount = !!preview.original_price_kopeks
+ const promoTotal = applyPromoDiscount(preview.total_price_kopeks, hasServerDiscount)
+ const displayTotal = promoTotal.price
+ const displayOriginal = hasServerDiscount ? preview.original_price_kopeks : promoTotal.original
+
+ return (
+
+
{t('subscription.total')}
+
+
{formatPrice(displayTotal)}
+ {displayOriginal && (
+
{formatPrice(displayOriginal)}
+ )}
+
+
+ )
+ })()}
{preview.discount_label && (
{preview.discount_label}