43 lines
2.0 KiB
TypeScript
43 lines
2.0 KiB
TypeScript
import { useModalFocus } from "@/shared/ui/use-modal-focus";
|
|
|
|
export type ConfirmDeactivateDialogProps = {
|
|
readonly confirmLabel?: string;
|
|
readonly errorMessage?: string;
|
|
readonly impactDescription: string;
|
|
readonly isPending?: boolean;
|
|
readonly onCancel: () => void;
|
|
readonly onConfirm: () => void;
|
|
readonly open: boolean;
|
|
readonly targetName: string;
|
|
};
|
|
|
|
export function ConfirmDeactivateDialog({ confirmLabel = "비활성화", errorMessage, impactDescription, isPending = false, onCancel, onConfirm, open, targetName }: ConfirmDeactivateDialogProps) {
|
|
const { dialogRef, trapFocus } = useModalFocus<HTMLElement>(open);
|
|
|
|
if (!open) {
|
|
return null;
|
|
}
|
|
|
|
const title = `${targetName} 비활성화 확인`;
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-modal grid place-items-center bg-background/80 p-4">
|
|
<section aria-busy={isPending ? true : undefined} aria-modal="true" className="flex w-full max-w-sm flex-col gap-4 rounded-lg border border-border bg-card p-6" onKeyDown={trapFocus} ref={dialogRef} role="alertdialog" aria-label={title}>
|
|
<div className="flex flex-col gap-2">
|
|
<h2 className="text-xl font-semibold">{title}</h2>
|
|
<p className="text-sm text-muted-foreground">{impactDescription}</p>
|
|
</div>
|
|
{errorMessage === undefined ? null : <p className="rounded-md border border-destructive bg-card p-3 text-sm font-semibold text-destructive" role="alert">{errorMessage}</p>}
|
|
<div className="flex justify-end gap-2">
|
|
<button className="rounded-md border border-input bg-card px-4 py-2 font-semibold hover:bg-accent disabled:opacity-60" disabled={isPending} onClick={onCancel} type="button">
|
|
취소
|
|
</button>
|
|
<button className="rounded-md border border-destructive bg-destructive px-4 py-2 font-semibold text-white hover:bg-destructive/90 active:bg-destructive disabled:opacity-60" disabled={isPending} onClick={onConfirm} type="button">
|
|
{isPending ? "처리 중" : confirmLabel}
|
|
</button>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|