import React, { useState } from 'react'; import { CreditCard, RefreshCw, SlidersHorizontal, Calendar, CheckCircle2, Clock, ShieldAlert, } from 'lucide-react'; import { useKccStore, useOperatorRole } from '../store/kccStore'; import { StatusBadge } from '../components/StatusBadge'; import { MoneyDisplay } from '../components/MoneyDisplay'; export const BillingPage: React.FC = () => { const subscriptions = useKccStore((state) => state.subscriptions); const modules = useKccStore((state) => state.modules); const renewSubscription = useKccStore((state) => state.renewSubscription); const grantGracePeriod = useKccStore((state) => state.grantGracePeriod); const openConfirmModal = useKccStore((state) => state.openConfirmModal); const openInspector = useKccStore((state) => state.openInspector); const { permissions } = useOperatorRole(); const [filter, setFilter] = useState<'all' | 'expiring_7d' | 'expiring_30d' | 'overdue' | 'grace'>('all'); const [selectedSubId, setSelectedSubId] = useState(subscriptions[0]?.subscriptionId || null); const selectedSub = subscriptions.find((s) => s.subscriptionId === selectedSubId) || subscriptions[0]; // Form state for renewal calculator const [newPeriod, setNewPeriod] = useState<'month' | 'year'>('year'); const [customModules, setCustomModules] = useState(null); const activeModulesToDisplay = customModules ?? (selectedSub ? selectedSub.activeModules : []); const filteredSubs = subscriptions.filter((sub) => { if (filter === 'all') return true; return sub.status === filter; }); // Calculate live preview amount const baseRatePerMonth = 1500000; // 15 000,00 ₽ const moduleRatePerMonth = 400000; // 4 000,00 ₽ const monthlyTotal = baseRatePerMonth + activeModulesToDisplay.length * moduleRatePerMonth; const calculatedTotal = newPeriod === 'year' ? monthlyTotal * 10 : monthlyTotal; const handleRenew = () => { if (!selectedSub) return; openConfirmModal({ title: `Продление подписки: ${selectedSub.organizationName}`, actionName: 'grant_grace_period', impactSummary: `Подписка будет продлена на ${newPeriod === 'year' ? '1 год' : '1 месяц'}. Состав модулей: ${activeModulesToDisplay.join(', ')}. Расчётная сумма: ${calculatedTotal / 100} ₽.`, targetType: 'subscription', targetId: selectedSub.subscriptionId, targetName: selectedSub.organizationName, onConfirm: async (reason) => { await renewSubscription(selectedSub.subscriptionId, newPeriod, activeModulesToDisplay, reason); }, }); }; const handleGrantGrace = () => { if (!selectedSub) return; openConfirmModal({ title: `Предоставление льготного периода: ${selectedSub.organizationName}`, actionName: 'grant_grace_period', impactSummary: `Организации будет предоставлен льготный период (Grace Period) на 14 дней с сохранением доступа ко всем модулям.`, targetType: 'subscription', targetId: selectedSub.subscriptionId, targetName: selectedSub.organizationName, onConfirm: async (reason) => { await grantGracePeriod(selectedSub.subscriptionId, 14, reason); }, }); }; const toggleModuleSelection = (moduleCode: string) => { if (activeModulesToDisplay.includes(moduleCode)) { setCustomModules(activeModulesToDisplay.filter((m) => m !== moduleCode)); } else { setCustomModules([...activeModulesToDisplay, moduleCode]); } }; return (
{/* Header */}

Подписки и биллинг платформы

Контроль сроков действия лицензий, предоставление льготных периодов и продление тарифов

Всего подписок: {subscriptions.length} (найдено:{' '} {filteredSubs.length})
{/* Filter Tabs */}
{[ { id: 'all', label: 'Все подписки' }, { id: 'expiring_7d', label: 'Истекают (< 7 дн.)' }, { id: 'expiring_30d', label: 'Истекают (< 30 дн.)' }, { id: 'grace', label: 'Льготный период' }, { id: 'overdue', label: 'Просроченные' }, ].map((tab) => ( ))}
{/* Two Column Layout: List on Left, Calculator on Right */}
{/* Left Column: Subscriptions List */}
{filteredSubs.map((sub) => { const isSelected = sub.subscriptionId === selectedSub?.subscriptionId; const validUntilDate = new Date(sub.validUntil); return (
{ setSelectedSubId(sub.subscriptionId); setCustomModules(null); }} className={`p-4 rounded-xl border transition-all cursor-pointer space-y-3 ${ isSelected ? 'border-krona-gold bg-krona-surface shadow-md ring-1 ring-krona-gold/30' : 'border-krona-border bg-krona-surface/60 hover:bg-krona-surface hover:border-krona-border' }`} data-testid={`subscription-card-${sub.subscriptionId}`} >

{sub.organizationName}

Тарифный план: {sub.planName}
Стоимость в месяц
Действует до
{validUntilDate.toLocaleDateString('ru-RU')}
Подключено модулей: {sub.activeModules.length}
); })} {filteredSubs.length === 0 && (
Подписки не найдены по выбранным критериям
)}
{/* Right Column: Calculator & Renewal Actions */}
{selectedSub ? (
Управление подпиской

{selectedSub.organizationName}

Текущий статус:
{/* Period Switcher */}
{/* Included Modules Checklist */}
{modules.map((mod) => { const isChecked = activeModulesToDisplay.includes(mod.code); return ( ); })}
{/* Total Calculation */}
Расчётная стоимость продления
{newPeriod === 'year' ? 'За 12 месяцев' : 'За 1 месяц'}
{/* Action Buttons */}
) : (
Выберите организацию из списка для продления или изменения состава модулей
)}
); };