From 41ad2455ac47d8e2da331d7240ded1354df9a784 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Tue, 18 Nov 2025 10:33:20 +0000
Subject: (최겸) 구매 피드백 반영
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/pq-input/pq-input-tabs.tsx | 136 +++++++++++++++++++++++++++-------
 1 file changed, 109 insertions(+), 27 deletions(-)

(limited to 'components/pq-input/pq-input-tabs.tsx')

diff --git a/components/pq-input/pq-input-tabs.tsx b/components/pq-input/pq-input-tabs.tsx
index f0d44d04..df911d5e 100644
--- a/components/pq-input/pq-input-tabs.tsx
+++ b/components/pq-input/pq-input-tabs.tsx
@@ -276,6 +276,55 @@ export function PQInputTabs({
     setAllSaved(allItemsSaved)
   }, [form.watch()])
 
+  // ----------------------------------------------------------------------
+  // C-1) Calculate item counts for display
+  // ----------------------------------------------------------------------
+
+  // ----------------------------------------------------------------------
+  // C-2) Tab color mapping for better visual distinction
+  // ----------------------------------------------------------------------
+  const getTabColorClasses = (groupName: string) => {
+    switch (groupName.toLowerCase()) {
+      case 'general':
+        return {
+          tab: 'data-[state=active]:bg-blue-50 data-[state=active]:text-blue-700 data-[state=active]:border-blue-200',
+          badge: 'bg-blue-100 text-blue-800 border-blue-200'
+        }
+      case 'hsg':
+        return {
+          tab: 'data-[state=active]:bg-green-50 data-[state=active]:text-green-700 data-[state=active]:border-green-200',
+          badge: 'bg-green-100 text-green-800 border-green-200'
+        }
+      case 'qms':
+        return {
+          tab: 'data-[state=active]:bg-orange-50 data-[state=active]:text-orange-700 data-[state=active]:border-orange-200',
+          badge: 'bg-orange-100 text-orange-800 border-orange-200'
+        }
+      case 'warranty':
+        return {
+          tab: 'data-[state=active]:bg-red-50 data-[state=active]:text-red-700 data-[state=active]:border-red-200',
+          badge: 'bg-red-100 text-red-800 border-red-200'
+        }
+      default:
+        return {
+          tab: 'data-[state=active]:bg-gray-50 data-[state=active]:text-gray-700 data-[state=active]:border-gray-200',
+          badge: 'bg-gray-100 text-gray-800 border-gray-200'
+        }
+    }
+  }
+  const getItemCounts = () => {
+    const values = form.getValues()
+    const totalItems = values.answers.length
+    const savedItems = values.answers.filter(
+      (answer) => answer.saved && (answer.answer || answer.uploadedFiles.length > 0)
+    ).length
+    const notSavedItems = totalItems - savedItems
+
+    return { totalItems, savedItems, notSavedItems }
+  }
+
+  const { totalItems, savedItems, notSavedItems } = getItemCounts()
+
   // Helper to find the array index by criteriaId
   const getAnswerIndex = (criteriaId: number): number => {
     return form.getValues().answers.findIndex((a) => a.criteriaId === criteriaId)
@@ -677,6 +726,30 @@ export function PQInputTabs({
         <Tabs defaultValue={data[0]?.groupName || ""} className="w-full">
           {/* Top Controls - Sticky Header */}
           <div className="sticky top-0 z-10 bg-background border-b border-border mb-4 pb-4">
+            {/* Item Count Display */}
+            <div className="mb-3 flex items-center gap-6 text-sm">
+              <div className="flex items-center gap-4">
+                <span className="font-medium">총 항목:</span>
+                <Badge variant="outline" className="text-xs">
+                  {totalItems}
+                </Badge>
+              </div>
+              <div className="flex items-center gap-2">
+                <CheckCircle2 className="h-4 w-4 text-green-600" />
+                <span className="text-green-600 font-medium">Saved:</span>
+                <Badge variant="outline" className="bg-green-50 text-green-700 border-green-200 text-xs">
+                  {savedItems}
+                </Badge>
+              </div>
+              <div className="flex items-center gap-2">
+                <AlertTriangle className="h-4 w-4 text-amber-600" />
+                <span className="text-amber-600 font-medium">Not Saved:</span>
+                <Badge variant="outline" className="bg-amber-50 text-amber-700 border-amber-200 text-xs">
+                  {notSavedItems}
+                </Badge>
+              </div>
+            </div>
+
             {/* Filter Controls */}
             <div className="mb-3 flex items-center gap-4">
               <span className="text-sm font-medium">필터:</span>
@@ -702,8 +775,11 @@ export function PQInputTabs({
                     checked={filterOptions.showSaved}
                     onCheckedChange={(checked) => {
                       const newOptions = { ...filterOptions, showSaved: !!checked };
-                      if (!checked && !filterOptions.showAll && !filterOptions.showNotSaved) {
-                        // 최소 하나는 체크되어 있어야 함
+                      // Save 항목이나 Not Save 항목을 선택하면 전체 항목 자동 해제
+                      if (checked) {
+                        newOptions.showAll = false;
+                      } else if (!filterOptions.showNotSaved && !filterOptions.showAll) {
+                        // 최소 하나는 체크되어 있어야 함 - 모두 해제되면 전체 항목 체크
                         newOptions.showAll = true;
                       }
                       setFilterOptions(newOptions);
@@ -717,8 +793,11 @@ export function PQInputTabs({
                     checked={filterOptions.showNotSaved}
                     onCheckedChange={(checked) => {
                       const newOptions = { ...filterOptions, showNotSaved: !!checked };
-                      if (!checked && !filterOptions.showAll && !filterOptions.showSaved) {
-                        // 최소 하나는 체크되어 있어야 함
+                      // Save 항목이나 Not Save 항목을 선택하면 전체 항목 자동 해제
+                      if (checked) {
+                        newOptions.showAll = false;
+                      } else if (!filterOptions.showSaved && !filterOptions.showAll) {
+                        // 최소 하나는 체크되어 있어야 함 - 모두 해제되면 전체 항목 체크
                         newOptions.showAll = true;
                       }
                       setFilterOptions(newOptions);
@@ -731,27 +810,30 @@ export function PQInputTabs({
 
             <div className="flex justify-between items-center">
               <TabsList className="grid grid-cols-4">
-                {data.map((group) => (
-                  <TabsTrigger
-                    key={group.groupName}
-                    value={group.groupName}
-                    className="truncate"
-                  >
-                    <div className="flex items-center gap-2">
-                      {/* Mobile: truncated version */}
-                      <span className="block sm:hidden">
-                        {group.groupName.length > 5
-                          ? group.groupName.slice(0, 5) + "..."
-                          : group.groupName}
-                      </span>
-                      {/* Desktop: full text */}
-                      <span className="hidden sm:block">{group.groupName}</span>
-                      <span className="inline-flex items-center justify-center h-5 min-w-5 px-1 rounded-full bg-muted text-xs font-medium">
-                        {group.items.length}
-                      </span>
-                    </div>
-                  </TabsTrigger>
-                ))}
+                {data.map((group) => {
+                  const colorClasses = getTabColorClasses(group.groupName)
+                  return (
+                    <TabsTrigger
+                      key={group.groupName}
+                      value={group.groupName}
+                      className={`truncate ${colorClasses.tab}`}
+                    >
+                      <div className="flex items-center gap-2">
+                        {/* Mobile: truncated version */}
+                        <span className="block sm:hidden">
+                          {group.groupName.length > 5
+                            ? group.groupName.slice(0, 5) + "..."
+                            : group.groupName}
+                        </span>
+                        {/* Desktop: full text */}
+                        <span className="hidden sm:block">{group.groupName}</span>
+                        <span className={`inline-flex items-center justify-center h-5 min-w-5 px-1 rounded-full text-xs font-medium ${colorClasses.badge}`}>
+                          {group.items.length}
+                        </span>
+                      </div>
+                    </TabsTrigger>
+                  )
+                })}
               </TabsList>
 
               <div className="flex gap-2">
@@ -849,13 +931,13 @@ export function PQInputTabs({
                             {/* Save Status & Button */}
                             <div className="flex items-center gap-2">
                               {!isSaved && canSave && (
-                                <span className="text-amber-600 text-xs flex items-center">
+                                <span className="text-amber-600 text-sm font-medium flex items-center">
                                   <AlertTriangle className="h-4 w-4 mr-1" />
                                   Not Saved
                                 </span>
                               )}
                               {isSaved && (
-                                <span className="text-green-600 text-xs flex items-center">
+                                <span className="text-green-600 text-sm font-medium flex items-center">
                                   <CheckCircle2 className="h-4 w-4 mr-1" />
                                   Saved
                                 </span>
-- 
cgit v1.2.3

