@mohasinac/appkit 2.7.35 → 2.7.37

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 (186) hide show
  1. package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
  2. package/dist/_internal/client/features/seller/print-center/InventoryLabel.d.ts +12 -0
  3. package/dist/_internal/client/features/seller/print-center/InventoryLabel.js +49 -0
  4. package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.d.ts +7 -0
  5. package/dist/_internal/client/features/seller/print-center/LabelDesignPicker.js +32 -0
  6. package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.d.ts +28 -0
  7. package/dist/_internal/client/features/seller/print-center/OrderPackingLabel.js +33 -0
  8. package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.d.ts +12 -0
  9. package/dist/_internal/client/features/seller/print-center/PhysicalLocationModal.js +30 -0
  10. package/dist/_internal/client/features/seller/print-center/PrintCenterView.d.ts +12 -0
  11. package/dist/_internal/client/features/seller/print-center/PrintCenterView.js +102 -0
  12. package/dist/_internal/client/features/seller/print-center/PrintGrid.d.ts +12 -0
  13. package/dist/_internal/client/features/seller/print-center/PrintGrid.js +13 -0
  14. package/dist/_internal/client/features/seller/print-center/StoreCard.d.ts +19 -0
  15. package/dist/_internal/client/features/seller/print-center/StoreCard.js +30 -0
  16. package/dist/_internal/client/features/seller/print-center/WebsiteCard.d.ts +11 -0
  17. package/dist/_internal/client/features/seller/print-center/WebsiteCard.js +25 -0
  18. package/dist/_internal/client/features/seller/print-center/index.d.ts +11 -0
  19. package/dist/_internal/client/features/seller/print-center/index.js +10 -0
  20. package/dist/_internal/client/features/seller/print-center/types.d.ts +20 -0
  21. package/dist/_internal/client/features/seller/print-center/types.js +20 -0
  22. package/dist/_internal/client/features/seller/print-center/useInventoryPdf.d.ts +18 -0
  23. package/dist/_internal/client/features/seller/print-center/useInventoryPdf.js +76 -0
  24. package/dist/_internal/server/features/auctions/og.d.ts +1 -0
  25. package/dist/_internal/server/features/auctions/og.js +2 -1
  26. package/dist/_internal/server/features/blog/og.d.ts +1 -0
  27. package/dist/_internal/server/features/blog/og.js +3 -2
  28. package/dist/_internal/server/features/brands/og.d.ts +1 -0
  29. package/dist/_internal/server/features/brands/og.js +2 -1
  30. package/dist/_internal/server/features/bundles/og.d.ts +1 -0
  31. package/dist/_internal/server/features/bundles/og.js +2 -1
  32. package/dist/_internal/server/features/categories/og.d.ts +1 -0
  33. package/dist/_internal/server/features/categories/og.js +2 -1
  34. package/dist/_internal/server/features/checkout/actions.js +13 -5
  35. package/dist/_internal/server/features/classified/og.d.ts +2 -0
  36. package/dist/_internal/server/features/classified/og.js +2 -1
  37. package/dist/_internal/server/features/digital-code/og.d.ts +2 -0
  38. package/dist/_internal/server/features/digital-code/og.js +2 -1
  39. package/dist/_internal/server/features/events/og.d.ts +1 -0
  40. package/dist/_internal/server/features/events/og.js +3 -1
  41. package/dist/_internal/server/features/live/og.d.ts +2 -0
  42. package/dist/_internal/server/features/live/og.js +2 -1
  43. package/dist/_internal/server/features/pre-orders/og.d.ts +1 -0
  44. package/dist/_internal/server/features/pre-orders/og.js +2 -1
  45. package/dist/_internal/server/features/products/og.d.ts +3 -1
  46. package/dist/_internal/server/features/products/og.js +2 -1
  47. package/dist/_internal/server/features/seo/index.d.ts +1 -1
  48. package/dist/_internal/server/features/seo/index.js +1 -1
  49. package/dist/_internal/server/features/seo/og.d.ts +8 -1
  50. package/dist/_internal/server/features/seo/og.js +28 -8
  51. package/dist/_internal/server/features/stores/og.d.ts +1 -0
  52. package/dist/_internal/server/features/stores/og.js +3 -2
  53. package/dist/_internal/server/features/sublisting-categories/og.d.ts +1 -0
  54. package/dist/_internal/server/features/sublisting-categories/og.js +2 -1
  55. package/dist/_internal/server/jobs/core/draftPrune.d.ts +2 -0
  56. package/dist/_internal/server/jobs/core/draftPrune.js +15 -0
  57. package/dist/_internal/server/jobs/core/onBidPlaced.js +1 -1
  58. package/dist/_internal/server/jobs/core/onScamReportCreate.js +18 -14
  59. package/dist/_internal/server/jobs/core/onScamReportRejected.js +10 -7
  60. package/dist/_internal/server/jobs/core/onScamReportVerified.js +10 -7
  61. package/dist/_internal/server/jobs/core/promotions.d.ts +1 -0
  62. package/dist/_internal/server/jobs/core/promotions.js +21 -6
  63. package/dist/_internal/server/jobs/handlers/assignSpinPrize.js +18 -1
  64. package/dist/_internal/server/jobs/handlers/draftPrune.d.ts +2 -0
  65. package/dist/_internal/server/jobs/handlers/draftPrune.js +2 -0
  66. package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
  67. package/dist/_internal/server/jobs/handlers/index.js +2 -0
  68. package/dist/_internal/server/jobs/handlers/triggerEventRaffle.js +15 -1
  69. package/dist/_internal/shared/actions/action-registry.js +32 -0
  70. package/dist/_internal/shared/features/blog/schema.d.ts +8 -8
  71. package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +10 -10
  72. package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
  73. package/dist/_internal/shared/features/products/schema.d.ts +8 -8
  74. package/dist/_internal/shared/features/promotions/schema.d.ts +6 -6
  75. package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
  76. package/dist/client.d.ts +13 -1
  77. package/dist/client.js +7 -1
  78. package/dist/configs/next.js +1 -0
  79. package/dist/constants/api-endpoints.d.ts +15 -0
  80. package/dist/constants/api-endpoints.js +5 -0
  81. package/dist/core/server-action.d.ts +4 -0
  82. package/dist/errors/error-codes.d.ts +18 -0
  83. package/dist/errors/error-codes.js +18 -0
  84. package/dist/errors/index.d.ts +1 -1
  85. package/dist/errors/index.js +1 -1
  86. package/dist/errors/messages.d.ts +1 -0
  87. package/dist/errors/messages.js +1 -0
  88. package/dist/features/account/components/UserSidebar.js +1 -1
  89. package/dist/features/account/schemas/index.d.ts +12 -12
  90. package/dist/features/admin/components/AdminBundlesView.js +20 -2
  91. package/dist/features/admin/components/AdminPayoutsView.js +2 -1
  92. package/dist/features/admin/components/AdminProductsView.js +13 -0
  93. package/dist/features/admin/components/AdminSidebar.js +1 -1
  94. package/dist/features/admin/components/AdminStoresView.js +43 -5
  95. package/dist/features/admin/components/AdminUsersView.js +53 -6
  96. package/dist/features/admin/schemas/firestore.d.ts +1 -1
  97. package/dist/features/auctions/actions/bid-actions.js +13 -6
  98. package/dist/features/auctions/components/PlaceBidFormClient.js +10 -2
  99. package/dist/features/auctions/repository/bid.repository.d.ts +7 -0
  100. package/dist/features/auctions/repository/bid.repository.js +16 -0
  101. package/dist/features/auctions/schemas/index.d.ts +18 -18
  102. package/dist/features/auth/schemas/index.d.ts +2 -2
  103. package/dist/features/before-after/schemas/index.d.ts +2 -2
  104. package/dist/features/blog/actions/blog-actions.d.ts +32 -32
  105. package/dist/features/blog/components/BlogPostForm.js +2 -1
  106. package/dist/features/blog/schemas/index.d.ts +38 -38
  107. package/dist/features/categories/components/CategoryForm.js +1 -0
  108. package/dist/features/categories/schemas/index.d.ts +10 -10
  109. package/dist/features/collections/schemas/index.d.ts +4 -4
  110. package/dist/features/consultation/schemas/index.d.ts +9 -9
  111. package/dist/features/corporate/schemas/index.d.ts +4 -4
  112. package/dist/features/events/schemas/index.d.ts +50 -50
  113. package/dist/features/faq/actions/faq-actions.d.ts +6 -6
  114. package/dist/features/faq/schemas/index.d.ts +8 -8
  115. package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
  116. package/dist/features/homepage/components/SectionCarousel.js +1 -8
  117. package/dist/features/layout/AppLayoutShell.js +1 -1
  118. package/dist/features/layout/AutoBreadcrumbs.js +1 -1
  119. package/dist/features/media/AvatarUpload.js +1 -1
  120. package/dist/features/media/types/index.d.ts +4 -4
  121. package/dist/features/media/upload/ImageUpload.js +18 -9
  122. package/dist/features/media/upload/MediaUploadList.js +2 -2
  123. package/dist/features/orders/schemas/firestore.d.ts +6 -0
  124. package/dist/features/orders/schemas/index.d.ts +10 -10
  125. package/dist/features/orders/types/index.d.ts +5 -0
  126. package/dist/features/payments/schemas/index.d.ts +4 -4
  127. package/dist/features/pre-orders/schemas/index.d.ts +8 -8
  128. package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
  129. package/dist/features/products/components/ProductForm.js +20 -2
  130. package/dist/features/products/repository/products.repository.d.ts +3 -1
  131. package/dist/features/products/repository/products.repository.js +12 -1
  132. package/dist/features/products/schemas/firestore.d.ts +7 -0
  133. package/dist/features/products/schemas/index.d.ts +34 -34
  134. package/dist/features/products/schemas/product-features.validators.d.ts +6 -6
  135. package/dist/features/products/types/index.d.ts +6 -0
  136. package/dist/features/promotions/schemas/index.d.ts +14 -14
  137. package/dist/features/reviews/schemas/index.d.ts +18 -18
  138. package/dist/features/seller/actions/offer-actions.js +10 -1
  139. package/dist/features/seller/components/PhysicalLocationModal.d.ts +12 -0
  140. package/dist/features/seller/components/PhysicalLocationModal.js +30 -0
  141. package/dist/features/seller/components/PrintCenterView.d.ts +40 -0
  142. package/dist/features/seller/components/PrintCenterView.js +6 -0
  143. package/dist/features/seller/components/SellerOrdersView.js +48 -3
  144. package/dist/features/seller/components/SellerProductShell.d.ts +1 -0
  145. package/dist/features/seller/components/SellerProductShell.js +26 -4
  146. package/dist/features/seller/components/SellerProductsView.js +54 -13
  147. package/dist/features/seller/components/SellerSidebar.js +1 -1
  148. package/dist/features/seller/components/index.d.ts +1 -0
  149. package/dist/features/seller/components/index.js +1 -0
  150. package/dist/features/seller/schemas/firestore.d.ts +2 -0
  151. package/dist/features/seller/schemas/firestore.js +1 -0
  152. package/dist/features/seller/schemas/index.d.ts +22 -22
  153. package/dist/features/shell/FormShell.js +1 -1
  154. package/dist/features/shell/StepForm.d.ts +3 -1
  155. package/dist/features/shell/StepForm.js +3 -3
  156. package/dist/features/stores/schemas/index.d.ts +4 -4
  157. package/dist/index.d.ts +9 -1
  158. package/dist/index.js +6 -1
  159. package/dist/next/routing/route-map.d.ts +8 -0
  160. package/dist/next/routing/route-map.js +3 -0
  161. package/dist/seed/homepage-sections-seed-data.js +10 -10
  162. package/dist/server.d.ts +1 -1
  163. package/dist/server.js +1 -1
  164. package/dist/tailwind-utilities.css +1 -1
  165. package/dist/ui/components/FormField.js +1 -0
  166. package/dist/ui/components/RowActionMenu.js +45 -10
  167. package/dist/ui/components/SideDrawer.style.css +2 -2
  168. package/dist/ui/forms/FieldCheckbox.d.ts +13 -0
  169. package/dist/ui/forms/FieldCheckbox.js +25 -0
  170. package/dist/ui/forms/FieldInput.d.ts +11 -0
  171. package/dist/ui/forms/FieldInput.js +25 -0
  172. package/dist/ui/forms/FieldSelect.d.ts +17 -0
  173. package/dist/ui/forms/FieldSelect.js +25 -0
  174. package/dist/ui/forms/FormShell.d.ts +48 -0
  175. package/dist/ui/forms/FormShell.js +176 -0
  176. package/dist/ui/forms/FormShell.style.css +287 -0
  177. package/dist/ui/forms/index.d.ts +8 -0
  178. package/dist/ui/forms/index.js +4 -0
  179. package/dist/ui/index.d.ts +9 -0
  180. package/dist/ui/index.js +5 -0
  181. package/dist/utils/action-response.d.ts +6 -0
  182. package/dist/utils/action-response.js +22 -0
  183. package/dist/utils/index.d.ts +1 -0
  184. package/dist/utils/index.js +1 -0
  185. package/dist/validation/schemas.d.ts +10 -10
  186. package/package.json +2 -2
