/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { useCallback, useEffect, useState } from 'react' import { Loader2 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { formatQuota, formatCompactNumber } from '@/lib/format' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Label } from '@/components/ui/label' import { getUserInfo } from '../../api' import type { UserInfo } from '../../types' interface UserInfoDialogProps { userId: number | null open: boolean onOpenChange: (open: boolean) => void } export function UserInfoDialog({ userId, open, onOpenChange, }: UserInfoDialogProps) { const { t } = useTranslation() const [userInfo, setUserInfo] = useState(null) const [isLoading, setIsLoading] = useState(false) const fetchUserInfo = useCallback( async (id: number) => { setIsLoading(true) try { const result = await getUserInfo(id) if (result.success) { setUserInfo(result.data || null) } else { toast.error(result.message || t('Failed to fetch user information')) } } catch (error) { // eslint-disable-next-line no-console console.error('Failed to fetch user info:', error) toast.error(t('Failed to fetch user information')) } finally { setIsLoading(false) } }, [t] ) useEffect(() => { if (open && userId) { fetchUserInfo(userId) } }, [open, userId, fetchUserInfo]) const InfoItem = ({ label, value, }: { label: string value: string | number }) => (
{value}
) return ( {t('User Information')} {t( 'View detailed information about this user including balance, usage statistics, and invitation details.' )} {isLoading ? (
) : userInfo ? (
{/* Basic Info */}
{userInfo.display_name && ( )}
{/* Balance Info */}
{/* Statistics */}
{userInfo.group && ( )}
{/* Invitation Info */} {(userInfo.aff_code || userInfo.aff_count !== undefined || (userInfo.aff_quota !== undefined && userInfo.aff_quota > 0)) && ( <>
{userInfo.aff_code && ( )} {userInfo.aff_count !== undefined && ( )}
{userInfo.aff_quota !== undefined && userInfo.aff_quota > 0 && ( )} )} {/* Remark */} {userInfo.remark && (
{userInfo.remark}
)}
) : (
{t('No user information available')}
)}
) }