Browse Source

feat: hide controls for products excluded by category

- Remove checkbox and switch controls for products excluded by category
- Prevent individual enabling of products that belong to excluded categories
- Update select all logic to only include selectable items
- Maintains "By Category" badge for visual indication of exclusion reason

When a category is excluded, products in that category cannot be individually
enabled until the category itself is included first. This enforces the
category-level exclusion policy in the WebUI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fszontagh 4 months ago
parent
commit
a55e40448d
1 changed files with 33 additions and 18 deletions
  1. 33 18
      shopcall.ai-main/src/components/ManageStoreDataContent.tsx

+ 33 - 18
shopcall.ai-main/src/components/ManageStoreDataContent.tsx

@@ -271,7 +271,7 @@ export function ManageStoreDataContent() {
     }
   };
 
-  const handleToggleItem = async (itemId: string, currentEnabled: boolean) => {
+  const handleToggleItem = async (itemId: string, currentEnabled: boolean, product?: Product) => {
     if (!selectedStore) return;
 
     try {
@@ -519,7 +519,11 @@ export function ManageStoreDataContent() {
   const handleSelectAll = (checked: boolean) => {
     setSelectAll(checked);
     if (checked) {
-      setSelectedItems(new Set(data.map(item => item.id)));
+      // Only select items that are not excluded by category (or are enabled)
+      const selectableItems = data.filter(item =>
+        !(item.excluded_by_category && !item.enabled_in_context)
+      );
+      setSelectedItems(new Set(selectableItems.map(item => item.id)));
     } else {
       setSelectedItems(new Set());
     }
@@ -533,7 +537,12 @@ export function ManageStoreDataContent() {
       newSelected.delete(itemId);
     }
     setSelectedItems(newSelected);
-    setSelectAll(newSelected.size === data.length);
+
+    // Check if all selectable items are selected
+    const selectableItems = data.filter(item =>
+      !(item.excluded_by_category && !item.enabled_in_context)
+    );
+    setSelectAll(newSelected.size === selectableItems.length);
   };
 
   const renderProductRow = (product: Product) => {
@@ -544,10 +553,13 @@ export function ManageStoreDataContent() {
     return (
       <TableRow key={product.id}>
         <TableCell>
-          <Checkbox
-            checked={selectedItems.has(product.id)}
-            onCheckedChange={(checked) => handleSelectItem(product.id, checked as boolean)}
-          />
+          {/* Hide checkbox for products excluded by category */}
+          {!(product.excluded_by_category && !product.enabled_in_context) && (
+            <Checkbox
+              checked={selectedItems.has(product.id)}
+              onCheckedChange={(checked) => handleSelectItem(product.id, checked as boolean)}
+            />
+          )}
         </TableCell>
         <TableCell className="text-white font-medium">{product.name}</TableCell>
         <TableCell className="text-white">{product.sku || 'N/A'}</TableCell>
@@ -560,11 +572,14 @@ export function ManageStoreDataContent() {
         </TableCell>
         <TableCell>
           <div className="flex items-center gap-2">
-            <Switch
-              checked={product.enabled_in_context}
-              onCheckedChange={() => handleToggleItem(product.id, product.enabled_in_context)}
-              className="data-[state=checked]:bg-cyan-500"
-            />
+            {/* Hide switch for products excluded by category */}
+            {!(product.excluded_by_category && !product.enabled_in_context) && (
+              <Switch
+                checked={product.enabled_in_context}
+                onCheckedChange={() => handleToggleItem(product.id, product.enabled_in_context, product)}
+                className="data-[state=checked]:bg-cyan-500"
+              />
+            )}
             {!product.enabled_in_context && product.exclusion_reason && (
               <Badge
                 variant={product.exclusion_reason === 'category' ? 'secondary' : 'destructive'}
@@ -673,7 +688,7 @@ export function ManageStoreDataContent() {
                 <SelectTrigger className="w-[180px] bg-slate-700 border-slate-600 text-white">
                   <SelectValue />
                 </SelectTrigger>
-                <SelectContent className="bg-slate-700 border-slate-600">
+                <SelectContent className="bg-slate-700 border-slate-600 text-white">
                   <SelectItem value="all">All Items</SelectItem>
                   <SelectItem value="enabled">Enabled Only</SelectItem>
                   <SelectItem value="disabled">Disabled Only</SelectItem>
@@ -692,10 +707,10 @@ export function ManageStoreDataContent() {
                     {categories.map((cat) => (
                       <SelectItem key={cat.category_id} value={cat.category_id}>
                         <div className="flex items-center justify-between w-full gap-2">
-                          <span className={cat.is_excluded ? 'line-through text-slate-500' : ''}>
+                          <span className={cat.is_excluded ? 'line-through text-slate-500' : 'text-white'}>
                             {cat.category_name}
                           </span>
-                          <Badge variant="secondary" className="text-xs">
+                          <Badge variant="secondary" className="text-xs text-white">
                             {cat.product_count}
                           </Badge>
                         </div>
@@ -758,7 +773,7 @@ export function ManageStoreDataContent() {
                   size="sm"
                   variant="outline"
                   onClick={() => handleBulkAction(false)}
-                  className="border-slate-400 text-slate-400 hover:bg-slate-600"
+                  className="bg-slate-700 border-slate-600 text-white"
                 >
                   Disable Selected
                 </Button>
@@ -775,7 +790,7 @@ export function ManageStoreDataContent() {
                   description: `Are you sure you want to enable all ${activeTab} for AI context? This will also clear all category exclusions.`,
                   action: handleEnableAll
                 })}
-                className="border-cyan-500 text-cyan-500 hover:bg-cyan-500 hover:text-white"
+                className="bg-slate-700 border-slate-600 text-white"
               >
                 Enable All
               </Button>
@@ -788,7 +803,7 @@ export function ManageStoreDataContent() {
                   description: `Are you sure you want to disable all ${activeTab} from AI context?`,
                   action: handleDisableAll
                 })}
-                className="border-slate-400 text-slate-400 hover:bg-slate-600"
+                className="bg-slate-700 border-slate-600 text-white"
               >
                 Disable All
               </Button>