ERP-node/frontend/components/dataflow/node-editor/dialogs/SaveConfirmDialog.tsx

202 lines
7.1 KiB
TypeScript
Raw Normal View History

2025-10-24 15:40:08 +09:00
"use client";
/**
*
*
*
*/
import { memo } from "react";
import { AlertTriangle, AlertCircle, Info } from "lucide-react";
import type { FlowValidation } from "@/lib/utils/flowValidation";
import { summarizeValidations } from "@/lib/utils/flowValidation";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
interface SaveConfirmDialogProps {
open: boolean;
validations: FlowValidation[];
onConfirm: () => void;
onCancel: () => void;
}
export const SaveConfirmDialog = memo(
({ open, validations, onConfirm, onCancel }: SaveConfirmDialogProps) => {
const summary = summarizeValidations(validations);
// 오류가 있으면 저장 불가
if (summary.hasBlockingIssues) {
return (
<Dialog open={open} onOpenChange={onCancel}>
<DialogContent className="max-w-[95vw] sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2 text-base sm:text-lg">
<AlertCircle className="h-5 w-5 text-red-500" />
</DialogTitle>
<DialogDescription className="text-xs sm:text-sm">
</DialogDescription>
</DialogHeader>
<div className="space-y-3">
<div className="flex items-center gap-2">
<Badge variant="destructive" className="gap-1">
<AlertCircle className="h-3 w-3" />
{summary.errorCount}
</Badge>
{summary.warningCount > 0 && (
<Badge className="gap-1 bg-yellow-500 hover:bg-yellow-600">
<AlertTriangle className="h-3 w-3" />
{summary.warningCount}
</Badge>
)}
</div>
<ScrollArea className="max-h-[300px]">
<div className="space-y-2">
{validations
.filter((v) => v.severity === "error")
.map((validation, index) => (
<div
key={index}
className="rounded-lg border-2 border-red-200 bg-red-50 p-3"
>
<div className="mb-1 text-xs font-medium text-red-600">
{validation.type}
</div>
<div className="text-sm text-red-800">
{validation.message}
</div>
</div>
))}
</div>
</ScrollArea>
<p className="text-xs text-gray-500">
.
.
</p>
</div>
<DialogFooter className="gap-2 sm:gap-0">
<Button
onClick={onCancel}
className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
// 경고만 있는 경우 - 저장 가능하지만 확인 필요
return (
<Dialog open={open} onOpenChange={onCancel}>
<DialogContent className="max-w-[95vw] sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2 text-base sm:text-lg">
<AlertTriangle className="h-5 w-5 text-yellow-500" />
</DialogTitle>
<DialogDescription className="text-xs sm:text-sm">
{summary.warningCount + summary.infoCount}
</DialogDescription>
</DialogHeader>
<div className="space-y-3">
<div className="flex items-center gap-2">
{summary.warningCount > 0 && (
<Badge className="gap-1 bg-yellow-500 hover:bg-yellow-600">
<AlertTriangle className="h-3 w-3" />
{summary.warningCount}
</Badge>
)}
{summary.infoCount > 0 && (
<Badge variant="secondary" className="gap-1">
<Info className="h-3 w-3" />
{summary.infoCount}
</Badge>
)}
</div>
<ScrollArea className="max-h-[300px]">
<div className="space-y-2">
{validations
.filter((v) => v.severity === "warning")
.map((validation, index) => (
<div
key={index}
className="rounded-lg border-2 border-yellow-200 bg-yellow-50 p-3"
>
<div className="mb-1 text-xs font-medium text-yellow-600">
{validation.type}
</div>
<div className="text-sm text-yellow-800">
{validation.message}
</div>
</div>
))}
{validations
.filter((v) => v.severity === "info")
.map((validation, index) => (
<div
key={index}
className="rounded-lg border-2 border-blue-200 bg-blue-50 p-3"
>
<div className="mb-1 text-xs font-medium text-blue-600">
{validation.type}
</div>
<div className="text-sm text-blue-800">
{validation.message}
</div>
</div>
))}
</div>
</ScrollArea>
<div className="rounded-lg bg-gray-50 p-3">
<p className="text-xs text-gray-600">
.
<br />
?
</p>
</div>
</div>
<DialogFooter className="gap-2 sm:gap-0">
<Button
variant="outline"
onClick={onCancel}
className="h-8 flex-1 text-xs sm:h-10 sm:flex-none sm:text-sm"
>
</Button>
<Button
onClick={onConfirm}
className="h-8 flex-1 bg-yellow-500 text-xs hover:bg-yellow-600 sm:h-10 sm:flex-none sm:text-sm"
>
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
);
SaveConfirmDialog.displayName = "SaveConfirmDialog";