@mohasinac/appkit 3.0.4 → 3.0.6

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 (149) hide show
  1. package/dist/_internal/server/features/auctions/data.d.ts +2 -4
  2. package/dist/_internal/server/features/auctions/data.js +3 -9
  3. package/dist/_internal/server/features/classified/adapters.d.ts +2 -15
  4. package/dist/_internal/server/features/classified/adapters.js +2 -17
  5. package/dist/_internal/server/features/classified/data.d.ts +1 -6
  6. package/dist/_internal/server/features/classified/data.js +2 -10
  7. package/dist/_internal/server/features/digital-code/adapters.d.ts +2 -15
  8. package/dist/_internal/server/features/digital-code/adapters.js +2 -17
  9. package/dist/_internal/server/features/digital-code/data.d.ts +1 -6
  10. package/dist/_internal/server/features/digital-code/data.js +2 -10
  11. package/dist/_internal/server/features/live/adapters.d.ts +2 -15
  12. package/dist/_internal/server/features/live/adapters.js +2 -17
  13. package/dist/_internal/server/features/live/data.d.ts +1 -6
  14. package/dist/_internal/server/features/live/data.js +2 -10
  15. package/dist/_internal/server/features/pre-orders/data.d.ts +2 -4
  16. package/dist/_internal/server/features/pre-orders/data.js +3 -9
  17. package/dist/_internal/server/features/prize-draws/actions.d.ts +2 -0
  18. package/dist/_internal/server/features/prize-draws/actions.js +22 -0
  19. package/dist/_internal/server/features/prize-draws/data.d.ts +1 -17
  20. package/dist/_internal/server/features/prize-draws/data.js +2 -20
  21. package/dist/_internal/server/features/prize-draws/index.d.ts +3 -1
  22. package/dist/_internal/server/features/prize-draws/index.js +2 -0
  23. package/dist/_internal/server/features/prize-draws/service.d.ts +3 -0
  24. package/dist/_internal/server/features/prize-draws/service.js +19 -0
  25. package/dist/_internal/server/features/shared/listing-adapters.d.ts +19 -0
  26. package/dist/_internal/server/features/shared/listing-adapters.js +20 -0
  27. package/dist/_internal/server/features/shared/listing-data-factory.d.ts +9 -0
  28. package/dist/_internal/server/features/shared/listing-data-factory.js +33 -0
  29. package/dist/_internal/server/features/stores/data.d.ts +3 -14
  30. package/dist/_internal/server/features/stores/data.js +6 -44
  31. package/dist/_internal/shared/features/cart/schema.d.ts +8 -8
  32. package/dist/_internal/shared/features/cart/schema.js +3 -0
  33. package/dist/_internal/shared/listing-types/_registry.js +2 -0
  34. package/dist/_internal/shared/listing-types/auction/schema.d.ts +3 -1
  35. package/dist/_internal/shared/listing-types/auction/schema.js +7 -1
  36. package/dist/_internal/shared/listing-types/classified/schema.d.ts +2 -1
  37. package/dist/_internal/shared/listing-types/classified/schema.js +3 -1
  38. package/dist/_internal/shared/listing-types/digital-code/schema.d.ts +3 -1
  39. package/dist/_internal/shared/listing-types/digital-code/schema.js +7 -1
  40. package/dist/_internal/shared/listing-types/live/schema.d.ts +2 -1
  41. package/dist/_internal/shared/listing-types/live/schema.js +3 -1
  42. package/dist/_internal/shared/listing-types/pre-order/schema.d.ts +3 -1
  43. package/dist/_internal/shared/listing-types/pre-order/schema.js +7 -1
  44. package/dist/_internal/shared/listing-types/prize-draw/schema.d.ts +3 -1
  45. package/dist/_internal/shared/listing-types/prize-draw/schema.js +13 -1
  46. package/dist/_internal/shared/listing-types/standard/schema.d.ts +2 -1
  47. package/dist/_internal/shared/listing-types/standard/schema.js +4 -1
  48. package/dist/_internal/shared/types/base-document.d.ts +15 -0
  49. package/dist/_internal/shared/types/base-document.js +1 -0
  50. package/dist/_internal/shared/types/index.d.ts +2 -0
  51. package/dist/_internal/shared/types/index.js +1 -0
  52. package/dist/client.d.ts +4 -4
  53. package/dist/client.js +2 -2
  54. package/dist/constants/api-endpoints.d.ts +12 -0
  55. package/dist/constants/api-endpoints.js +4 -0
  56. package/dist/features/addresses/schemas/firestore.d.ts +2 -4
  57. package/dist/features/admin/components/AdminFulfillmentView.d.ts +6 -0
  58. package/dist/features/admin/components/AdminFulfillmentView.js +107 -0
  59. package/dist/features/admin/components/AdminProductEditorView.js +21 -9
  60. package/dist/features/admin/components/AdminProductsView.js +3 -0
  61. package/dist/features/admin/components/DataListingView.d.ts +1 -0
  62. package/dist/features/admin/components/index.d.ts +2 -0
  63. package/dist/features/admin/components/index.js +1 -0
  64. package/dist/features/admin/schemas/firestore.d.ts +3 -8
  65. package/dist/features/auctions/schemas/firestore.d.ts +2 -4
  66. package/dist/features/auctions/schemas/index.d.ts +2 -2
  67. package/dist/features/before-after/schemas/index.d.ts +2 -2
  68. package/dist/features/blog/schemas/firestore.d.ts +2 -4
  69. package/dist/features/blog/schemas/index.d.ts +4 -4
  70. package/dist/features/cart/schemas/firestore.d.ts +2 -4
  71. package/dist/features/categories/schemas/firestore.d.ts +2 -4
  72. package/dist/features/categories/schemas/index.d.ts +4 -4
  73. package/dist/features/events/schemas/firestore.d.ts +2 -4
  74. package/dist/features/events/schemas/index.d.ts +2 -2
  75. package/dist/features/faq/schemas/firestore.d.ts +2 -4
  76. package/dist/features/faq/schemas/index.d.ts +2 -2
  77. package/dist/features/grouped/schemas/index.d.ts +2 -2
  78. package/dist/features/homepage/schemas/firestore.d.ts +4 -12
  79. package/dist/features/homepage/schemas/index.d.ts +2 -2
  80. package/dist/features/messages/schemas/firestore.d.ts +2 -4
  81. package/dist/features/messages/schemas/index.d.ts +2 -2
  82. package/dist/features/orders/repository/orders.repository.d.ts +5 -0
  83. package/dist/features/orders/repository/orders.repository.js +26 -0
  84. package/dist/features/orders/schemas/firestore.d.ts +9 -5
  85. package/dist/features/orders/schemas/firestore.js +3 -0
  86. package/dist/features/payments/schemas/firestore.d.ts +2 -4
  87. package/dist/features/pre-orders/schemas/index.d.ts +2 -2
  88. package/dist/features/products/constants/action-defs.d.ts +16 -0
  89. package/dist/features/products/constants/action-defs.js +16 -0
  90. package/dist/features/products/constants/listing-tabs.d.ts +48 -0
  91. package/dist/features/products/constants/listing-tabs.js +12 -0
  92. package/dist/features/products/repository/products.repository.d.ts +37 -0
  93. package/dist/features/products/repository/products.repository.js +28 -1
  94. package/dist/features/products/schemas/firestore.d.ts +8 -6
  95. package/dist/features/products/schemas/firestore.js +2 -0
  96. package/dist/features/products/schemas/index.d.ts +6 -6
  97. package/dist/features/products/types/index.d.ts +2 -0
  98. package/dist/features/promotions/schemas/firestore.d.ts +2 -4
  99. package/dist/features/promotions/schemas/index.d.ts +4 -4
  100. package/dist/features/reviews/schemas/firestore.d.ts +2 -4
  101. package/dist/features/reviews/schemas/index.d.ts +2 -2
  102. package/dist/features/scams/schemas/firestore.d.ts +2 -4
  103. package/dist/features/scams/schemas/index.d.ts +4 -4
  104. package/dist/features/search/schemas/index.d.ts +2 -2
  105. package/dist/features/seller/components/BarcodeField.d.ts +17 -0
  106. package/dist/features/seller/components/BarcodeField.js +30 -0
  107. package/dist/features/seller/components/FulfillmentView.d.ts +5 -0
  108. package/dist/features/seller/components/FulfillmentView.js +120 -0
  109. package/dist/features/seller/components/PrintCenterView.d.ts +3 -1
  110. package/dist/features/seller/components/PrintCenterView.js +52 -4
  111. package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
  112. package/dist/features/seller/components/SellerProductShell.js +2 -1
  113. package/dist/features/seller/components/index.d.ts +4 -0
  114. package/dist/features/seller/components/index.js +2 -0
  115. package/dist/features/seller/schemas/index.d.ts +2 -2
  116. package/dist/features/store-extensions/schemas/firestore.d.ts +12 -44
  117. package/dist/features/stores/components/StoreClassifiedsListing.d.ts +5 -0
  118. package/dist/features/stores/components/StoreClassifiedsListing.js +48 -0
  119. package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -0
  120. package/dist/features/stores/components/StoreClassifiedsPageView.js +20 -0
  121. package/dist/features/stores/components/StoreDetailLayoutView.js +23 -2
  122. package/dist/features/stores/components/StoreDigitalCodesListing.d.ts +5 -0
  123. package/dist/features/stores/components/StoreDigitalCodesListing.js +48 -0
  124. package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -0
  125. package/dist/features/stores/components/StoreDigitalCodesPageView.js +20 -0
  126. package/dist/features/stores/components/StoreLiveItemsListing.d.ts +5 -0
  127. package/dist/features/stores/components/StoreLiveItemsListing.js +48 -0
  128. package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -0
  129. package/dist/features/stores/components/StoreLiveItemsPageView.js +20 -0
  130. package/dist/features/stores/components/index.d.ts +9 -0
  131. package/dist/features/stores/components/index.js +3 -0
  132. package/dist/features/stores/schemas/firestore.d.ts +2 -4
  133. package/dist/features/stores/schemas/index.d.ts +4 -4
  134. package/dist/features/support/schemas/firestore.d.ts +2 -4
  135. package/dist/features/support/schemas/index.d.ts +2 -2
  136. package/dist/next/routing/route-map.d.ts +11 -0
  137. package/dist/next/routing/route-map.js +5 -0
  138. package/dist/schemas/registry.d.ts +24 -24
  139. package/dist/seed/grouped-listings-seed-data.d.ts +2 -1
  140. package/dist/seed/products-preorders-seed-data.d.ts +2 -1
  141. package/dist/seed/products-standard-seed-data.js +8 -0
  142. package/dist/server-entry.d.ts +3 -0
  143. package/dist/server-entry.js +3 -0
  144. package/dist/server.d.ts +4 -4
  145. package/dist/styles.css +1 -1
  146. package/dist/tailwind-utilities.css +1 -1
  147. package/dist/utils/id-generators.d.ts +8 -0
  148. package/dist/utils/id-generators.js +14 -0
  149. package/package.json +2 -1
