'use client'; import { useEffect, useState, useCallback } from 'react'; import { Search, Plus, MoreVertical, Edit, Trash2, UserCheck, UserX, Crown, } from 'lucide-react'; import { fetchAdminUsers, createAdminUser, updateAdminUser, deleteAdminUser } from '@/lib/api'; import type { AdminUser, UserRole, UserTier } from '@/lib/types'; interface UserModalProps { user?: AdminUser; onClose: () => void; onSave: (data: { email: string; password?: string; displayName: string; role: UserRole; tier: UserTier }) => void; } function UserModal({ user, onClose, onSave }: UserModalProps) { const [email, setEmail] = useState(user?.email || ''); const [password, setPassword] = useState(''); const [displayName, setDisplayName] = useState(user?.displayName || ''); const [role, setRole] = useState(user?.role || 'user'); const [tier, setTier] = useState(user?.tier || 'free'); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); onSave({ email, password: password || undefined, displayName, role, tier }); }; return (

{user ? 'Редактировать пользователя' : 'Новый пользователь'}

setEmail(e.target.value)} className="w-full px-3 py-2 bg-base border border-border/50 rounded-lg text-primary focus:outline-none focus:border-primary" required />
{!user && (
setPassword(e.target.value)} className="w-full px-3 py-2 bg-base border border-border/50 rounded-lg text-primary focus:outline-none focus:border-primary" required={!user} />
)}
setDisplayName(e.target.value)} className="w-full px-3 py-2 bg-base border border-border/50 rounded-lg text-primary focus:outline-none focus:border-primary" required />
); } export default function AdminUsersPage() { const [users, setUsers] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [search, setSearch] = useState(''); const [loading, setLoading] = useState(true); const [modalUser, setModalUser] = useState(undefined); const [activeMenu, setActiveMenu] = useState(null); const loadUsers = useCallback(async () => { setLoading(true); try { const data = await fetchAdminUsers(page, 20, search || undefined); setUsers(data.users); setTotal(data.total); } catch (err) { console.error('Failed to load users:', err); } finally { setLoading(false); } }, [page, search]); useEffect(() => { loadUsers(); }, [loadUsers]); const handleSave = async (data: { email: string; password?: string; displayName: string; role: UserRole; tier: UserTier }) => { try { if (modalUser) { await updateAdminUser(modalUser.id, data); } else { await createAdminUser({ ...data, password: data.password || '' }); } setModalUser(undefined); loadUsers(); } catch (err) { console.error('Failed to save user:', err); } }; const handleDelete = async (id: string) => { if (!confirm('Удалить пользователя?')) return; try { await deleteAdminUser(id); loadUsers(); } catch (err) { console.error('Failed to delete user:', err); } }; const handleToggleActive = async (user: AdminUser) => { try { await updateAdminUser(user.id, { isActive: !user.isActive }); loadUsers(); } catch (err) { console.error('Failed to toggle user:', err); } }; const totalPages = Math.ceil(total / 20); return (

Пользователи

Управление пользователями платформы

{ setSearch(e.target.value); setPage(1); }} className="w-full pl-10 pr-4 py-2 bg-base border border-border/50 rounded-lg text-primary placeholder:text-muted focus:outline-none focus:border-primary" />
{loading ? (
) : ( <>
{users.map((user) => ( ))}
Пользователь Роль Тариф Статус Создан
{user.avatarUrl ? ( ) : ( {user.displayName.charAt(0).toUpperCase()} )}

{user.displayName}

{user.email}

{user.role === 'admin' && } {user.role === 'admin' ? 'Админ' : 'Пользователь'} {user.tier.toUpperCase()} {user.isActive ? : } {user.isActive ? 'Активен' : 'Неактивен'} {new Date(user.createdAt).toLocaleDateString('ru-RU')}
{activeMenu === user.id && (
)}
{totalPages > 1 && (

Показано {users.length} из {total}

{page} / {totalPages}
)} )}
{modalUser !== undefined && ( setModalUser(undefined)} onSave={handleSave} /> )}
); }