76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
import { XMarkIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
|
|
import Portal from './Portal';
|
|
import { useOverlayDismiss } from '../../hooks/useOverlayDismiss';
|
|
|
|
interface Props {
|
|
open: boolean;
|
|
title: string;
|
|
message: string;
|
|
confirmLabel?: string;
|
|
cancelLabel?: string;
|
|
danger?: boolean;
|
|
loading?: boolean;
|
|
onConfirm: () => void;
|
|
onCancel: () => void;
|
|
/** محتوای اضافه زیر پیام (مثلاً فیلد دلیل). */
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
export default function ConfirmDialog({
|
|
open,
|
|
title,
|
|
message,
|
|
confirmLabel = 'تأیید',
|
|
cancelLabel = 'لغو',
|
|
danger = false,
|
|
loading = false,
|
|
onConfirm,
|
|
onCancel,
|
|
children,
|
|
}: Props) {
|
|
const dismiss = useOverlayDismiss(onCancel, open);
|
|
|
|
if (!open) return null;
|
|
|
|
return (
|
|
<Portal>
|
|
<div className="overlay" {...dismiss}>
|
|
<div className="modal" style={{ maxWidth: 420 }}>
|
|
<div className="modal-head">
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
|
<span style={{
|
|
width: 36, height: 36, borderRadius: 10, display: 'grid', placeItems: 'center', flexShrink: 0,
|
|
background: danger ? 'var(--danger-bg)' : 'var(--warning-bg)',
|
|
color: danger ? 'var(--danger)' : 'var(--warning)',
|
|
}}>
|
|
<ExclamationTriangleIcon style={{ width: 18, height: 18 }} />
|
|
</span>
|
|
<h2 style={{ fontSize: 16 }}>{title}</h2>
|
|
</div>
|
|
<button className="mini-btn" onClick={onCancel}>
|
|
<XMarkIcon style={{ width: 18, height: 18 }} />
|
|
</button>
|
|
</div>
|
|
<div className="modal-body">
|
|
<p style={{ color: 'var(--text-2)', lineHeight: 1.75, margin: 0 }}>{message}</p>
|
|
{children}
|
|
</div>
|
|
<div className="modal-foot" style={{ justifyContent: 'flex-end' }}>
|
|
<button className="btn ghost sm" onClick={onCancel} disabled={loading}>
|
|
{cancelLabel}
|
|
</button>
|
|
<button
|
|
className={`btn ${danger ? 'danger' : 'primary'} sm`}
|
|
onClick={onConfirm}
|
|
disabled={loading}
|
|
>
|
|
{loading ? 'در حال انجام...' : confirmLabel}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Portal>
|
|
);
|
|
}
|