@burdenoff/microfe-adaptercloud 2026.625.2 → 2026.628.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/dist/adaptercloud/AdapterCloudRoot.js +65 -121
  2. package/dist/adaptercloud/AdapterCloudRoot.js.map +1 -1
  3. package/dist/adaptercloud/AdapterCloudRoutes.js +70 -182
  4. package/dist/adaptercloud/AdapterCloudRoutes.js.map +1 -1
  5. package/dist/adaptercloud/components/DataState.js +42 -0
  6. package/dist/adaptercloud/components/DataState.js.map +1 -0
  7. package/dist/adaptercloud/components/SeverityBadge.js +12 -0
  8. package/dist/adaptercloud/components/SeverityBadge.js.map +1 -0
  9. package/dist/adaptercloud/components/StatusBadge.js +43 -44
  10. package/dist/adaptercloud/components/StatusBadge.js.map +1 -1
  11. package/dist/adaptercloud/context/AdapterCloudContext.js +22 -30
  12. package/dist/adaptercloud/context/AdapterCloudContext.js.map +1 -1
  13. package/dist/adaptercloud/hooks/useAdapterCloudApi.js +397 -194
  14. package/dist/adaptercloud/hooks/useAdapterCloudApi.js.map +1 -1
  15. package/dist/adaptercloud/index.js +1 -0
  16. package/dist/adaptercloud/pages/OverviewPage.js +334 -0
  17. package/dist/adaptercloud/pages/OverviewPage.js.map +1 -0
  18. package/dist/adaptercloud/pages/adapters/AdapterDetailPage.js +187 -0
  19. package/dist/adaptercloud/pages/adapters/AdapterDetailPage.js.map +1 -0
  20. package/dist/adaptercloud/pages/adapters/AdapterFormPage.js +278 -0
  21. package/dist/adaptercloud/pages/adapters/AdapterFormPage.js.map +1 -0
  22. package/dist/adaptercloud/pages/adapters/AdaptersListPage.js +172 -0
  23. package/dist/adaptercloud/pages/adapters/AdaptersListPage.js.map +1 -0
  24. package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js +247 -0
  25. package/dist/adaptercloud/pages/connections/ConnectionDetailPage.js.map +1 -0
  26. package/dist/adaptercloud/pages/connections/ConnectionFormPage.js +271 -0
  27. package/dist/adaptercloud/pages/connections/ConnectionFormPage.js.map +1 -0
  28. package/dist/adaptercloud/pages/connections/ConnectionsListPage.js +167 -0
  29. package/dist/adaptercloud/pages/connections/ConnectionsListPage.js.map +1 -0
  30. package/dist/adaptercloud/pages/costs/CostsPage.js +169 -0
  31. package/dist/adaptercloud/pages/costs/CostsPage.js.map +1 -0
  32. package/dist/adaptercloud/pages/drift/DriftListPage.js +132 -0
  33. package/dist/adaptercloud/pages/drift/DriftListPage.js.map +1 -0
  34. package/dist/adaptercloud/pages/policies/PoliciesListPage.js +171 -0
  35. package/dist/adaptercloud/pages/policies/PoliciesListPage.js.map +1 -0
  36. package/dist/adaptercloud/pages/policies/PolicyDetailPage.js +185 -0
  37. package/dist/adaptercloud/pages/policies/PolicyDetailPage.js.map +1 -0
  38. package/dist/adaptercloud/pages/policies/PolicyFormPage.js +215 -0
  39. package/dist/adaptercloud/pages/policies/PolicyFormPage.js.map +1 -0
  40. package/dist/adaptercloud/pages/resources/ResourceDetailPage.js +207 -0
  41. package/dist/adaptercloud/pages/resources/ResourceDetailPage.js.map +1 -0
  42. package/dist/adaptercloud/pages/resources/ResourcesListPage.js +182 -0
  43. package/dist/adaptercloud/pages/resources/ResourcesListPage.js.map +1 -0
  44. package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js +196 -0
  45. package/dist/adaptercloud/pages/sync-runs/SyncRunsListPage.js.map +1 -0
  46. package/dist/adaptercloud/pages/violations/ViolationsListPage.js +258 -0
  47. package/dist/adaptercloud/pages/violations/ViolationsListPage.js.map +1 -0
  48. package/dist/adaptercloud/store/adaptercloudStore.js +1 -7
  49. package/dist/adaptercloud/store/adaptercloudStore.js.map +1 -1
  50. package/dist/adaptercloud/utils/domain.js +105 -0
  51. package/dist/adaptercloud/utils/domain.js.map +1 -0
  52. package/dist/adaptercloud/utils/formatters.js +1 -12
  53. package/dist/adaptercloud/utils/formatters.js.map +1 -1
  54. package/dist/index.js +5 -4
  55. package/package.json +1 -1
  56. package/dist/adaptercloud/components/InvestmentCard.js +0 -98
  57. package/dist/adaptercloud/components/InvestmentCard.js.map +0 -1
  58. package/dist/adaptercloud/components/RatingDisplay.js +0 -35
  59. package/dist/adaptercloud/components/RatingDisplay.js.map +0 -1
  60. package/dist/adaptercloud/mocks/data.js +0 -1517
  61. package/dist/adaptercloud/mocks/data.js.map +0 -1
  62. package/dist/adaptercloud/mocks/users.js +0 -34
  63. package/dist/adaptercloud/mocks/users.js.map +0 -1
  64. package/dist/adaptercloud/pages/HomePage.js +0 -934
  65. package/dist/adaptercloud/pages/HomePage.js.map +0 -1
  66. package/dist/adaptercloud/pages/admin/AdminAnalyticsPage.js +0 -653
  67. package/dist/adaptercloud/pages/admin/AdminAnalyticsPage.js.map +0 -1
  68. package/dist/adaptercloud/pages/admin/AdminDashboard.js +0 -665
  69. package/dist/adaptercloud/pages/admin/AdminDashboard.js.map +0 -1
  70. package/dist/adaptercloud/pages/admin/AdminFinancialPage.js +0 -426
  71. package/dist/adaptercloud/pages/admin/AdminFinancialPage.js.map +0 -1
  72. package/dist/adaptercloud/pages/admin/AdminOrdersPage.js +0 -665
  73. package/dist/adaptercloud/pages/admin/AdminOrdersPage.js.map +0 -1
  74. package/dist/adaptercloud/pages/admin/AdminProfilePage.js +0 -261
  75. package/dist/adaptercloud/pages/admin/AdminProfilePage.js.map +0 -1
  76. package/dist/adaptercloud/pages/admin/AdminSettingsPage.js +0 -663
  77. package/dist/adaptercloud/pages/admin/AdminSettingsPage.js.map +0 -1
  78. package/dist/adaptercloud/pages/admin/CartManagementPage.js +0 -874
  79. package/dist/adaptercloud/pages/admin/CartManagementPage.js.map +0 -1
  80. package/dist/adaptercloud/pages/admin/UserManagementPage.js +0 -898
  81. package/dist/adaptercloud/pages/admin/UserManagementPage.js.map +0 -1
  82. package/dist/adaptercloud/pages/cart-owner/AnalyticsDashboard.js +0 -840
  83. package/dist/adaptercloud/pages/cart-owner/AnalyticsDashboard.js.map +0 -1
  84. package/dist/adaptercloud/pages/cart-owner/BusinessSettingsPage.js +0 -714
  85. package/dist/adaptercloud/pages/cart-owner/BusinessSettingsPage.js.map +0 -1
  86. package/dist/adaptercloud/pages/cart-owner/CartOwnerDashboard.js +0 -788
  87. package/dist/adaptercloud/pages/cart-owner/CartOwnerDashboard.js.map +0 -1
  88. package/dist/adaptercloud/pages/cart-owner/CartOwnerProfilePage.js +0 -888
  89. package/dist/adaptercloud/pages/cart-owner/CartOwnerProfilePage.js.map +0 -1
  90. package/dist/adaptercloud/pages/cart-owner/CartServiceConfigPage.js +0 -634
  91. package/dist/adaptercloud/pages/cart-owner/CartServiceConfigPage.js.map +0 -1
  92. package/dist/adaptercloud/pages/cart-owner/InventoryManagementPage.js +0 -907
  93. package/dist/adaptercloud/pages/cart-owner/InventoryManagementPage.js.map +0 -1
  94. package/dist/adaptercloud/pages/cart-owner/OrderManagementPage.js +0 -875
  95. package/dist/adaptercloud/pages/cart-owner/OrderManagementPage.js.map +0 -1
  96. package/dist/adaptercloud/pages/cart-owner/StaffManagementPage.js +0 -827
  97. package/dist/adaptercloud/pages/cart-owner/StaffManagementPage.js.map +0 -1
  98. package/dist/adaptercloud/pages/common/HelpSupportPage.js +0 -1329
  99. package/dist/adaptercloud/pages/common/HelpSupportPage.js.map +0 -1
  100. package/dist/adaptercloud/pages/common/NotificationCenterPage.js +0 -671
  101. package/dist/adaptercloud/pages/common/NotificationCenterPage.js.map +0 -1
  102. package/dist/adaptercloud/pages/common/SettingsPage.js +0 -982
  103. package/dist/adaptercloud/pages/common/SettingsPage.js.map +0 -1
  104. package/dist/adaptercloud/pages/customer/BookingDetailsPage.js +0 -596
  105. package/dist/adaptercloud/pages/customer/BookingDetailsPage.js.map +0 -1
  106. package/dist/adaptercloud/pages/customer/CartDetailPage.js +0 -623
  107. package/dist/adaptercloud/pages/customer/CartDetailPage.js.map +0 -1
  108. package/dist/adaptercloud/pages/customer/CartDiscoveryPage.js +0 -552
  109. package/dist/adaptercloud/pages/customer/CartDiscoveryPage.js.map +0 -1
  110. package/dist/adaptercloud/pages/customer/CheckoutPage.js +0 -534
  111. package/dist/adaptercloud/pages/customer/CheckoutPage.js.map +0 -1
  112. package/dist/adaptercloud/pages/customer/CustomerDashboard.js +0 -525
  113. package/dist/adaptercloud/pages/customer/CustomerDashboard.js.map +0 -1
  114. package/dist/adaptercloud/pages/customer/CustomerProfilePage.js +0 -623
  115. package/dist/adaptercloud/pages/customer/CustomerProfilePage.js.map +0 -1
  116. package/dist/adaptercloud/pages/customer/DirectServiceBookingPage.js +0 -629
  117. package/dist/adaptercloud/pages/customer/DirectServiceBookingPage.js.map +0 -1
  118. package/dist/adaptercloud/pages/customer/FavoritesPage.js +0 -480
  119. package/dist/adaptercloud/pages/customer/FavoritesPage.js.map +0 -1
  120. package/dist/adaptercloud/pages/customer/OrderHistoryPage.js +0 -444
  121. package/dist/adaptercloud/pages/customer/OrderHistoryPage.js.map +0 -1
  122. package/dist/adaptercloud/pages/customer/OrderTrackingPage.js +0 -391
  123. package/dist/adaptercloud/pages/customer/OrderTrackingPage.js.map +0 -1
  124. package/dist/adaptercloud/pages/customer/PaymentMethodsPage.js +0 -504
  125. package/dist/adaptercloud/pages/customer/PaymentMethodsPage.js.map +0 -1
  126. package/dist/adaptercloud/pages/customer/ReviewsPage.js +0 -609
  127. package/dist/adaptercloud/pages/customer/ReviewsPage.js.map +0 -1
  128. package/dist/adaptercloud/pages/customer/SavedAddressesPage.js +0 -459
  129. package/dist/adaptercloud/pages/customer/SavedAddressesPage.js.map +0 -1
  130. package/dist/adaptercloud/pages/investor/InvestmentDetailsPage.js +0 -851
  131. package/dist/adaptercloud/pages/investor/InvestmentDetailsPage.js.map +0 -1
  132. package/dist/adaptercloud/pages/investor/InvestmentOpportunitiesPage.js +0 -942
  133. package/dist/adaptercloud/pages/investor/InvestmentOpportunitiesPage.js.map +0 -1
  134. package/dist/adaptercloud/pages/investor/InvestorAnalyticsPage.js +0 -683
  135. package/dist/adaptercloud/pages/investor/InvestorAnalyticsPage.js.map +0 -1
  136. package/dist/adaptercloud/pages/investor/InvestorDashboard.js +0 -452
  137. package/dist/adaptercloud/pages/investor/InvestorDashboard.js.map +0 -1
  138. package/dist/adaptercloud/pages/investor/InvestorInvestmentsPage.js +0 -402
  139. package/dist/adaptercloud/pages/investor/InvestorInvestmentsPage.js.map +0 -1
  140. package/dist/adaptercloud/pages/investor/InvestorPortfolioPage.js +0 -571
  141. package/dist/adaptercloud/pages/investor/InvestorPortfolioPage.js.map +0 -1
  142. package/dist/adaptercloud/pages/investor/InvestorProfilePage.js +0 -1067
  143. package/dist/adaptercloud/pages/investor/InvestorProfilePage.js.map +0 -1
  144. package/dist/adaptercloud/pages/worker/TaskDetailsPage.js +0 -526
  145. package/dist/adaptercloud/pages/worker/TaskDetailsPage.js.map +0 -1
  146. package/dist/adaptercloud/pages/worker/WorkerDashboard.js +0 -659
  147. package/dist/adaptercloud/pages/worker/WorkerDashboard.js.map +0 -1
  148. package/dist/adaptercloud/pages/worker/WorkerOrdersPage.js +0 -678
  149. package/dist/adaptercloud/pages/worker/WorkerOrdersPage.js.map +0 -1
  150. package/dist/adaptercloud/pages/worker/WorkerProfilePage.js +0 -689
  151. package/dist/adaptercloud/pages/worker/WorkerProfilePage.js.map +0 -1
  152. package/dist/adaptercloud/pages/worker/WorkerSchedulePage.js +0 -582
  153. package/dist/adaptercloud/pages/worker/WorkerSchedulePage.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"InventoryManagementPage.js","names":[],"sources":["../../../../src/adaptercloud/pages/cart-owner/InventoryManagementPage.tsx"],"sourcesContent":["/**\n * Inventory Management Page\n *\n * Full product/service CRUD with add/edit modal, filters, table+card views,\n * bulk actions, category detection (product vs service), dietary info,\n * service-specific fields, stock management.\n *\n * @module adaptercloud/pages/cart-owner\n */\n\nimport { useState, useMemo } from'react';\nimport {\n Search,\n Plus,\n Edit2,\n Trash2,\n Filter,\n Package,\n ChevronDown,\n X,\n Save,\n AlertCircle,\n CheckCircle2,\n Upload,\n} from'lucide-react';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from'../../components/PageLayout';\nimport { EmptyState } from'../../components/EmptyState';\nimport { useAdapterCloud } from'../../context/AdapterCloudContext';\nimport { mockProducts } from'../../mocks/data';\nimport { formatCurrency } from'../../utils/formatters';\nimport { cn } from'../../utils/cn';\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface InventoryItem {\n id: string;\n name: string;\n description: string;\n price: number;\n originalPrice?: number;\n category: string;\n stock: number;\n isAvailable: boolean;\n cartName: string;\n preparationTime: number;\n calories: number;\n isVegetarian: boolean;\n isVegan: boolean;\n isGlutenFree: boolean;\n spiceLevel: string;\n tags: string[];\n allergens: string[];\n // Service-specific\n duration: number;\n serviceType: string;\n requirements: string[];\n}\n\ninterface ProductFormData {\n name: string;\n description: string;\n category: string;\n price: number;\n originalPrice: number | undefined;\n isAvailable: boolean;\n stock: number;\n preparationTime: number;\n calories: number;\n isVegetarian: boolean;\n isVegan: boolean;\n isGlutenFree: boolean;\n spiceLevel: string;\n tags: string[];\n allergens: string[];\n duration: number;\n serviceType: string;\n requirements: string[];\n}\n\ninterface StatusMessage {\n text: string;\n type: 'success' | 'error';\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst SERVICE_KEYWORDS = [\n 'Service',\n 'Repair',\n 'Beauty',\n 'Care',\n 'Cleaning',\n 'Health',\n 'Wellness',\n 'Education',\n];\n\nconst isServiceCategory = (category: string): boolean => {\n return SERVICE_KEYWORDS.some((kw) => category.includes(kw));\n};\n\nconst isFoodCategory = (category: string): boolean => {\n return category === 'Food & Beverage';\n};\n\n// ============================================================================\n// Mock Inventory Data\n// ============================================================================\n\nconst stockValues = [10, 25, 0, 50, 8, 15, 3, 100, 42, 0, 20, 6, 35, 18, 12, 30, 5, 22, 0, 45];\n\nconst buildInventory = (): InventoryItem[] =>\n mockProducts.slice(0, 20).map((p, i) => ({\n id: p.id,\n name: p.name,\n description: p.description ?? `${p.name} - quality offering from ${p.cartName}`,\n price: p.price,\n originalPrice: i % 4 === 0 ? Math.round(p.price * 1.2) : undefined,\n category: p.category,\n stock: stockValues[i] ?? 10,\n isAvailable: i !== 2 && i !== 9 && i !== 18,\n cartName: p.cartName,\n preparationTime: 15,\n calories: isFoodCategory(p.category) ? Math.floor(Math.random() * 400) + 100 : 0,\n isVegetarian: i % 3 === 0,\n isVegan: i % 5 === 0,\n isGlutenFree: i % 7 === 0,\n spiceLevel: ['mild', 'medium', 'spicy', 'none'][i % 4],\n tags: ['popular', 'trending', 'new'].slice(0, (i % 3) + 1),\n allergens: isFoodCategory(p.category) ? ['nuts', 'dairy'].slice(0, (i % 2) + 1) : [],\n duration: isServiceCategory(p.category) ? 30 + i * 5 : 0,\n serviceType: isServiceCategory(p.category)\n ? ['instant', 'appointment', 'recurring', 'consultation'][i % 4]\n : '',\n requirements: isServiceCategory(p.category) ? ['advance booking'] : [],\n }));\n\nconst emptyFormData: ProductFormData = {\n name: '',\n description: '',\n category: '',\n price: 0,\n originalPrice: undefined,\n isAvailable: true,\n stock: 0,\n preparationTime: 15,\n calories: 0,\n isVegetarian: false,\n isVegan: false,\n isGlutenFree: false,\n spiceLevel: 'mild',\n tags: [],\n allergens: [],\n duration: 30,\n serviceType: 'instant',\n requirements: [],\n};\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const InventoryManagementPage = () => {\n const { navigateTo } = useAdapterCloud();\n\n // Data\n const [products, setProducts] = useState<InventoryItem[]>(buildInventory);\n\n // Filters\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedCategory, setSelectedCategory] = useState('');\n const [availability, setAvailability] = useState('');\n const [sortBy, setSortBy] = useState('name');\n const [showCategoryDropdown, setShowCategoryDropdown] = useState(false);\n\n // Modal\n const [showAddModal, setShowAddModal] = useState(false);\n const [editingProduct, setEditingProduct] = useState<InventoryItem | null>(null);\n const [formData, setFormData] = useState<ProductFormData>(emptyFormData);\n const [tagsInput, setTagsInput] = useState('');\n const [allergensInput, setAllergensInput] = useState('');\n const [requirementsInput, setRequirementsInput] = useState('');\n\n // Status\n const [statusMessage, setStatusMessage] = useState<StatusMessage | null>(null);\n\n // Derived\n const categories = useMemo(\n () => [...new Set(products.map((p) => p.category))].sort(),\n [products]\n );\n\n const filteredProducts = useMemo(() => {\n let result = [...products];\n\n if (searchQuery) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.description.toLowerCase().includes(q) ||\n p.category.toLowerCase().includes(q) ||\n p.tags.some((t) => t.toLowerCase().includes(q))\n );\n }\n\n if (selectedCategory) {\n result = result.filter((p) => p.category === selectedCategory);\n }\n\n if (availability === 'available') {\n result = result.filter((p) => p.isAvailable);\n } else if (availability === 'unavailable') {\n result = result.filter((p) => !p.isAvailable);\n }\n\n switch (sortBy) {\n case'name':\n result.sort((a, b) => a.name.localeCompare(b.name));\n break;\n case'price_low':\n result.sort((a, b) => a.price - b.price);\n break;\n case'price_high':\n result.sort((a, b) => b.price - a.price);\n break;\n case'stock':\n result.sort((a, b) => a.stock - b.stock);\n break;\n }\n\n return result;\n }, [products, searchQuery, selectedCategory, availability, sortBy]);\n\n const totalItems = products.length;\n const availableCount = products.filter((p) => p.isAvailable).length;\n const outOfStockCount = products.filter(\n (p) => !isServiceCategory(p.category) && p.stock === 0\n ).length;\n const lowStockCount = products.filter(\n (p) => !isServiceCategory(p.category) && p.stock > 0 && p.stock < 10\n ).length;\n\n // ---- Handlers ----\n\n const showStatus = (text: string, type: 'success' | 'error') => {\n setStatusMessage({ text, type });\n setTimeout(() => setStatusMessage(null), 3000);\n };\n\n const handleAddProduct = () => {\n setEditingProduct(null);\n setFormData({ ...emptyFormData, category: categories[0] || '' });\n setTagsInput('');\n setAllergensInput('');\n setRequirementsInput('');\n setShowAddModal(true);\n };\n\n const handleEditProduct = (product: InventoryItem) => {\n setEditingProduct(product);\n setFormData({\n name: product.name,\n description: product.description,\n category: product.category,\n price: product.price,\n originalPrice: product.originalPrice,\n isAvailable: product.isAvailable,\n stock: product.stock,\n preparationTime: product.preparationTime,\n calories: product.calories,\n isVegetarian: product.isVegetarian,\n isVegan: product.isVegan,\n isGlutenFree: product.isGlutenFree,\n spiceLevel: product.spiceLevel,\n tags: product.tags,\n allergens: product.allergens,\n duration: product.duration,\n serviceType: product.serviceType,\n requirements: product.requirements,\n });\n setTagsInput(product.tags.join(', '));\n setAllergensInput(product.allergens.join(', '));\n setRequirementsInput(product.requirements.join(', '));\n setShowAddModal(true);\n };\n\n const handleSaveProduct = () => {\n if (!formData.name || !formData.description || !formData.category || formData.price <= 0) {\n showStatus(\n 'Please fill all required fields (name, description, category, price > 0)',\n 'error'\n );\n return;\n }\n\n const processedTags = tagsInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const processedAllergens = allergensInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n const processedRequirements = requirementsInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n\n const isService = isServiceCategory(formData.category);\n const itemType = isService ? 'Service' : 'Product';\n\n if (editingProduct) {\n setProducts((prev) =>\n prev.map((p) =>\n p.id === editingProduct.id\n ? {\n ...p,\n ...formData,\n tags: processedTags,\n allergens: processedAllergens,\n requirements: processedRequirements,\n }\n : p\n )\n );\n showStatus(`${itemType} updated successfully`, 'success');\n } else {\n const newItem: InventoryItem = {\n id: `item-${Date.now()}`,\n ...formData,\n tags: processedTags,\n allergens: processedAllergens,\n requirements: processedRequirements,\n cartName: 'Dosa Express',\n };\n setProducts((prev) => [newItem, ...prev]);\n showStatus(`${itemType} added successfully`, 'success');\n }\n\n setShowAddModal(false);\n };\n\n const handleDeleteProduct = (productId: string) => {\n if (!confirm('Are you sure you want to delete this offering?')) return;\n setProducts((prev) => prev.filter((p) => p.id !== productId));\n showStatus('Offering deleted successfully', 'success');\n };\n\n const handleToggleAvailability = (productId: string, isAvail: boolean) => {\n setProducts((prev) =>\n prev.map((p) => (p.id === productId ? { ...p, isAvailable: isAvail } : p))\n );\n showStatus(`Offering ${isAvail ? 'enabled' : 'disabled'} successfully`, 'success');\n };\n\n const handleBulkUpdate = (action: 'enable' | 'disable') => {\n const target = action === 'enable';\n const count = products.filter((p) => p.isAvailable !== target).length;\n if (count === 0) {\n showStatus(`No offerings to ${action}`, 'error');\n return;\n }\n setProducts((prev) => prev.map((p) => ({ ...p, isAvailable: target })));\n showStatus(`${count} offerings ${action}d successfully`, 'success');\n };\n\n const getStockStatus = (item: InventoryItem) => {\n if (isServiceCategory(item.category)) {\n return { color: 'text-status-success-text', label: 'Available' };\n }\n if (item.stock === 0) return { color: 'text-status-error-text', label: 'Out of Stock' };\n if (item.stock < 10)\n return { color: 'text-status-warning-text', label: `Low Stock (${item.stock})` };\n return { color: 'text-status-success-text', label: `In Stock (${item.stock})` };\n };\n\n const isFormService = formData.category ? isServiceCategory(formData.category) : false;\n const isFormFood = formData.category ? isFoodCategory(formData.category) : false;\n const showFoodFields = !isFormService && isFormFood;\n\n const canSave =\n formData.name &&\n formData.description &&\n formData.category &&\n formData.price > 0 &&\n (!isFormService || (formData.duration && formData.duration > 0)) &&\n (isFormService || formData.stock >= 0);\n\n return (\n <PageLayout\n title=\"Offerings Management\"\n description=\"Manage your products and services\"\n purpose=\"Build the menu customers order from — add products and services, set prices and photos, and keep stock and availability up to date. Anything you list and mark available here is instantly bookable by customers.\"\n actions={\n <button\n type=\"button\"\n onClick={handleAddProduct}\n className=\"inline-flex items-center gap-2 rounded-md bg-accent px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent/80 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Add Item\n </button>\n }\n >\n <div className=\"space-y-4\">\n {/* Status Message */}\n {statusMessage && (\n <div\n className={cn(\n 'flex items-center gap-2 rounded-lg border p-3',\n statusMessage.type === 'success'\n ? 'border-status-success-border/30 bg-status-success-bg-subtle/10'\n : 'border-status-error-border/30 bg-status-error-bg-subtle/10'\n )}\n >\n {statusMessage.type === 'success' ? (\n <CheckCircle2 className=\"h-4 w-4 text-status-success-text\" />\n ) : (\n <AlertCircle className=\"h-4 w-4 text-status-error-text\" />\n )}\n <span\n className={cn(\n 'text-sm font-medium',\n statusMessage.type === 'success'\n ? 'text-status-success-text'\n : 'text-status-error-text'\n )}\n >\n {statusMessage.text}\n </span>\n </div>\n )}\n\n {/* Summary Stats (emphasis zone) */}\n <EmphasisPanel>\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-3\">\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <p className=\"text-xs text-text-secondary\">Total Items</p>\n <p className=\"text-2xl font-bold text-text-primary\">{totalItems}</p>\n </div>\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <p className=\"text-xs text-text-secondary\">Available</p>\n <p className=\"text-2xl font-bold text-status-success-text\">\n {availableCount}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <p className=\"text-xs text-text-secondary\">Out of Stock</p>\n <p className=\"text-2xl font-bold text-status-error-text\">{outOfStockCount}</p>\n </div>\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\">\n <p className=\"text-xs text-text-secondary\">Low Stock</p>\n <p className=\"text-2xl font-bold text-status-warning-text\">\n {lowStockCount}\n </p>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Actions + Filters */}\n <div className=\"rounded-lg border border-border-seam bg-bg-surface p-4 space-y-4 bg-gloss-card shadow-pop\">\n <div className=\"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-3\">\n <div className=\"flex flex-wrap gap-2\">\n <button\n type=\"button\"\n onClick={handleAddProduct}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-medium text-text-primary hover:bg-accent/80 transition-colors\"\n >\n <Plus className=\"h-4 w-4\" />\n Add Item\n </button>\n <button\n type=\"button\"\n onClick={() => handleBulkUpdate('enable')}\n className=\"rounded-md border border-border-subtle px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n Enable All\n </button>\n <button\n type=\"button\"\n onClick={() => handleBulkUpdate('disable')}\n className=\"rounded-md border border-border-subtle px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n Disable All\n </button>\n </div>\n <button\n type=\"button\"\n onClick={() => alert('Import/Export feature coming soon!')}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <Upload className=\"h-4 w-4\" />\n Import/Export\n </button>\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3\">\n <div className=\"relative sm:col-span-2 lg:col-span-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <input\n type=\"text\"\n placeholder=\"Search offerings...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface pl-10 pr-4 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"\">All Categories</option>\n {categories.map((cat) => (\n <option key={cat} value={cat}>\n {cat}\n </option>\n ))}\n </select>\n <select\n value={availability}\n onChange={(e) => setAvailability(e.target.value)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"\">All Status</option>\n <option value=\"available\">Available</option>\n <option value=\"unavailable\">Unavailable</option>\n </select>\n <select\n value={sortBy}\n onChange={(e) => setSortBy(e.target.value)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"name\">Name A-Z</option>\n <option value=\"price_low\">Price: Low to High</option>\n <option value=\"price_high\">Price: High to Low</option>\n <option value=\"stock\">Stock: Low to High</option>\n </select>\n </div>\n </div>\n\n {/* Empty State */}\n {filteredProducts.length === 0 ? (\n <EmptyState\n illustration={\n searchQuery || selectedCategory || availability ? 'empty-search' : 'empty-files'\n }\n title=\"No Items Found\"\n description={\n searchQuery || selectedCategory || availability\n ? 'No items match your current filters. Try adjusting your search criteria.'\n : \"You haven't added any items yet. Start building your offerings!\"\n }\n action={\n <div className=\"flex flex-wrap justify-center gap-3\">\n <button\n type=\"button\"\n onClick={handleAddProduct}\n className=\"inline-flex items-center gap-2 rounded-md bg-accent px-4 py-2 text-sm font-medium text-text-primary hover:bg-accent/80\"\n >\n <Plus className=\"h-4 w-4\" />\n Add Your First Item\n </button>\n {(searchQuery || selectedCategory || availability) && (\n <button\n type=\"button\"\n onClick={() => {\n setSearchQuery('');\n setSelectedCategory('');\n setAvailability('');\n setSortBy('name');\n }}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm text-text-primary hover:bg-bg-sunken\"\n >\n Clear Filters\n </button>\n )}\n </div>\n }\n />\n ) : (\n <>\n {/* Desktop Table View */}\n <div className=\"hidden lg:block rounded-lg border border-border-subtle bg-bg-surface shadow-sm overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken/50\">\n <th className=\"px-5 py-3 text-left font-medium text-text-secondary\">\n Item\n </th>\n <th className=\"px-5 py-3 text-left font-medium text-text-secondary\">\n Category\n </th>\n <th className=\"px-5 py-3 text-right font-medium text-text-secondary\">\n Price\n </th>\n <th className=\"px-5 py-3 text-left font-medium text-text-secondary\">\n Stock/Status\n </th>\n <th className=\"px-5 py-3 text-center font-medium text-text-secondary\">\n Available\n </th>\n <th className=\"px-5 py-3 text-right font-medium text-text-secondary\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredProducts.map((item) => {\n const stockStatus = getStockStatus(item);\n return (\n <tr\n key={item.id}\n className=\"border-b border-border-subtle last:border-0 hover:bg-bg-sunken/30 transition-colors\"\n >\n <td className=\"px-5 py-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-md bg-bg-sunken\">\n <Package className=\"h-4 w-4 text-text-secondary\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">{item.name}</p>\n <p className=\"text-xs text-text-secondary line-clamp-1\">\n {item.description.slice(0, 50)}...\n </p>\n </div>\n </div>\n </td>\n <td className=\"px-5 py-3\">\n <span className=\"inline-flex rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs font-medium text-text-secondary\">\n {item.category}\n </span>\n </td>\n <td className=\"px-5 py-3 text-right\">\n <p className=\"font-medium text-text-primary\">\n {formatCurrency(item.price, { minimumFractionDigits: 0 })}\n </p>\n {item.originalPrice && (\n <p className=\"text-xs text-text-secondary line-through\">\n {formatCurrency(item.originalPrice, { minimumFractionDigits: 0 })}\n </p>\n )}\n </td>\n <td className=\"px-5 py-3\">\n <span className={cn('text-sm font-medium', stockStatus.color)}>\n {stockStatus.label}\n </span>\n </td>\n <td className=\"px-5 py-3 text-center\">\n <button\n type=\"button\"\n onClick={() => handleToggleAvailability(item.id, !item.isAvailable)}\n className={cn(\n 'h-6 w-11 rounded-full transition-colors relative inline-block',\n item.isAvailable ? 'bg-accent-blue-subtle' : 'bg-muted-foreground/30'\n )}\n >\n <div\n className={cn(\n 'absolute top-0.5 h-5 w-5 rounded-full bg-white transition-transform',\n item.isAvailable ? 'translate-x-5' : 'translate-x-0.5'\n )}\n />\n </button>\n </td>\n <td className=\"px-5 py-3\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => handleEditProduct(item)}\n className=\"rounded p-1.5 text-text-secondary hover:bg-bg-sunken hover:text-text-primary transition-colors\"\n title=\"Edit\"\n >\n <Edit2 className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => handleDeleteProduct(item.id)}\n className=\"rounded p-1.5 text-text-secondary hover:bg-status-error-bg-subtle/10 hover:text-status-error-text transition-colors\"\n title=\"Delete\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Mobile Card View */}\n <div className=\"lg:hidden space-y-3\">\n {filteredProducts.map((item) => {\n const stockStatus = getStockStatus(item);\n return (\n <div\n key={item.id}\n className=\"rounded-lg border border-border-seam bg-bg-surface p-4 bg-gloss-card shadow-pop\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-14 w-14 items-center justify-center rounded-md bg-bg-sunken shrink-0\">\n <Package className=\"h-6 w-6 text-text-secondary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between mb-1\">\n <div className=\"flex-1\">\n <h3 className=\"text-sm font-medium text-text-primary line-clamp-1\">\n {item.name}\n </h3>\n <p className=\"text-xs text-text-secondary mt-0.5 line-clamp-2\">\n {item.description}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => handleToggleAvailability(item.id, !item.isAvailable)}\n className={cn(\n 'h-5 w-9 rounded-full transition-colors relative ml-2 shrink-0',\n item.isAvailable ? 'bg-accent-blue-subtle' : 'bg-muted-foreground/30'\n )}\n >\n <div\n className={cn(\n 'absolute top-0.5 h-4 w-4 rounded-full bg-white transition-transform',\n item.isAvailable ? 'translate-x-4' : 'translate-x-0.5'\n )}\n />\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-2 mt-2 text-xs\">\n <span className=\"px-2 py-0.5 rounded-full bg-bg-sunken text-text-secondary\">\n {item.category}\n </span>\n <span className={cn('font-medium', stockStatus.color)}>\n {stockStatus.label}\n </span>\n </div>\n <div className=\"flex items-center justify-between mt-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-semibold text-text-primary\">\n {formatCurrency(item.price, { minimumFractionDigits: 0 })}\n </span>\n {item.originalPrice && (\n <span className=\"text-xs text-text-secondary line-through\">\n {formatCurrency(item.originalPrice, { minimumFractionDigits: 0 })}\n </span>\n )}\n </div>\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => handleEditProduct(item)}\n className=\"rounded px-2 py-1 text-xs border border-border-subtle text-text-primary hover:bg-bg-sunken\"\n >\n Edit\n </button>\n <button\n type=\"button\"\n onClick={() => handleDeleteProduct(item.id)}\n className=\"rounded px-2 py-1 text-xs border border-border-subtle text-status-error-text hover:bg-status-error-bg-subtle/10\"\n >\n Delete\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n </>\n )}\n </div>\n\n {/* Add/Edit Modal */}\n {showAddModal && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-lg border border-border-subtle bg-bg-surface shadow-xl\">\n <div className=\"p-6\">\n <div className=\"flex items-center justify-between mb-4\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {editingProduct ? 'Edit Item' : 'Add New Item'}\n </h3>\n {formData.category && (\n <p className=\"text-sm text-text-secondary mt-0.5\">\n Type: {isFormService ? 'Service' : 'Product'} | Category: {formData.category}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={() => setShowAddModal(false)}\n className=\"rounded p-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Item Name *\n </label>\n <input\n type=\"text\"\n value={formData.name}\n onChange={(e) => setFormData((p) => ({ ...p, name: e.target.value }))}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n placeholder=\"Enter item name\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Category *\n </label>\n <select\n value={formData.category}\n onChange={(e) => setFormData((p) => ({ ...p, category: e.target.value }))}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"\">Select category</option>\n {categories.map((cat) => (\n <option key={cat} value={cat}>\n {cat}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Description *\n </label>\n <textarea\n value={formData.description}\n onChange={(e) => setFormData((p) => ({ ...p, description: e.target.value }))}\n rows={3}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary resize-none\"\n placeholder=\"Describe the offering...\"\n />\n </div>\n\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Price *\n </label>\n <input\n type=\"number\"\n value={formData.price}\n onChange={(e) =>\n setFormData((p) => ({ ...p, price: parseInt(e.target.value) || 0 }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Original Price\n </label>\n <input\n type=\"number\"\n value={formData.originalPrice ?? ''}\n onChange={(e) =>\n setFormData((p) => ({\n ...p,\n originalPrice: e.target.value ? parseInt(e.target.value) : undefined,\n }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n placeholder=\"Optional\"\n />\n </div>\n </div>\n\n {/* Product-specific fields */}\n {!isFormService && (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Stock Quantity *\n </label>\n <input\n type=\"number\"\n value={formData.stock}\n onChange={(e) =>\n setFormData((p) => ({ ...p, stock: parseInt(e.target.value) || 0 }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Preparation Time (min)\n </label>\n <input\n type=\"number\"\n value={formData.preparationTime}\n onChange={(e) =>\n setFormData((p) => ({\n ...p,\n preparationTime: parseInt(e.target.value) || 0,\n }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n {showFoodFields && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Calories\n </label>\n <input\n type=\"number\"\n value={formData.calories}\n onChange={(e) =>\n setFormData((p) => ({ ...p, calories: parseInt(e.target.value) || 0 }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n )}\n </div>\n )}\n\n {/* Service-specific fields */}\n {isFormService && (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Service Duration (min) *\n </label>\n <input\n type=\"number\"\n value={formData.duration}\n onChange={(e) =>\n setFormData((p) => ({ ...p, duration: parseInt(e.target.value) || 30 }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Setup Time (min)\n </label>\n <input\n type=\"number\"\n value={formData.preparationTime}\n onChange={(e) =>\n setFormData((p) => ({\n ...p,\n preparationTime: parseInt(e.target.value) || 0,\n }))\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n </div>\n )}\n\n {/* Food-specific options */}\n {showFoodFields && (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Spice Level\n </label>\n <select\n value={formData.spiceLevel}\n onChange={(e) => setFormData((p) => ({ ...p, spiceLevel: e.target.value }))}\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"none\">None</option>\n <option value=\"mild\">Mild</option>\n <option value=\"medium\">Medium</option>\n <option value=\"spicy\">Spicy</option>\n <option value=\"very-spicy\">Very Spicy</option>\n </select>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-2\">\n Dietary Options\n </label>\n <div className=\"space-y-2\">\n {(['isVegetarian', 'isVegan', 'isGlutenFree'] as const).map((field) => (\n <label\n key={field}\n className=\"flex items-center gap-2 text-sm text-text-primary\"\n >\n <input\n type=\"checkbox\"\n checked={formData[field]}\n onChange={(e) =>\n setFormData((p) => ({ ...p, [field]: e.target.checked }))\n }\n className=\"rounded border-border-subtle\"\n />\n {field === 'isVegetarian'\n ? 'Vegetarian'\n : field === 'isVegan'\n ? 'Vegan'\n : 'Gluten Free'}\n </label>\n ))}\n </div>\n </div>\n </div>\n )}\n\n {/* Service-specific: service type */}\n {isFormService && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Service Type *\n </label>\n <select\n value={formData.serviceType}\n onChange={(e) => setFormData((p) => ({ ...p, serviceType: e.target.value }))}\n className=\"w-full sm:w-64 rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"instant\">Instant Service</option>\n <option value=\"appointment\">Appointment Based</option>\n <option value=\"recurring\">Recurring Service</option>\n <option value=\"consultation\">Consultation</option>\n </select>\n </div>\n )}\n\n {/* Tags */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Tags (comma separated)\n </label>\n <input\n type=\"text\"\n value={tagsInput}\n onChange={(e) => setTagsInput(e.target.value)}\n placeholder={\n isFormService\n ? 'professional, certified, quick'\n : 'popular, spicy, traditional'\n }\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">\n {\n tagsInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean).length\n }{' '}\n tags\n </p>\n </div>\n\n {/* Allergens (food only) */}\n {showFoodFields && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Allergens (comma separated)\n </label>\n <input\n type=\"text\"\n value={allergensInput}\n onChange={(e) => setAllergensInput(e.target.value)}\n placeholder=\"nuts, dairy, gluten, soy\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n )}\n\n {/* Requirements (service only) */}\n {isFormService && (\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Service Requirements (comma separated)\n </label>\n <input\n type=\"text\"\n value={requirementsInput}\n onChange={(e) => setRequirementsInput(e.target.value)}\n placeholder=\"advance booking, payment required, tools provided\"\n className=\"w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n )}\n </div>\n\n {/* Modal Actions */}\n <div className=\"flex gap-3 mt-6\">\n <button\n type=\"button\"\n onClick={() => setShowAddModal(false)}\n className=\"flex-1 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSaveProduct}\n disabled={!canSave}\n className={cn(\n 'flex-1 rounded-md px-4 py-2 text-sm font-medium transition-colors',\n canSave\n ? 'bg-accent text-text-primary hover:bg-accent/80'\n : 'bg-bg-sunken text-text-secondary cursor-not-allowed'\n )}\n >\n {editingProduct ? 'Update Item' : 'Add Item'}\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}