Replace window.confirm() with themed ConfirmModal across dashboard
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
// ⚠️ CONVENTION: This component uses Tailwind utility classes (e.g. bg-white, rounded-lg, hover:bg-gray-50)
|
||||
// instead of inline styles or App.css global classes. This is the legacy modal kept for UserMenu quick-access;
|
||||
// the themed replacement lives in AdminPage.js.
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { X, Plus, Edit2, Trash2, Loader, AlertCircle, CheckCircle, User, Mail, Shield } from 'lucide-react';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import ConfirmModal from './ConfirmModal';
|
||||
|
||||
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';
|
||||
|
||||
@@ -35,6 +39,7 @@ export default function UserManagement({ onClose }) {
|
||||
});
|
||||
const [formError, setFormError] = useState('');
|
||||
const [formSuccess, setFormSuccess] = useState('');
|
||||
const [pendingConfirm, setPendingConfirm] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUsers();
|
||||
@@ -55,29 +60,10 @@ export default function UserManagement({ onClose }) {
|
||||
}
|
||||
};
|
||||
|
||||
const confirmGroupChange = (targetUser, newGroup) => {
|
||||
let message = `Are you sure you want to change ${targetUser.username}'s group from ${targetUser.group} to ${newGroup}?`;
|
||||
|
||||
// Extra warning when downgrading an Admin user
|
||||
if (targetUser.group === 'Admin' && newGroup !== 'Admin') {
|
||||
message += `\n\n⚠️ WARNING: You are removing Admin privileges from ${targetUser.username}. They will lose full system access.`;
|
||||
}
|
||||
|
||||
return window.confirm(message);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const doSubmit = async () => {
|
||||
setFormError('');
|
||||
setFormSuccess('');
|
||||
|
||||
// If editing and group changed, show confirmation dialog
|
||||
if (editingUser && formData.group !== editingUser.group) {
|
||||
if (!confirmGroupChange(editingUser, formData.group)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const url = editingUser
|
||||
? `${API_BASE}/users/${editingUser.id}`
|
||||
@@ -117,6 +103,31 @@ export default function UserManagement({ onClose }) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// If editing and group changed, show confirmation modal
|
||||
if (editingUser && formData.group !== editingUser.group) {
|
||||
let message = `Are you sure you want to change ${editingUser.username}'s group from ${editingUser.group} to ${formData.group}?`;
|
||||
if (editingUser.group === 'Admin' && formData.group !== 'Admin') {
|
||||
message += ` WARNING: You are removing Admin privileges from ${editingUser.username}. They will lose full system access.`;
|
||||
}
|
||||
setPendingConfirm({
|
||||
title: 'Change User Group',
|
||||
message,
|
||||
confirmText: 'Change Group',
|
||||
variant: editingUser.group === 'Admin' ? 'danger' : 'warning',
|
||||
onConfirm: () => {
|
||||
setPendingConfirm(null);
|
||||
doSubmit();
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
doSubmit();
|
||||
};
|
||||
|
||||
const handleEdit = (user) => {
|
||||
setEditingUser(user);
|
||||
setFormData({
|
||||
@@ -131,26 +142,30 @@ export default function UserManagement({ onClose }) {
|
||||
};
|
||||
|
||||
const handleDelete = async (userId) => {
|
||||
if (!window.confirm('Are you sure you want to delete this user?')) {
|
||||
return;
|
||||
}
|
||||
setPendingConfirm({
|
||||
title: 'Delete User',
|
||||
message: 'Are you sure you want to delete this user?',
|
||||
confirmText: 'Delete',
|
||||
onConfirm: async () => {
|
||||
setPendingConfirm(null);
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/users/${userId}`, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include'
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/users/${userId}`, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include'
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
const data = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Delete failed');
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || 'Delete failed');
|
||||
}
|
||||
|
||||
fetchUsers();
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
}
|
||||
fetchUsers();
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleActive = async (user) => {
|
||||
@@ -418,6 +433,17 @@ export default function UserManagement({ onClose }) {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Confirmation Modal */}
|
||||
<ConfirmModal
|
||||
open={!!pendingConfirm}
|
||||
title={pendingConfirm?.title}
|
||||
message={pendingConfirm?.message}
|
||||
confirmText={pendingConfirm?.confirmText}
|
||||
variant={pendingConfirm?.variant || 'danger'}
|
||||
onConfirm={pendingConfirm?.onConfirm}
|
||||
onCancel={() => setPendingConfirm(null)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user