diff --git a/src/pages/TopUpAgent.jsx b/src/pages/TopUpAgent.jsx index 16114338..d6629bca 100644 --- a/src/pages/TopUpAgent.jsx +++ b/src/pages/TopUpAgent.jsx @@ -1,7 +1,7 @@ import React, { useEffect, useMemo, useState, useCallback } from 'react'; import DataTable from '../components/DataTable'; -import { topUpAgentAPI, cityAPI, generalAPI } from '../services/api'; -import { Plus, Search, Pencil, Trash2, Power, DollarSign, Wallet, X } from 'lucide-react'; +import { topUpAgentAPI, cityAPI, generalAPI, currencyAPI } from '../services/api'; +import { Plus, Search, Pencil, Trash2, Power, DollarSign, Wallet, X, Users } from 'lucide-react'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { getErrorMessage, getSuccessMessage } from '../utils/errorHandler'; @@ -40,6 +40,16 @@ const TopUpAgent = () => { const [walletData, setWalletData] = useState(null); const [walletTransactions, setWalletTransactions] = useState([]); const [depositForm, setDepositForm] = useState({ amount: 0, currencyCode: '' }); + + // Admin management states + const [selectedAgentForAdmin, setSelectedAgentForAdmin] = useState(null); + const [isAdminModalOpen, setIsAdminModalOpen] = useState(false); + const [agentAdmins, setAgentAdmins] = useState([]); + const [adminForm, setAdminForm] = useState({ + email: '', + }); + const [searchedUser, setSearchedUser] = useState(null); + const [searchingUser, setSearchingUser] = useState(false); // دریافت شهرها و ارزها useEffect(() => { @@ -54,7 +64,7 @@ const TopUpAgent = () => { const fetchCurrencies = async () => { try { - const list = await generalAPI.getCurrencies(); + const list = await currencyAPI.list({ pageSize: 1000 }); setCurrencies(Array.isArray(list) ? list : []); } catch (err) { console.error('Failed to load currencies:', err); @@ -272,6 +282,77 @@ const TopUpAgent = () => { } }; + // باز کردن modal مدیریت Admin + const openAdminModal = async (agent) => { + setSelectedAgentForAdmin(agent); + setSearchedUser(null); + setAdminForm({ email: '' }); + try { + const list = await topUpAgentAPI.getAdmins(agent.id); + setAgentAdmins(Array.isArray(list) ? list : []); + } catch (err) { + toast.error(getErrorMessage(err)); + } + setIsAdminModalOpen(true); + }; + + // جستجوی کاربر با ایمیل + const handleSearchUser = async () => { + if (!adminForm.email?.trim()) { + toast.error('Please enter an email address'); + return; + } + try { + setSearchingUser(true); + const users = await generalAPI.searchUsersByEmail(adminForm.email); + if (users && users.length > 0) { + setSearchedUser(users[0]); // استفاده از اولین نتیجه + toast.success('User found'); + } else { + setSearchedUser(null); + toast.error('No user found with this email'); + } + } catch (err) { + setSearchedUser(null); + toast.error(getErrorMessage(err) || 'Failed to search user'); + } finally { + setSearchingUser(false); + } + }; + + // اضافه کردن Admin + const handleAddAdmin = async () => { + if (!searchedUser?.id) { + toast.error('Please search and select a user first'); + return; + } + try { + await topUpAgentAPI.addAdmin(selectedAgentForAdmin.id, searchedUser.id); + toast.success('Admin added successfully'); + const list = await topUpAgentAPI.getAdmins(selectedAgentForAdmin.id); + setAgentAdmins(Array.isArray(list) ? list : []); + setAdminForm({ email: '' }); + setSearchedUser(null); + } catch (err) { + toast.error(getErrorMessage(err)); + } + }; + + // حذف Admin + const handleDeleteAdmin = async (admin) => { + if (!window.confirm(`Are you sure you want to remove admin "${admin.email}"?`)) { + return; + } + try { + await topUpAgentAPI.removeAdmin(selectedAgentForAdmin.id, admin.id); + toast.success('Admin removed successfully'); + const list = await topUpAgentAPI.getAdmins(selectedAgentForAdmin.id); + setAgentAdmins(Array.isArray(list) ? list : []); + } catch (err) { + toast.error(getErrorMessage(err)); + } + }; + // Reset filters const handleResetFilters = () => { setFilters({ @@ -334,6 +415,12 @@ const TopUpAgent = () => { > Wallet + openAdminModal(row)} + className="inline-flex items-center px-2 py-1 text-xs rounded-md bg-teal-100 text-teal-700 hover:opacity-90" + > + Admins + handleDelete(row)} className="inline-flex items-center px-2 py-1 text-xs rounded-md bg-red-100 text-red-700 hover:opacity-90" @@ -716,6 +803,112 @@ const TopUpAgent = () => { > )} + + {/* Admin Management Modal */} + {isAdminModalOpen && selectedAgentForAdmin && ( + <> + setIsAdminModalOpen(false)} /> + + + + + Manage Admins - {selectedAgentForAdmin.name} + + setIsAdminModalOpen(false)} className="text-gray-400 hover:text-gray-600"> + + + + + + + Search User by Email * + + { + setAdminForm({ email: e.target.value }); + setSearchedUser(null); + }} + onKeyPress={(e) => { + if (e.key === 'Enter') { + e.preventDefault(); + handleSearchUser(); + } + }} + className="flex-1 p-2 border rounded-lg" + placeholder="Enter user email..." + /> + + {searchingUser ? 'Searching...' : 'Search'} + + + + + {searchedUser && ( + + User Found: + + Email: {searchedUser.email || '—'} + {searchedUser.firstName && ( + Name: {searchedUser.firstName} {searchedUser.lastName || ''} + )} + {searchedUser.phoneNumber && ( + Phone: {searchedUser.phoneNumber} + )} + + + Add as Admin + + + )} + + + + Current Admins + + {agentAdmins.length === 0 ? ( + No admins added + ) : ( + agentAdmins.map((admin) => ( + + + {admin.email} + {admin.firstName && admin.lastName && ( + + ({admin.firstName} {admin.lastName}) + + )} + {admin.phoneNumber && ( + + - {admin.phoneNumber} + + )} + + handleDeleteAdmin(admin)} + className="text-red-600 hover:text-red-800" + > + + + + )) + )} + + + + + > + )} ); }; diff --git a/src/services/topUpAgentAPI.js b/src/services/topUpAgentAPI.js index d7bb280e..4d955b7f 100644 --- a/src/services/topUpAgentAPI.js +++ b/src/services/topUpAgentAPI.js @@ -205,5 +205,62 @@ export const topUpAgentAPI = { }); return res?.data?.data?.data || []; }, + + // POST /api/v1/TopUpAgent/{topUpAgentId}/Admin + async addAdmin(topUpAgentId, userId) { + try { + const payload = { + userId: String(userId || '').trim(), + }; + const res = await api.post(`/api/v1/TopUpAgent/${encodeURIComponent(topUpAgentId)}/Admin`, payload, { + skipAuthRedirect: true + }); + return res?.data?.data || res?.data; + } catch (error) { + console.error('🔴 TopUpAgent API - addAdmin error:', error); + throw error; + } + }, + + // GET /api/v1/TopUpAgent/{topUpAgentId}/Admin + async getAdmins(topUpAgentId, params = {}) { + try { + const { currentPage = 1, pageSize = 10, ...otherParams } = params; + const res = await api.get(`/api/v1/TopUpAgent/${encodeURIComponent(topUpAgentId)}/Admin`, { + params: { currentPage, pageSize, ...otherParams }, + skipAuthRedirect: true + }); + // بررسی ساختار response + if (res?.data?.data?.data) { + return Array.isArray(res.data.data.data) ? res.data.data.data : []; + } + if (res?.data?.data) { + return Array.isArray(res.data.data) ? res.data.data : []; + } + if (res?.data) { + return Array.isArray(res.data) ? res.data : []; + } + return []; + } catch (error) { + console.error('🔴 TopUpAgent API - getAdmins error:', error); + throw error; + } + }, + + // DELETE /api/v1/TopUpAgent/{topUpAgentId}/Admin + async removeAdmin(topUpAgentId, adminId) { + try { + const url = `/api/v1/TopUpAgent/${encodeURIComponent(topUpAgentId)}/Admin`; + const config = { + skipAuthRedirect: true, + params: adminId ? { adminId } : {} + }; + const res = await api.delete(url, config); + return res?.data; + } catch (error) { + console.error('🔴 TopUpAgent API - removeAdmin error:', error); + throw error; + } + }, };
No admins added