153 lines
4.3 KiB
TypeScript
153 lines
4.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
|
|
|
|
DialogHeader,
|
|
|
|
} from "@/components/ui/resizable-dialog";
|
|
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 } from "lucide-react";
|
|
|
|
interface SaveAsTemplateModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
onSave: (data: { templateNameKor: string; templateNameEng?: string; description?: string }) => Promise<void>;
|
|
}
|
|
|
|
export function SaveAsTemplateModal({ isOpen, onClose, onSave }: SaveAsTemplateModalProps) {
|
|
const [formData, setFormData] = useState({
|
|
templateNameKor: "",
|
|
templateNameEng: "",
|
|
description: "",
|
|
});
|
|
const [isSaving, setIsSaving] = useState(false);
|
|
|
|
const handleSave = async () => {
|
|
if (!formData.templateNameKor.trim()) {
|
|
alert("템플릿명을 입력해주세요.");
|
|
return;
|
|
}
|
|
|
|
setIsSaving(true);
|
|
try {
|
|
await onSave({
|
|
templateNameKor: formData.templateNameKor,
|
|
templateNameEng: formData.templateNameEng || undefined,
|
|
description: formData.description || undefined,
|
|
});
|
|
|
|
// 초기화
|
|
setFormData({
|
|
templateNameKor: "",
|
|
templateNameEng: "",
|
|
description: "",
|
|
});
|
|
onClose();
|
|
} catch (error) {
|
|
console.error("템플릿 저장 실패:", error);
|
|
} finally {
|
|
setIsSaving(false);
|
|
}
|
|
};
|
|
|
|
const handleClose = () => {
|
|
if (!isSaving) {
|
|
setFormData({
|
|
templateNameKor: "",
|
|
templateNameEng: "",
|
|
description: "",
|
|
});
|
|
onClose();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog open={isOpen} onOpenChange={handleClose}>
|
|
<DialogContent className="sm:max-w-[500px]">
|
|
<DialogHeader>
|
|
<ResizableDialogTitle>템플릿으로 저장</ResizableDialogTitle>
|
|
<DialogDescription>
|
|
현재 리포트 레이아웃을 템플릿으로 저장하면 다른 리포트에서 재사용할 수 있습니다.
|
|
</ResizableDialogDescription>
|
|
</DialogHeader>
|
|
|
|
<div className="space-y-4 py-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="templateNameKor">
|
|
템플릿명 (한국어) <span className="text-red-500">*</span>
|
|
</Label>
|
|
<Input
|
|
id="templateNameKor"
|
|
value={formData.templateNameKor}
|
|
onChange={(e) =>
|
|
setFormData({
|
|
...formData,
|
|
templateNameKor: e.target.value,
|
|
})
|
|
}
|
|
placeholder="예: 발주서 양식"
|
|
disabled={isSaving}
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="templateNameEng">템플릿명 (영어)</Label>
|
|
<Input
|
|
id="templateNameEng"
|
|
value={formData.templateNameEng}
|
|
onChange={(e) =>
|
|
setFormData({
|
|
...formData,
|
|
templateNameEng: e.target.value,
|
|
})
|
|
}
|
|
placeholder="예: Purchase Order Template"
|
|
disabled={isSaving}
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="description">설명</Label>
|
|
<Textarea
|
|
id="description"
|
|
value={formData.description}
|
|
onChange={(e) =>
|
|
setFormData({
|
|
...formData,
|
|
description: e.target.value,
|
|
})
|
|
}
|
|
placeholder="템플릿에 대한 간단한 설명을 입력하세요"
|
|
rows={3}
|
|
disabled={isSaving}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<ResizableDialogFooter>
|
|
<Button variant="outline" onClick={handleClose} disabled={isSaving}>
|
|
취소
|
|
</Button>
|
|
<Button onClick={handleSave} disabled={isSaving}>
|
|
{isSaving ? (
|
|
<>
|
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
저장 중...
|
|
</>
|
|
) : (
|
|
"저장"
|
|
)}
|
|
</Button>
|
|
</ResizableDialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|