ERP-node/frontend/components/screen/CopyScreenModal.tsx

193 lines
5.9 KiB
TypeScript
Raw Normal View History

2025-09-03 18:23:47 +09:00
"use client";
import React, { useState, useEffect } from "react";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogDescription,
DialogFooter,
} from "@/components/ui/dialog";
2025-09-03 18:23:47 +09:00
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Loader2, Copy } from "lucide-react";
import { ScreenDefinition } from "@/types/screen";
import { screenApi } from "@/lib/api/screen";
import { toast } from "sonner";
interface CopyScreenModalProps {
isOpen: boolean;
onClose: () => void;
sourceScreen: ScreenDefinition | null;
onCopySuccess: () => void;
}
export default function CopyScreenModal({ isOpen, onClose, sourceScreen, onCopySuccess }: CopyScreenModalProps) {
const [screenName, setScreenName] = useState("");
const [screenCode, setScreenCode] = useState("");
const [description, setDescription] = useState("");
const [isCopying, setIsCopying] = useState(false);
// 모달이 열릴 때 초기값 설정
useEffect(() => {
if (isOpen && sourceScreen) {
setScreenName(`${sourceScreen.screenName} (복사본)`);
setDescription(sourceScreen.description || "");
// 화면 코드 자동 생성
generateNewScreenCode();
}
}, [isOpen, sourceScreen]);
// 새로운 화면 코드 자동 생성
const generateNewScreenCode = async () => {
if (!sourceScreen?.companyCode) return;
try {
const newCode = await screenApi.generateScreenCode(sourceScreen.companyCode);
setScreenCode(newCode);
} catch (error) {
// console.error("화면 코드 생성 실패:", error);
2025-09-03 18:23:47 +09:00
toast.error("화면 코드 생성에 실패했습니다.");
}
};
// 화면 복사 실행
const handleCopy = async () => {
if (!sourceScreen) return;
// 입력값 검증
if (!screenName.trim()) {
toast.error("화면명을 입력해주세요.");
return;
}
if (!screenCode.trim()) {
toast.error("화면 코드 생성에 실패했습니다. 잠시 후 다시 시도해주세요.");
return;
}
try {
setIsCopying(true);
// 화면 복사 API 호출
await screenApi.copyScreen(sourceScreen.screenId, {
screenName: screenName.trim(),
screenCode: screenCode.trim(),
description: description.trim(),
});
toast.success("화면이 성공적으로 복사되었습니다.");
onCopySuccess();
handleClose();
} catch (error: any) {
// console.error("화면 복사 실패:", error);
2025-09-03 18:23:47 +09:00
const errorMessage = error.response?.data?.message || "화면 복사에 실패했습니다.";
toast.error(errorMessage);
} finally {
setIsCopying(false);
}
};
// 모달 닫기
const handleClose = () => {
setScreenName("");
setScreenCode("");
setDescription("");
onClose();
};
return (
<Dialog open={isOpen} onOpenChange={handleClose}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
2025-09-03 18:23:47 +09:00
<Copy className="h-5 w-5" />
</DialogTitle>
2025-09-03 18:23:47 +09:00
<DialogDescription>
{sourceScreen?.screenName} . .
</DialogDescription>
2025-09-03 18:23:47 +09:00
</DialogHeader>
<div className="space-y-4">
{/* 원본 화면 정보 */}
<div className="rounded-md bg-gray-50 p-3">
<h4 className="mb-2 text-sm font-medium text-gray-700"> </h4>
<div className="space-y-1 text-sm text-muted-foreground">
2025-09-03 18:23:47 +09:00
<div>
<span className="font-medium">:</span> {sourceScreen?.screenName}
</div>
<div>
<span className="font-medium">:</span> {sourceScreen?.screenCode}
</div>
<div>
<span className="font-medium">:</span> {sourceScreen?.companyCode}
</div>
</div>
</div>
{/* 새 화면 정보 입력 */}
<div className="space-y-3">
<div>
<Label htmlFor="screenName"> *</Label>
<Input
id="screenName"
value={screenName}
onChange={(e) => setScreenName(e.target.value)}
placeholder="복사될 화면의 이름을 입력하세요"
className="mt-1"
/>
</div>
<div>
<Label htmlFor="screenCode"> ()</Label>
<Input
id="screenCode"
value={screenCode}
readOnly
className="mt-1 bg-gray-50"
placeholder="화면 코드가 자동으로 생성됩니다"
/>
</div>
<div>
<Label htmlFor="description"></Label>
<Textarea
id="description"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="화면 설명을 입력하세요 (선택사항)"
className="mt-1"
rows={3}
/>
</div>
</div>
</div>
<DialogFooter>
2025-09-03 18:23:47 +09:00
<Button variant="outline" onClick={handleClose} disabled={isCopying}>
</Button>
<Button onClick={handleCopy} disabled={isCopying}>
{isCopying ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
...
</>
) : (
<>
<Copy className="mr-2 h-4 w-4" />
</>
)}
</Button>
</DialogFooter>
2025-09-03 18:23:47 +09:00
</DialogContent>
</Dialog>
);
}