@@ -8,14 +8,14 @@ export declare const addToCartSchema: z.ZodObject<{
8
8
  storeId: z.ZodString;
9
9
  storeName: z.ZodDefault<z.ZodString>;
10
10
  quantity: z.ZodDefault<z.ZodNumber>;
11
- listingType: z.ZodEnum<["standard", "auction", "pre-order", "prize-draw"]>;
11
+ listingType: z.ZodEnum<["standard", "auction", "pre-order", "prize-draw", "classified", "digital-code", "live"]>;
12
12
  isOffer: z.ZodOptional<z.ZodBoolean>;
13
13
  offerId: z.ZodOptional<z.ZodString>;
14
14
  lockedPrice: z.ZodOptional<z.ZodNumber>;
15
15
  }, "strip", z.ZodTypeAny, {
16
16
  currency: string;
17
17
  storeId: string;
18
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
18
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
19
19
  price: number;
20
20
  storeName: string;
21
21
  productId: string;
@@ -27,7 +27,7 @@ export declare const addToCartSchema: z.ZodObject<{
27
27
  isOffer?: boolean | undefined;
28
28
  }, {
29
29
  storeId: string;
30
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
30
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
31
31
  price: number;
32
32
  productId: string;
33
33
  productTitle: string;
@@ -66,14 +66,14 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
66
66
  storeId: z.ZodString;
67
67
  storeName: z.ZodDefault<z.ZodString>;
68
68
  quantity: z.ZodDefault<z.ZodNumber>;
69
- listingType: z.ZodEnum<["standard", "auction", "pre-order", "prize-draw"]>;
69
+ listingType: z.ZodEnum<["standard", "auction", "pre-order", "prize-draw", "classified", "digital-code", "live"]>;
70
70
  isOffer: z.ZodOptional<z.ZodBoolean>;
71
71
  offerId: z.ZodOptional<z.ZodString>;
72
72
  lockedPrice: z.ZodOptional<z.ZodNumber>;
73
73
  }, "strip", z.ZodTypeAny, {
74
74
  currency: string;
75
75
  storeId: string;
76
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
76
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
77
77
  price: number;
78
78
  storeName: string;
79
79
  productId: string;
@@ -85,7 +85,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
85
85
  isOffer?: boolean | undefined;
86
86
  }, {
87
87
  storeId: string;
88
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
88
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
89
89
  price: number;
90
90
  productId: string;
91
91
  productTitle: string;
@@ -101,7 +101,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
101
101
  guestItems: {
102
102
  currency: string;
103
103
  storeId: string;
104
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
104
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
105
105
  price: number;
106
106
  storeName: string;
107
107
  productId: string;
@@ -115,7 +115,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
115
115
  }, {
116
116
  guestItems: {
117
117
  storeId: string;
118
- listingType: "standard" | "auction" | "pre-order" | "prize-draw";
118
+ listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "classified" | "digital-code" | "live";
119
119
  price: number;
120
120
  productId: string;
121
121
  productTitle: string;
@@ -15,6 +15,9 @@ const cartItemBaseSchema = z.object({
15
15
  "auction",
16
16
  "pre-order",
17
17
  "prize-draw",
18
+ "classified",
19
+ "digital-code",
20
+ "live",
18
21
  ]),
19
22
  isOffer: z.boolean().optional(),
20
23
  offerId: z.string().optional(),
@@ -28,6 +28,8 @@ export const LISTING_TYPE_REGISTRY = {
28
28
  "digital-code": digitalCode.config,
29
29
  live: live.config,
30
30
  };
31
+ // Returns undefined for "bundle" — bundles are CategoryDocument, not in this registry.
32
+ // Callers must null-check: `pluginFor(lt) ?? fallbackBehavior`.
31
33
  export function pluginFor(type) {
32
34
  return LISTING_TYPE_REGISTRY[type];
33
35
  }
@@ -1 +1,3 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isAuctionProduct(doc: ProductDocument): boolean;
3
+ export declare function isActiveAuction(doc: ProductDocument): boolean;
@@ -1 +1,7 @@
1
- export {};
1
+ export function isAuctionProduct(doc) {
2
+ return doc.listingType === "auction" && doc.auctionEndDate != null;
3
+ }
4
+ // True when the auction end date is in the future — gates the Bid button.
5
+ export function isActiveAuction(doc) {
6
+ return isAuctionProduct(doc) && doc.auctionEndDate > new Date();
7
+ }
@@ -1 +1,2 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isClassifiedProduct(doc: ProductDocument): boolean;
@@ -1 +1,3 @@
1
- export {};
1
+ export function isClassifiedProduct(doc) {
2
+ return doc.listingType === "classified";
3
+ }
@@ -1 +1,3 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isDigitalCodeProduct(doc: ProductDocument): boolean;
3
+ export declare function hasCodesAvailable(doc: ProductDocument): boolean;
@@ -1 +1,7 @@
1
- export {};
1
+ export function isDigitalCodeProduct(doc) {
2
+ return doc.listingType === "digital-code";
3
+ }
4
+ // True when there are codes remaining — gates the Buy Now CTA.
5
+ export function hasCodesAvailable(doc) {
6
+ return isDigitalCodeProduct(doc) && (doc.digitalCode?.codesAvailable ?? 0) > 0;
7
+ }
@@ -1 +1,2 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isLiveItemProduct(doc: ProductDocument): boolean;
@@ -1 +1,3 @@
1
- export {};
1
+ export function isLiveItemProduct(doc) {
2
+ return doc.listingType === "live";
3
+ }
@@ -1 +1,3 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isPreOrderProduct(doc: ProductDocument): boolean;
3
+ export declare function isOpenPreOrder(doc: ProductDocument): boolean;
@@ -1 +1,7 @@
1
- export {};
1
+ export function isPreOrderProduct(doc) {
2
+ return doc.listingType === "pre-order";
3
+ }
4
+ // True when the pre-order window is still open (not closed, delivery date in future).
5
+ export function isOpenPreOrder(doc) {
6
+ return isPreOrderProduct(doc) && !doc.preOrderClosed && doc.preOrderDeliveryDate > new Date();
7
+ }
@@ -1 +1,3 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isPrizeDrawProduct(doc: ProductDocument): boolean;
3
+ export declare function isOpenPrizeDraw(doc: ProductDocument): boolean;
@@ -1 +1,13 @@
1
- export {};
1
+ export function isPrizeDrawProduct(doc) {
2
+ return doc.listingType === "prize-draw";
3
+ }
4
+ // True when entries are still accepted (reveal window has not started, slots not exhausted).
5
+ export function isOpenPrizeDraw(doc) {
6
+ if (!isPrizeDrawProduct(doc))
7
+ return false;
8
+ const max = doc.prizeMaxEntries ?? null;
9
+ const current = doc.prizeCurrentEntries ?? 0;
10
+ if (typeof max === "number" && current >= max)
11
+ return false;
12
+ return !doc.prizeRevealWindowStart || doc.prizeRevealWindowStart > new Date();
13
+ }
@@ -1 +1,2 @@
1
- export {};
1
+ import type { ProductDocument } from "../../../../features/products/schemas/firestore";
2
+ export declare function isStandardProduct(doc: ProductDocument): boolean;
@@ -1 +1,4 @@
1
- export {};
1
+ // Standard is the default — any product without an explicit listingType is treated as standard.
2
+ export function isStandardProduct(doc) {
3
+ return doc.listingType === "standard" || doc.listingType == null;
4
+ }
@@ -0,0 +1,15 @@
1
+ export interface BaseDocument {
2
+ id: string;
3
+ createdAt: Date;
4
+ updatedAt: Date;
5
+ }
6
+ export interface WithSlug {
7
+ slug?: string;
8
+ }
9
+ export interface WithStoreOwnership {
10
+ storeId: string;
11
+ ownerId?: string;
12
+ }
13
+ export interface WithStatus<S extends string> {
14
+ status: S;
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export type { BaseDocument, WithSlug, WithStoreOwnership, WithStatus } from "./base-document";
2
+ export type { ActionResult } from "./action-result";
@@ -0,0 +1 @@
1
+ export {};
package/dist/client.d.ts CHANGED
@@ -135,8 +135,8 @@ export { ZodSetup } from "./validation/ZodSetup";
135
135
  export type { ZodSetupProps } from "./validation/ZodSetup";
136
136
  export { AdminSidebar } from "./features/admin/components/AdminSidebar";
137
137
  export type { AdminSidebarProps, AdminNavItem, AdminNavGroup } from "./features/admin/components/AdminSidebar";
138
- export { AdminDashboardView, AdminAnalyticsView, AdminPrizeDrawsView, AdminCarouselView, AdminSublistingCategoriesView, DataTable, DataListingView, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
139
- export type { AdminDashboardViewProps, AdminAnalyticsViewProps, AdminAnalyticsViewLabels, AdminPrizeDrawsViewProps, AdminCarouselViewProps, AdminListingScaffoldRow, ListingViewConfig } from "./features/admin/index";
138
+ export { AdminDashboardView, AdminAnalyticsView, AdminPrizeDrawsView, AdminCarouselView, AdminSublistingCategoriesView, AdminFulfillmentView, DataTable, DataListingView, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
139
+ export type { AdminDashboardViewProps, AdminAnalyticsViewProps, AdminAnalyticsViewLabels, AdminPrizeDrawsViewProps, AdminCarouselViewProps, AdminFulfillmentViewProps, AdminListingScaffoldRow, ListingViewConfig } from "./features/admin/index";
140
140
  export type { BulkActionItem } from "./ui/components/BulkActionBar";
141
141
  export { ADMIN_ENDPOINTS } from "./constants/index";
142
142
  export { apiClient, ApiClientError } from "./http/index";
@@ -232,8 +232,8 @@ export { UserOffersPanel } from "./features/account/components/UserOffersPanel";
232
232
  export type { UserOffersPanelProps } from "./features/account/components/UserOffersPanel";
233
233
  export { SellerDashboardView as StoreDashboardView, SellerDashboardView, useSellerDashboard as useStoreDashboard, useSellerDashboard } from "./features/seller/index";
234
234
  export type { SellerDashboardViewProps as StoreDashboardViewProps, SellerDashboardViewProps } from "./features/seller/index";
235
- export { SellerPayoutSettingsView, SellerShippingView, SellerReviewsView, SellerPayoutRequestView, SellerAnalyticsStats, SellerTopProducts, SellerAnalyticsView, SellerPayoutsView, SellerCouponEditorView, SellerBidsView, SellerAddressesView, SellerPreOrdersView, SellerPrizeDrawsView, PrintCenterView, SellerOffersView, SellerGroupedListingsView, StoreGroupedListingsView, SellerAnalyticsAlertsView, StoreAnalyticsAlertsView } from "./features/seller/components/index";
236
- export type { SellerPayoutSettingsViewProps, SellerShippingViewProps, SellerReviewsViewProps, SellerPayoutRequestViewProps, SellerAnalyticsViewProps, SellerPayoutsViewProps, SellerCouponEditorViewProps, CouponEditorDraft, SellerBidsViewProps, SellerAddressesViewProps, SellerPreOrdersViewProps, SellerPrizeDrawsViewProps, SellerOffersViewProps, SellerGroupedListingsViewProps, SellerAnalyticsAlertsViewProps } from "./features/seller/components/index";
235
+ export { SellerPayoutSettingsView, SellerShippingView, SellerReviewsView, SellerPayoutRequestView, SellerAnalyticsStats, SellerTopProducts, SellerAnalyticsView, SellerPayoutsView, SellerCouponEditorView, SellerBidsView, SellerAddressesView, SellerPreOrdersView, SellerPrizeDrawsView, PrintCenterView, SellerOffersView, SellerGroupedListingsView, StoreGroupedListingsView, SellerAnalyticsAlertsView, StoreAnalyticsAlertsView, BarcodeField, FulfillmentView } from "./features/seller/components/index";
236
+ export type { SellerPayoutSettingsViewProps, SellerShippingViewProps, SellerReviewsViewProps, SellerPayoutRequestViewProps, SellerAnalyticsViewProps, SellerPayoutsViewProps, SellerCouponEditorViewProps, CouponEditorDraft, SellerBidsViewProps, SellerAddressesViewProps, SellerPreOrdersViewProps, SellerPrizeDrawsViewProps, SellerOffersViewProps, SellerGroupedListingsViewProps, SellerAnalyticsAlertsViewProps, BarcodeFieldProps, FulfillmentViewProps } from "./features/seller/components/index";
237
237
  export type { SellerAnalyticsSummary, SellerAnalyticsTopProduct } from "./features/seller/types/index";
238
238
  export { UserAccountHubView, UserOrdersView, OrderDetailView, UserNotificationsView, UserReturnsView, UserSupportView, useNotifications } from "./features/account/index";
239
239
  export type { UserAccountHubViewProps, UserAccountHubViewLabels, UserOrdersViewProps, UserOrdersViewLabels, OrderDetailViewProps, OrderDetailViewLabels, UserNotificationsViewProps, UserNotificationsViewLabels, UserReturnsViewProps, UserReturnsViewLabels, UserSupportViewProps } from "./features/account/index";
package/dist/client.js CHANGED
@@ -182,7 +182,7 @@ export { Search } from "./features/search/components";
182
182
  export { ToastProvider, SkipToMain, NavigationLoader } from "./ui/index";
183
183
  export { ZodSetup } from "./validation/ZodSetup";
184
184
  export { AdminSidebar } from "./features/admin/components/AdminSidebar";
185
- export { AdminDashboardView, AdminAnalyticsView, AdminPrizeDrawsView, AdminCarouselView, AdminSublistingCategoriesView, DataTable, DataListingView, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
185
+ export { AdminDashboardView, AdminAnalyticsView, AdminPrizeDrawsView, AdminCarouselView, AdminSublistingCategoriesView, AdminFulfillmentView, DataTable, DataListingView, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
186
186
  export { ADMIN_ENDPOINTS } from "./constants/index";
187
187
  export { apiClient, ApiClientError } from "./http/index";
188
188
  export { UserSidebar } from "./features/account/components/UserSidebar";
@@ -246,7 +246,7 @@ export { FeatureBadge, FeatureBadgeList } from "./features/products/components/F
246
246
  export { SellerOffersPanel } from "./features/seller/components/SellerOffersPanel";
247
247
  export { UserOffersPanel } from "./features/account/components/UserOffersPanel";
248
248
  export { SellerDashboardView as StoreDashboardView, SellerDashboardView, useSellerDashboard as useStoreDashboard, useSellerDashboard } from "./features/seller/index";
249
- export { SellerPayoutSettingsView, SellerShippingView, SellerReviewsView, SellerPayoutRequestView, SellerAnalyticsStats, SellerTopProducts, SellerAnalyticsView, SellerPayoutsView, SellerCouponEditorView, SellerBidsView, SellerAddressesView, SellerPreOrdersView, SellerPrizeDrawsView, PrintCenterView, SellerOffersView, SellerGroupedListingsView, StoreGroupedListingsView, SellerAnalyticsAlertsView, StoreAnalyticsAlertsView } from "./features/seller/components/index";
249
+ export { SellerPayoutSettingsView, SellerShippingView, SellerReviewsView, SellerPayoutRequestView, SellerAnalyticsStats, SellerTopProducts, SellerAnalyticsView, SellerPayoutsView, SellerCouponEditorView, SellerBidsView, SellerAddressesView, SellerPreOrdersView, SellerPrizeDrawsView, PrintCenterView, SellerOffersView, SellerGroupedListingsView, StoreGroupedListingsView, SellerAnalyticsAlertsView, StoreAnalyticsAlertsView, BarcodeField, FulfillmentView } from "./features/seller/components/index";
250
250
  export { UserAccountHubView, UserOrdersView, OrderDetailView, UserNotificationsView, UserReturnsView, UserSupportView, useNotifications } from "./features/account/index";
251
251
  export { useOrders, useOrder, OrdersList } from "./features/orders/index";
252
252
  export { useCouponValidate } from "./features/promotions/hooks/useCouponValidate";
@@ -139,6 +139,7 @@ export declare const ADMIN_ENDPOINTS: {
139
139
  readonly ADDRESS_BY_ID: (id: string) => string;
140
140
  readonly GROUPED_LISTINGS: "/api/admin/grouped-listings";
141
141
  readonly GROUPED_LISTING_BY_ID: (id: string) => string;
142
+ readonly ADMIN_FULFILLMENT: (storeId: string) => string;
142
143
  };
143
144
  export declare const CHAT_ENDPOINTS: {
144
145
  readonly LIST: "/api/chat";
@@ -282,6 +283,9 @@ export declare const SELLER_ENDPOINTS: {
282
283
  readonly SHIPPING_CONFIG_BY_ID: (id: string) => string;
283
284
  readonly GOOGLE_REVIEWS: "/api/store/google-reviews";
284
285
  readonly GOOGLE_REVIEWS_SYNC: "/api/store/google-reviews/sync";
286
+ readonly PRODUCTS_SCAN: (barcode: string) => string;
287
+ readonly ORDERS_FULFILLMENT: "/api/store/fulfillment";
288
+ readonly ORDERS_ASSIGN: (orderId: string) => string;
285
289
  };
286
290
  export declare const BLOG_ENDPOINTS: {
287
291
  readonly LIST: "/api/blog";
@@ -462,6 +466,7 @@ export declare const API_ENDPOINTS: {
462
466
  readonly ADDRESS_BY_ID: (id: string) => string;
463
467
  readonly GROUPED_LISTINGS: "/api/admin/grouped-listings";
464
468
  readonly GROUPED_LISTING_BY_ID: (id: string) => string;
469
+ readonly ADMIN_FULFILLMENT: (storeId: string) => string;
465
470
  };
466
471
  readonly CHAT: {
467
472
  readonly LIST: "/api/chat";
@@ -608,6 +613,9 @@ export declare const API_ENDPOINTS: {
608
613
  readonly SHIPPING_CONFIG_BY_ID: (id: string) => string;
609
614
  readonly GOOGLE_REVIEWS: "/api/store/google-reviews";
610
615
  readonly GOOGLE_REVIEWS_SYNC: "/api/store/google-reviews/sync";
616
+ readonly PRODUCTS_SCAN: (barcode: string) => string;
617
+ readonly ORDERS_FULFILLMENT: "/api/store/fulfillment";
618
+ readonly ORDERS_ASSIGN: (orderId: string) => string;
611
619
  };
612
620
  readonly BLOG: {
613
621
  readonly LIST: "/api/blog";
@@ -787,6 +795,7 @@ export declare const API_ROUTES: {
787
795
  readonly ADDRESS_BY_ID: (id: string) => string;
788
796
  readonly GROUPED_LISTINGS: "/api/admin/grouped-listings";
789
797
  readonly GROUPED_LISTING_BY_ID: (id: string) => string;
798
+ readonly ADMIN_FULFILLMENT: (storeId: string) => string;
790
799
  };
791
800
  readonly CHAT: {
792
801
  readonly LIST: "/api/chat";
@@ -933,6 +942,9 @@ export declare const API_ROUTES: {
933
942
  readonly SHIPPING_CONFIG_BY_ID: (id: string) => string;
934
943
  readonly GOOGLE_REVIEWS: "/api/store/google-reviews";
935
944
  readonly GOOGLE_REVIEWS_SYNC: "/api/store/google-reviews/sync";
945
+ readonly PRODUCTS_SCAN: (barcode: string) => string;
946
+ readonly ORDERS_FULFILLMENT: "/api/store/fulfillment";
947
+ readonly ORDERS_ASSIGN: (orderId: string) => string;
936
948
  };
937
949
  readonly BLOG: {
938
950
  readonly LIST: "/api/blog";
@@ -158,6 +158,7 @@ export const ADMIN_ENDPOINTS = {
158
158
  ADDRESS_BY_ID: (id) => `/api/admin/addresses/${id}`,
159
159
  GROUPED_LISTINGS: "/api/admin/grouped-listings",
160
160
  GROUPED_LISTING_BY_ID: (id) => `/api/admin/grouped-listings/${id}`,
161
+ ADMIN_FULFILLMENT: (storeId) => `/api/store/fulfillment?storeId=${encodeURIComponent(storeId)}`,
161
162
  };
162
163
  // ---------------------------------------------------------------------------
163
164
  // Chat
@@ -371,6 +372,9 @@ export const SELLER_ENDPOINTS = {
371
372
  SHIPPING_CONFIG_BY_ID: (id) => `/api/store/shipping-configs/${id}`,
372
373
  GOOGLE_REVIEWS: "/api/store/google-reviews",
373
374
  GOOGLE_REVIEWS_SYNC: "/api/store/google-reviews/sync",
375
+ PRODUCTS_SCAN: (barcode) => `/api/store/products/scan?barcode=${encodeURIComponent(barcode)}`,
376
+ ORDERS_FULFILLMENT: "/api/store/fulfillment",
377
+ ORDERS_ASSIGN: (orderId) => `/api/store/orders/${orderId}/assign`,
374
378
  };
375
379
  // ---------------------------------------------------------------------------
376
380
  // Blog
@@ -7,9 +7,9 @@
7
7
  * are encrypted at rest via the existing `encryptPiiFields` pipeline; the
8
8
  * repository overrides `createWithId` and `create` to inject encryption.
9
9
  */
10
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
10
11
  export type AddressOwnerType = "user" | "store";
11
- export interface AddressDocument {
12
- id: string;
12
+ export interface AddressDocument extends BaseDocument {
13
13
  ownerType: AddressOwnerType;
14
14
  ownerId: string;
15
15
  label: string;
@@ -23,8 +23,6 @@ export interface AddressDocument {
23
23
  postalCode: string;
24
24
  country: string;
25
25
  isDefault: boolean;
26
- createdAt: Date;
27
- updatedAt: Date;
28
26
  }
29
27
  export declare const ADDRESSES_COLLECTION: "addresses";
30
28
  export declare const ADDRESS_INDEXED_FIELDS: readonly ["ownerType", "ownerId", "isDefault", "createdAt"];
@@ -0,0 +1,6 @@
1
+ export interface AdminFulfillmentViewProps {
2
+ /** Pre-selected store ID — skips the store picker when provided. */
3
+ initialStoreId?: string;
4
+ initialStoreName?: string;
5
+ }
6
+ export declare function AdminFulfillmentView({ initialStoreId, initialStoreName, }: AdminFulfillmentViewProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,107 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { Heading, Text } from "../../../ui/components/Typography";
5
+ import { Stack, Row } from "../../../ui/components/Layout";
6
+ import { Button } from "../../../ui/components/Button";
7
+ import { Badge } from "../../../ui/components/Badge";
8
+ import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
9
+ import { apiClient } from "../../../http";
10
+ import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
11
+ import { normalizeError } from "../../../errors/normalize";
12
+ import { useToast } from "../../../ui";
13
+ async function loadStoreOptions(query, page) {
14
+ const params = new URLSearchParams({ page: String(page), pageSize: "25" });
15
+ if (query)
16
+ params.set("q", query);
17
+ const res = await apiClient.get(`${ADMIN_ENDPOINTS.STORES}?${params.toString()}`);
18
+ const items = (res.items ?? []).map((s) => ({ value: s.id, label: s.storeName }));
19
+ return { items, hasMore: res.hasMore ?? false };
20
+ }
21
+ function statusBadgeVariant(status) {
22
+ if (status === "confirmed")
23
+ return "warning";
24
+ if (status === "processing")
25
+ return "info";
26
+ if (status === "shipped")
27
+ return "success";
28
+ return "default";
29
+ }
30
+ export function AdminFulfillmentView({ initialStoreId, initialStoreName, }) {
31
+ const [storeId, setStoreId] = useState(initialStoreId ?? null);
32
+ const [orders, setOrders] = useState([]);
33
+ const [isLoading, setIsLoading] = useState(false);
34
+ const [actionLoadingId, setActionLoadingId] = useState(null);
35
+ const { showToast } = useToast();
36
+ const fetchOrders = useCallback(async (sid) => {
37
+ // toast-intentionally-silent: background data loader — stale list is kept on error
38
+ setIsLoading(true);
39
+ try {
40
+ const res = await apiClient.get(ADMIN_ENDPOINTS.ADMIN_FULFILLMENT(sid));
41
+ setOrders(res.orders ?? []);
42
+ }
43
+ catch {
44
+ // keep stale list on error
45
+ }
46
+ finally {
47
+ setIsLoading(false);
48
+ }
49
+ }, []);
50
+ useEffect(() => {
51
+ if (storeId)
52
+ void fetchOrders(storeId);
53
+ }, [storeId, fetchOrders]);
54
+ const handleMarkPicked = useCallback(async (orderId) => {
55
+ if (!storeId)
56
+ return;
57
+ setActionLoadingId(orderId + ":picked");
58
+ try {
59
+ await apiClient.patch(`/api/store/orders/${orderId}`, { markPicked: true });
60
+ showToast("Order marked as picked.", "success");
61
+ await fetchOrders(storeId);
62
+ }
63
+ catch (err) {
64
+ showToast(normalizeError(err).message, "error");
65
+ }
66
+ finally {
67
+ setActionLoadingId(null);
68
+ }
69
+ }, [storeId, fetchOrders, showToast]);
70
+ const handleMarkPacked = useCallback(async (orderId) => {
71
+ if (!storeId)
72
+ return;
73
+ setActionLoadingId(orderId + ":packed");
74
+ try {
75
+ await apiClient.patch(`/api/store/orders/${orderId}`, { markPacked: true });
76
+ showToast("Order marked as packed.", "success");
77
+ await fetchOrders(storeId);
78
+ }
79
+ catch (err) {
80
+ showToast(normalizeError(err).message, "error");
81
+ }
82
+ finally {
83
+ setActionLoadingId(null);
84
+ }
85
+ }, [storeId, fetchOrders, showToast]);
86
+ const handleUnassign = useCallback(async (orderId) => {
87
+ if (!storeId)
88
+ return;
89
+ setActionLoadingId(orderId + ":unassign");
90
+ try {
91
+ await apiClient.patch(`/api/store/orders/${orderId}/assign`, { workerId: null });
92
+ showToast("Worker unassigned.", "success");
93
+ await fetchOrders(storeId);
94
+ }
95
+ catch (err) {
96
+ showToast(normalizeError(err).message, "error");
97
+ }
98
+ finally {
99
+ setActionLoadingId(null);
100
+ }
101
+ }, [storeId, fetchOrders, showToast]);
102
+ return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsxs(Row, { align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsx(Heading, { level: 3, children: "Fulfillment Queue" }), storeId && (_jsx(Button, { variant: "secondary", size: "sm", onClick: () => {
103
+ setStoreId(null);
104
+ setOrders([]);
105
+ }, children: "Change Store" }))] }), !storeId && (_jsxs(Stack, { gap: "sm", children: [_jsx(Text, { size: "sm", color: "muted", children: "Select a store to view its fulfilment queue." }), _jsx(PaginatedSelect, { value: null, onChange: (v) => { if (v)
106
+ setStoreId(v); }, loadOptions: loadStoreOptions, placeholder: "Search stores\u2026", searchPlaceholder: "Type store name\u2026", noResultsText: "No stores found", ariaLabel: "Store" })] })), storeId && (_jsxs(Stack, { gap: "sm", children: [isLoading && (_jsx(Text, { size: "sm", color: "muted", children: "Loading orders\u2026" })), !isLoading && orders.length === 0 && (_jsx(Text, { color: "muted", children: "No orders in the fulfillment queue \u2014 great work!" })), orders.map((order) => (_jsxs(Stack, { surface: "card", padding: "sm", rounded: "md", gap: "xs", children: [_jsxs(Row, { align: "center", gap: "xs", wrap: true, children: [_jsxs(Text, { size: "sm", weight: "medium", children: ["#", order.id] }), _jsx(Badge, { variant: statusBadgeVariant(order.status), children: order.status }), order.pickedAt && _jsx(Badge, { variant: "success", children: "Picked" }), order.packedAt && _jsx(Badge, { variant: "success", children: "Packed" })] }), _jsxs(Text, { size: "xs", color: "muted", children: [order.userName, order.items && order.items.length > 0 && (_jsxs(_Fragment, { children: [" \u00B7 ", order.items.map((i) => i.productTitle).join(", ")] }))] }), order.assignedWorkerId && (_jsxs(Text, { size: "xs", color: "muted", children: ["Assigned to: ", order.assignedWorkerId] })), _jsxs(Row, { gap: "xs", children: [!order.pickedAt && (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => handleMarkPicked(order.id), isLoading: actionLoadingId === order.id + ":picked", children: "Mark Picked" })), order.pickedAt && !order.packedAt && (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => handleMarkPacked(order.id), isLoading: actionLoadingId === order.id + ":packed", children: "Mark Packed" })), order.assignedWorkerId && (_jsx(Button, { size: "sm", variant: "secondary", onClick: () => handleUnassign(order.id), isLoading: actionLoadingId === order.id + ":unassign", children: "Unassign" }))] })] }, order.id)))] })), initialStoreName && !storeId && (_jsxs(Text, { size: "xs", color: "muted", children: ["Previously viewing: ", initialStoreName] }))] }));
107
+ }
@@ -13,8 +13,10 @@ import { GroupSettingsPanel } from "../../products/components/GroupSettingsPanel
13
13
  import { GroupInlineSelect } from "../../seller/components/GroupInlineSelect";
14
14
  import { CategoryQuickCreateForm } from "./CategoryQuickCreateForm";
15
15
  import { BrandQuickCreateForm } from "./BrandQuickCreateForm";
16
+ import { BarcodeField } from "../../seller/components/BarcodeField";
16
17
  const __P = {
17
18
  p4: "p-4",
19
+ sectionLabel: "tracking-widest mb-4",
18
20
  };
19
21
  const __O = {
20
22
  yAuto: "overflow-y-auto",
@@ -25,6 +27,14 @@ function modeFromProduct(product) {
25
27
  return "auction";
26
28
  if (lt === "pre-order")
27
29
  return "preorder";
30
+ if (lt === "prize-draw")
31
+ return "prize-draw";
32
+ if (lt === "classified")
33
+ return "classified";
34
+ if (lt === "digital-code")
35
+ return "digital-code";
36
+ if (lt === "live")
37
+ return "live";
28
38
  return "standard";
29
39
  }
30
40
  /**
@@ -32,14 +42,16 @@ function modeFromProduct(product) {
32
42
  * `listingType` discriminator. Nothing else needs to be written for the mode flip.
33
43
  */
34
44
  function applyMode(product, mode) {
35
- return {
36
- ...product,
37
- listingType: mode === "auction"
38
- ? "auction"
39
- : mode === "preorder"
40
- ? "pre-order"
41
- : "standard",
45
+ const map = {
46
+ standard: "standard",
47
+ auction: "auction",
48
+ preorder: "pre-order",
49
+ "prize-draw": "prize-draw",
50
+ classified: "classified",
51
+ "digital-code": "digital-code",
52
+ live: "live",
42
53
  };
54
+ return { ...product, listingType: map[mode] };
43
55
  }
44
56
  async function loadStoreOptions(query, page) {
45
57
  const params = new URLSearchParams({ page: String(page), pageSize: "25" });
@@ -154,9 +166,9 @@ export function AdminProductEditorView({ productId, onSaved, onDeleted, embedded
154
166
  const formContent = (_jsxs(Form, { id: "product-editor-form", onSubmit: (e) => {
155
167
  e.preventDefault();
156
168
  saveMutation.mutate();
157
- }, spacing: "lg", children: [_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: "tracking-widest mb-4", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Listing Type" }), _jsxs(Tabs, { value: mode, onChange: handleModeChange, children: [_jsxs(TabsList, { children: [(!enabledListingTypes || enabledListingTypes.includes("standard")) && (_jsx(TabsTrigger, { value: "standard", children: "Standard" })), (!enabledListingTypes || enabledListingTypes.includes("auction")) && (_jsx(TabsTrigger, { value: "auction", children: "Auction" })), (!enabledListingTypes || enabledListingTypes.includes("pre-order")) && (_jsx(TabsTrigger, { value: "preorder", children: "Pre-order" }))] }), _jsx(TabsContent, { value: "standard" }), _jsx(TabsContent, { value: "auction" }), _jsx(TabsContent, { value: "preorder" })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: "tracking-widest mb-4", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Classification" }), _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: "Store" }), _jsx(PaginatedSelect, { value: product.storeId ?? null, onChange: handleStoreSelect, loadOptions: loadStoreOptions, placeholder: "Search stores\u2026", searchPlaceholder: "Type store name\u2026", noResultsText: "No stores found", ariaLabel: "Store" })] }), _jsx(ProductForm, { product: product, onChange: setProduct, renderGroupSettings: isEdit && productId
169
+ }, spacing: "lg", children: [_jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Listing Type" }), _jsxs(Tabs, { value: mode, onChange: handleModeChange, children: [_jsxs(TabsList, { children: [(!enabledListingTypes || enabledListingTypes.includes("standard")) && (_jsx(TabsTrigger, { value: "standard", children: "Standard" })), (!enabledListingTypes || enabledListingTypes.includes("auction")) && (_jsx(TabsTrigger, { value: "auction", children: "Auction" })), (!enabledListingTypes || enabledListingTypes.includes("pre-order")) && (_jsx(TabsTrigger, { value: "preorder", children: "Pre-order" })), (!enabledListingTypes || enabledListingTypes.includes("prize-draw")) && (_jsx(TabsTrigger, { value: "prize-draw", children: "Prize Draw" })), (!enabledListingTypes || enabledListingTypes.includes("classified")) && (_jsx(TabsTrigger, { value: "classified", children: "Classified" })), (!enabledListingTypes || enabledListingTypes.includes("digital-code")) && (_jsx(TabsTrigger, { value: "digital-code", children: "Digital Code" })), (!enabledListingTypes || enabledListingTypes.includes("live")) && (_jsx(TabsTrigger, { value: "live", children: "Live Item" }))] }), _jsx(TabsContent, { value: "standard" }), _jsx(TabsContent, { value: "auction" }), _jsx(TabsContent, { value: "preorder" }), _jsx(TabsContent, { value: "prize-draw" }), _jsx(TabsContent, { value: "classified" }), _jsx(TabsContent, { value: "digital-code" }), _jsx(TabsContent, { value: "live" })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Classification" }), _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: "Store" }), _jsx(PaginatedSelect, { value: product.storeId ?? null, onChange: handleStoreSelect, loadOptions: loadStoreOptions, placeholder: "Search stores\u2026", searchPlaceholder: "Type store name\u2026", noResultsText: "No stores found", ariaLabel: "Store" })] }), _jsx(ProductForm, { product: product, onChange: setProduct, renderGroupSettings: isEdit && productId
158
170
  ? (p) => (_jsx(GroupSettingsPanel, { productId: productId, productSlug: p.slug ?? productId, groupId: p.groupId, isGroupParent: p.isGroupParent, groupParentSlug: p.groupParentSlug, groupChildSlugs: p.groupChildSlugs, groupTitle: p.groupTitle, isAuction: modeFromProduct(p) === "auction", storeProductsEndpoint: "/api/admin/products", onGroupChanged: () => productQuery.refetch() }))
159
- : undefined, renderGroupJoinField: ({ label, value, onChange, disabled }) => (_jsx(GroupInlineSelect, { scope: "admin", value: value ?? "", onChange: (id) => onChange(id || undefined), disabled: disabled, label: label, placeholder: "None (standalone product)", allowCreate: false })), renderCategorySelector: ({ label, value, onChange, disabled }) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: label }), _jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadCategoryOptions, placeholder: "Search categories\u2026", searchPlaceholder: "Type category name\u2026", noResultsText: "No categories found", ariaLabel: label, disabled: disabled, createLabel: "Category", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })), renderBrandSelector: (args) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: args.label }), _jsx(PaginatedSelect, { value: args.multi ? null : (args.value || null), onChange: (v) => args.onValueChange(v ?? ""), loadOptions: loadBrandOptions, placeholder: "Search brands\u2026", searchPlaceholder: "Type brand name\u2026", noResultsText: "No brands found", ariaLabel: args.label, disabled: args.disabled, createLabel: "Brand", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })) })] })] }), _jsxs(Row, { gap: "3", className: "lg:hidden", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] })] }, "product-form"));
171
+ : undefined, renderGroupJoinField: ({ label, value, onChange, disabled }) => (_jsx(GroupInlineSelect, { scope: "admin", value: value ?? "", onChange: (id) => onChange(id || undefined), disabled: disabled, label: label, placeholder: "None (standalone product)", allowCreate: false })), renderCategorySelector: ({ label, value, onChange, disabled }) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: label }), _jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadCategoryOptions, placeholder: "Search categories\u2026", searchPlaceholder: "Type category name\u2026", noResultsText: "No categories found", ariaLabel: label, disabled: disabled, createLabel: "Category", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })), renderBrandSelector: (args) => (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", color: "primary", children: args.label }), _jsx(PaginatedSelect, { value: args.multi ? null : (args.value || null), onChange: (v) => args.onValueChange(v ?? ""), loadOptions: loadBrandOptions, placeholder: "Search brands\u2026", searchPlaceholder: "Type brand name\u2026", noResultsText: "No brands found", ariaLabel: args.label, disabled: args.disabled, createLabel: "Brand", renderCreateForm: ({ onCreated, onCancel }) => (_jsx(BrandQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel })) })] })) })] })] }), _jsxs(Card, { variant: "outlined", padding: "lg", children: [_jsx(Text, { className: __P.sectionLabel, color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Inventory" }), _jsx(BarcodeField, { value: product.barcodeId ?? "", onChange: (v) => setProduct((prev) => ({ ...prev, barcodeId: v || undefined })), onScan: (v) => setProduct((prev) => ({ ...prev, barcodeId: v })), helperText: "Leave blank to auto-generate. Scan a pre-printed sticker to link it." })] }), _jsxs(Row, { gap: "3", className: "lg:hidden", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !product.title || isSubmitting, children: isEdit ? "Save changes" : "Create product" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteOpen(true), children: "Delete product" }))] })] }, "product-form"));
160
172
  if (embedded) {
161
173
  return _jsx(Div, { className: `${__O.yAuto} ${__P.p4}`, children: formContent });
162
174
  }