@@ -39,8 +39,8 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
39
39
  };
40
40
  isPinned: boolean;
41
41
  useSiteSettings: boolean;
42
- template?: string | undefined;
43
42
  tags?: string[] | undefined;
43
+ template?: string | undefined;
44
44
  variables?: Record<string, string> | undefined;
45
45
  relatedFAQs?: string[] | undefined;
46
46
  }, {
@@ -50,8 +50,8 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
50
50
  text: string;
51
51
  format?: "html" | "plain" | "markdown" | undefined;
52
52
  };
53
- template?: string | undefined;
54
53
  tags?: string[] | undefined;
54
+ template?: string | undefined;
55
55
  order?: number | undefined;
56
56
  priority?: number | undefined;
57
57
  isActive?: boolean | undefined;
@@ -75,8 +75,8 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
75
75
  };
76
76
  isPinned: boolean;
77
77
  useSiteSettings: boolean;
78
- template?: string | undefined;
79
78
  tags?: string[] | undefined;
79
+ template?: string | undefined;
80
80
  variables?: Record<string, string> | undefined;
81
81
  relatedFAQs?: string[] | undefined;
82
82
  }, {
@@ -86,8 +86,8 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
86
86
  text: string;
87
87
  format?: "html" | "plain" | "markdown" | undefined;
88
88
  };
89
- template?: string | undefined;
90
89
  tags?: string[] | undefined;
90
+ template?: string | undefined;
91
91
  order?: number | undefined;
92
92
  priority?: number | undefined;
93
93
  isActive?: boolean | undefined;
