모달화(삭제, 복사)

This commit is contained in:
dohyeons 2025-10-16 18:09:46 +09:00
parent 7155f76345
commit 7241d1b91f
1 changed files with 73 additions and 12 deletions

View File

@ -15,7 +15,18 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Plus, Search, MoreVertical, Edit, Trash2, Copy } from "lucide-react";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Plus, Search, MoreVertical, Edit, Trash2, Copy, CheckCircle2 } from "lucide-react";
/**
*
@ -29,6 +40,12 @@ export default function DashboardListPage() {
const [searchTerm, setSearchTerm] = useState("");
const [error, setError] = useState<string | null>(null);
// 모달 상태
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [deleteTarget, setDeleteTarget] = useState<{ id: string; title: string } | null>(null);
const [successDialogOpen, setSuccessDialogOpen] = useState(false);
const [successMessage, setSuccessMessage] = useState("");
// 대시보드 목록 로드
const loadDashboards = async () => {
try {
@ -48,19 +65,27 @@ export default function DashboardListPage() {
loadDashboards();
}, [searchTerm]);
// 대시보드 삭제
const handleDelete = async (id: string, title: string) => {
if (!confirm(`"${title}" 대시보드를 삭제하시겠습니까?`)) {
return;
}
// 대시보드 삭제 확인 모달 열기
const handleDeleteClick = (id: string, title: string) => {
setDeleteTarget({ id, title });
setDeleteDialogOpen(true);
};
// 대시보드 삭제 실행
const handleDeleteConfirm = async () => {
if (!deleteTarget) return;
try {
await dashboardApi.deleteDashboard(id);
alert("대시보드가 삭제되었습니다.");
await dashboardApi.deleteDashboard(deleteTarget.id);
setDeleteDialogOpen(false);
setDeleteTarget(null);
setSuccessMessage("대시보드가 삭제되었습니다.");
setSuccessDialogOpen(true);
loadDashboards();
} catch (err) {
console.error("Failed to delete dashboard:", err);
alert("대시보드 삭제에 실패했습니다.");
setDeleteDialogOpen(false);
setError("대시보드 삭제에 실패했습니다.");
}
};
@ -79,11 +104,12 @@ export default function DashboardListPage() {
category: fullDashboard.category,
settings: (fullDashboard as any).settings, // 해상도와 배경색 설정도 복사
});
alert("대시보드가 복사되었습니다.");
setSuccessMessage("대시보드가 복사되었습니다.");
setSuccessDialogOpen(true);
loadDashboards();
} catch (err) {
console.error("Failed to copy dashboard:", err);
alert("대시보드 복사에 실패했습니다.");
setError("대시보드 복사에 실패했습니다.");
}
};
@ -194,7 +220,7 @@ export default function DashboardListPage() {
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleDelete(dashboard.id, dashboard.title)}
onClick={() => handleDeleteClick(dashboard.id, dashboard.title)}
className="gap-2 text-red-600 focus:text-red-600"
>
<Trash2 className="h-4 w-4" />
@ -210,6 +236,41 @@ export default function DashboardListPage() {
</Card>
)}
</div>
{/* 삭제 확인 모달 */}
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle> </AlertDialogTitle>
<AlertDialogDescription>
&quot;{deleteTarget?.title}&quot; ?
<br /> .
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction onClick={handleDeleteConfirm} className="bg-red-600 hover:bg-red-700">
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
{/* 성공 모달 */}
<Dialog open={successDialogOpen} onOpenChange={setSuccessDialogOpen}>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
<CheckCircle2 className="h-6 w-6 text-green-600" />
</div>
<DialogTitle className="text-center"></DialogTitle>
<DialogDescription className="text-center">{successMessage}</DialogDescription>
</DialogHeader>
<div className="flex justify-center pt-4">
<Button onClick={() => setSuccessDialogOpen(false)}></Button>
</div>
</DialogContent>
</Dialog>
</div>
);
}