@@ -128,6 +128,7 @@ export function AdminProductsView({ children, ...props }) {
128
128
  isPromoted: Boolean(item.isPromoted),
129
129
  isOnSale: Boolean(item.isOnSale),
130
130
  isSold: Boolean(item.isSold),
131
+ barcodeId: typeof item.barcodeId === "string" ? item.barcodeId : undefined,
131
132
  };
132
133
  return overrides[id] ? { ...base, ...overrides[id] } : base;
133
134
  }),
@@ -217,11 +218,13 @@ export function AdminProductsView({ children, ...props }) {
217
218
  },
218
219
  { name: "featured", label: "Featured", type: "toggle" },
219
220
  { name: "isPromoted", label: "Promoted", type: "toggle" },
221
+ { name: "barcodeId", label: "Barcode ID", type: "text" },
220
222
  ],
221
223
  defaultValues: {
222
224
  status: row.status,
223
225
  featured: row.featured,
224
226
  isPromoted: row.isPromoted,
227
+ barcodeId: String(row.barcodeId ?? ""),
225
228
  },
226
229
  onSubmit: (vals) => handleQuickEdit(row.id, vals),
227
230
  submitLabel: "Save",
@@ -38,6 +38,7 @@ export interface AdminListingScaffoldRow {
38
38
  isPromoted?: boolean;
39
39
  isOnSale?: boolean;
40
40
  isSold?: boolean;
41
+ barcodeId?: string;
41
42
  }
42
43
  export interface ListingSortOption {
43
44
  value: string;
@@ -153,3 +153,5 @@ export { AdminScammersView } from "./AdminScammersView";
153
153
  export type { AdminScammersViewProps } from "./AdminScammersView";
154
154
  export { AdminScammerEditorView } from "./AdminScammerEditorView";
155
155
  export type { AdminScammerEditorViewProps } from "./AdminScammerEditorView";
156
+ export { AdminFulfillmentView } from "./AdminFulfillmentView";
157
+ export type { AdminFulfillmentViewProps } from "./AdminFulfillmentView";
@@ -80,3 +80,4 @@ export { AdminSupportTicketsView } from "./AdminSupportTicketsView";
80
80
  export { AdminSupportTicketDetailView } from "./AdminSupportTicketDetailView";
81
81
  export { AdminScammersView } from "./AdminScammersView";
82
82
  export { AdminScammerEditorView } from "./AdminScammerEditorView";
83
+ export { AdminFulfillmentView } from "./AdminFulfillmentView";