fix(topup-agent-management): fix wallet deposit fields

This commit is contained in:
ghazall-ag
2026-01-06 12:28:42 +03:30
parent 964965f0d1
commit 80d0c675a0
6 changed files with 398 additions and 257 deletions

View File

@@ -1,5 +1,9 @@
import React, { useState, useEffect } from 'react';
import { Save, Key, Globe, DollarSign, Bell, Shield, Database } from 'lucide-react';
import { Save, Key, Globe, DollarSign, Bell, Shield, Database, Ticket } from 'lucide-react';
import { generalAPI } from '../services/api';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { getErrorMessage, getSuccessMessage } from '../utils/errorHandler';
const Settings = () => {
const [settings, setSettings] = useState({
@@ -21,12 +25,21 @@ const Settings = () => {
}
});
const [voucherConfig, setVoucherConfig] = useState({
expireInDays: 0,
refundUponVoucherExpiration: true,
canPurchaseByAgentVouchers: true,
canTopUpWithUserVouchers: true
});
const [loading, setLoading] = useState(false);
const [voucherLoading, setVoucherLoading] = useState(false);
const [message, setMessage] = useState('');
const [activeTab, setActiveTab] = useState('payment');
useEffect(() => {
loadSettings();
loadVoucherConfiguration();
}, []);
const loadSettings = () => {
@@ -36,6 +49,26 @@ const Settings = () => {
}
};
const loadVoucherConfiguration = async () => {
try {
setVoucherLoading(true);
const config = await generalAPI.getVoucherConfiguration();
if (config) {
setVoucherConfig({
expireInDays: config.expireInDays ?? 0,
refundUponVoucherExpiration: config.refundUponVoucherExpiration ?? true,
canPurchaseByAgentVouchers: config.canPurchaseByAgentVouchers ?? true,
canTopUpWithUserVouchers: config.canTopUpWithUserVouchers ?? true
});
}
} catch (err) {
console.error('Error loading voucher configuration:', err);
toast.error(getErrorMessage(err));
} finally {
setVoucherLoading(false);
}
};
const handleInputChange = (section, field, value) => {
setSettings(prev => ({
...prev,
@@ -72,11 +105,32 @@ const Settings = () => {
}
};
const handleVoucherSave = async () => {
setVoucherLoading(true);
try {
const result = await generalAPI.updateVoucherConfiguration(voucherConfig);
toast.success(getSuccessMessage(result) || 'Voucher configuration saved successfully');
await loadVoucherConfiguration();
} catch (err) {
toast.error(getErrorMessage(err));
} finally {
setVoucherLoading(false);
}
};
const handleVoucherChange = (field, value) => {
setVoucherConfig(prev => ({
...prev,
[field]: value
}));
};
const tabs = [
{ id: 'payment', label: 'Payment', icon: DollarSign },
{ id: 'notifications', label: 'Notifications', icon: Bell },
{ id: 'security', label: 'Security', icon: Shield },
{ id: 'data', label: 'Data', icon: Database }
{ id: 'data', label: 'Data', icon: Database },
{ id: 'voucher', label: 'Voucher', icon: Ticket }
];
const currencies = [
@@ -90,6 +144,7 @@ const Settings = () => {
return (
<div className="p-6">
<ToastContainer position="top-right" autoClose={3000} />
<div className="mb-8">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">Settings</h1>
<p className="text-gray-600 dark:text-gray-400">Configure your payment system preferences</p>
@@ -331,16 +386,105 @@ const Settings = () => {
</div>
)}
{/* Voucher Settings */}
{activeTab === 'voucher' && (
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6">Voucher Configuration</h3>
{voucherLoading ? (
<div className="flex justify-center py-10">
<div className="w-8 h-8 border-4 border-t-transparent border-primary-500 rounded-full animate-spin" />
</div>
) : (
<div className="space-y-6">
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Expire In Days
</label>
<input
type="number"
min="0"
value={voucherConfig.expireInDays}
onChange={(e) => handleVoucherChange('expireInDays', Number(e.target.value) || 0)}
className="input-field w-32"
/>
<p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
Number of days before vouchers expire
</p>
</div>
<div className="flex items-center justify-between">
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300">Refund Upon Voucher Expiration</label>
<p className="text-xs text-gray-500 dark:text-gray-400">Automatically refund when voucher expires</p>
</div>
<label className="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
checked={voucherConfig.refundUponVoucherExpiration}
onChange={(e) => handleVoucherChange('refundUponVoucherExpiration', e.target.checked)}
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 dark:peer-focus:ring-primary-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-primary-600"></div>
</label>
</div>
<div className="flex items-center justify-between">
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300">Can Purchase By Agent Vouchers</label>
<p className="text-xs text-gray-500 dark:text-gray-400">Allow purchases using agent-generated vouchers</p>
</div>
<label className="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
checked={voucherConfig.canPurchaseByAgentVouchers}
onChange={(e) => handleVoucherChange('canPurchaseByAgentVouchers', e.target.checked)}
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 dark:peer-focus:ring-primary-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-primary-600"></div>
</label>
</div>
<div className="flex items-center justify-between">
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300">Can Top Up With User Vouchers</label>
<p className="text-xs text-gray-500 dark:text-gray-400">Allow top-up using user-generated vouchers</p>
</div>
<label className="relative inline-flex items-center cursor-pointer">
<input
type="checkbox"
checked={voucherConfig.canTopUpWithUserVouchers}
onChange={(e) => handleVoucherChange('canTopUpWithUserVouchers', e.target.checked)}
className="sr-only peer"
/>
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary-300 dark:peer-focus:ring-primary-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-primary-600"></div>
</label>
</div>
</div>
)}
</div>
)}
{/* Save Button */}
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<button
onClick={handleSave}
disabled={loading}
className="btn-primary flex items-center"
>
<Save className="h-4 w-4 mr-2" />
{loading ? 'Saving...' : 'Save Settings'}
</button>
{activeTab === 'voucher' ? (
<button
onClick={handleVoucherSave}
disabled={voucherLoading}
className="btn-primary flex items-center"
>
<Save className="h-4 w-4 mr-2" />
{voucherLoading ? 'Saving...' : 'Save Voucher Settings'}
</button>
) : (
<button
onClick={handleSave}
disabled={loading}
className="btn-primary flex items-center"
>
<Save className="h-4 w-4 mr-2" />
{loading ? 'Saving...' : 'Save Settings'}
</button>
)}
</div>
</div>
</div>