summaryrefslogtreecommitdiff
path: root/lib/b-rfq/vendor-response/comment-edit-dialog.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-17 09:02:32 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-17 09:02:32 +0000
commit7a1524ba54f43d0f2a19e4bca2c6a2e0b01c5ef1 (patch)
treedaa214d404c7fc78b32419a028724e5671a6c7a4 /lib/b-rfq/vendor-response/comment-edit-dialog.tsx
parentfa6a6093014c5d60188edfc9c4552e81c4b97bd1 (diff)
(대표님) 20250617 18시 작업사항
Diffstat (limited to 'lib/b-rfq/vendor-response/comment-edit-dialog.tsx')
-rw-r--r--lib/b-rfq/vendor-response/comment-edit-dialog.tsx187
1 files changed, 187 insertions, 0 deletions
diff --git a/lib/b-rfq/vendor-response/comment-edit-dialog.tsx b/lib/b-rfq/vendor-response/comment-edit-dialog.tsx
new file mode 100644
index 00000000..0c2c0c62
--- /dev/null
+++ b/lib/b-rfq/vendor-response/comment-edit-dialog.tsx
@@ -0,0 +1,187 @@
+// components/rfq/comment-edit-dialog.tsx
+"use client";
+
+import { useState } from "react";
+import { Button } from "@/components/ui/button";
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+ DialogTrigger,
+} from "@/components/ui/dialog";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form";
+import { Textarea } from "@/components/ui/textarea";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import * as z from "zod";
+import { MessageSquare, Loader2 } from "lucide-react";
+import { useToast } from "@/hooks/use-toast";
+import { useRouter } from "next/navigation";
+
+const commentFormSchema = z.object({
+ responseComment: z.string().optional(),
+ vendorComment: z.string().optional(),
+});
+
+type CommentFormData = z.infer<typeof commentFormSchema>;
+
+interface CommentEditDialogProps {
+ responseId: number;
+ currentResponseComment?: string;
+ currentVendorComment?: string;
+ trigger?: React.ReactNode;
+ onSuccess?: () => void;
+}
+
+export function CommentEditDialog({
+ responseId,
+ currentResponseComment,
+ currentVendorComment,
+ trigger,
+ onSuccess,
+}: CommentEditDialogProps) {
+ const [open, setOpen] = useState(false);
+ const [isSaving, setIsSaving] = useState(false);
+ const { toast } = useToast();
+ const router = useRouter();
+
+ const form = useForm<CommentFormData>({
+ resolver: zodResolver(commentFormSchema),
+ defaultValues: {
+ responseComment: currentResponseComment || "",
+ vendorComment: currentVendorComment || "",
+ },
+ });
+
+ const onSubmit = async (data: CommentFormData) => {
+ setIsSaving(true);
+
+ try {
+ const response = await fetch("/api/vendor-responses/update-comment", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({
+ responseId,
+ responseComment: data.responseComment,
+ vendorComment: data.vendorComment,
+ }),
+ });
+
+ if (!response.ok) {
+ const error = await response.json();
+ throw new Error(error.message || "코멘트 업데이트 실패");
+ }
+
+ toast({
+ title: "코멘트 업데이트 완료",
+ description: "코멘트가 성공적으로 업데이트되었습니다.",
+ });
+
+ setOpen(false);
+
+ router.refresh();
+ onSuccess?.();
+
+ } catch (error) {
+ console.error("Comment update error:", error);
+ toast({
+ title: "업데이트 실패",
+ description: error instanceof Error ? error.message : "알 수 없는 오류가 발생했습니다.",
+ variant: "destructive",
+ });
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ return (
+ <Dialog open={open} onOpenChange={setOpen}>
+ <DialogTrigger asChild>
+ {trigger || (
+ <Button size="sm" variant="outline">
+ <MessageSquare className="h-3 w-3 mr-1" />
+ 코멘트
+ </Button>
+ )}
+ </DialogTrigger>
+ <DialogContent className="max-w-lg">
+ <DialogHeader>
+ <DialogTitle className="flex items-center gap-2">
+ <MessageSquare className="h-5 w-5" />
+ 코멘트 수정
+ </DialogTitle>
+ </DialogHeader>
+
+ <Form {...form}>
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
+ {/* 응답 코멘트 */}
+ <FormField
+ control={form.control}
+ name="responseComment"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>응답 코멘트</FormLabel>
+ <FormControl>
+ <Textarea
+ placeholder="응답에 대한 설명을 입력하세요..."
+ className="resize-none"
+ rows={3}
+ {...field}
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 벤더 코멘트 */}
+ <FormField
+ control={form.control}
+ name="vendorComment"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel>벤더 코멘트 (내부용)</FormLabel>
+ <FormControl>
+ <Textarea
+ placeholder="내부 참고용 코멘트를 입력하세요..."
+ className="resize-none"
+ rows={3}
+ {...field}
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ {/* 버튼 */}
+ <div className="flex justify-end gap-2">
+ <Button
+ type="button"
+ variant="outline"
+ onClick={() => setOpen(false)}
+ disabled={isSaving}
+ >
+ 취소
+ </Button>
+ <Button type="submit" disabled={isSaving}>
+ {isSaving && <Loader2 className="h-4 w-4 mr-2 animate-spin" />}
+ {isSaving ? "저장 중..." : "저장"}
+ </Button>
+ </div>
+ </form>
+ </Form>
+ </DialogContent>
+ </Dialog>
+ );
+} \ No newline at end of file