feat(Issuer): add admin selection page for issuer

This commit is contained in:
ghazall-ag
2025-12-15 14:04:15 +03:30
parent fd2b6537cd
commit ecf6574e5d
5 changed files with 1174 additions and 257 deletions

View File

@@ -16,13 +16,13 @@ import {
const Sidebar = ({ isOpen, onToggle }) => {
const navigation = [
{ name: 'Dashboard', href: '/', icon: LayoutDashboard },
{ name: 'Transactions', href: '/transactions', icon: CreditCard },
// { name: 'Transactions', href: '/transactions', icon: CreditCard },
{ name: 'Roles', href: '/roles', icon: Shield },
{ name: 'Users', href: '/users', icon: Users },
{ name: 'Currency', href: '/currency', icon: DollarSign },
{ name: 'Location', href: '/location', icon: MapPin },
{ name: 'Issuer', href: '/issuer', icon: Building2 },
{ name: 'Settings', href: '/settings', icon: Settings },
// { name: 'Settings', href: '/settings', icon: Settings },
];
return (

File diff suppressed because it is too large Load Diff

View File

@@ -117,12 +117,10 @@ const Location = () => {
}
}, []);
// دریافت کشورها برای dropdown ها
// دریافت کشورها - لود اولیه (برای country tab و dropdown ها)
useEffect(() => {
if (activeTab === 'province' || activeTab === 'city') {
fetchCountries();
}
}, [activeTab, fetchCountries]);
fetchCountries();
}, [fetchCountries]);
// دریافت provinces برای province tab - وقتی tab تغییر می‌کند یا فیلتر country تغییر می‌کند
useEffect(() => {

View File

@@ -39,5 +39,20 @@ export const generalAPI = {
throw error;
}
},
// GET /api/v1/General/SearchUsersByEmail
async searchUsersByEmail(email) {
try {
const res = await api.get('/api/v1/General/SearchUsersByEmail', {
params: { email: email || '' },
skipAuthRedirect: true
});
// پاسخ به صورت { data: [...], statusCode: 200, ... } است
return res?.data?.data || [];
} catch (error) {
console.error('🔴 General API - searchUsersByEmail error:', error);
throw error;
}
},
};

View File

