import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { useSearchParams } from 'react-router'; import { subscriptionApi } from '../api/subscription'; import { WebBackButton } from '../components/WebBackButton'; import { getGlassColors } from '../utils/glassTheme'; import { useTheme } from '../hooks/useTheme'; import type { Tariff, ClassicPurchaseOptions } from '../types'; import { useCloseOnSuccessNotification } from '../store/successNotification'; import { SwitchTariffSheet } from '../components/subscription/sheets/SwitchTariffSheet'; import { TariffPurchaseForm } from '../components/subscription/purchase/TariffPurchaseForm'; import { TariffPickerGrid } from '../components/subscription/purchase/TariffPickerGrid'; import { ClassicPurchaseWizard } from '../components/subscription/purchase/ClassicPurchaseWizard'; import { ExclamationIcon, SparklesIcon } from '@/components/icons'; export default function SubscriptionPurchase() { const { t } = useTranslation(); const [searchParams] = useSearchParams(); const subscriptionId = searchParams.get('subscriptionId') ? parseInt(searchParams.get('subscriptionId')!, 10) : undefined; const { isDark } = useTheme(); const g = getGlassColors(isDark); // Subscription query (shares cache with /subscription page) const { data: subscriptionResponse, isLoading } = useQuery({ queryKey: ['subscription', subscriptionId], queryFn: () => subscriptionApi.getSubscription(subscriptionId), retry: false, staleTime: 0, refetchOnMount: 'always', }); const subscription = subscriptionResponse?.subscription ?? null; // Purchase options const { data: purchaseOptions, isLoading: optionsLoading, isError: optionsError, refetch: refetchOptions, } = useQuery({ queryKey: ['purchase-options', subscriptionId], queryFn: () => subscriptionApi.getPurchaseOptions(subscriptionId), staleTime: 0, refetchOnMount: 'always', }); // Sales mode detection const isTariffsMode = purchaseOptions?.sales_mode === 'tariffs'; const classicOptions = !isTariffsMode ? (purchaseOptions as ClassicPurchaseOptions) : null; const tariffs = isTariffsMode && purchaseOptions && 'tariffs' in purchaseOptions ? purchaseOptions.tariffs : []; // Multi-tariff: check via subscriptions list query const { data: multiSubData } = useQuery({ queryKey: ['subscriptions-list'], queryFn: () => subscriptionApi.getSubscriptions(), staleTime: 60_000, }); const isMultiTariff = multiSubData?.multi_tariff_enabled ?? false; // (active promo discount + applyPromoDiscount live in usePromoDiscount; // consumed directly by the sub-components, not threaded as props) // (classic-mode state moved into ) // Tariffs mode state const [selectedTariff, setSelectedTariff] = useState(null); const [showTariffPurchase, setShowTariffPurchase] = useState(false); // (selectedTariffPeriod / customDays / customTrafficGb / useCustomDays / // useCustomTraffic moved into ; form remounts with // fresh state via key=tariff.id when the parent picks a new tariff) // (tariffPurchaseRef moved into ; switch-modal ref // moved into ) // Tariff switch const [switchTariffId, setSwitchTariffId] = useState(null); // Auto-close all modals on success notification const handleCloseAllModals = () => { // setShowPurchaseForm moved into 's own useCloseOnSuccessNotification setShowTariffPurchase(false); setSwitchTariffId(null); setSelectedTariff(null); // (selectedTariffPeriod lives inside now; unmount clears it) }; useCloseOnSuccessNotification(handleCloseAllModals); // (switch preview query + switchTariffMutation moved into ) // (tariffPurchaseMutation moved into ) // (auto-scroll effects: switch-modal into , // tariff-purchase into ) // (classic-mode helpers moved into ) if (isLoading || optionsLoading) { return (
); } if (optionsError || (!purchaseOptions && !optionsLoading)) { return (

{t('subscription.extend')}

{t('subscription.loadError', 'Не удалось загрузить варианты подписки')}

); } return (
{/* Header */}

{isMultiTariff && !subscriptionId ? t('subscription.newTariff', 'Новый тариф') : !isMultiTariff && subscription?.is_daily && !subscription?.is_trial ? t('subscription.switchTariff.title') : subscription && !subscription.is_trial ? t('subscription.extend') : t('subscription.getSubscription')}

{/* Tariffs Section */} {isTariffsMode && tariffs.length > 0 && (
{/* Trial upgrade prompt — hidden when expired banner is active */} {subscription?.is_trial && !( isTariffsMode && purchaseOptions && 'subscription_is_expired' in purchaseOptions && purchaseOptions.subscription_is_expired ) && (
{t('subscription.trialUpgrade.title')}
{t('subscription.trialUpgrade.description')}
)} {/* Expired subscription notice */} {isTariffsMode && purchaseOptions && 'subscription_is_expired' in purchaseOptions && purchaseOptions.subscription_is_expired && (
{t('subscription.expiredBanner.title')}
{t('subscription.expiredBanner.selectTariff')}
)} {/* Legacy subscription notice */} {subscription && !subscription.is_trial && !subscription.tariff_id && (
{t('subscription.legacy.selectTariffTitle')}
{t('subscription.legacy.selectTariffDescription')}
{t('subscription.legacy.currentSubContinues')}
)} {/* Switch Tariff Preview Modal */} setSwitchTariffId(null)} onExpiredFallback={(tariff) => { setSelectedTariff(tariff); setShowTariffPurchase(true); }} /> {!showTariffPurchase ? ( { setSelectedTariff(tariff); setShowTariffPurchase(true); }} onSwitchTariff={(tariffId) => setSwitchTariffId(tariffId)} /> ) : ( selectedTariff && ( /* Tariff Purchase Form (extracted into its own component) */ { setShowTariffPurchase(false); setSelectedTariff(null); }} /> ) )}
)} {/* Purchase/Extend Section - Classic Mode */} {classicOptions && classicOptions.periods.length > 0 && ( )} {/* No options available fallback */} {purchaseOptions && !optionsLoading && !(isTariffsMode && tariffs.length > 0) && !(classicOptions && classicOptions.periods.length > 0) && (

{t('subscription.noOptionsAvailable', 'Нет доступных вариантов подписки')}

)}
); }