import { useState, useEffect } from 'react' import { adminApi } from '../../api/client' import { useToast } from '../shared/Toast' import { Key, Trash2, User, Loader2 } from 'lucide-react' import { useTranslation } from '../../i18n' interface AdminMcpToken { id: number name: string token_prefix: string created_at: string last_used_at: string | null user_id: number username: string } export default function AdminMcpTokensPanel() { const [tokens, setTokens] = useState([]) const [isLoading, setIsLoading] = useState(true) const [deleteConfirmId, setDeleteConfirmId] = useState(null) const toast = useToast() const { t, locale } = useTranslation() useEffect(() => { setIsLoading(true) adminApi.mcpTokens() .then(d => setTokens(d.tokens || [])) .catch(() => toast.error(t('admin.mcpTokens.loadError'))) .finally(() => setIsLoading(false)) }, []) const handleDelete = async (id: number) => { try { await adminApi.deleteMcpToken(id) setTokens(prev => prev.filter(tk => tk.id !== id)) setDeleteConfirmId(null) toast.success(t('admin.mcpTokens.deleteSuccess')) } catch { toast.error(t('admin.mcpTokens.deleteError')) } } return (

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

{t('admin.mcpTokens.subtitle')}

{isLoading ? (
) : tokens.length === 0 ? (

{t('admin.mcpTokens.empty')}

) : ( <>
{t('admin.mcpTokens.tokenName')} {t('admin.mcpTokens.owner')} {t('admin.mcpTokens.created')} {t('admin.mcpTokens.lastUsed')}
{tokens.map((token, i) => (

{token.name}

{token.token_prefix}...

{token.username}
{new Date(token.created_at).toLocaleDateString(locale)} {token.last_used_at ? new Date(token.last_used_at).toLocaleDateString(locale) : t('admin.mcpTokens.never')}
))} )}
{deleteConfirmId !== null && (
{ if (e.target === e.currentTarget) setDeleteConfirmId(null) }}>

{t('admin.mcpTokens.deleteTitle')}

{t('admin.mcpTokens.deleteMessage')}

)}
) }