@@ -69,8 +69,8 @@ export const issuerAPI = {
// Validate GUID format (basic check)
const guidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (guidPattern.test(issuer.cityId)) {
payload.cityId = issuer.cityId;
} else {
payload.cityId = issuer.cityId;
} else {
console.warn('⚠️ Invalid cityId GUID format:', issuer.cityId);
}
}
@@ -79,9 +79,9 @@ export const issuerAPI = {
console.log('🔵 Issuer Create Payload (original):', issuer);
try {
const res = await api.post('/api/v1/Issuer', payload, { skipAuthRedirect: true });
const res = await api.post('/api/v1/Issuer', payload, { skipAuthRedirect: true });
console.log('🟢 Issuer Create Response:', res?.data);
return res?.data;
return res?.data;
} catch (err) {
console.error('🔴 Issuer Create Error:', {
status: err?.response?.status,
@@ -131,8 +131,8 @@ export const issuerAPI = {
// Validate GUID format (basic check)
const guidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (guidPattern.test(issuer.cityId)) {
payload.cityId = issuer.cityId;
} else {
payload.cityId = issuer.cityId;
} else {
console.warn('⚠️ Invalid cityId GUID format:', issuer.cityId);
}
}
@@ -140,11 +140,11 @@ export const issuerAPI = {
console.log('🔵 Issuer Update Payload:', JSON.stringify(payload, null, 2));
try {
const res = await api.put(`/api/v1/Issuer/${encodeURIComponent(id)}`, payload, {
skipAuthRedirect: true
});
const res = await api.put(`/api/v1/Issuer/${encodeURIComponent(id)}`, payload, {
skipAuthRedirect: true
});
console.log('🟢 Issuer Update Response:', res?.data);
return res?.data;
return res?.data;
} catch (err) {
console.error('🔴 Issuer Update Error:', {
status: err?.response?.status,
@@ -213,7 +213,7 @@ export const issuerAPI = {
}
if (typeof cap === 'object' && cap !== null) {
const capabilityValue = cap.capability || cap.capabilityName || '';
return capabilityValue && String(capabilityValue).trim() !== '';
return capabilityValue && String(capabilityValue).trim() !== '';
}
return false;
})
@@ -276,14 +276,15 @@ export const issuerAPI = {
},
// GET /api/v1/Issuer/{issuerId}/AllowedCurrencies
// Response: { data: [{ currencyCode, currencyEnglishName, allowed }, ...], statusCode, ... }
async getAllowedCurrencies(issuerId) {
try {
console.log('🔵 Getting allowed currencies for issuer:', issuerId);
const res = await api.get(`/api/v1/Issuer/${encodeURIComponent(issuerId)}/AllowedCurrencies`, {
skipAuthRedirect: true
});
// Response is a direct array: [{code, name, nativeName, symbol, numericCode, decimalPlaces, allowed}, ...]
// Or wrapped: { data: [...] }
// Response structure: { data: [{ currencyCode, currencyEnglishName, allowed }, ...], statusCode, ... }
// Or direct array: [{ currencyCode, currencyEnglishName, allowed }, ...]
const currencies = Array.isArray(res?.data) ? res.data : (res?.data?.data || []);
console.log('🟢 Allowed Currencies from API:', currencies);
return currencies;
@@ -369,6 +370,213 @@ export const issuerAPI = {
}
throw err;
}
},
// ========== TopUpAgentManagement API ==========
// GET /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement
async getTopUpAgentManagement(issuerId) {
try {
const res = await api.get(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement`, {
skipAuthRedirect: true
});
return res?.data?.data || { maxAgents: 0, isActive: false };
} catch (error) {
console.error('🔴 TopUpAgentManagement GET error:', error);
throw error;
}
},
// PUT /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement
async updateTopUpAgentManagement(issuerId, maxAgents) {
try {
const payload = { maxAgents: Number(maxAgents) || 0 };
const res = await api.put(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement`, payload, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 TopUpAgentManagement PUT error:', error);
throw error;
}
},
// GET /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency
async getTopUpAgentManagementCurrencies(issuerId) {
try {
const res = await api.get(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency`, {
skipAuthRedirect: true
});
return Array.isArray(res?.data?.data) ? res?.data?.data : [];
} catch (error) {
console.error('🔴 TopUpAgentManagement Currencies GET error:', error);
throw error;
}
},
// GET /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}
async getTopUpAgentManagementCurrency(issuerId, currencyCode) {
try {
const res = await api.get(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}`, {
skipAuthRedirect: true
});
return res?.data?.data || null;
} catch (error) {
console.error('🔴 TopUpAgentManagement Currency GET error:', error);
throw error;
}
},
// POST /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}
async createTopUpAgentManagementCurrency(issuerId, currencyCode, currencyData) {
try {
const payload = {
voucherGeneratingFee: {
percent: Number(currencyData.voucherGeneratingFee?.percent) || 0,
fixed: Number(currencyData.voucherGeneratingFee?.fixed) || 0,
minAmount: Number(currencyData.voucherGeneratingFee?.minAmount) || 0,
maxAmount: Number(currencyData.voucherGeneratingFee?.maxAmount) || 0
},
agentMarketingFee: {
percent: Number(currencyData.agentMarketingFee?.percent) || 0,
fixed: Number(currencyData.agentMarketingFee?.fixed) || 0,
minAmount: Number(currencyData.agentMarketingFee?.minAmount) || 0,
maxAmount: Number(currencyData.agentMarketingFee?.maxAmount) || 0
},
agentWalletMaxBalanceLimit: {
min: Number(currencyData.agentWalletMaxBalanceLimit?.min) || 0,
max: Number(currencyData.agentWalletMaxBalanceLimit?.max) || 0
},
agentWalletDepositMonthlyLimit: {
amount: Number(currencyData.agentWalletDepositMonthlyLimit?.amount) || 0
}
};
const res = await api.post(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}`, payload, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 TopUpAgentManagement Currency POST error:', error);
throw error;
}
},
// PUT /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}
async updateTopUpAgentManagementCurrency(issuerId, currencyCode, currencyData) {
try {
const payload = {
voucherGeneratingFee: {
percent: Number(currencyData.voucherGeneratingFee?.percent) || 0,
fixed: Number(currencyData.voucherGeneratingFee?.fixed) || 0,
minAmount: Number(currencyData.voucherGeneratingFee?.minAmount) || 0,
maxAmount: Number(currencyData.voucherGeneratingFee?.maxAmount) || 0
},
agentMarketingFee: {
percent: Number(currencyData.agentMarketingFee?.percent) || 0,
fixed: Number(currencyData.agentMarketingFee?.fixed) || 0,
minAmount: Number(currencyData.agentMarketingFee?.minAmount) || 0,
maxAmount: Number(currencyData.agentMarketingFee?.maxAmount) || 0
},
agentWalletMaxBalanceLimit: {
min: Number(currencyData.agentWalletMaxBalanceLimit?.min) || 0,
max: Number(currencyData.agentWalletMaxBalanceLimit?.max) || 0
},
agentWalletDepositMonthlyLimit: {
amount: Number(currencyData.agentWalletDepositMonthlyLimit?.amount) || 0
}
};
const res = await api.put(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}`, payload, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 TopUpAgentManagement Currency PUT error:', error);
throw error;
}
},
// DELETE /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}
async deleteTopUpAgentManagementCurrency(issuerId, currencyCode) {
try {
const res = await api.delete(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}`, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 TopUpAgentManagement Currency DELETE error:', error);
throw error;
}
},
// ========== TopUpAgentManagement Wallet API ==========
// GET /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}/Wallet/Balance
async getTopUpAgentManagementWalletBalance(issuerId, currencyCode) {
try {
const res = await api.get(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}/Wallet/Balance`, {
skipAuthRedirect: true
});
return res?.data?.data || null;
} catch (error) {
console.error('🔴 TopUpAgentManagement Wallet Balance GET error:', error);
throw error;
}
},
// POST /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}/Wallet/Deposit
async depositTopUpAgentManagementWallet(issuerId, currencyCode, amount) {
try {
const payload = { amount: Number(amount) || 0 };
const res = await api.post(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}/Wallet/Deposit`, payload, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 TopUpAgentManagement Wallet Deposit POST error:', error);
throw error;
}
},
// GET /api/v1/issuer/{issuerId}/Capability/TopUpAgentManagement/Currency/{currencyCode}/Wallet/Transactions
async getTopUpAgentManagementWalletTransactions(issuerId, currencyCode) {
try {
const res = await api.get(`/api/v1/issuer/${encodeURIComponent(issuerId)}/Capability/TopUpAgentManagement/Currency/${encodeURIComponent(currencyCode)}/Wallet/Transactions`, {
skipAuthRedirect: true
});
return Array.isArray(res?.data?.data) ? res?.data?.data : [];
} catch (error) {
console.error('🔴 TopUpAgentManagement Wallet Transactions GET error:', error);
throw error;
}
},
// ========== Issuer Admin API ==========
// GET /api/v1/Issuer/{issuerId}/Admin
async getAdmins(issuerId) {
try {
const res = await api.get(`/api/v1/Issuer/${encodeURIComponent(issuerId)}/Admin`, {
skipAuthRedirect: true
});
// Response structure: { data: { data: [...], filterSummary: {...} }, statusCode, ... }
return res?.data?.data?.data || [];
} catch (error) {
console.error('🔴 Issuer Admin GET error:', error);
throw error;
}
},
// POST /api/v1/Issuer/{issuerId}/Admin
async addAdmin(issuerId, adminData) {
try {
const res = await api.post(`/api/v1/Issuer/${encodeURIComponent(issuerId)}/Admin`, adminData, {
skipAuthRedirect: true
});
return res?.data;
} catch (error) {
console.error('🔴 Issuer Admin POST error:', error);
throw error;
}
}
};