@@ -123,9 +123,9 @@ export declare const faqUpdateSchema: z.ZodObject<{
123
123
  variables: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
124
124
  template: z.ZodOptional<z.ZodOptional<z.ZodString>>;
125
125
  }, "strip", z.ZodTypeAny, {
126
- template?: string | undefined;
127
126
  category?: string | undefined;
128
127
  tags?: string[] | undefined;
128
+ template?: string | undefined;
129
129
  order?: number | undefined;
130
130
  priority?: number | undefined;
131
131
  isActive?: boolean | undefined;
@@ -141,9 +141,9 @@ export declare const faqUpdateSchema: z.ZodObject<{
141
141
  relatedFAQs?: string[] | undefined;
142
142
  useSiteSettings?: boolean | undefined;
143
143
  }, {
144
- template?: string | undefined;
145
144
  category?: string | undefined;
146
145
  tags?: string[] | undefined;
146
+ template?: string | undefined;
147
147
  order?: number | undefined;
148
148
  priority?: number | undefined;
149
149
  isActive?: boolean | undefined;
@@ -82,16 +82,16 @@ export declare const faqSchema: z.ZodObject<{
82
82
  createdAt: z.ZodOptional<z.ZodString>;
83
83
  updatedAt: z.ZodOptional<z.ZodString>;
84
84
  }, "strip", z.ZodTypeAny, {
85
- id: string;
86
85
  category: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general";
86
+ id: string;
87
87
  question: string;
88
88
  answer: {
89
89
  text: string;
90
90
  format: "html" | "plain" | "markdown";
91
91
  };
92
92
  createdAt?: string | undefined;
93
- updatedAt?: string | undefined;
94
93
  tags?: string[] | undefined;
94
+ updatedAt?: string | undefined;
95
95
  order?: number | undefined;
96
96
  priority?: number | undefined;
97
97
  stats?: {
@@ -108,16 +108,16 @@ export declare const faqSchema: z.ZodObject<{
108
108
  isPinned?: boolean | undefined;
109
109
  relatedFAQs?: string[] | undefined;
110
110
  }, {
111
- id: string;
112
111
  category: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general";
112
+ id: string;
113
113
  question: string;
114
114
  answer: {
115
115
  text: string;
116
116
  format: "html" | "plain" | "markdown";
117
117
  };
118
118
  createdAt?: string | undefined;
119
- updatedAt?: string | undefined;
120
119
  tags?: string[] | undefined;
120
+ updatedAt?: string | undefined;
121
121
  order?: number | undefined;
122
122
  priority?: number | undefined;
123
123
  stats?: {
@@ -142,16 +142,16 @@ export declare const faqListParamsSchema: z.ZodObject<{
142
142
  page: z.ZodOptional<z.ZodNumber>;
143
143
  perPage: z.ZodOptional<z.ZodNumber>;
144
144
  }, "strip", z.ZodTypeAny, {
145
- perPage?: number | undefined;
146
- q?: string | undefined;
147
145
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
146
+ q?: string | undefined;
148
147
  page?: number | undefined;
148
+ perPage?: number | undefined;
149
149
  homepage?: boolean | undefined;
150
150
  }, {
151
- perPage?: number | undefined;
152
- q?: string | undefined;
153
151
  category?: "orders_payment" | "shipping_delivery" | "returns_refunds" | "product_information" | "account_security" | "technical_support" | "general" | undefined;
152
+ q?: string | undefined;
154
153
  page?: number | undefined;
154
+ perPage?: number | undefined;
155
155
  homepage?: boolean | undefined;
156
156
  }>;
157
157
  export * from "./firestore";
@@ -7,14 +7,14 @@ export declare const createSectionSchema: z.ZodObject<{
7
7
  order: z.ZodDefault<z.ZodNumber>;
8
8
  config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- enabled: boolean;
11
10
  type: string;
12
11
  order: number;
12
+ enabled: boolean;
13
13
  config?: Record<string, unknown> | undefined;
14
14
  }, {
15
15
  type: string;
16
- enabled?: boolean | undefined;
17
16
  order?: number | undefined;
17
+ enabled?: boolean | undefined;
18
18
  config?: Record<string, unknown> | undefined;
19
19
  }>;
20
20
  export declare const updateSectionSchema: z.ZodObject<{
@@ -22,12 +22,12 @@ export declare const updateSectionSchema: z.ZodObject<{
22
22
  enabled: z.ZodOptional<z.ZodBoolean>;
23
23
  config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
24
  }, "strip", z.ZodTypeAny, {
25
- enabled?: boolean | undefined;
26
25
  order?: number | undefined;
26
+ enabled?: boolean | undefined;
27
27
  config?: Record<string, unknown> | undefined;
28
28
  }, {
29
- enabled?: boolean | undefined;
30
29
  order?: number | undefined;
30
+ enabled?: boolean | undefined;
31
31
  config?: Record<string, unknown> | undefined;
32
32
  }>;
33
33
  export type CreateHomepageSectionInput = z.infer<typeof createSectionSchema>;
@@ -36,14 +36,7 @@ export function SectionCarousel({ title, description, headingVariant = "editoria
36
36
  headingClass,
37
37
  ]
38
38
  .filter(Boolean)
39
- .join(" "), children: title }), headingVariant === "editorial" && (_jsxs("div", { className: `${flex.center} gap-2 mt-1 text-zinc-400 dark:text-zinc-500 text-xs select-none`, "aria-hidden": "true", "data-section": "sectioncarousel-div-355", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { className: "text-xs", children: "\u2736" }), _jsx(Span, { className: "h-px w-6 bg-current" })] })), description && (_jsx(Text, { className: `text-base ${descVariant} mt-2`, children: description }))] }), isLoading ? (_jsx(CarouselSkeleton, { count: skeletonCount })) : (_jsx(HorizontalScroller, { items: items, renderItem: renderItem, perView: perView, gap: gap, autoScroll: autoScroll, autoScrollInterval: autoScrollInterval, keyExtractor: keyExtractor, rows: rows, minItemWidth: minItemWidth,
40
- /* Default behaviour for homepage sections using cards:
41
- - show arrows for easier navigation
42
- - snap to items for a tidy carousel feel
43
- - show fade edges for visual affordance
44
- - hide native scrollbar for cleaner appearance
45
- */
46
- showArrows: true, snapToItems: true, showFadeEdges: true, showScrollbar: false, pauseOnHover: true })), viewMoreHref && !isLoading && (_jsx("div", { className: "mt-6 flex justify-center", "data-section": "sectioncarousel-div-356", children: _jsx(TextLink, { href: viewMoreHref, className: `inline-flex items-center gap-1.5 rounded-lg border px-6 py-2.5 text-sm font-medium transition-colors ${useLightText
39
+ .join(" "), children: title }), headingVariant === "editorial" && (_jsxs("div", { className: `${flex.center} gap-2 mt-1 text-zinc-400 dark:text-zinc-500 text-xs select-none`, "aria-hidden": "true", "data-section": "sectioncarousel-div-355", children: [_jsx(Span, { className: "h-px w-6 bg-current" }), _jsx(Span, { className: "text-xs", children: "\u2736" }), _jsx(Span, { className: "h-px w-6 bg-current" })] })), description && (_jsx(Text, { className: `text-base ${descVariant} mt-2`, children: description }))] }), isLoading ? (_jsx(CarouselSkeleton, { count: skeletonCount })) : (_jsx(HorizontalScroller, { items: items, renderItem: renderItem, perView: perView, gap: gap, autoScroll: autoScroll, autoScrollInterval: autoScrollInterval, loop: autoScroll && rows === 1, keyExtractor: keyExtractor, rows: rows, minItemWidth: minItemWidth, showArrows: true, snapToItems: true, showFadeEdges: true, showScrollbar: false, pauseOnHover: true })), viewMoreHref && !isLoading && (_jsx("div", { className: "mt-6 flex justify-center", "data-section": "sectioncarousel-div-356", children: _jsx(TextLink, { href: viewMoreHref, className: `inline-flex items-center gap-1.5 rounded-lg border px-6 py-2.5 text-sm font-medium transition-colors ${useLightText
47
40
  ? "border-white/40 text-white hover:bg-white/10"
48
41
  : "border-zinc-200 dark:border-zinc-700 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-800"}`, children: viewMoreLabel }) }))] })] }));
49
42
  }
@@ -147,5 +147,5 @@ export function AppLayoutShell({ children, navItems, sidebarItems = [], sidebarS
147
147
  opacity: darkBackground.overlay?.opacity ?? 0,
148
148
  },
149
149
  };
150
- return (_jsx(QueryClientProvider, { client: queryClient, children: _jsxs(Div, { className: "flex min-h-screen w-full flex-col overflow-x-clip transition-colors duration-300", children: [_jsx(BackgroundRenderer, { mode: theme === "dark" ? "dark" : "light", lightMode: normalizedLightBackground, darkMode: normalizedDarkBackground }), _jsxs(Div, { ref: headerRef, className: "sticky top-0 z-50 w-full", children: [_jsx(TitleBar, { onToggleSidebar: handleTogglePublicSidebar, sidebarOpen: sidebarOpen, onSearchToggle: () => setSearchOpen((prev) => !prev), searchOpen: searchOpen, brandName: brandName, brandShortName: brandShortName, siteLogoUrl: siteLogoUrl, logoHref: logoHref, promotionsHref: promotionsHref, cartHref: cartHref, wishlistHref: wishlistHref, userId: userId, profileHref: profileHref, loginHref: loginHref, registerHref: registerHref, user: user, navSlot: titleBarNavSlot, notificationSlot: titleBarNotificationSlot, devSlot: titleBarDevSlot, promoStripText: titleBarPromoStripText, isDark: theme === "dark", onToggleTheme: showThemeToggle ? toggleTheme : undefined, onBeforeToggleDashboardNav: handleBeforeDashboardNavToggle, suppressDashboardNav: suppressDashboardNav, hideSidebarToggle: hideSidebarToggle }), _jsx(NavbarWithSettings, { navItems: navItems, hiddenNavItems: hiddenNavItems, permissions: authUser?.permissions }), searchOpen && (searchSlotRenderer ? searchSlotRenderer(() => setSearchOpen(false)) : searchSlot)] }), eventBannerSlot, _jsx(AutoBreadcrumbs, {}), _jsxs(Div, { className: "relative flex w-full flex-1 overflow-x-clip", children: [_jsx(SidebarLayout, { isOpen: sidebarOpen, ariaLabel: "Secondary navigation", header: user ? (_jsx(SidebarUserHeader, { user: user, onClose: () => setSidebarOpen(false) })) : (_jsx(SidebarGuestHeader, { sidebarTitle: sidebarTitle, onClose: () => setSidebarOpen(false) })), onClose: () => setSidebarOpen(false), children: sidebarContent }), _jsx(Main, { id: "main-content", className: `w-full flex-1 ${hasBottomActions ? "mb-28" : "mb-16"} md:mb-0`, children: _jsx(Div, { className: contentClassName ?? "w-full px-4 py-6 md:px-6 lg:px-8", children: children }) })] }), _jsx(BackToTop, {}), _jsx(FooterLayout, { ...footer }), _jsx(BottomActions, {}), _jsx(BottomNavbar, { user: user, homeHref: homeHref, shopHref: shopHref, cartHref: cartHref, profileHref: profileHref, loginHref: loginHref, onSearchToggle: () => setSearchOpen((prev) => !prev), navItems: navItems, onMoreToggle: hasDashboardNav ? toggleDashboardNav : handleTogglePublicSidebar }), _jsx(UnsavedChangesModal, {})] }) }));
150
+ return (_jsx(QueryClientProvider, { client: queryClient, children: _jsxs(Div, { className: "flex min-h-screen w-full flex-col overflow-x-clip transition-colors duration-300", children: [_jsx(BackgroundRenderer, { mode: theme === "dark" ? "dark" : "light", lightMode: normalizedLightBackground, darkMode: normalizedDarkBackground }), _jsxs(Div, { ref: headerRef, className: "sticky top-0 z-50 w-full", children: [_jsx(TitleBar, { onToggleSidebar: handleTogglePublicSidebar, sidebarOpen: sidebarOpen, onSearchToggle: () => setSearchOpen((prev) => !prev), searchOpen: searchOpen, brandName: brandName, brandShortName: brandShortName, siteLogoUrl: siteLogoUrl, logoHref: logoHref, promotionsHref: promotionsHref, cartHref: cartHref, wishlistHref: wishlistHref, userId: userId, profileHref: profileHref, loginHref: loginHref, registerHref: registerHref, user: user, navSlot: titleBarNavSlot, notificationSlot: titleBarNotificationSlot, devSlot: titleBarDevSlot, promoStripText: titleBarPromoStripText, isDark: theme === "dark", onToggleTheme: showThemeToggle ? toggleTheme : undefined, onBeforeToggleDashboardNav: handleBeforeDashboardNavToggle, suppressDashboardNav: suppressDashboardNav, hideSidebarToggle: hideSidebarToggle }), _jsx(NavbarWithSettings, { navItems: navItems, hiddenNavItems: hiddenNavItems, permissions: authUser?.permissions }), searchOpen && (searchSlotRenderer ? searchSlotRenderer(() => setSearchOpen(false)) : searchSlot)] }), eventBannerSlot, _jsx(AutoBreadcrumbs, {}), _jsxs(Div, { className: "relative flex w-full flex-1 overflow-x-clip", children: [_jsx(SidebarLayout, { isOpen: sidebarOpen, ariaLabel: "Secondary navigation", header: user ? (_jsx(SidebarUserHeader, { user: user, onClose: () => setSidebarOpen(false) })) : (_jsx(SidebarGuestHeader, { sidebarTitle: sidebarTitle, onClose: () => setSidebarOpen(false) })), onClose: () => setSidebarOpen(false), children: sidebarContent }), _jsx(Main, { id: "main-content", className: `w-full flex-1 ${hasBottomActions ? "mb-28" : "mb-16"} md:mb-0`, children: _jsx(Div, { className: contentClassName ?? "w-full px-5 py-6 md:px-6 lg:px-8", children: children }) })] }), _jsx(BackToTop, {}), _jsx(FooterLayout, { ...footer }), _jsx(BottomActions, {}), _jsx(BottomNavbar, { user: user, homeHref: homeHref, shopHref: shopHref, cartHref: cartHref, profileHref: profileHref, loginHref: loginHref, onSearchToggle: () => setSearchOpen((prev) => !prev), navItems: navItems, onMoreToggle: hasDashboardNav ? toggleDashboardNav : handleTogglePublicSidebar }), _jsx(UnsavedChangesModal, {})] }) }));
151
151
  }
@@ -77,7 +77,7 @@ export function AutoBreadcrumbs({ pathLabels, separator = "/", className = "", r
77
77
  href: `${localePrefix}/${segments.slice(0, i + 1).join("/")}`,
78
78
  }));
79
79
  const allCrumbs = [{ label: "Home", href: localePrefix || "/" }, ...crumbs];
80
- return (_jsx(Div, { className: "border-y border-zinc-200/80 bg-white/95 backdrop-blur supports-[backdrop-filter]:bg-white/90 dark:border-slate-800 dark:bg-slate-950/95 dark:supports-[backdrop-filter]:bg-slate-950/85", children: _jsx(Div, { className: "container mx-auto max-w-[1920px] px-4 py-2 sm:px-6 lg:px-8", children: _jsx(Nav, { "aria-label": "Breadcrumb", className: className, children: _jsx(Ol, { className: "flex items-center gap-2 text-sm flex-wrap", children: allCrumbs.map((crumb, index) => {
80
+ return (_jsx(Div, { className: "border-y border-zinc-200/80 bg-white/95 backdrop-blur supports-[backdrop-filter]:bg-white/90 dark:border-slate-800 dark:bg-slate-950/95 dark:supports-[backdrop-filter]:bg-slate-950/85", children: _jsx(Div, { className: "container mx-auto max-w-[1920px] px-5 py-2 sm:px-6 lg:px-8", children: _jsx(Nav, { "aria-label": "Breadcrumb", className: className, children: _jsx(Ol, { className: "flex items-center gap-2 text-sm flex-wrap", children: allCrumbs.map((crumb, index) => {
81
81
  const isLast = index === allCrumbs.length - 1;
82
82
  return (_jsxs(Li, { className: "flex items-center gap-2", children: [isLast ? (_jsx(Span, { "aria-current": "page", className: "text-zinc-700 dark:text-zinc-200", children: crumb.label })) : renderLink ? (renderLink(crumb.href, crumb.label)) : (_jsx(Link, { href: crumb.href, className: "text-zinc-700 dark:text-zinc-300 hover:text-zinc-950 dark:hover:text-white transition-colors", children: crumb.label })), !isLast && (_jsx(Span, { className: "text-zinc-500 dark:text-zinc-400/90 select-none", "aria-hidden": "true", children: separator }))] }, crumb.href));
83
83
  }) }) }) }) }));
@@ -106,6 +106,6 @@ export function AvatarUpload({ currentPhotoURL, currentCropData, userId, display
106
106
  fileInputRef.current.value = "";
107
107
  };
108
108
  const hasPending = pendingCropData !== null && pendingUploadFile !== null;
109
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-4", "data-section": "avatarupload-div-404", children: [_jsxs("div", { className: "flex items-start gap-6", "data-section": "avatarupload-div-405", children: [_jsx("div", { className: "shrink-0", "data-section": "avatarupload-div-406", children: _jsx(AvatarDisplay, { cropData: hasPending ? pendingCropData : cropData, size: "2xl", className: `border-4 ${hasPending ? "border-primary/60 ring-2 ring-primary/20" : "border-zinc-200 dark:border-slate-700"}`, displayName: displayName }) }), _jsxs("div", { className: "flex-1 space-y-3", "data-section": "avatarupload-div-407", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: "JPG, PNG, WEBP or GIF up to 10MB." }), isUploading ? (_jsx(Progress, { value: 50, variant: "primary", size: "sm", label: t.uploading })) : null, hasPending && !isUploading ? (_jsxs("div", { className: "space-y-2", "data-section": "avatarupload-div-408", children: [_jsx(Text, { variant: "secondary", className: "text-xs text-primary", children: t.readyToSave }), _jsxs("div", { className: "flex gap-3", "data-section": "avatarupload-div-409", children: [_jsx(Button, { type: "button", onClick: handleConfirmSave, size: "sm", children: t.saveAvatar }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleCancelPending, children: t.cancelChange })] })] })) : null, !hasPending && !isUploading ? (_jsxs("div", { className: "flex gap-3", "data-section": "avatarupload-div-410", children: [_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), size: "sm", children: previewUrl ? t.changePhoto : t.chooseImage }), previewUrl ? (_jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleRemovePhoto, children: t.removePhoto })) : null] })) : null, _jsx(Input, { ref: fileInputRef, bare: true, type: "file", accept: "image/jpeg,image/png,image/webp,image/gif", onChange: handleFileSelect, className: "hidden", "aria-label": t.changePhoto })] })] }), uploadApiError ? (_jsx(Alert, { variant: "error", children: uploadApiError.message })) : null] }), showCropModal && tempImageUrl ? (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: tempImageUrl, onClose: handleCropCancel, onSave: handleCropSave, initialCropData: cropData || undefined })) : null] }));
109
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-4", "data-section": "avatarupload-div-404", children: [_jsxs("div", { className: "flex items-start gap-6", "data-section": "avatarupload-div-405", children: [_jsx("div", { className: "shrink-0", "data-section": "avatarupload-div-406", children: _jsx(AvatarDisplay, { cropData: hasPending ? pendingCropData : cropData, size: "2xl", className: `border-4 ${hasPending ? "border-primary/60 ring-2 ring-primary/20" : "border-zinc-200 dark:border-slate-700"}`, displayName: displayName }) }), _jsxs("div", { className: "flex-1 space-y-3", "data-section": "avatarupload-div-407", children: [_jsx(Text, { variant: "secondary", className: "text-xs", children: "JPG, PNG, WEBP or GIF up to 10MB." }), isUploading ? (_jsx(Progress, { value: 50, variant: "primary", size: "sm", label: t.uploading })) : null, hasPending && !isUploading ? (_jsxs("div", { className: "space-y-2", "data-section": "avatarupload-div-408", children: [_jsx(Text, { variant: "secondary", className: "text-xs text-primary", children: t.readyToSave }), _jsxs("div", { className: "flex gap-3", "data-section": "avatarupload-div-409", children: [_jsx(Button, { type: "button", onClick: handleConfirmSave, size: "sm", children: t.saveAvatar }), _jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleCancelPending, children: t.cancelChange })] })] })) : null, !hasPending && !isUploading ? (_jsxs("div", { className: "flex gap-3", "data-section": "avatarupload-div-410", children: [_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), size: "sm", children: previewUrl ? t.changePhoto : t.chooseImage }), previewUrl ? (_jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: handleRemovePhoto, children: t.removePhoto })) : null] })) : null, _jsx(Input, { ref: fileInputRef, bare: true, type: "file", accept: "image/*", onChange: handleFileSelect, className: "hidden", "aria-label": t.changePhoto })] })] }), uploadApiError ? (_jsx(Alert, { variant: "error", children: uploadApiError.message })) : null] }), showCropModal && tempImageUrl ? (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: tempImageUrl, onClose: handleCropCancel, onSave: handleCropSave, initialCropData: cropData || undefined })) : null] }));
110
110
  }
111
111
  export default AvatarUpload;
@@ -21,18 +21,18 @@ export declare const mediaFieldSchema: z.ZodObject<{
21
21
  source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
22
22
  youtubeId: z.ZodOptional<z.ZodString>;
23
23
  }, "strip", z.ZodTypeAny, {
24
- type: "video" | "image" | "file";
25
24
  url: string;
26
- source?: "upload" | "youtube" | "external" | undefined;
25
+ type: "image" | "video" | "file";
27
26
  alt?: string | undefined;
28
27
  thumbnailUrl?: string | undefined;
28
+ source?: "upload" | "youtube" | "external" | undefined;
29
29
  youtubeId?: string | undefined;
30
30
  }, {
31
- type: "video" | "image" | "file";
32
31
  url: string;
33
- source?: "upload" | "youtube" | "external" | undefined;
32
+ type: "image" | "video" | "file";
34
33
  alt?: string | undefined;
35
34
  thumbnailUrl?: string | undefined;
35
+ source?: "upload" | "youtube" | "external" | undefined;
36
36
  youtubeId?: string | undefined;
37
37
  }>;
38
38
  export declare function coerceMediaField(value: MediaFieldInput, fallbackType?: MediaFieldType): MediaField | null;
@@ -10,7 +10,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
10
10
  import { useState, useRef } from "react";
11
11
  import { useTranslations } from "next-intl";
12
12
  import { useCamera } from "../../../react";
13
- import { Alert, Button, Div, Label, Progress, Row, Span, Spinner, Text, } from "../../../ui";
13
+ import { Alert, Button, Div, Label, Progress, Row, Spinner, Text, } from "../../../ui";
14
14
  import { MediaImage } from "../MediaImage";
15
15
  import { ImageCropModal } from "../modals/ImageCropModal";
16
16
  import CameraCapture from "./CameraCapture";
@@ -19,7 +19,18 @@ function formatFileSize(bytes) {
19
19
  return `${(bytes / 1024).toFixed(1)}KB`;
20
20
  return `${(bytes / (1024 * 1024)).toFixed(2)}MB`;
21
21
  }
22
- export function ImageUpload({ currentImage, onUpload, onChange, accept = "image/jpeg,image/png,image/gif,image/webp", maxSizeMB = 10, label = "Upload Image", helperText, captureSource = "both", enableCrop = true, onCropDataChange, }) {
22
+ function matchesMimeAccept(fileType, accept) {
23
+ return accept.split(",").map((a) => a.trim()).some((pattern) => {
24
+ if (pattern === "*" || pattern === "*/*")
25
+ return true;
26
+ const [pType, pSub] = pattern.split("/");
27
+ const [fType, fSub] = fileType.split("/");
28
+ if (pType !== fType)
29
+ return false;
30
+ return pSub === "*" || pSub === fSub;
31
+ });
32
+ }
33
+ export function ImageUpload({ currentImage, onUpload, onChange, accept = "image/*", maxSizeMB = 10, label = "Upload Image", helperText, captureSource = "both", enableCrop = true, onCropDataChange, }) {
23
34
  const [uploading, setUploading] = useState(false);
24
35
  const [preview, setPreview] = useState(currentImage || "");
25
36
  const [error, setError] = useState("");
@@ -110,8 +121,7 @@ export function ImageUpload({ currentImage, onUpload, onChange, accept = "image/
110
121
  setError(`File size must be less than ${maxSizeMB}MB (current: ${formatFileSize(file.size)})`);
111
122
  return;
112
123
  }
113
- const acceptedTypes = accept.split(",").map((t) => t.trim());
114
- if (!acceptedTypes.includes(file.type)) {
124
+ if (!matchesMimeAccept(file.type, accept)) {
115
125
  setError(`Invalid file type. Accepted: ${accept}`);
116
126
  return;
117
127
  }
@@ -124,11 +134,10 @@ export function ImageUpload({ currentImage, onUpload, onChange, accept = "image/
124
134
  fileInputRef.current.value = "";
125
135
  onChange?.("");
126
136
  };
127
- return (_jsxs(Div, { className: "space-y-3", children: [label && (_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Div, { className: "relative aspect-[16/9] overflow-hidden rounded-xl border-2 border-zinc-200 dark:border-zinc-700", children: [_jsx(MediaImage, { src: preview, alt: "Preview", size: "card" }), uploading && progress > 0 && (_jsx(Div, { className: "absolute inset-x-0 bottom-0", children: _jsx(Progress, { value: progress, size: "sm" }) }))] }), !uploading && (_jsxs(Row, { wrap: true, gap: "sm", children: [enableCrop && (_jsx(Button, { type: "button", onClick: () => {
137
+ return (_jsxs(Div, { className: "space-y-3", children: [label && (_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label })), _jsx(Div, { className: "relative", children: preview ? (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Div, { className: "relative h-32 max-w-xs mx-auto overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700", children: [_jsx(MediaImage, { src: preview, alt: "Preview", size: "card" }), uploading && progress > 0 && (_jsx(Div, { className: "absolute inset-x-0 bottom-0", children: _jsx(Progress, { value: progress, size: "sm" }) }))] }), !uploading && (_jsxs(Row, { wrap: true, gap: "sm", children: [enableCrop && (_jsx(Button, { type: "button", onClick: () => {
128
138
  setCropPreviewUrl(preview);
129
139
  setShowCropModal(true);
130
- }, variant: "secondary", size: "sm", children: tMediaEditor("editImage") })), _jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), variant: "outline", size: "sm", children: tUpload("change") }), _jsx(Button, { type: "button", onClick: handleRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] })) : (_jsxs(_Fragment, { children: [captureSource === "both" && isCameraSupported && (_jsxs(Row, { justify: "center", className: "gap-2 mb-3", children: [_jsx(Button, { type: "button", variant: captureMode === "file" ? "primary" : "outline", size: "sm", onClick: () => setCaptureMode("file"), children: t("switchToUpload") }), _jsx(Button, { type: "button", variant: captureMode === "camera" ? "primary" : "outline", size: "sm", onClick: () => setCaptureMode("camera"), children: t("switchToCamera") })] })), showCamera && isCameraSupported && (_jsx(CameraCapture, { mode: "photo", facingMode: "environment", onCapture: handleCameraCapture, onError: setError })), showCamera && !isCameraSupported && (_jsx(Button, { type: "button", onClick: () => mobileCaptureRef.current?.click(), disabled: uploading, variant: "ghost", className: "w-full aspect-[16/9] border-2 border-dashed border-zinc-200 dark:border-zinc-700 rounded-xl flex items-center justify-center flex-col text-zinc-500 dark:text-zinc-400", children: _jsx(Span, { className: "text-sm font-medium", children: t("switchToCamera") }) })), showFileInput && (_jsxs(Button, { type: "button", onClick: () => fileInputRef.current?.click(), disabled: uploading, variant: "ghost", className: "w-full aspect-[16/9] border-2 border-dashed border-zinc-200 dark:border-zinc-700 rounded-xl flex items-center justify-center flex-col text-zinc-500 dark:text-zinc-400", children: [_jsx("svg", { className: "w-12 h-12 mb-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }), _jsx(Span, { className: "text-sm font-medium", children: uploading ? tUpload("uploading") : tUpload("clickToUpload") }), _jsxs(Span, { className: "text-xs mt-1", children: [accept
131
- .split(",")
132
- .map((t) => t.split("/")[1]?.toUpperCase() ?? t)
133
- .join(", "), " ", "(max ", maxSizeMB, "MB)"] })] }))] })) }), _jsx("input", { ref: fileInputRef, type: "file", accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-input" }), showCamera && !isCameraSupported && (_jsx("input", { ref: mobileCaptureRef, type: "file", accept: "image/*", capture: "environment", onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-capture-input" })), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error }), uploading && (_jsxs(Row, { className: "gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: tUpload("uploadingProgress", { progress }) })] })), cropPreviewUrl && (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: cropPreviewUrl, onClose: handleCropClose, onSave: handleCropSave }))] }));
140
+ }, variant: "secondary", size: "sm", children: tMediaEditor("editImage") })), _jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), variant: "outline", size: "sm", children: tUpload("change") }), _jsx(Button, { type: "button", onClick: handleRemove, variant: "danger", size: "sm", children: tUpload("remove") })] }))] })) : (_jsxs(_Fragment, { children: [showCamera && isCameraSupported && (_jsx(CameraCapture, { mode: "photo", facingMode: "environment", onCapture: handleCameraCapture, onError: setError })), !showCamera && (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Row, { gap: "sm", className: "flex-wrap", children: [showFileInput && (_jsx(Button, { type: "button", onClick: () => fileInputRef.current?.click(), disabled: uploading, variant: "outline", size: "sm", children: uploading ? tUpload("uploading") : tUpload("clickToUpload") })), captureSource !== "file-only" && isCameraSupported && (_jsx(Button, { type: "button", onClick: () => setCaptureMode("camera"), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") })), captureSource !== "file-only" && !isCameraSupported && (_jsx(Button, { type: "button", onClick: () => mobileCaptureRef.current?.click(), disabled: uploading, variant: "ghost", size: "sm", children: t("switchToCamera") }))] }), _jsxs(Text, { size: "xs", variant: "secondary", children: [accept === "image/*"
141
+ ? `JPG PNG GIF WebP`
142
+ : accept.split(",").map((a) => a.split("/")[1]?.toUpperCase() ?? a).join(" "), " ", "\u2014 max ", maxSizeMB, "MB"] })] }))] })) }), _jsx("input", { ref: fileInputRef, type: "file", accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-input" }), showCamera && !isCameraSupported && (_jsx("input", { ref: mobileCaptureRef, type: "file", accept: "image/*", capture: "environment", onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-capture-input" })), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error }), uploading && (_jsxs(Row, { className: "gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: tUpload("uploadingProgress", { progress }) })] })), cropPreviewUrl && (_jsx(ImageCropModal, { isOpen: showCropModal, imageUrl: cropPreviewUrl, onClose: handleCropClose, onSave: handleCropSave }))] }));
134
143
  }
@@ -14,7 +14,7 @@ function fileNameFromUrl(url) {
14
14
  return url;
15
15
  }
16
16
  }
17
- export function MediaUploadList({ label, value, onChange, onUpload, accept = "image/*,video/*", maxSizeMB = 50, maxItems = 12, disabled = false, helperText, onAbort, onStagedUrlsChange, isPersisted = false, }) {
17
+ export function MediaUploadList({ label, value, onChange, onUpload, accept = "image/*,video/*,application/pdf", maxSizeMB = 50, maxItems = 12, disabled = false, helperText, onAbort, onStagedUrlsChange, isPersisted = false, }) {
18
18
  const inputRef = useRef(null);
19
19
  const [isLoading, setIsLoading] = useState(false);
20
20
  const [error, setError] = useState(null);
@@ -100,5 +100,5 @@ export function MediaUploadList({ label, value, onChange, onUpload, accept = "im
100
100
  unstageUrl(target.url);
101
101
  }
102
102
  };
103
- return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label }), value.length > 0 && (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: value.map((item, index) => (_jsxs(Div, { className: "rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 p-3", children: [item.type === "video" ? (_jsx(Div, { className: "relative aspect-video overflow-hidden rounded-lg", children: _jsx(MediaVideo, { src: item.url, alt: item.alt || `Media ${index + 1}`, controls: true }) })) : item.type === "image" ? (_jsx(Div, { className: "relative aspect-video overflow-hidden rounded-lg", children: _jsx(MediaImage, { src: item.url, alt: item.alt || `Media ${index + 1}`, size: "card", objectFit: "contain" }) })) : (_jsx("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", className: "text-sm underline break-all text-blue-600 dark:text-blue-400", children: fileNameFromUrl(item.url) })), !disabled && (_jsx(Div, { className: "mt-2", children: _jsx(Button, { type: "button", size: "sm", variant: "danger", onClick: () => removeAt(index), children: "Remove" }) }))] }, `${item.url}-${index}`))) })), !disabled && value.length < maxItems && (_jsx(Button, { type: "button", variant: "ghost", className: "w-full py-3 border-2 border-dashed border-zinc-200 dark:border-zinc-700 rounded-xl text-sm text-zinc-500 dark:text-zinc-400", onClick: () => inputRef.current?.click(), disabled: isLoading, children: isLoading ? "Uploading..." : "Add media" })), isLoading && (_jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: "Uploading" })] })), _jsx("input", { ref: inputRef, type: "file", multiple: true, accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-list-input" }), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error })] }));
103
+ return (_jsxs(Div, { className: "space-y-2", children: [_jsx(Label, { className: "block text-sm font-medium text-zinc-600 dark:text-zinc-400", children: label }), value.length > 0 && (_jsx(Div, { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: value.map((item, index) => (_jsxs(Div, { className: "rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-900 p-3", children: [item.type === "video" ? (_jsx(Div, { className: "relative aspect-square max-h-24 overflow-hidden rounded-lg", children: _jsx(MediaVideo, { src: item.url, alt: item.alt || `Media ${index + 1}`, controls: true }) })) : item.type === "image" ? (_jsx(Div, { className: "relative aspect-square max-h-24 overflow-hidden rounded-lg", children: _jsx(MediaImage, { src: item.url, alt: item.alt || `Media ${index + 1}`, size: "card", objectFit: "contain" }) })) : (_jsx("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", className: "text-sm underline break-all text-blue-600 dark:text-blue-400", children: fileNameFromUrl(item.url) })), !disabled && (_jsx(Div, { className: "mt-2", children: _jsx(Button, { type: "button", size: "sm", variant: "danger", onClick: () => removeAt(index), children: "Remove" }) }))] }, `${item.url}-${index}`))) })), !disabled && value.length < maxItems && (_jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => inputRef.current?.click(), disabled: isLoading, children: isLoading ? "Uploading..." : `+ Add Files (${value.length}/${maxItems})` })), isLoading && (_jsxs(Div, { className: "flex items-center gap-2", children: [_jsx(Spinner, { size: "sm" }), _jsx(Text, { size: "sm", variant: "secondary", children: "Uploading" })] })), _jsx("input", { ref: inputRef, type: "file", multiple: true, accept: accept, onChange: handleFileChange, className: "hidden", "aria-hidden": "true", "data-testid": "media-upload-list-input" }), helperText && !error && (_jsx(Text, { variant: "secondary", size: "xs", children: helperText })), error && _jsx(Alert, { variant: "error", children: error })] }));
104
104
  }
@@ -197,6 +197,12 @@ export interface OrderDocument {
197
197
  shippingProofMimeType?: string;
198
198
  shippingProofUploadedAt?: Date;
199
199
  shippingProofUploadedBy?: string;
200
+ /** Physical staging location for fulfilment management (Print & Label Center). */
201
+ physicalLocation?: {
202
+ zone: string;
203
+ shelf: string;
204
+ bin: string;
205
+ };
200
206
  createdAt: Date;
201
207
  updatedAt: Date;
202
208
  }
@@ -16,8 +16,8 @@ export declare const orderItemSchema: z.ZodObject<{
16
16
  productId: string;
17
17
  quantity: number;
18
18
  currency?: string | undefined;
19
- storeId?: string | undefined;
20
19
  image?: string | undefined;
20
+ storeId?: string | undefined;
21
21
  attributes?: Record<string, string> | undefined;
22
22
  }, {
23
23
  title: string;
@@ -25,8 +25,8 @@ export declare const orderItemSchema: z.ZodObject<{
25
25
  productId: string;
26
26
  quantity: number;
27
27
  currency?: string | undefined;
28
- storeId?: string | undefined;
29
28
  image?: string | undefined;
29
+ storeId?: string | undefined;
30
30
  attributes?: Record<string, string> | undefined;
31
31
  }>;
32
32
  export declare const orderTimelineSchema: z.ZodObject<{
@@ -76,8 +76,8 @@ export declare const orderSchema: z.ZodObject<{
76
76
  productId: string;
77
77
  quantity: number;
78
78
  currency?: string | undefined;
79
- storeId?: string | undefined;
80
79
  image?: string | undefined;
80
+ storeId?: string | undefined;
81
81
  attributes?: Record<string, string> | undefined;
82
82
  }, {
83
83
  title: string;
@@ -85,8 +85,8 @@ export declare const orderSchema: z.ZodObject<{
85
85
  productId: string;
86
86
  quantity: number;
87
87
  currency?: string | undefined;
88
- storeId?: string | undefined;
89
88
  image?: string | undefined;
89
+ storeId?: string | undefined;
90
90
  attributes?: Record<string, string> | undefined;
91
91
  }>, "many">;
92
92
  address: z.ZodRecord<z.ZodString, z.ZodUnknown>;
@@ -131,8 +131,8 @@ export declare const orderSchema: z.ZodObject<{
131
131
  productId: string;
132
132
  quantity: number;
133
133
  currency?: string | undefined;
134
- storeId?: string | undefined;
135
134
  image?: string | undefined;
135
+ storeId?: string | undefined;
136
136
  attributes?: Record<string, string> | undefined;
137
137
  }[];
138
138
  total: number;
@@ -143,10 +143,10 @@ export declare const orderSchema: z.ZodObject<{
143
143
  createdAt?: string | undefined;
144
144
  updatedAt?: string | undefined;
145
145
  notes?: string | undefined;
146
+ tax?: number | undefined;
146
147
  trackingNumber?: string | undefined;
147
148
  couponCode?: string | undefined;
148
149
  shippingCarrier?: string | undefined;
149
- tax?: number | undefined;
150
150
  discount?: number | undefined;
151
151
  paymentGateway?: string | undefined;
152
152
  shippingCost?: number | undefined;
@@ -166,8 +166,8 @@ export declare const orderSchema: z.ZodObject<{
166
166
  productId: string;
167
167
  quantity: number;
168
168
  currency?: string | undefined;
169
- storeId?: string | undefined;
170
169
  image?: string | undefined;
170
+ storeId?: string | undefined;
171
171
  attributes?: Record<string, string> | undefined;
172
172
  }[];
173
173
  total: number;
@@ -178,10 +178,10 @@ export declare const orderSchema: z.ZodObject<{
178
178
  createdAt?: string | undefined;
179
179
  updatedAt?: string | undefined;
180
180
  notes?: string | undefined;
181
+ tax?: number | undefined;
181
182
  trackingNumber?: string | undefined;
182
183
  couponCode?: string | undefined;
183
184
  shippingCarrier?: string | undefined;
184
- tax?: number | undefined;
185
185
  discount?: number | undefined;
186
186
  paymentGateway?: string | undefined;
187
187
  shippingCost?: number | undefined;
@@ -202,15 +202,15 @@ export declare const orderListParamsSchema: z.ZodObject<{
202
202
  perPage: z.ZodOptional<z.ZodNumber>;
203
203
  }, "strip", z.ZodTypeAny, {
204
204
  sort?: string | undefined;
205
- perPage?: number | undefined;
206
205
  page?: number | undefined;
206
+ perPage?: number | undefined;
207
207
  userId?: string | undefined;
208
208
  paymentStatus?: string | undefined;
209
209
  orderStatus?: "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "cancelled" | "return_requested" | "returned" | undefined;
210
210
  }, {
211
211
  sort?: string | undefined;
212
- perPage?: number | undefined;
213
212
  page?: number | undefined;
213
+ perPage?: number | undefined;
214
214
  userId?: string | undefined;
215
215
  paymentStatus?: string | undefined;
216
216
  orderStatus?: "pending" | "processing" | "refunded" | "confirmed" | "shipped" | "delivered" | "cancelled" | "return_requested" | "returned" | undefined;
@@ -71,6 +71,11 @@ export interface Order {
71
71
  shippingCarrier?: string;
72
72
  notes?: string;
73
73
  timeline?: OrderTimeline[];
74
+ physicalLocation?: {
75
+ zone: string;
76
+ shelf: string;
77
+ bin: string;
78
+ };
74
79
  createdAt?: string;
75
80
  updatedAt?: string;
76
81
  }
@@ -39,8 +39,8 @@ export declare const paymentRecordSchema: z.ZodObject<{
39
39
  createdAt: z.ZodOptional<z.ZodString>;
40
40
  }, "strip", z.ZodTypeAny, {
41
41
  currency: string;
42
+ status: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded";
42
43
  id: string;
43
- status: "failed" | "captured" | "pending" | "authorized" | "refunded" | "partially_refunded";
44
44
  amount: number;
45
45
  orderId: string;
46
46
  gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
@@ -52,8 +52,8 @@ export declare const paymentRecordSchema: z.ZodObject<{
52
52
  orderId: string;
53
53
  gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
54
54
  currency?: string | undefined;
55
+ status?: "pending" | "failed" | "captured" | "authorized" | "refunded" | "partially_refunded" | undefined;
55
56
  createdAt?: string | undefined;
56
- status?: "failed" | "captured" | "pending" | "authorized" | "refunded" | "partially_refunded" | undefined;
57
57
  gatewayPaymentId?: string | undefined;
58
58
  }>;
59
59
  export declare const paymentGatewayConfigSchema: z.ZodObject<{
@@ -64,14 +64,14 @@ export declare const paymentGatewayConfigSchema: z.ZodObject<{
64
64
  sortOrder: z.ZodDefault<z.ZodNumber>;
65
65
  }, "strip", z.ZodTypeAny, {
66
66
  id: string;
67
+ displayName: string;
67
68
  gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
68
69
  isEnabled: boolean;
69
- displayName: string;
70
70
  sortOrder: number;
71
71
  }, {
72
72
  id: string;
73
- gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
74
73
  displayName: string;
74
+ gateway: "bank_transfer" | "upi" | "razorpay" | "stripe" | "paypal" | "cod" | "whatsapp";
75
75
  isEnabled?: boolean | undefined;
76
76
  sortOrder?: number | undefined;
77
77
  }>;
@@ -22,18 +22,18 @@ export declare const preorderItemSchema: z.ZodObject<{
22
22
  source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
23
23
  youtubeId: z.ZodOptional<z.ZodString>;
24
24
  }, "strip", z.ZodTypeAny, {
25
- type: "video" | "image" | "file";
26
25
  url: string;
27
- source?: "upload" | "youtube" | "external" | undefined;
26
+ type: "image" | "video" | "file";
28
27
  alt?: string | undefined;
29
28
  thumbnailUrl?: string | undefined;
29
+ source?: "upload" | "youtube" | "external" | undefined;
30
30
  youtubeId?: string | undefined;
31
31
  }, {
32
- type: "video" | "image" | "file";
33
32
  url: string;
34
- source?: "upload" | "youtube" | "external" | undefined;
33
+ type: "image" | "video" | "file";
35
34
  alt?: string | undefined;
36
35
  thumbnailUrl?: string | undefined;
36
+ source?: "upload" | "youtube" | "external" | undefined;
37
37
  youtubeId?: string | undefined;
38
38
  }>, "many">>;
39
39
  salePrice: z.ZodNumber;
@@ -56,11 +56,11 @@ export declare const preorderItemSchema: z.ZodObject<{
56
56
  brand?: string | undefined;
57
57
  images?: string[] | undefined;
58
58
  media?: {
59
- type: "video" | "image" | "file";
60
59
  url: string;
61
- source?: "upload" | "youtube" | "external" | undefined;
60
+ type: "image" | "video" | "file";
62
61
  alt?: string | undefined;
63
62
  thumbnailUrl?: string | undefined;
63
+ source?: "upload" | "youtube" | "external" | undefined;
64
64
  youtubeId?: string | undefined;
65
65
  }[] | undefined;
66
66
  franchise?: string | undefined;
@@ -75,11 +75,11 @@ export declare const preorderItemSchema: z.ZodObject<{
75
75
  brand?: string | undefined;
76
76
  images?: string[] | undefined;
77
77
  media?: {
78
- type: "video" | "image" | "file";
79
78
  url: string;
80
- source?: "upload" | "youtube" | "external" | undefined;
79
+ type: "image" | "video" | "file";
81
80
  alt?: string | undefined;
82
81
  thumbnailUrl?: string | undefined;
82
+ source?: "upload" | "youtube" | "external" | undefined;
83
83
  youtubeId?: string | undefined;
84
84
  }[] | undefined;
85
85
  active?: boolean | undefined;
@@ -93,7 +93,7 @@ export function PrizeDrawItemsEditor({ items, onChange, onUploadImage, onUploadV
93
93
  }), disabled: locked, placeholder: "2999" }) })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { className: "text-sm font-medium", children: ["Images (", (it.images ?? []).length, "/", MAX_IMAGES_PER_ITEM, ")"] }), _jsx(Row, { gap: "sm", className: "flex-wrap", children: Array.from({ length: MAX_IMAGES_PER_ITEM }).map((_, slot) => {
94
94
  const existing = (it.images ?? [])[slot];
95
95
  return (_jsxs(Div, { className: "w-40", children: [_jsx(ImageUpload, { currentImage: existing, label: existing ? "Replace" : `Image ${slot + 1}`, onUpload: (file) => onUploadImage(file, it.itemNumber), onChange: (url) => setImage(index, slot, url) }), existing && !locked ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => removeImage(index, slot), children: "Remove" })) : null] }, slot));
96
- }) })] }), onUploadVideo ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { className: "text-sm font-medium", children: "Video (optional)" }), _jsx("input", { type: "file", accept: "video/mp4,video/webm", disabled: locked, onChange: (e) => handleVideoFileChange(e, index, it.itemNumber) }), it.video?.url ? (_jsxs(Text, { className: "text-xs text-[var(--appkit-color-text-muted)] truncate", children: ["Current: ", it.video.url] })) : null] })) : null] })] }, `prize-item-${it.itemNumber}-${index}`));
96
+ }) })] }), onUploadVideo ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { className: "text-sm font-medium", children: "Video (optional)" }), _jsx("input", { type: "file", accept: "video/*", disabled: locked, onChange: (e) => handleVideoFileChange(e, index, it.itemNumber) }), it.video?.url ? (_jsxs(Text, { className: "text-xs text-[var(--appkit-color-text-muted)] truncate", children: ["Current: ", it.video.url] })) : null] })) : null] })] }, `prize-item-${it.itemNumber}-${index}`));
97
97
  }) }), items.length < MIN_ITEMS ? (_jsxs(Div, { className: "rounded border border-red-400/40 bg-red-50 px-3 py-2 text-sm text-red-900 dark:bg-red-900/30 dark:text-red-100", children: ["At least ", MIN_ITEMS, " prizes are required."] })) : null] }));
98
98
  }
99
99
  export default PrizeDrawItemsEditor;
@@ -90,7 +90,7 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
90
90
  name: product.title || "product",
91
91
  category: (product.categorySlugs?.[0] ?? product.category) || "uncategorized",
92
92
  store: product.storeName || "store",
93
- }), onChange: (url) => update({ mainImage: url }), label: t("formMainImage"), helperText: "Recommended: 800x800px (1:1)" })), isReadonly && product.mainImage && (_jsx(FormField, { name: "mainImage", label: t("formMainImage"), type: "text", value: product.mainImage, onChange: () => { }, disabled: true })), !isReadonly && (_jsx(MediaUploadList, { label: t("formGalleryImages"), value: galleryImages, onChange: (fields) => update({ images: fields.map((f) => f.url) }), onUpload: handleGalleryUpload, accept: "image/*", maxItems: 5, maxSizeMB: 10, helperText: t("formGalleryImagesHelper"), onAbort: onMediaAbort })), !isReadonly && (_jsx(MediaUploadField, { label: t("formVideo"), value: product.video?.url || "", onChange: (url) => update({
93
+ }), onChange: (url) => update({ mainImage: url }), label: t("formMainImage"), helperText: "Recommended: 800x800px (1:1)" })), isReadonly && product.mainImage && (_jsx(FormField, { name: "mainImage", label: t("formMainImage"), type: "text", value: product.mainImage, onChange: () => { }, disabled: true })), !isReadonly && (_jsx(MediaUploadList, { label: t("formGalleryImages"), value: galleryImages, onChange: (fields) => update({ images: fields.map((f) => f.url) }), onUpload: handleGalleryUpload, accept: "image/*,video/*", maxItems: 5, maxSizeMB: 10, helperText: t("formGalleryImagesHelper"), onAbort: onMediaAbort })), !isReadonly && (_jsx(MediaUploadField, { label: t("formVideo"), value: product.video?.url || "", onChange: (url) => update({
94
94
  video: url
95
95
  ? {
96
96
  url,
@@ -178,5 +178,23 @@ export function ProductForm({ product, onChange, isReadonly = false, renderDescr
178
178
  ? "auction"
179
179
  : isPreOrderListing(product)
180
180
  ? "preorder"
181
- : "product"), storeId: product.storeId, disabled: isReadonly }), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Custom Sections" }), _jsx(Text, { className: "mb-3 text-xs text-zinc-500 dark:text-zinc-400", children: "Add up to 3 custom tabs to your product page \u2014 e.g. \"Box Contents\", \"Compatibility\", \"Grading Details\"." }), _jsx(CustomSectionsEditor, { sections: product.customSections ?? [], onChange: (sections) => update({ customSections: sections }) })] }), _jsx(FormField, { name: "shippingInfo", label: t("formShipping"), type: "textarea", value: product.shippingInfo || "", onChange: (value) => update({ shippingInfo: value }), disabled: isReadonly, placeholder: "Shipping information..." }), _jsx(FormField, { name: "returnPolicy", label: t("formReturnPolicy"), type: "textarea", value: product.returnPolicy || "", onChange: (value) => update({ returnPolicy: value }), disabled: isReadonly, placeholder: "Return policy details..." }), product.storeName && (_jsx(FormField, { name: "storeName", label: t("formSeller"), type: "text", value: product.storeName, onChange: () => { }, disabled: true }))] }));
181
+ : "product"), storeId: product.storeId, disabled: isReadonly }), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Custom Sections" }), _jsx(Text, { className: "mb-3 text-xs text-zinc-500 dark:text-zinc-400", children: "Add up to 3 custom tabs to your product page \u2014 e.g. \"Box Contents\", \"Compatibility\", \"Grading Details\"." }), _jsx(CustomSectionsEditor, { sections: product.customSections ?? [], onChange: (sections) => update({ customSections: sections }) })] }), _jsx(FormField, { name: "shippingInfo", label: t("formShipping"), type: "textarea", value: product.shippingInfo || "", onChange: (value) => update({ shippingInfo: value }), disabled: isReadonly, placeholder: "Shipping information..." }), _jsx(FormField, { name: "returnPolicy", label: t("formReturnPolicy"), type: "textarea", value: product.returnPolicy || "", onChange: (value) => update({ returnPolicy: value }), disabled: isReadonly, placeholder: "Return policy details..." }), _jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-1 text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Physical Inventory" }), _jsx(Text, { className: "mb-3 text-xs text-zinc-500 dark:text-zinc-400", children: "Assign a storage location for warehouse or shelf organisation. Used by the Print & Label Center." }), _jsxs(FormGroup, { columns: 3, children: [_jsx(FormField, { name: "physicalLocation.zone", label: "Zone", type: "text", placeholder: "e.g. A", value: product.physicalLocation?.zone ?? "", onChange: (v) => update({
182
+ physicalLocation: {
183
+ zone: v,
184
+ shelf: product.physicalLocation?.shelf ?? "",
185
+ bin: product.physicalLocation?.bin ?? "",
186
+ },
187
+ }), disabled: isReadonly }), _jsx(FormField, { name: "physicalLocation.shelf", label: "Shelf", type: "text", placeholder: "e.g. 3", value: product.physicalLocation?.shelf ?? "", onChange: (v) => update({
188
+ physicalLocation: {
189
+ zone: product.physicalLocation?.zone ?? "",
190
+ shelf: v,
191
+ bin: product.physicalLocation?.bin ?? "",
192
+ },
193
+ }), disabled: isReadonly }), _jsx(FormField, { name: "physicalLocation.bin", label: "Bin", type: "text", placeholder: "e.g. Blue", value: product.physicalLocation?.bin ?? "", onChange: (v) => update({
194
+ physicalLocation: {
195
+ zone: product.physicalLocation?.zone ?? "",
196
+ shelf: product.physicalLocation?.shelf ?? "",
197
+ bin: v,
198
+ },
199
+ }), disabled: isReadonly })] })] }), product.storeName && (_jsx(FormField, { name: "storeName", label: t("formSeller"), type: "text", value: product.storeName, onChange: () => { }, disabled: true }))] }));
182
200
  }