'use client'; import { useState, useEffect } from 'react'; import { adminUserApi, AdminUser } from '@/lib/api'; type TabType = 'active' | 'deleted'; interface DeletedUser extends AdminUser { deleted_at?: string; withdrawal_reason?: string; } export default function AdminUsersPage() { const [activeTab, setActiveTab] = useState('active'); // Active users state const [users, setUsers] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [pageSize] = useState(20); const [search, setSearch] = useState(''); const [filterDealer, setFilterDealer] = useState(undefined); const [loading, setLoading] = useState(true); // Deleted users state const [deletedUsers, setDeletedUsers] = useState([]); const [deletedTotal, setDeletedTotal] = useState(0); const [deletedPage, setDeletedPage] = useState(1); const [deletedSearch, setDeletedSearch] = useState(''); const [deletedLoading, setDeletedLoading] = useState(true); // Modal state const [selectedUser, setSelectedUser] = useState(null); const [showCCModal, setShowCCModal] = useState(false); const [ccAmount, setCCAmount] = useState(''); const [ccReason, setCCReason] = useState(''); // Delete modal state const [showDeleteModal, setShowDeleteModal] = useState(false); const [deleteUser, setDeleteUser] = useState(null); const [deleteLoading, setDeleteLoading] = useState(false); const [hardDelete, setHardDelete] = useState(false); // Restore state const [restoreLoading, setRestoreLoading] = useState(null); useEffect(() => { if (activeTab === 'active') { loadUsers(); } else { loadDeletedUsers(); } }, [page, filterDealer, activeTab, deletedPage]); const loadUsers = async () => { try { setLoading(true); const response = await adminUserApi.getUsers({ page, page_size: pageSize, search: search || undefined, is_dealer: filterDealer, }); setUsers(response.users); setTotal(response.total); } catch (error) { console.error('Failed to load users:', error); } finally { setLoading(false); } }; const loadDeletedUsers = async () => { try { setDeletedLoading(true); const response = await adminUserApi.getDeletedUsers({ page: deletedPage, page_size: pageSize, search: deletedSearch || undefined, }); setDeletedUsers(response.users); setDeletedTotal(response.total); } catch (error) { console.error('Failed to load deleted users:', error); } finally { setDeletedLoading(false); } }; const handleSearch = (e: React.FormEvent) => { e.preventDefault(); setPage(1); loadUsers(); }; const handleDeletedSearch = (e: React.FormEvent) => { e.preventDefault(); setDeletedPage(1); loadDeletedUsers(); }; const handleAdjustCC = async () => { if (!selectedUser || !ccAmount) return; try { const result = await adminUserApi.adjustCC( selectedUser.id, parseFloat(ccAmount), ccReason || 'Admin adjustment' ); alert(`CC adjusted! New balance: ${result.new_balance}`); setShowCCModal(false); setCCAmount(''); setCCReason(''); loadUsers(); } catch (error) { console.error('Failed to adjust CC:', error); alert('Failed to adjust CC'); } }; const handleDeleteUser = async () => { if (!deleteUser) return; setDeleteLoading(true); try { const result = await adminUserApi.deleteUser(deleteUser.id, hardDelete); alert(result.message); setShowDeleteModal(false); setDeleteUser(null); setHardDelete(false); loadUsers(); loadDeletedUsers(); } catch (error: any) { console.error('Failed to delete user:', error); alert(error.response?.data?.detail || 'Failed to delete user'); } finally { setDeleteLoading(false); } }; const handleRestoreUser = async (userId: number) => { if (!confirm('Are you sure you want to restore this user?')) return; setRestoreLoading(userId); try { const result = await adminUserApi.restoreUser(userId); alert(result.message); loadDeletedUsers(); loadUsers(); } catch (error: any) { console.error('Failed to restore user:', error); alert(error.response?.data?.detail || 'Failed to restore user'); } finally { setRestoreLoading(null); } }; const handlePermanentDelete = async (user: DeletedUser) => { if (!confirm(`Are you sure you want to PERMANENTLY delete ${user.email}? This cannot be undone!`)) return; setRestoreLoading(user.id); try { const result = await adminUserApi.deleteUser(user.id, true); alert(result.message); loadDeletedUsers(); } catch (error: any) { console.error('Failed to permanently delete user:', error); alert(error.response?.data?.detail || 'Failed to delete user'); } finally { setRestoreLoading(null); } }; const formatDate = (dateStr?: string) => { if (!dateStr) return '-'; return new Date(dateStr).toLocaleDateString('ko-KR', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', }); }; const totalPages = Math.ceil(total / pageSize); const deletedTotalPages = Math.ceil(deletedTotal / pageSize); return (

User Management

{/* Tabs */}
{/* Active Users Tab */} {activeTab === 'active' && ( <> {/* Search & Filter */}
setSearch(e.target.value)} placeholder="Search by email, name, or phone..." className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500" />
{/* Users Table */}
{loading ? (
) : users.length === 0 ? (
No users found
) : (
{users.map((user) => ( ))}
ID Email Name Phone Country CC Balance Type Referral Promo Interest Registered Actions
{user.id} {user.email} {user.name || '-'} {user.phone || '-'} {user.country || '-'} {user.cc_balance.toLocaleString()} CC {user.is_dealer ? ( Dealer ) : ( User )}
Code: {user.referral_code || '-'}
{user.referred_by &&
By: {user.referred_by}
}
{user.promo_preferred_maker || user.promo_preferred_model ? (
{user.promo_preferred_maker || '-'} / {user.promo_preferred_model || '-'}
{user.promo_email_enabled && ( Email Alert ON )}
) : ( - )}
{formatDate(user.created_at)}
)} {/* Pagination */} {totalPages > 1 && (
Page {page} of {totalPages}
)}
)} {/* Deleted Users Tab */} {activeTab === 'deleted' && ( <> {/* Search */}
setDeletedSearch(e.target.value)} placeholder="Search deleted users by email, name, or phone..." className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500" />
{/* Deleted Users Table */}
{deletedLoading ? (
) : deletedUsers.length === 0 ? (
No deleted users found
) : (
{deletedUsers.map((user) => ( ))}
ID Email Name Phone CC Balance Deleted At Reason Actions
{user.id} {user.email} {user.name || '-'} {user.phone || '-'} {user.cc_balance.toLocaleString()} CC {formatDate(user.deleted_at)} {user.withdrawal_reason || '-'}
)} {/* Pagination */} {deletedTotalPages > 1 && (
Page {deletedPage} of {deletedTotalPages}
)}
)} {/* CC Adjustment Modal */} {showCCModal && selectedUser && (

Adjust CC Balance

User: {selectedUser.email}

Current Balance: {selectedUser.cc_balance.toLocaleString()} CC

setCCAmount(e.target.value)} placeholder="e.g., 100 or -50" className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500" />
setCCReason(e.target.value)} placeholder="e.g., Bonus credit, Refund, etc." className="w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500" />
)} {/* Delete User Modal */} {showDeleteModal && deleteUser && (

Delete User

Are you sure you want to delete this user?

Email: {deleteUser.email}

Name: {deleteUser.name || '-'}

CC Balance: {deleteUser.cc_balance.toLocaleString()} CC

{hardDelete ? 'User and all related data will be permanently deleted from the database.' : 'User will be soft deleted (can be restored from Deleted Users tab).'}

)}
); }