import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useTranslation } from 'react-i18next' import { Link } from 'react-router-dom' import { tariffsApi, TariffListItem, TariffDetail, TariffCreateRequest, TariffUpdateRequest, PeriodPrice, ServerInfo } from '../api/tariffs' // Icons const BackIcon = () => ( ) const PlusIcon = () => ( ) const EditIcon = () => ( ) const TrashIcon = () => ( ) const CheckIcon = () => ( ) const XIcon = () => ( ) const InfinityIcon = () => ( ) const CalendarIcon = () => ( ) const SunIcon = () => ( ) // Type selection modal interface TariffTypeSelectProps { onSelect: (isDaily: boolean) => void onClose: () => void } function TariffTypeSelect({ onSelect, onClose }: TariffTypeSelectProps) { return (

Выберите тип тарифа

) } // Period tariff modal interface PeriodTariffModalProps { tariff?: TariffDetail | null servers: ServerInfo[] onSave: (data: TariffCreateRequest | TariffUpdateRequest) => void onClose: () => void isLoading?: boolean } function PeriodTariffModal({ tariff, servers, onSave, onClose, isLoading }: PeriodTariffModalProps) { const isEdit = !!tariff const [name, setName] = useState(tariff?.name || '') const [description, setDescription] = useState(tariff?.description || '') const [trafficLimitGb, setTrafficLimitGb] = useState(tariff?.traffic_limit_gb || 100) const [deviceLimit, setDeviceLimit] = useState(tariff?.device_limit || 1) const [devicePriceKopeks, setDevicePriceKopeks] = useState(tariff?.device_price_kopeks || 0) const [maxDeviceLimit, setMaxDeviceLimit] = useState(tariff?.max_device_limit || 0) const [tierLevel, setTierLevel] = useState(tariff?.tier_level || 1) const [periodPrices, setPeriodPrices] = useState( tariff?.period_prices?.length ? tariff.period_prices : [] ) const [selectedSquads, setSelectedSquads] = useState(tariff?.allowed_squads || []) // Докупка трафика const [trafficTopupEnabled, setTrafficTopupEnabled] = useState(tariff?.traffic_topup_enabled || false) const [maxTopupTrafficGb, setMaxTopupTrafficGb] = useState(tariff?.max_topup_traffic_gb || 0) const [trafficTopupPackages, setTrafficTopupPackages] = useState>( tariff?.traffic_topup_packages || {} ) // Режим сброса трафика const [trafficResetMode, setTrafficResetMode] = useState(tariff?.traffic_reset_mode || null) // Плавающий тариф - произвольное количество дней const [customDaysEnabled, setCustomDaysEnabled] = useState(tariff?.custom_days_enabled || false) const [pricePerDayKopeks, setPricePerDayKopeks] = useState(tariff?.price_per_day_kopeks || 0) const [minDays, setMinDays] = useState(tariff?.min_days || 1) const [maxDays, setMaxDays] = useState(tariff?.max_days || 365) // Плавающий тариф - произвольный трафик const [customTrafficEnabled, setCustomTrafficEnabled] = useState(tariff?.custom_traffic_enabled || false) const [trafficPricePerGbKopeks, setTrafficPricePerGbKopeks] = useState(tariff?.traffic_price_per_gb_kopeks || 0) const [minTrafficGb, setMinTrafficGb] = useState(tariff?.min_traffic_gb || 1) const [maxTrafficGb, setMaxTrafficGb] = useState(tariff?.max_traffic_gb || 1000) // Новый период для добавления const [newPeriodDays, setNewPeriodDays] = useState(30) const [newPeriodPrice, setNewPeriodPrice] = useState(300) const [activeTab, setActiveTab] = useState<'basic' | 'periods' | 'servers' | 'extra'>('basic') const handleSubmit = () => { const data: TariffCreateRequest | TariffUpdateRequest = { name, description: description || undefined, traffic_limit_gb: trafficLimitGb, device_limit: deviceLimit, device_price_kopeks: devicePriceKopeks > 0 ? devicePriceKopeks : undefined, max_device_limit: maxDeviceLimit > 0 ? maxDeviceLimit : undefined, tier_level: tierLevel, period_prices: periodPrices.filter(p => p.price_kopeks > 0), allowed_squads: selectedSquads, traffic_topup_enabled: trafficTopupEnabled, traffic_topup_packages: trafficTopupPackages, max_topup_traffic_gb: maxTopupTrafficGb, is_daily: false, daily_price_kopeks: 0, traffic_reset_mode: trafficResetMode, // Плавающий тариф custom_days_enabled: customDaysEnabled, price_per_day_kopeks: pricePerDayKopeks, min_days: minDays, max_days: maxDays, custom_traffic_enabled: customTrafficEnabled, traffic_price_per_gb_kopeks: trafficPricePerGbKopeks, min_traffic_gb: minTrafficGb, max_traffic_gb: maxTrafficGb, } onSave(data) } const toggleServer = (uuid: string) => { setSelectedSquads(prev => prev.includes(uuid) ? prev.filter(s => s !== uuid) : [...prev, uuid] ) } const addPeriod = () => { if (newPeriodDays > 0 && newPeriodPrice > 0) { // Проверяем, нет ли уже такого периода const exists = periodPrices.some(p => p.days === newPeriodDays) if (!exists) { setPeriodPrices(prev => [...prev, { days: newPeriodDays, price_kopeks: newPeriodPrice * 100 }].sort((a, b) => a.days - b.days)) setNewPeriodDays(30) setNewPeriodPrice(300) } } } const removePeriod = (days: number) => { setPeriodPrices(prev => prev.filter(p => p.days !== days)) } const updatePeriodPrice = (days: number, priceRubles: number) => { setPeriodPrices(prev => prev.map(p => p.days === days ? { ...p, price_kopeks: priceRubles * 100 } : p )) } return (
{/* Header */}

{isEdit ? 'Редактирование тарифа' : 'Новый периодный тариф'}

Оплата за период

{/* Tabs */}
{(['basic', 'periods', 'servers', 'extra'] as const).map(tab => ( ))}
{/* Content */}
{activeTab === 'basic' && (
{/* Name */}
setName(e.target.value)} className="w-full px-3 py-2 bg-dark-700 border border-dark-600 rounded-lg text-dark-100 focus:outline-none focus:border-accent-500" placeholder="Например: Стандарт" />
{/* Description */}