import { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { adminPaymentMethodsApi } from '../api/adminPaymentMethods'; import type { PromoGroupSimple } from '../types'; import { useBackButton } from '../platform/hooks/useBackButton'; import { usePlatform } from '../platform/hooks/usePlatform'; const BackIcon = () => ( ); const METHOD_ICONS: Record = { telegram_stars: '⭐', tribute: '🎁', cryptobot: '🪙', heleket: '⚡', yookassa: '🏦', mulenpay: '💳', pal24: '💸', platega: '💰', wata: '💧', freekassa: '💵', cloudpayments: '☁️', kassa_ai: '🏦', }; const METHOD_LABELS: Record = { telegram_stars: 'Telegram Stars', tribute: 'Tribute', cryptobot: 'CryptoBot', heleket: 'Heleket', yookassa: 'YooKassa', mulenpay: 'MulenPay', pal24: 'PayPalych', platega: 'Platega', wata: 'WATA', freekassa: 'Freekassa', cloudpayments: 'CloudPayments', kassa_ai: 'Kassa AI', }; const CheckIcon = () => ( ); const SaveIcon = () => ( ); export default function AdminPaymentMethodEdit() { const { t } = useTranslation(); const { methodId } = useParams<{ methodId: string }>(); const navigate = useNavigate(); const queryClient = useQueryClient(); const { capabilities } = usePlatform(); // Use native Telegram back button in Mini App useBackButton(() => navigate('/admin/payment-methods', { replace: true })); // Fetch payment methods const { data: methods, isLoading } = useQuery({ queryKey: ['admin-payment-methods'], queryFn: adminPaymentMethodsApi.getAll, }); // Fetch promo groups const { data: promoGroups = [] } = useQuery({ queryKey: ['admin-payment-methods-promo-groups'], queryFn: adminPaymentMethodsApi.getPromoGroups, }); const config = methods?.find((m) => m.method_id === methodId); // Local state for editing const [isEnabled, setIsEnabled] = useState(false); const [customName, setCustomName] = useState(''); const [subOptions, setSubOptions] = useState>({}); const [minAmount, setMinAmount] = useState(''); const [maxAmount, setMaxAmount] = useState(''); const [userTypeFilter, setUserTypeFilter] = useState<'all' | 'telegram' | 'email'>('all'); const [firstTopupFilter, setFirstTopupFilter] = useState<'any' | 'yes' | 'no'>('any'); const [promoGroupFilterMode, setPromoGroupFilterMode] = useState<'all' | 'selected'>('all'); const [selectedPromoGroupIds, setSelectedPromoGroupIds] = useState([]); // Initialize state when config loads useEffect(() => { if (config) { setIsEnabled(config.is_enabled); setCustomName(config.display_name || ''); setSubOptions(config.sub_options || {}); setMinAmount(config.min_amount_kopeks?.toString() || ''); setMaxAmount(config.max_amount_kopeks?.toString() || ''); setUserTypeFilter(config.user_type_filter); setFirstTopupFilter(config.first_topup_filter); setPromoGroupFilterMode(config.promo_group_filter_mode); setSelectedPromoGroupIds(config.allowed_promo_group_ids); } }, [config]); // Update method mutation const updateMethodMutation = useMutation({ mutationFn: (data: Record) => adminPaymentMethodsApi.update(methodId!, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['admin-payment-methods'] }); navigate('/admin/payment-methods'); }, }); const handleSave = () => { if (!config) return; const data: Record = { is_enabled: isEnabled, user_type_filter: userTypeFilter, first_topup_filter: firstTopupFilter, promo_group_filter_mode: promoGroupFilterMode, allowed_promo_group_ids: promoGroupFilterMode === 'selected' ? selectedPromoGroupIds : [], }; // Display name if (customName.trim()) { data.display_name = customName.trim(); } else { data.reset_display_name = true; } // Sub-options if (config.available_sub_options) { data.sub_options = subOptions; } // Amounts if (minAmount.trim()) { data.min_amount_kopeks = parseInt(minAmount, 10) || null; } else { data.reset_min_amount = true; } if (maxAmount.trim()) { data.max_amount_kopeks = parseInt(maxAmount, 10) || null; } else { data.reset_max_amount = true; } updateMethodMutation.mutate(data); }; const togglePromoGroup = (id: number) => { setSelectedPromoGroupIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id], ); }; if (isLoading) { return (
); } if (!config) { return (
{/* Show back button only on web, not in Telegram Mini App */} {!capabilities.hasBackButton && ( )}

{t('admin.paymentMethods.notFound', 'Payment method not found')}

); } const displayName = config.display_name || config.default_display_name; const icon = METHOD_ICONS[config.method_id] || '💳'; return (
{/* Header */}
{/* Show back button only on web, not in Telegram Mini App */} {!capabilities.hasBackButton && ( )}
{icon}

{displayName}

{METHOD_LABELS[config.method_id] || config.method_id}

{/* Form */}
{/* Enable toggle */}
{t('admin.paymentMethods.methodEnabled')}
{!config.is_provider_configured && (
{t('admin.paymentMethods.providerNotConfigured')}
)}
{/* Display name */}
setCustomName(e.target.value)} placeholder={config.default_display_name} className="input" />

{t('admin.paymentMethods.displayNameHint')}: {config.default_display_name}

{/* Sub-options */} {config.available_sub_options && config.available_sub_options.length > 0 && (
{config.available_sub_options.map((opt) => { const enabled = subOptions[opt.id] !== false; return ( ); })}
)} {/* Min/Max amounts */}
setMinAmount(e.target.value)} placeholder={config.default_min_amount_kopeks.toString()} className="input" />
setMaxAmount(e.target.value)} placeholder={config.default_max_amount_kopeks.toString()} className="input" />
{/* Display conditions */}

{t('admin.paymentMethods.conditions')}

{/* User type filter */}
{(['all', 'telegram', 'email'] as const).map((val) => ( ))}
{/* First topup filter */}
{(['any', 'yes', 'no'] as const).map((val) => ( ))}
{/* Promo groups filter */}
{(['all', 'selected'] as const).map((val) => ( ))}
{promoGroupFilterMode === 'selected' && (
{promoGroups.length === 0 ? (

{t('admin.paymentMethods.noPromoGroups')}

) : ( promoGroups.map((group) => { const selected = selectedPromoGroupIds.includes(group.id); return ( ); }) )}
)}
{/* Actions */}
); }