'use client'; import React, { useState, useEffect } from 'react'; import { apiClient } from '@/app/utils/apiClient'; import { Container, Typography, Button, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, IconButton, Dialog, DialogTitle, DialogContent, DialogActions, TextField, FormControlLabel, Switch, CircularProgress, Stack, Alert, Snackbar } from '@mui/material'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; import './Payment.scss'; interface PaymentMethod { id: number; name: string; description: string | null; icon: string | null; is_active: boolean; processing_time: string | null; fee_percentage: number | null; fee_fixed: number | null; min_amount: number | null; max_amount: number | null; display_order: number; } const emptyPaymentMethod: PaymentMethod = { id: 0, name: '', description: '', icon: '', is_active: true, processing_time: '', fee_percentage: null, fee_fixed: null, min_amount: null, max_amount: null, display_order: 999 }; const PaymentMethodsManager = () => { const [paymentMethods, setPaymentMethods] = useState([]); const [loading, setLoading] = useState(true); const [openDialog, setOpenDialog] = useState(false); const [currentMethod, setCurrentMethod] = useState({...emptyPaymentMethod}); const [isEditing, setIsEditing] = useState(false); const [snackbar, setSnackbar] = useState({ open: false, message: '', severity: 'success' as 'success' | 'error' }); useEffect(() => { fetchPaymentMethods(); }, []); const fetchPaymentMethods = async () => { setLoading(true); try { const response = await apiClient('/payment-methods'); if (response.success) { setPaymentMethods(response.data); } } catch (error) { console.error('Error fetching payment methods:', error); showSnackbar('Failed to load payment methods', 'error'); } finally { setLoading(false); } }; const handleOpenDialog = (method?: PaymentMethod) => { if (method) { setCurrentMethod({...method}); setIsEditing(true); } else { setCurrentMethod({...emptyPaymentMethod}); setIsEditing(false); } setOpenDialog(true); }; const handleCloseDialog = () => { setOpenDialog(false); }; const handleInputChange = (e: React.ChangeEvent) => { const { name, value, type, checked } = e.target; if (type === 'checkbox') { setCurrentMethod(prev => ({...prev, [name]: checked})); } else if (['fee_percentage', 'fee_fixed', 'min_amount', 'max_amount', 'display_order'].includes(name)) { // Convert to number or null if empty const numValue = value === '' ? null : Number(value); setCurrentMethod(prev => ({...prev, [name]: numValue})); } else { setCurrentMethod(prev => ({...prev, [name]: value})); } }; const handleSave = async () => { try { if (!currentMethod.name) { showSnackbar('Payment method name is required', 'error'); return; } const endpoint = isEditing ? `/payment-methods/${currentMethod.id}` : '/payment-methods'; const method = isEditing ? 'PUT' : 'POST'; const response = await apiClient(endpoint, { method: method, body: JSON.stringify(currentMethod) }); if (response.success) { showSnackbar( isEditing ? `Payment method "${currentMethod.name}" updated successfully` : `Payment method "${currentMethod.name}" created successfully`, 'success' ); fetchPaymentMethods(); handleCloseDialog(); } } catch (error) { console.error('Error saving payment method:', error); showSnackbar(`Failed to ${isEditing ? 'update' : 'create'} payment method`, 'error'); } }; const handleDelete = async (id: number, name: string) => { if (window.confirm(`Are you sure you want to delete payment method "${name}"? This action cannot be undone.`)) { try { const response = await apiClient(`/payment-methods/${id}`, { method: 'DELETE' }); if (response.success) { showSnackbar(`Payment method "${name}" deleted successfully`, 'success'); fetchPaymentMethods(); } } catch (error) { console.error('Error deleting payment method:', error); showSnackbar(`Failed to delete payment method "${name}"`, 'error'); } } }; const showSnackbar = (message: string, severity: 'success' | 'error') => { setSnackbar({ open: true, message, severity }); }; const handleCloseSnackbar = () => { setSnackbar(prev => ({ ...prev, open: false })); }; return ( Payment Methods {loading ? (
) : ( Name Description Processing Time Fee Status Display Order Actions {paymentMethods.length === 0 ? ( No payment methods found ) : ( paymentMethods.map((method) => (
{method.icon && ( {method.icon} )} {method.name}
{method.description || '-'} {method.processing_time || '-'} {method.fee_percentage ? `${method.fee_percentage}%` : ''} {(method.fee_percentage && method.fee_fixed) ? ' + ' : ''} {method.fee_fixed ? `$${method.fee_fixed.toFixed(2)}` : ''} {!method.fee_percentage && !method.fee_fixed ? 'No fee' : ''} {method.is_active ? 'Active' : 'Inactive'} {method.display_order} handleOpenDialog(method)} size="small" > handleDelete(method.id, method.name)} size="small" >
)) )}
)} {isEditing ? `Edit Payment Method: ${currentMethod.name}` : 'Add New Payment Method'}
} label="Active" />
{snackbar.message}
); }; export default PaymentMethodsManager;