feat: replace native confirm() dialogs with custom modal component

- Add ModalProvider context and useConfirm hook (confirm-modal.tsx)
- Support danger/warning/info variants with icons and colors
- Animated backdrop and dialog with CSS keyframes
- Accessible: aria-modal, role=dialog, ESC to close, auto-focus
- Replace all 6 native confirm() calls across dashboard pages
- Integrate ModalProvider in app providers
This commit is contained in:
keyhan
2026-04-07 23:38:55 +03:30
parent 5979b48a61
commit ac5278d73b
10 changed files with 222 additions and 14 deletions
@@ -6,6 +6,7 @@ import api from '@/lib/api';
import { toast } from 'react-toastify';
import type { Cluster, ClusterResources } from '@/types';
import { Server, CheckCircle, XCircle, BarChart3, Clock, RotateCw, Plug, X } from 'lucide-react';
import { useConfirm } from '@/components/confirm-modal';
function ResourcePanel({ clusterId }: { clusterId: string }) {
const { data, isLoading, error } = useQuery<ClusterResources>({
@@ -121,6 +122,7 @@ function ResourcePanel({ clusterId }: { clusterId: string }) {
export default function AdminClustersPage() {
const queryClient = useQueryClient();
const confirm = useConfirm();
const [showForm, setShowForm] = useState(false);
const [testingId, setTestingId] = useState<string | null>(null);
const [expandedResources, setExpandedResources] = useState<Set<string>>(new Set());
@@ -333,7 +335,10 @@ export default function AdminClustersPage() {
{testingId === cluster.id ? <><Clock className="w-3 h-3 inline animate-spin" /> Testing...</> : <><Plug className="w-3 h-3 inline" /> Test</>}
</button>
<button
onClick={() => { if (confirm('Remove this cluster?')) deleteMutation.mutate(cluster.id); }}
onClick={async () => {
const ok = await confirm({ title: 'Remove Cluster', message: `Are you sure you want to remove "${cluster.name}"?`, confirmText: 'Remove', variant: 'danger' });
if (ok) deleteMutation.mutate(cluster.id);
}}
className="text-sm text-red-600 hover:text-red-800 font-medium"
>
Remove