@mytec: iter9.1 ready for test
This commit is contained in:
81
frontend/src/components/ui/ConfirmDialog.tsx
Normal file
81
frontend/src/components/ui/ConfirmDialog.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
interface ConfirmDialogProps {
|
||||
title: string;
|
||||
message: string;
|
||||
confirmLabel?: string;
|
||||
cancelLabel?: string;
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
danger?: boolean;
|
||||
}
|
||||
|
||||
export default function ConfirmDialog({
|
||||
title,
|
||||
message,
|
||||
confirmLabel = 'Confirm',
|
||||
cancelLabel = 'Cancel',
|
||||
onConfirm,
|
||||
onCancel,
|
||||
danger = false,
|
||||
}: ConfirmDialogProps) {
|
||||
const confirmRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
// Auto-focus the cancel button (safer default)
|
||||
confirmRef.current?.focus();
|
||||
|
||||
const handleKey = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
e.stopPropagation();
|
||||
onCancel();
|
||||
}
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
onConfirm();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleKey);
|
||||
return () => window.removeEventListener('keydown', handleKey);
|
||||
}, [onCancel, onConfirm]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="fixed inset-0 z-[9500] bg-black/50 flex items-center justify-center"
|
||||
onClick={onCancel}
|
||||
>
|
||||
<div
|
||||
className="bg-white dark:bg-dark-surface rounded-lg shadow-xl p-5 max-w-sm mx-4 border border-gray-200 dark:border-dark-border"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<h3 className="text-base font-semibold text-gray-800 dark:text-dark-text mb-2">
|
||||
{title}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-dark-muted mb-5">
|
||||
{message}
|
||||
</p>
|
||||
<div className="flex gap-3 justify-end">
|
||||
<button
|
||||
onClick={onCancel}
|
||||
className="px-4 py-2 text-sm rounded-md bg-gray-100 dark:bg-dark-border text-gray-700 dark:text-dark-text
|
||||
hover:bg-gray-200 dark:hover:bg-dark-muted transition-colors"
|
||||
>
|
||||
{cancelLabel}
|
||||
</button>
|
||||
<button
|
||||
ref={confirmRef}
|
||||
onClick={onConfirm}
|
||||
className={`px-4 py-2 text-sm rounded-md text-white transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2
|
||||
${danger
|
||||
? 'bg-red-600 hover:bg-red-700 focus:ring-red-500'
|
||||
: 'bg-blue-600 hover:bg-blue-700 focus:ring-blue-500'
|
||||
}`}
|
||||
>
|
||||
{confirmLabel}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user