102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
'use client';
|
|
|
|
import React, { useEffect } from 'react';
|
|
|
|
interface DeleteConfirmModalProps {
|
|
isOpen: boolean;
|
|
title: string;
|
|
message: string;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
danger?: boolean;
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
}
|
|
|
|
export function DeleteConfirmModal({
|
|
isOpen,
|
|
title,
|
|
message,
|
|
confirmText = 'Confirm',
|
|
cancelText = 'Keep Ride',
|
|
danger = true,
|
|
onClose,
|
|
onConfirm,
|
|
}: DeleteConfirmModalProps) {
|
|
useEffect(() => {
|
|
function handleKeyDown(e: KeyboardEvent) {
|
|
if (e.key === 'Escape') onClose();
|
|
}
|
|
if (isOpen) {
|
|
document.addEventListener('keydown', handleKeyDown);
|
|
}
|
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
}, [isOpen, onClose]);
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="confirm-modal-title"
|
|
className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-slate-950/80 backdrop-blur-md animate-in fade-in duration-200"
|
|
>
|
|
<div className="relative w-full max-w-md bg-surface-container-low border border-outline-variant/40 rounded-2xl p-6 shadow-2xl space-y-4">
|
|
{/* Icon & Title */}
|
|
<div className="flex items-center gap-3">
|
|
<div
|
|
className={`w-10 h-10 rounded-xl flex items-center justify-center ${
|
|
danger
|
|
? 'bg-error/20 text-error border border-error/30'
|
|
: 'bg-primary-container/20 text-primary-container border border-primary-container/30'
|
|
}`}
|
|
>
|
|
<span className="material-symbols-outlined text-[22px]">
|
|
{danger ? 'warning' : 'help'}
|
|
</span>
|
|
</div>
|
|
<div>
|
|
<h2 id="confirm-modal-title" className="font-headline-md text-base font-bold text-on-surface">
|
|
{title}
|
|
</h2>
|
|
<span className="font-mono text-[10px] text-on-surface-variant">
|
|
Formation Telemetry Safeguard
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Message */}
|
|
<p className="font-body-sm text-sm text-on-surface-variant leading-relaxed">
|
|
{message}
|
|
</p>
|
|
|
|
{/* Actions */}
|
|
<div className="flex items-center justify-end gap-3 pt-2">
|
|
<button
|
|
type="button"
|
|
onClick={onClose}
|
|
className="px-4 py-2 rounded-xl bg-surface-container hover:bg-surface-container-high border border-outline-variant/30 text-xs font-semibold text-on-surface transition cursor-pointer"
|
|
>
|
|
{cancelText}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={() => {
|
|
onConfirm();
|
|
onClose();
|
|
}}
|
|
className={`px-4 py-2 rounded-xl text-xs font-semibold transition cursor-pointer ${
|
|
danger
|
|
? 'bg-error text-on-error hover:bg-error/90 shadow-[0_0_16px_rgba(255,82,82,0.3)]'
|
|
: 'bg-primary-container text-on-primary-container hover:bg-primary-container/90'
|
|
}`}
|
|
>
|
|
{confirmText}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|