import { useParams, useNavigate } from 'react-router'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { partnerApi } from '../api/partners'; import { AdminBackButton } from '../components/admin'; import { useCurrency } from '../hooks/useCurrency'; // Status badge config — keys must match backend PartnerStatus enum values const statusConfig: Record = { approved: { labelKey: 'admin.partnerDetail.status.approved', color: 'text-success-400', bgColor: 'bg-success-500/20', }, pending: { labelKey: 'admin.partnerDetail.status.pending', color: 'text-warning-400', bgColor: 'bg-warning-500/20', }, rejected: { labelKey: 'admin.partnerDetail.status.rejected', color: 'text-error-400', bgColor: 'bg-error-500/20', }, none: { labelKey: 'admin.partnerDetail.status.none', color: 'text-dark-400', bgColor: 'bg-dark-600', }, }; const unknownStatus = { labelKey: 'admin.partnerDetail.status.none', color: 'text-dark-400', bgColor: 'bg-dark-600', }; export default function AdminPartnerDetail() { const { t } = useTranslation(); const { userId } = useParams<{ userId: string }>(); const navigate = useNavigate(); const queryClient = useQueryClient(); const { formatWithCurrency } = useCurrency(); const unassignMutation = useMutation({ mutationFn: (campaignId: number) => partnerApi.unassignCampaign(Number(userId), campaignId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['admin-partner-detail', userId] }); }, }); // Fetch partner detail const { data: partner, isLoading, error, } = useQuery({ queryKey: ['admin-partner-detail', userId], queryFn: () => partnerApi.getPartnerDetail(Number(userId)), enabled: !!userId, }); if (isLoading) { return (
); } if (error || !partner) { return (

{t('admin.partnerDetail.title')}

{t('admin.partnerDetail.loadError')}

); } const badge = statusConfig[partner.partner_status] || unknownStatus; return (
{/* Header */}

{partner.first_name || partner.username || `#${partner.user_id}`}

{t(badge.labelKey)}
{partner.username &&

@{partner.username}

}
{/* Referral Stats */}
{partner.total_referrals}
{t('admin.partnerDetail.stats.totalReferrals')}
{partner.paid_referrals}
{t('admin.partnerDetail.stats.paidReferrals')}
{partner.active_referrals}
{t('admin.partnerDetail.stats.activeReferrals')}
{partner.conversion_to_paid}%
{t('admin.partnerDetail.stats.conversionRate')}
{/* Earnings */}

{t('admin.partnerDetail.earnings.title')}

{t('admin.partnerDetail.earnings.allTime')}
{formatWithCurrency(partner.earnings_all_time / 100)}
{t('admin.partnerDetail.earnings.today')}
{formatWithCurrency(partner.earnings_today / 100)}
{t('admin.partnerDetail.earnings.week')}
{formatWithCurrency(partner.earnings_week / 100)}
{t('admin.partnerDetail.earnings.month')}
{formatWithCurrency(partner.earnings_month / 100)}
{/* Commission */}

{t('admin.partnerDetail.commission.title')}

{partner.commission_percent ?? 0}%
{/* Campaigns */}

{t('admin.partnerDetail.campaigns.title')}

{partner.campaigns.length === 0 ? (
{t('admin.partnerDetail.campaigns.noCampaigns')}
) : (
{partner.campaigns.map((campaign) => (
{campaign.name}
?start={campaign.start_parameter}
{campaign.is_active ? ( {t('admin.partnerDetail.campaigns.active')} ) : ( {t('admin.partnerDetail.campaigns.inactive')} )}
{campaign.registrations_count}
{t('admin.partnerDetail.campaigns.registrations', 'Регистрации')}
{campaign.referrals_count}
{t('admin.partnerDetail.campaigns.referrals', 'Рефералы')}
0 ? 'text-success-400' : 'text-dark-400'}`} > {formatWithCurrency(campaign.earnings_kopeks / 100)}
{t('admin.partnerDetail.campaigns.earnings', 'Доход')}
))}
)}
{/* Actions */}

{t('admin.partnerDetail.dangerZone.title')}

); }