2026-04-09 14:28:57 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import React from "react";
|
|
|
|
|
|
|
|
|
|
export interface ConfirmModalProps {
|
2026-04-09 14:38:28 +09:00
|
|
|
open: boolean;
|
|
|
|
|
title?: string;
|
|
|
|
|
message: string;
|
|
|
|
|
confirmText?: string;
|
|
|
|
|
cancelText?: string;
|
|
|
|
|
variant?: "primary" | "danger" | "success";
|
|
|
|
|
onConfirm: () => void;
|
|
|
|
|
onCancel: () => void;
|
2026-04-09 14:28:57 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* POP 공용 확인 모달 (native confirm() 대체)
|
|
|
|
|
* 모바일 친화 디자인, bottom-sheet 스타일
|
|
|
|
|
*/
|
|
|
|
|
export function ConfirmModal({
|
2026-04-09 14:38:28 +09:00
|
|
|
open,
|
|
|
|
|
title,
|
|
|
|
|
message,
|
|
|
|
|
confirmText = "확인",
|
|
|
|
|
cancelText = "취소",
|
|
|
|
|
variant = "primary",
|
|
|
|
|
onConfirm,
|
|
|
|
|
onCancel,
|
2026-04-09 14:28:57 +09:00
|
|
|
}: ConfirmModalProps) {
|
2026-04-09 14:38:28 +09:00
|
|
|
if (!open) return null;
|
2026-04-09 14:28:57 +09:00
|
|
|
|
2026-04-09 14:38:28 +09:00
|
|
|
const confirmBg =
|
|
|
|
|
variant === "danger"
|
|
|
|
|
? "bg-gradient-to-b from-red-500 to-red-600 hover:from-red-600 hover:to-red-700"
|
|
|
|
|
: variant === "success"
|
|
|
|
|
? "bg-gradient-to-b from-emerald-500 to-emerald-600 hover:from-emerald-600 hover:to-emerald-700"
|
|
|
|
|
: "bg-gradient-to-b from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700";
|
2026-04-09 14:28:57 +09:00
|
|
|
|
2026-04-09 14:38:28 +09:00
|
|
|
return (
|
|
|
|
|
<div className="fixed inset-0 z-[100]" onClick={onCancel}>
|
|
|
|
|
{/* Overlay */}
|
|
|
|
|
<div className="absolute inset-0 bg-black/50" />
|
2026-04-09 14:28:57 +09:00
|
|
|
|
2026-04-09 14:38:28 +09:00
|
|
|
{/* Center modal */}
|
|
|
|
|
<div className="absolute inset-0 flex items-center justify-center p-6">
|
|
|
|
|
<div
|
|
|
|
|
className="w-full max-w-md bg-white rounded-2xl shadow-2xl overflow-hidden"
|
|
|
|
|
onClick={(e) => e.stopPropagation()}
|
|
|
|
|
>
|
|
|
|
|
{/* Body */}
|
|
|
|
|
<div className="px-6 py-7 text-center">
|
|
|
|
|
{title && (
|
|
|
|
|
<h3 className="text-lg font-bold text-gray-900 mb-3">{title}</h3>
|
|
|
|
|
)}
|
|
|
|
|
<p className="text-base text-gray-700 whitespace-pre-line leading-relaxed">
|
|
|
|
|
{message}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
2026-04-09 14:28:57 +09:00
|
|
|
|
2026-04-09 14:38:28 +09:00
|
|
|
{/* Buttons */}
|
|
|
|
|
<div className="flex border-t border-gray-100">
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={onCancel}
|
|
|
|
|
className="flex-1 py-4 text-base font-semibold text-gray-600 hover:bg-gray-50 active:bg-gray-100 transition-colors"
|
|
|
|
|
>
|
|
|
|
|
{cancelText}
|
|
|
|
|
</button>
|
|
|
|
|
<div className="w-px bg-gray-100" />
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={onConfirm}
|
|
|
|
|
className={`flex-1 py-4 text-base font-bold text-white transition-all active:scale-[0.98] ${confirmBg}`}
|
|
|
|
|
>
|
|
|
|
|
{confirmText}
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2026-04-09 14:28:57 +09:00
|
|
|
}
|