feat: Replace browser alerts with toast notifications
This commit is contained in:
parent
79d6c3c5e6
commit
9cba460d4d
|
|
@ -14,6 +14,9 @@ const Customers = () => {
|
||||||
const [showPlanModal, setShowPlanModal] = useState(false);
|
const [showPlanModal, setShowPlanModal] = useState(false);
|
||||||
const [showEditModal, setShowEditModal] = useState(false);
|
const [showEditModal, setShowEditModal] = useState(false);
|
||||||
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
||||||
|
const [showToast, setShowToast] = useState(false);
|
||||||
|
const [toastMessage, setToastMessage] = useState('');
|
||||||
|
const [toastType, setToastType] = useState('success'); // success, error
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
|
|
@ -43,16 +46,30 @@ const Customers = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showSuccessToast = (message) => {
|
||||||
|
setToastMessage(message);
|
||||||
|
setToastType('success');
|
||||||
|
setShowToast(true);
|
||||||
|
setTimeout(() => setShowToast(false), 3000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showErrorToast = (message) => {
|
||||||
|
setToastMessage(message);
|
||||||
|
setToastType('error');
|
||||||
|
setShowToast(true);
|
||||||
|
setTimeout(() => setShowToast(false), 5000);
|
||||||
|
};
|
||||||
|
|
||||||
const handleUpdatePlan = async (customerId, planData) => {
|
const handleUpdatePlan = async (customerId, planData) => {
|
||||||
try {
|
try {
|
||||||
await customerService.updateCustomerPlan(customerId, planData);
|
await customerService.updateCustomerPlan(customerId, planData);
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
setShowPlanModal(false);
|
setShowPlanModal(false);
|
||||||
setSelectedCustomer(null);
|
setSelectedCustomer(null);
|
||||||
alert('Plan updated successfully!');
|
showSuccessToast('Plan updated successfully!');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to update plan:', err);
|
console.error('Failed to update plan:', err);
|
||||||
alert('Failed to update plan: ' + (err.response?.data?.message || err.message));
|
showErrorToast('Failed to update plan: ' + (err.response?.data?.message || err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -62,10 +79,10 @@ const Customers = () => {
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
setShowEditModal(false);
|
setShowEditModal(false);
|
||||||
setSelectedCustomer(null);
|
setSelectedCustomer(null);
|
||||||
alert('Customer updated successfully!');
|
showSuccessToast('Customer updated successfully!');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to update customer:', err);
|
console.error('Failed to update customer:', err);
|
||||||
alert('Failed to update customer: ' + (err.response?.data?.message || err.message));
|
showErrorToast('Failed to update customer: ' + (err.response?.data?.message || err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -75,36 +92,32 @@ const Customers = () => {
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
setShowDeleteConfirm(false);
|
setShowDeleteConfirm(false);
|
||||||
setSelectedCustomer(null);
|
setSelectedCustomer(null);
|
||||||
alert('Customer deleted successfully!');
|
showSuccessToast('Customer deleted successfully!');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to delete customer:', err);
|
console.error('Failed to delete customer:', err);
|
||||||
alert('Failed to delete customer: ' + (err.response?.data?.message || err.message));
|
showErrorToast('Failed to delete customer: ' + (err.response?.data?.message || err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSuspendCustomer = async (customerId) => {
|
const handleSuspendCustomer = async (customerId) => {
|
||||||
if (!confirm('Are you sure you want to suspend this customer?')) return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await customerService.suspendCustomer(customerId);
|
await customerService.suspendCustomer(customerId);
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
alert('Customer suspended successfully!');
|
showSuccessToast('Customer suspended successfully!');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to suspend customer:', err);
|
console.error('Failed to suspend customer:', err);
|
||||||
alert('Failed to suspend customer: ' + (err.response?.data?.message || err.message));
|
showErrorToast('Failed to suspend customer: ' + (err.response?.data?.message || err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleActivateCustomer = async (customerId) => {
|
const handleActivateCustomer = async (customerId) => {
|
||||||
if (!confirm('Are you sure you want to activate this customer?')) return;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await customerService.activateCustomer(customerId);
|
await customerService.activateCustomer(customerId);
|
||||||
fetchCustomers();
|
fetchCustomers();
|
||||||
alert('Customer activated successfully!');
|
showSuccessToast('Customer activated successfully!');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to activate customer:', err);
|
console.error('Failed to activate customer:', err);
|
||||||
alert('Failed to activate customer: ' + (err.response?.data?.message || err.message));
|
showErrorToast('Failed to activate customer: ' + (err.response?.data?.message || err.message));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -315,6 +328,28 @@ const Customers = () => {
|
||||||
onConfirm={handleDeleteCustomer}
|
onConfirm={handleDeleteCustomer}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Toast Notification */}
|
||||||
|
{showToast && (
|
||||||
|
<div className={`fixed bottom-6 right-6 px-6 py-4 rounded-lg shadow-lg transform transition-all duration-300 z-50 ${
|
||||||
|
toastType === 'success'
|
||||||
|
? 'bg-green-500 text-white'
|
||||||
|
: 'bg-red-500 text-white'
|
||||||
|
}`}>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
{toastType === 'success' ? (
|
||||||
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
<span className="font-medium">{toastMessage}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue