From 4ee8b24cfadf47452807fa2af801385ed60ab47c Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 15 Sep 2025 14:41:01 +0000
Subject: (대표님) 작업사항 - rfqLast, tbeLast, pdfTron, userAuth
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/tbe-last/vendor/vendor-comment-dialog.tsx | 313 ++++++++++++++++++++++++++
 1 file changed, 313 insertions(+)
 create mode 100644 lib/tbe-last/vendor/vendor-comment-dialog.tsx

(limited to 'lib/tbe-last/vendor/vendor-comment-dialog.tsx')

diff --git a/lib/tbe-last/vendor/vendor-comment-dialog.tsx b/lib/tbe-last/vendor/vendor-comment-dialog.tsx
new file mode 100644
index 00000000..8aa8d97c
--- /dev/null
+++ b/lib/tbe-last/vendor/vendor-comment-dialog.tsx
@@ -0,0 +1,313 @@
+// lib/vendor-rfq-response/vendor-tbe-table/vendor-qa-dialog.tsx
+
+"use client"
+
+import * as React from "react"
+import {
+  Dialog,
+  DialogContent,
+  DialogHeader,
+  DialogTitle,
+  DialogDescription,
+} from "@/components/ui/dialog"
+import { Button } from "@/components/ui/button"
+import { Label } from "@/components/ui/label"
+import { Textarea } from "@/components/ui/textarea"
+import {
+  Select,
+  SelectContent,
+  SelectItem,
+  SelectTrigger,
+  SelectValue,
+} from "@/components/ui/select"
+import { Badge } from "@/components/ui/badge"
+import { ScrollArea } from "@/components/ui/scroll-area"
+import { toast } from "sonner"
+import { 
+  MessageSquare, 
+  Send, 
+  Loader2, 
+  Clock, 
+  CheckCircle,
+  AlertCircle 
+} from "lucide-react"
+import { formatDate } from "@/lib/utils"
+
+interface VendorQuestion {
+  id: string
+  category: string
+  question: string
+  askedAt: string
+  askedBy: number
+  askedByName?: string
+  answer?: string
+  answeredAt?: string
+  answeredBy?: number
+  answeredByName?: string
+  status: "open" | "answered" | "closed"
+  priority?: "high" | "normal" | "low"
+}
+
+interface VendorQADialogProps {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+  sessionId: number | null
+  sessionDetail: any
+  onQuestionSubmit: () => void
+}
+
+export function VendorQADialog({
+  open,
+  onOpenChange,
+  sessionId,
+  sessionDetail,
+  onQuestionSubmit
+}: VendorQADialogProps) {
+  
+  const [category, setCategory] = React.useState("general")
+  const [priority, setPriority] = React.useState("normal")
+  const [question, setQuestion] = React.useState("")
+  const [isSubmitting, setIsSubmitting] = React.useState(false)
+  const [questions, setQuestions] = React.useState<VendorQuestion[]>([])
+  const [isLoading, setIsLoading] = React.useState(false)
+  
+  // Load questions when dialog opens
+  React.useEffect(() => {
+    if (open && sessionId) {
+      loadQuestions()
+    }
+  }, [open, sessionId])
+  
+  const loadQuestions = async () => {
+    if (!sessionId) return
+    
+    setIsLoading(true)
+    try {
+      const response = await fetch(`/api/tbe/sessions/${sessionId}/vendor-questions`)
+      if (response.ok) {
+        const data = await response.json()
+        setQuestions(data)
+      }
+    } catch (error) {
+      console.error("Failed to load questions:", error)
+    } finally {
+      setIsLoading(false)
+    }
+  }
+  
+  // Submit question
+  const handleSubmit = async () => {
+    if (!sessionId || !question.trim()) {
+      toast.error("질문을 입력해주세요")
+      return
+    }
+    
+    setIsSubmitting(true)
+    
+    try {
+      const response = await fetch(`/api/tbe/sessions/${sessionId}/vendor-questions`, {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/json",
+        },
+        body: JSON.stringify({
+          category,
+          question,
+          priority
+        })
+      })
+      
+      if (!response.ok) throw new Error("Failed to submit question")
+      
+      toast.success("질문이 제출되었습니다")
+      
+      // Reset form
+      setCategory("general")
+      setPriority("normal")
+      setQuestion("")
+      
+      // Reload questions
+      await loadQuestions()
+      
+      // Callback
+      onQuestionSubmit()
+      
+    } catch (error) {
+      console.error("Question submission error:", error)
+      toast.error("질문 제출 중 오류가 발생했습니다")
+    } finally {
+      setIsSubmitting(false)
+    }
+  }
+  
+  // Get status icon
+  const getStatusIcon = (status: string) => {
+    switch (status) {
+      case "answered":
+        return <CheckCircle className="h-4 w-4 text-green-600" />
+      case "closed":
+        return <CheckCircle className="h-4 w-4 text-gray-600" />
+      default:
+        return <Clock className="h-4 w-4 text-orange-600" />
+    }
+  }
+  
+  // Get priority color
+  const getPriorityColor = (priority?: string) => {
+    switch (priority) {
+      case "high":
+        return "destructive"
+      case "low":
+        return "secondary"
+      default:
+        return "default"
+    }
+  }
+  
+  return (
+    <Dialog open={open} onOpenChange={onOpenChange}>
+      <DialogContent className="max-w-3xl max-h-[80vh]">
+        <DialogHeader>
+          <DialogTitle>Q&A with Buyer</DialogTitle>
+          <DialogDescription>
+            {sessionDetail?.session?.sessionCode} - 구매자에게 질문하기
+          </DialogDescription>
+        </DialogHeader>
+        
+        <div className="space-y-4">
+          {/* Previous Questions */}
+          {questions.length > 0 && (
+            <div>
+              <Label className="text-sm font-medium mb-2">Previous Q&A</Label>
+              <ScrollArea className="h-[200px] border rounded-lg p-3">
+                <div className="space-y-3">
+                  {questions.map(q => (
+                    <div key={q.id} className="border-b pb-3 last:border-0">
+                      <div className="flex items-start justify-between mb-2">
+                        <div className="flex items-center gap-2">
+                          {getStatusIcon(q.status)}
+                          <Badge variant="outline" className="text-xs">
+                            {q.category}
+                          </Badge>
+                          {q.priority && q.priority !== "normal" && (
+                            <Badge variant={getPriorityColor(q.priority)} className="text-xs">
+                              {q.priority}
+                            </Badge>
+                          )}
+                        </div>
+                        <span className="text-xs text-muted-foreground">
+                          {formatDate(q.askedAt, "KR")}
+                        </span>
+                      </div>
+                      
+                      <div className="space-y-2">
+                        <div className="text-sm">
+                          <strong>Q:</strong> {q.question}
+                        </div>
+                        
+                        {q.answer && (
+                          <div className="text-sm text-muted-foreground ml-4">
+                            <strong>A:</strong> {q.answer}
+                            <span className="text-xs ml-2">
+                              ({formatDate(q.answeredAt!, "KR")})
+                            </span>
+                          </div>
+                        )}
+                      </div>
+                    </div>
+                  ))}
+                </div>
+              </ScrollArea>
+            </div>
+          )}
+          
+          {/* New Question Form */}
+          <div className="space-y-3">
+            <div className="grid grid-cols-2 gap-3">
+              <div>
+                <Label htmlFor="category">Category</Label>
+                <Select value={category} onValueChange={setCategory}>
+                  <SelectTrigger>
+                    <SelectValue />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="general">일반 문의</SelectItem>
+                    <SelectItem value="technical">기술 관련</SelectItem>
+                    <SelectItem value="commercial">상업 조건</SelectItem>
+                    <SelectItem value="delivery">납기 관련</SelectItem>
+                    <SelectItem value="quality">품질 관련</SelectItem>
+                    <SelectItem value="document">문서 관련</SelectItem>
+                    <SelectItem value="clarification">명확화 요청</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+              
+              <div>
+                <Label htmlFor="priority">Priority</Label>
+                <Select value={priority} onValueChange={setPriority}>
+                  <SelectTrigger>
+                    <SelectValue />
+                  </SelectTrigger>
+                  <SelectContent>
+                    <SelectItem value="high">High</SelectItem>
+                    <SelectItem value="normal">Normal</SelectItem>
+                    <SelectItem value="low">Low</SelectItem>
+                  </SelectContent>
+                </Select>
+              </div>
+            </div>
+            
+            <div>
+              <Label htmlFor="question">Your Question</Label>
+              <Textarea
+                id="question"
+                value={question}
+                onChange={(e) => setQuestion(e.target.value)}
+                placeholder="구매자에게 질문할 내용을 입력하세요..."
+                className="min-h-[100px]"
+                disabled={isSubmitting}
+              />
+            </div>
+            
+            <div className="flex justify-end gap-2">
+              <Button
+                variant="outline"
+                onClick={() => onOpenChange(false)}
+                disabled={isSubmitting}
+              >
+                취소
+              </Button>
+              <Button
+                onClick={handleSubmit}
+                disabled={!question.trim() || isSubmitting}
+              >
+                {isSubmitting ? (
+                  <>
+                    <Loader2 className="h-4 w-4 mr-2 animate-spin" />
+                    제출 중...
+                  </>
+                ) : (
+                  <>
+                    <Send className="h-4 w-4 mr-2" />
+                    질문 제출
+                  </>
+                )}
+              </Button>
+            </div>
+          </div>
+          
+          {/* Info Box */}
+          <div className="p-3 bg-muted/50 rounded-lg">
+            <div className="flex items-start gap-2">
+              <AlertCircle className="h-4 w-4 text-muted-foreground mt-0.5" />
+              <p className="text-xs text-muted-foreground">
+                제출된 질문은 구매담당자가 확인 후 답변을 제공합니다.
+                긴급한 질문은 Priority를 High로 설정해주세요.
+              </p>
+            </div>
+          </div>
+        </div>
+      </DialogContent>
+    </Dialog>
+  )
+}
\ No newline at end of file
-- 
cgit v1.2.3

