@mohasinac/appkit 2.7.49 → 2.7.50

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 (110) hide show
  1. package/dist/_internal/client/features/layout/SidebarCollapseToggle.d.ts +19 -0
  2. package/dist/_internal/client/features/layout/SidebarCollapseToggle.js +15 -0
  3. package/dist/_internal/client/features/layout/index.d.ts +2 -0
  4. package/dist/_internal/client/features/layout/index.js +1 -0
  5. package/dist/_internal/server/features/checkout/actions.js +25 -2
  6. package/dist/_internal/server/features/promotions/actions.js +3 -1
  7. package/dist/_internal/shared/actions/action-registry.js +149 -0
  8. package/dist/client.d.ts +16 -0
  9. package/dist/client.js +11 -0
  10. package/dist/features/account/components/UserSidebar.js +2 -1
  11. package/dist/features/admin/components/AdminBlogEditorView.js +6 -2
  12. package/dist/features/admin/components/AdminSidebar.js +2 -1
  13. package/dist/features/auth/repository/session.repository.js +16 -1
  14. package/dist/features/cart/hooks/useAddToCart.d.ts +2 -0
  15. package/dist/features/cart/hooks/useAddToCart.js +2 -0
  16. package/dist/features/cart/hooks/useGuestCart.d.ts +2 -0
  17. package/dist/features/cart/utils/guest-cart.d.ts +7 -0
  18. package/dist/features/cart/utils/pending-ops.d.ts +6 -0
  19. package/dist/features/categories/components/CategoryBundlesListing.js +9 -1
  20. package/dist/features/categories/components/CategoryProductsListing.js +6 -10
  21. package/dist/features/categories/schemas/firestore.d.ts +9 -0
  22. package/dist/features/events/components/EventRaffleWinnerView.d.ts +9 -1
  23. package/dist/features/events/components/EventRaffleWinnerView.js +3 -3
  24. package/dist/features/events/components/SpinWheelView.js +3 -3
  25. package/dist/features/layout/BottomNavLayout.d.ts +5 -0
  26. package/dist/features/layout/BottomNavLayout.js +21 -0
  27. package/dist/features/layout/TitleBar.js +7 -1
  28. package/dist/features/layout/TitleBarLayout.d.ts +8 -2
  29. package/dist/features/layout/TitleBarLayout.js +11 -7
  30. package/dist/features/orders/schemas/index.d.ts +2 -2
  31. package/dist/features/pre-orders/components/PreOrdersIndexListing.js +9 -5
  32. package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
  33. package/dist/features/products/components/PrizeDrawEntryActions.d.ts +3 -1
  34. package/dist/features/products/components/PrizeDrawEntryActions.js +8 -12
  35. package/dist/features/products/components/ProductDetailActions.d.ts +5 -1
  36. package/dist/features/products/components/ProductDetailActions.js +3 -1
  37. package/dist/features/products/components/ProductDetailPageView.d.ts +2 -0
  38. package/dist/features/products/components/ProductDetailPageView.js +4 -0
  39. package/dist/features/products/components/ProductGrid.js +3 -3
  40. package/dist/features/products/components/ProductsIndexListing.js +15 -8
  41. package/dist/features/promotions/components/CouponCard.d.ts +11 -1
  42. package/dist/features/promotions/components/CouponCard.js +36 -2
  43. package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +27 -0
  44. package/dist/features/promotions/repository/claimed-coupons.repository.js +115 -0
  45. package/dist/features/promotions/schemas/firestore.d.ts +34 -0
  46. package/dist/features/promotions/schemas/firestore.js +13 -0
  47. package/dist/features/seller/components/SellerAddressesView.js +3 -2
  48. package/dist/features/seller/components/SellerBidsView.js +33 -3
  49. package/dist/features/seller/components/SellerOrdersView.js +35 -0
  50. package/dist/features/seller/components/SellerProductShell.d.ts +2 -0
  51. package/dist/features/seller/components/SellerProductShell.js +26 -4
  52. package/dist/features/seller/components/SellerProductsCards.d.ts +19 -0
  53. package/dist/features/seller/components/SellerProductsCards.js +19 -0
  54. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +14 -0
  55. package/dist/features/seller/components/SellerProductsFilterDrawer.js +20 -0
  56. package/dist/features/seller/components/SellerProductsView.d.ts +3 -1
  57. package/dist/features/seller/components/SellerProductsView.js +68 -19
  58. package/dist/features/seller/components/SellerReviewsView.js +67 -4
  59. package/dist/features/seller/components/SellerSidebar.js +2 -1
  60. package/dist/features/seller/components/seller-products-styles.d.ts +7 -0
  61. package/dist/features/seller/components/seller-products-styles.js +14 -0
  62. package/dist/features/shell/FormShell.d.ts +7 -1
  63. package/dist/features/shell/FormShell.js +5 -2
  64. package/dist/features/store-extensions/index.d.ts +4 -0
  65. package/dist/features/store-extensions/index.js +4 -0
  66. package/dist/features/store-extensions/repository/rbac.repositories.d.ts +23 -0
  67. package/dist/features/store-extensions/repository/rbac.repositories.js +32 -0
  68. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +91 -0
  69. package/dist/features/store-extensions/repository/store-extensions.repositories.js +127 -0
  70. package/dist/features/store-extensions/schemas/firestore.d.ts +244 -0
  71. package/dist/features/store-extensions/schemas/firestore.js +158 -0
  72. package/dist/features/store-extensions/schemas/rbac.d.ts +65 -0
  73. package/dist/features/store-extensions/schemas/rbac.js +43 -0
  74. package/dist/features/stores/components/InteractiveStoreCard.js +7 -3
  75. package/dist/features/stores/components/StoreProductsListing.js +6 -10
  76. package/dist/features/stores/schemas/firestore.d.ts +2 -0
  77. package/dist/index.d.ts +6 -0
  78. package/dist/index.js +8 -0
  79. package/dist/next/routing/route-map.d.ts +79 -0
  80. package/dist/next/routing/route-map.js +34 -0
  81. package/dist/react/hooks/useFormStatePreservation.d.ts +17 -0
  82. package/dist/react/hooks/useFormStatePreservation.js +62 -0
  83. package/dist/react/hooks/useInlineRowEdit.d.ts +24 -0
  84. package/dist/react/hooks/useInlineRowEdit.js +68 -0
  85. package/dist/react/index.d.ts +4 -0
  86. package/dist/react/index.js +4 -0
  87. package/dist/repositories/index.d.ts +4 -0
  88. package/dist/repositories/index.js +5 -0
  89. package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
  90. package/dist/seed/claimed-coupons-seed-data.d.ts +13 -0
  91. package/dist/seed/claimed-coupons-seed-data.js +79 -0
  92. package/dist/seed/index.d.ts +2 -0
  93. package/dist/seed/index.js +3 -0
  94. package/dist/seed/manifest.js +17 -0
  95. package/dist/seed/store-extensions-seed-data.d.ts +19 -0
  96. package/dist/seed/store-extensions-seed-data.js +421 -0
  97. package/dist/tailwind-utilities.css +1 -1
  98. package/dist/ui/components/Button.style.css +20 -12
  99. package/dist/ui/components/ClaimCouponButton.d.ts +28 -0
  100. package/dist/ui/components/ClaimCouponButton.js +89 -0
  101. package/dist/ui/components/QuickCreateModal.d.ts +15 -0
  102. package/dist/ui/components/QuickCreateModal.js +48 -0
  103. package/dist/ui/components/QuickCreateModal.style.css +84 -0
  104. package/dist/ui/components/StickyBottomBar.d.ts +22 -0
  105. package/dist/ui/components/StickyBottomBar.js +20 -0
  106. package/dist/ui/components/VacationBanner.d.ts +11 -0
  107. package/dist/ui/components/VacationBanner.js +16 -0
  108. package/dist/ui/index.d.ts +8 -0
  109. package/dist/ui/index.js +4 -0
  110. package/package.json +1 -1
@@ -77,19 +77,15 @@ export function StoreProductsListing({ storeId, initialData }) {
77
77
  });
78
78
  }, [wishlistedIds, localWishlist, showToast, requireAuth]);
79
79
  const handleAddToCart = useCallback((product) => {
80
- localCart.add(product.id, 1, {
80
+ const snapshot = {
81
81
  productTitle: product.title,
82
82
  productImage: product.mainImage,
83
83
  price: product.price,
84
- });
85
- pushCartOp({
86
- op: "add",
87
- productId: product.id,
88
- quantity: 1,
89
- productTitle: product.title,
90
- productImage: product.mainImage,
91
- price: product.price,
92
- });
84
+ storeId: product.storeId,
85
+ storeName: product.storeName,
86
+ };
87
+ localCart.add(product.id, 1, snapshot);
88
+ pushCartOp({ op: "add", productId: product.id, quantity: 1, ...snapshot });
93
89
  showToast("Added to cart", "success");
94
90
  }, [localCart, showToast]);
95
91
  return (_jsxs("div", { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search store products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || "-createdAt", sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => {
@@ -77,6 +77,8 @@ export interface StoreDocument {
77
77
  totalReviews: number;
78
78
  averageRating?: number;
79
79
  };
80
+ /** When the seller plans to return. Banner shows the date if set. */
81
+ vacationReturnDate?: Date | string;
80
82
  /**
81
83
  * Explicit capability set for this store. Defaults: ["suggest_brands", "create_coupons"].
82
84
  * Checked server-side on every relevant API route.
package/dist/index.d.ts CHANGED
@@ -486,6 +486,7 @@ export type { ResolvedUser } from "./security/index";
486
486
  export type { RoleDefinition } from "./security/index";
487
487
  export type { UserRole } from "./security/index";
488
488
  export { AddressesRepository } from "./repositories/index";
489
+ export * from "./features/store-extensions/index";
489
490
  export { BaseRepository } from "./repositories/index";
490
491
  export { BlogRepository } from "./repositories/index";
491
492
  export { CartRepository } from "./repositories/index";
@@ -519,6 +520,9 @@ export { cartRepository } from "./repositories/index";
519
520
  export { categoriesRepository } from "./repositories/index";
520
521
  export { chatRepository } from "./repositories/index";
521
522
  export { couponsRepository } from "./repositories/index";
523
+ export { claimedCouponsRepository, ClaimedCouponsRepository } from "./repositories/index";
524
+ export type { ClaimedCouponCreateInput } from "./repositories/index";
525
+ export type { ClaimedCouponDocument, ClaimedCouponStatus, ClaimedCouponSource, ClaimedCouponSnapshot, } from "./features/promotions/schemas";
522
526
  export { emailVerificationTokenRepository } from "./repositories/index";
523
527
  export { eventEntryRepository } from "./repositories/index";
524
528
  export { eventRepository } from "./repositories/index";
@@ -541,6 +545,7 @@ export type { SupportTicketDocument, SupportTicketCreateInput, SupportTicketUpda
541
545
  export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_TICKET_STATUSES, SUPPORT_TICKET_FIELDS, TicketCategoryValues, TicketStatusValues, TicketPriorityValues, } from "./features/support/schemas/firestore";
542
546
  export { supportTicketsSeedData } from "./seed/index";
543
547
  export { offersSeedData } from "./seed/index";
548
+ export { payoutMethodsSeedData, shippingConfigsSeedData, analyticsCardsSeedData, analyticsAlertsSeedData, storeCategoriesSeedData, listingTemplatesSeedData, moderationQueueSeedData, reportsSeedData, itemRequestsSeedData, storeWhatsAppConfigSeedData, storeGoogleConfigSeedData, } from "./seed/index";
544
549
  export { productFeaturesRepository } from "./repositories/index";
545
550
  export type { ProductFeatureListFilter } from "./repositories/index";
546
551
  export { loadProductFeaturesForStore } from "./repositories/index";
@@ -576,6 +581,7 @@ export { categoriesSeedData } from "./seed/index";
576
581
  export { couponsSeedData } from "./seed/index";
577
582
  export type { CouponUsageSeedRecord } from "./seed/index";
578
583
  export { couponUsageSeedData } from "./seed/index";
584
+ export { claimedCouponsSeedData } from "./seed/index";
579
585
  export { eventEntriesSeedData } from "./seed/index";
580
586
  export { eventsSeedData } from "./seed/index";
581
587
  export { faqSeedData } from "./seed/index";
package/dist/index.js CHANGED
@@ -932,6 +932,8 @@ export { resolvePermissions } from "./security/index";
932
932
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
933
933
  // AddressesRepository - unified top-level addresses collection (SB-UNI-A 2026-05-13).
934
934
  export { AddressesRepository } from "./repositories/index";
935
+ // S-STORE foundation — 14 schemas + 14 repositories + RBAC
936
+ export * from "./features/store-extensions/index";
935
937
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
936
938
  // BaseRepository - Shared export for base repository.
937
939
  export { BaseRepository } from "./repositories/index";
@@ -1035,6 +1037,8 @@ export { chatRepository } from "./repositories/index";
1035
1037
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
1036
1038
  // couponsRepository - Shared export for coupons repository.
1037
1039
  export { couponsRepository } from "./repositories/index";
1040
+ // [DB] claimedCouponsRepository — user-wallet claims (plan §10).
1041
+ export { claimedCouponsRepository, ClaimedCouponsRepository } from "./repositories/index";
1038
1042
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
1039
1043
  // emailVerificationTokenRepository - Shared export for email verification token repository.
1040
1044
  export { emailVerificationTokenRepository } from "./repositories/index";
@@ -1094,6 +1098,8 @@ export { ELIGIBLE_ORDER_STATUSES_FOR_TICKET, SUPPORT_TICKET_COLLECTION, ACTIVE_T
1094
1098
  // Support tickets â€" seed data
1095
1099
  export { supportTicketsSeedData } from "./seed/index";
1096
1100
  export { offersSeedData } from "./seed/index";
1101
+ // S-STORE foundation seed data
1102
+ export { payoutMethodsSeedData, shippingConfigsSeedData, analyticsCardsSeedData, analyticsAlertsSeedData, storeCategoriesSeedData, listingTemplatesSeedData, moderationQueueSeedData, reportsSeedData, itemRequestsSeedData, storeWhatsAppConfigSeedData, storeGoogleConfigSeedData, } from "./seed/index";
1097
1103
  // SB-UNI-B â€" sublistingCategoriesRepository + SublistingCategoryDocument deleted.
1098
1104
  // Use categoriesRepository.findBySlugAndType(slug, "sublisting") and CategoryDocument with categoryType:"sublisting".
1099
1105
  // [DB]-Database layer â€" uses firebase-admin; server-only.
@@ -1184,6 +1190,8 @@ export { categoriesSeedData } from "./seed/index";
1184
1190
  // couponsSeedData - Model for coupons seed data.
1185
1191
  export { couponsSeedData } from "./seed/index";
1186
1192
  export { couponUsageSeedData } from "./seed/index";
1193
+ // claimedCouponsSeedData - Plan §10 wallet seed (active/expired/used rows).
1194
+ export { claimedCouponsSeedData } from "./seed/index";
1187
1195
  // demoSeed has been moved to "@mohasinac/appkit/server" â€" it transitively
1188
1196
  // reaches firebase-admin via the seed runner, which must not leak into client
1189
1197
  // bundles. Import from `@mohasinac/appkit/server` in server-only code.
@@ -80,6 +80,10 @@ export declare const DEFAULT_ROUTE_MAP: {
80
80
  readonly SCAMS: "/scams";
81
81
  readonly SCAM_DETAIL: (id: string) => string;
82
82
  readonly SCAM_REPORT: "/scams/report";
83
+ readonly REPORT_ENTITY: "/report";
84
+ readonly ITEM_REQUESTS: "/item-requests";
85
+ readonly ITEM_REQUEST_DETAIL: (id: string) => string;
86
+ readonly ITEM_REQUESTS_NEW: "/item-requests/new";
83
87
  readonly SCAM_TYPES: "/scams/types";
84
88
  readonly SCAM_FAQS: "/scams/faqs";
85
89
  readonly CLASSIFIED: "/classified";
@@ -116,6 +120,8 @@ export declare const DEFAULT_ROUTE_MAP: {
116
120
  readonly ORDER_INVOICE: (id: string) => string;
117
121
  readonly NOTIFICATIONS: "/user/notifications";
118
122
  readonly MESSAGES: "/user/messages";
123
+ /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
124
+ readonly CLAIMED_COUPONS: "/user/coupons";
119
125
  readonly BECOME_SELLER: "/user/become-seller";
120
126
  readonly CART: "/cart";
121
127
  readonly CHECKOUT: "/checkout";
@@ -185,6 +191,21 @@ export declare const DEFAULT_ROUTE_MAP: {
185
191
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
186
192
  readonly PRINT_CENTER: "/store/print-center";
187
193
  readonly INVENTORY_PRINT: "/store/inventory/print";
194
+ readonly PAYOUT_METHODS: "/store/payout-methods";
195
+ readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
196
+ readonly PAYOUT_METHODS_EDIT: (id: string) => string;
197
+ readonly SHIPPING_CONFIGS: "/store/shipping-configs";
198
+ readonly SHIPPING_CONFIGS_NEW: "/store/shipping-configs/new";
199
+ readonly SHIPPING_CONFIGS_EDIT: (id: string) => string;
200
+ readonly ANALYTICS_CARDS: "/store/analytics/cards";
201
+ readonly ANALYTICS_ALERTS: "/store/analytics/alerts";
202
+ readonly STORE_CATEGORIES: "/store/categories";
203
+ readonly STORE_CATEGORIES_NEW: "/store/categories/new";
204
+ readonly STORE_CATEGORIES_EDIT: (id: string) => string;
205
+ readonly LISTING_TEMPLATES: "/store/listing-templates";
206
+ readonly LISTING_TEMPLATES_NEW: "/store/listing-templates/new";
207
+ readonly LISTING_TEMPLATES_EDIT: (id: string) => string;
208
+ readonly GOOGLE_REVIEWS: "/store/google-reviews";
188
209
  };
189
210
  readonly ADMIN: {
190
211
  readonly DASHBOARD: "/admin/dashboard";
@@ -266,6 +287,17 @@ export declare const DEFAULT_ROUTE_MAP: {
266
287
  readonly SETTINGS_ACTIONS: "/admin/settings/actions";
267
288
  readonly SETTINGS_NAVIGATION: "/admin/settings/navigation";
268
289
  readonly PRINT_CENTER: "/admin/print-center";
290
+ readonly MODERATION: "/admin/moderation";
291
+ readonly MODERATION_DETAIL: (id: string) => string;
292
+ readonly REPORTS: "/admin/reports";
293
+ readonly REPORT_DETAIL: (id: string) => string;
294
+ readonly ITEM_REQUESTS: "/admin/item-requests";
295
+ readonly ITEM_REQUEST_DETAIL: (id: string) => string;
296
+ readonly ROLES: "/admin/roles";
297
+ readonly ROLES_NEW: "/admin/roles/new";
298
+ readonly ROLES_EDIT: (id: string) => string;
299
+ readonly PERMISSIONS: "/admin/permissions";
300
+ readonly ADMIN_NOTIFICATIONS: "/admin/admin-notifications";
269
301
  };
270
302
  readonly DEMO: {
271
303
  readonly SEED: "/demo/seed";
@@ -345,6 +377,10 @@ export declare const ROUTES: {
345
377
  readonly SCAMS: "/scams";
346
378
  readonly SCAM_DETAIL: (id: string) => string;
347
379
  readonly SCAM_REPORT: "/scams/report";
380
+ readonly REPORT_ENTITY: "/report";
381
+ readonly ITEM_REQUESTS: "/item-requests";
382
+ readonly ITEM_REQUEST_DETAIL: (id: string) => string;
383
+ readonly ITEM_REQUESTS_NEW: "/item-requests/new";
348
384
  readonly SCAM_TYPES: "/scams/types";
349
385
  readonly SCAM_FAQS: "/scams/faqs";
350
386
  readonly CLASSIFIED: "/classified";
@@ -381,6 +417,8 @@ export declare const ROUTES: {
381
417
  readonly ORDER_INVOICE: (id: string) => string;
382
418
  readonly NOTIFICATIONS: "/user/notifications";
383
419
  readonly MESSAGES: "/user/messages";
420
+ /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
421
+ readonly CLAIMED_COUPONS: "/user/coupons";
384
422
  readonly BECOME_SELLER: "/user/become-seller";
385
423
  readonly CART: "/cart";
386
424
  readonly CHECKOUT: "/checkout";
@@ -450,6 +488,21 @@ export declare const ROUTES: {
450
488
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
451
489
  readonly PRINT_CENTER: "/store/print-center";
452
490
  readonly INVENTORY_PRINT: "/store/inventory/print";
491
+ readonly PAYOUT_METHODS: "/store/payout-methods";
492
+ readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
493
+ readonly PAYOUT_METHODS_EDIT: (id: string) => string;
494
+ readonly SHIPPING_CONFIGS: "/store/shipping-configs";
495
+ readonly SHIPPING_CONFIGS_NEW: "/store/shipping-configs/new";
496
+ readonly SHIPPING_CONFIGS_EDIT: (id: string) => string;
497
+ readonly ANALYTICS_CARDS: "/store/analytics/cards";
498
+ readonly ANALYTICS_ALERTS: "/store/analytics/alerts";
499
+ readonly STORE_CATEGORIES: "/store/categories";
500
+ readonly STORE_CATEGORIES_NEW: "/store/categories/new";
501
+ readonly STORE_CATEGORIES_EDIT: (id: string) => string;
502
+ readonly LISTING_TEMPLATES: "/store/listing-templates";
503
+ readonly LISTING_TEMPLATES_NEW: "/store/listing-templates/new";
504
+ readonly LISTING_TEMPLATES_EDIT: (id: string) => string;
505
+ readonly GOOGLE_REVIEWS: "/store/google-reviews";
453
506
  };
454
507
  readonly ADMIN: {
455
508
  readonly DASHBOARD: "/admin/dashboard";
@@ -531,6 +584,17 @@ export declare const ROUTES: {
531
584
  readonly SETTINGS_ACTIONS: "/admin/settings/actions";
532
585
  readonly SETTINGS_NAVIGATION: "/admin/settings/navigation";
533
586
  readonly PRINT_CENTER: "/admin/print-center";
587
+ readonly MODERATION: "/admin/moderation";
588
+ readonly MODERATION_DETAIL: (id: string) => string;
589
+ readonly REPORTS: "/admin/reports";
590
+ readonly REPORT_DETAIL: (id: string) => string;
591
+ readonly ITEM_REQUESTS: "/admin/item-requests";
592
+ readonly ITEM_REQUEST_DETAIL: (id: string) => string;
593
+ readonly ROLES: "/admin/roles";
594
+ readonly ROLES_NEW: "/admin/roles/new";
595
+ readonly ROLES_EDIT: (id: string) => string;
596
+ readonly PERMISSIONS: "/admin/permissions";
597
+ readonly ADMIN_NOTIFICATIONS: "/admin/admin-notifications";
534
598
  };
535
599
  readonly DEMO: {
536
600
  readonly SEED: "/demo/seed";
@@ -595,6 +659,21 @@ export declare const SELLER_ROUTES: {
595
659
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
596
660
  readonly PRINT_CENTER: "/store/print-center";
597
661
  readonly INVENTORY_PRINT: "/store/inventory/print";
662
+ readonly PAYOUT_METHODS: "/store/payout-methods";
663
+ readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
664
+ readonly PAYOUT_METHODS_EDIT: (id: string) => string;
665
+ readonly SHIPPING_CONFIGS: "/store/shipping-configs";
666
+ readonly SHIPPING_CONFIGS_NEW: "/store/shipping-configs/new";
667
+ readonly SHIPPING_CONFIGS_EDIT: (id: string) => string;
668
+ readonly ANALYTICS_CARDS: "/store/analytics/cards";
669
+ readonly ANALYTICS_ALERTS: "/store/analytics/alerts";
670
+ readonly STORE_CATEGORIES: "/store/categories";
671
+ readonly STORE_CATEGORIES_NEW: "/store/categories/new";
672
+ readonly STORE_CATEGORIES_EDIT: (id: string) => string;
673
+ readonly LISTING_TEMPLATES: "/store/listing-templates";
674
+ readonly LISTING_TEMPLATES_NEW: "/store/listing-templates/new";
675
+ readonly LISTING_TEMPLATES_EDIT: (id: string) => string;
676
+ readonly GOOGLE_REVIEWS: "/store/google-reviews";
598
677
  };
599
678
  export declare const PUBLIC_ROUTES: readonly ["/", string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, "/unauthorized", "/auth/login", "/auth/register", "/auth/forgot-password", "/auth/reset-password", "/auth/verify-email"];
600
679
  export declare const PROTECTED_ROUTES: readonly [string, string, string, string, string, string, string];
@@ -68,6 +68,10 @@ export const DEFAULT_ROUTE_MAP = {
68
68
  SCAMS: "/scams",
69
69
  SCAM_DETAIL: (id) => `/scams/${id}`,
70
70
  SCAM_REPORT: "/scams/report",
71
+ REPORT_ENTITY: "/report",
72
+ ITEM_REQUESTS: "/item-requests",
73
+ ITEM_REQUEST_DETAIL: (id) => `/item-requests/${id}`,
74
+ ITEM_REQUESTS_NEW: "/item-requests/new",
71
75
  SCAM_TYPES: "/scams/types",
72
76
  SCAM_FAQS: "/scams/faqs",
73
77
  CLASSIFIED: "/classified",
@@ -104,6 +108,8 @@ export const DEFAULT_ROUTE_MAP = {
104
108
  ORDER_INVOICE: (id) => `/user/orders/${id}/invoice`,
105
109
  NOTIFICATIONS: "/user/notifications",
106
110
  MESSAGES: "/user/messages",
111
+ /** Plan §10 — claimed-coupons wallet (Active / Expired / Used tabs). */
112
+ CLAIMED_COUPONS: "/user/coupons",
107
113
  BECOME_SELLER: "/user/become-seller",
108
114
  CART: "/cart",
109
115
  CHECKOUT: "/checkout",
@@ -175,6 +181,22 @@ export const DEFAULT_ROUTE_MAP = {
175
181
  LIVE_ITEMS_EDIT: (id) => `/store/live/${id}/edit`,
176
182
  PRINT_CENTER: "/store/print-center",
177
183
  INVENTORY_PRINT: "/store/inventory/print",
184
+ // S-STORE Tier — new extension routes
185
+ PAYOUT_METHODS: "/store/payout-methods",
186
+ PAYOUT_METHODS_NEW: "/store/payout-methods/new",
187
+ PAYOUT_METHODS_EDIT: (id) => `/store/payout-methods/${id}/edit`,
188
+ SHIPPING_CONFIGS: "/store/shipping-configs",
189
+ SHIPPING_CONFIGS_NEW: "/store/shipping-configs/new",
190
+ SHIPPING_CONFIGS_EDIT: (id) => `/store/shipping-configs/${id}/edit`,
191
+ ANALYTICS_CARDS: "/store/analytics/cards",
192
+ ANALYTICS_ALERTS: "/store/analytics/alerts",
193
+ STORE_CATEGORIES: "/store/categories",
194
+ STORE_CATEGORIES_NEW: "/store/categories/new",
195
+ STORE_CATEGORIES_EDIT: (id) => `/store/categories/${id}/edit`,
196
+ LISTING_TEMPLATES: "/store/listing-templates",
197
+ LISTING_TEMPLATES_NEW: "/store/listing-templates/new",
198
+ LISTING_TEMPLATES_EDIT: (id) => `/store/listing-templates/${id}/edit`,
199
+ GOOGLE_REVIEWS: "/store/google-reviews",
178
200
  },
179
201
  ADMIN: {
180
202
  DASHBOARD: "/admin/dashboard",
@@ -258,6 +280,18 @@ export const DEFAULT_ROUTE_MAP = {
258
280
  SETTINGS_ACTIONS: "/admin/settings/actions",
259
281
  SETTINGS_NAVIGATION: "/admin/settings/navigation",
260
282
  PRINT_CENTER: "/admin/print-center",
283
+ // S-STORE Tier — admin moderation + reports + item requests
284
+ MODERATION: "/admin/moderation",
285
+ MODERATION_DETAIL: (id) => `/admin/moderation/${id}`,
286
+ REPORTS: "/admin/reports",
287
+ REPORT_DETAIL: (id) => `/admin/reports/${id}`,
288
+ ITEM_REQUESTS: "/admin/item-requests",
289
+ ITEM_REQUEST_DETAIL: (id) => `/admin/item-requests/${id}`,
290
+ ROLES: "/admin/roles",
291
+ ROLES_NEW: "/admin/roles/new",
292
+ ROLES_EDIT: (id) => `/admin/roles/${id}/edit`,
293
+ PERMISSIONS: "/admin/permissions",
294
+ ADMIN_NOTIFICATIONS: "/admin/admin-notifications",
261
295
  },
262
296
  DEMO: {
263
297
  SEED: "/demo/seed",
@@ -0,0 +1,17 @@
1
+ export interface FormStatePreservationOptions<TValues> {
2
+ /** Current form values to persist. */
3
+ values: TValues;
4
+ /** Callback invoked with restored values on mount (if any). */
5
+ onRestore: (values: TValues) => void;
6
+ /** Field paths whose values are stripped before encoding (PII). */
7
+ stripFields?: string[];
8
+ /** URL query-param name. Default: "_s". */
9
+ paramName?: string;
10
+ /** Debounce in ms. Default: 500. */
11
+ debounceMs?: number;
12
+ /** Disable persistence (e.g. while submitting). */
13
+ enabled?: boolean;
14
+ }
15
+ export declare function useFormStatePreservation<TValues extends Record<string, unknown>>({ values, onRestore, stripFields, paramName, debounceMs, enabled, }: FormStatePreservationOptions<TValues>): {
16
+ clearPreservedState: () => void;
17
+ };
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { useEffect, useRef, useCallback } from "react";
3
+ const PARAM_DEFAULT = "_s";
4
+ function stripPii(values, stripFields) {
5
+ if (!stripFields.length || typeof values !== "object" || values === null) {
6
+ return values;
7
+ }
8
+ const clone = { ...values };
9
+ for (const path of stripFields) {
10
+ if (path in clone) {
11
+ delete clone[path];
12
+ }
13
+ }
14
+ return clone;
15
+ }
16
+ export function useFormStatePreservation({ values, onRestore, stripFields = [], paramName = PARAM_DEFAULT, debounceMs = 500, enabled = true, }) {
17
+ const restoredRef = useRef(false);
18
+ const timerRef = useRef(null);
19
+ useEffect(() => {
20
+ if (restoredRef.current || typeof window === "undefined")
21
+ return;
22
+ restoredRef.current = true;
23
+ const url = new URL(window.location.href);
24
+ const encoded = url.searchParams.get(paramName);
25
+ if (!encoded)
26
+ return;
27
+ try {
28
+ const decoded = JSON.parse(atob(encoded));
29
+ onRestore(decoded);
30
+ }
31
+ catch {
32
+ // ignore corrupt payloads
33
+ }
34
+ }, [paramName, onRestore]);
35
+ useEffect(() => {
36
+ if (!enabled || typeof window === "undefined" || !restoredRef.current)
37
+ return;
38
+ if (timerRef.current)
39
+ clearTimeout(timerRef.current);
40
+ timerRef.current = setTimeout(() => {
41
+ const stripped = stripPii(values, stripFields);
42
+ const encoded = btoa(JSON.stringify(stripped));
43
+ const url = new URL(window.location.href);
44
+ url.searchParams.set(paramName, encoded);
45
+ window.history.replaceState({}, "", url.toString());
46
+ }, debounceMs);
47
+ return () => {
48
+ if (timerRef.current)
49
+ clearTimeout(timerRef.current);
50
+ };
51
+ }, [values, enabled, paramName, debounceMs, stripFields]);
52
+ const clearPreservedState = useCallback(() => {
53
+ if (typeof window === "undefined")
54
+ return;
55
+ const url = new URL(window.location.href);
56
+ if (url.searchParams.has(paramName)) {
57
+ url.searchParams.delete(paramName);
58
+ window.history.replaceState({}, "", url.toString());
59
+ }
60
+ }, [paramName]);
61
+ return { clearPreservedState };
62
+ }
@@ -0,0 +1,24 @@
1
+ export interface InlineEditOptions<TValue> {
2
+ rowId: string;
3
+ field: string;
4
+ initialValue: TValue;
5
+ save: (rowId: string, field: string, value: TValue) => Promise<unknown>;
6
+ onError?: (err: unknown, previous: TValue) => void;
7
+ }
8
+ export interface InlineToggleResult {
9
+ value: boolean;
10
+ isSaving: boolean;
11
+ toggle: () => Promise<void>;
12
+ }
13
+ export declare function useInlineToggle({ rowId, field, initialValue, save, onError, }: InlineEditOptions<boolean>): InlineToggleResult;
14
+ export interface InlineTextResult {
15
+ value: string;
16
+ draft: string;
17
+ isEditing: boolean;
18
+ isSaving: boolean;
19
+ startEdit: () => void;
20
+ cancelEdit: () => void;
21
+ commitEdit: () => Promise<void>;
22
+ setDraft: (next: string) => void;
23
+ }
24
+ export declare function useInlineTextEdit({ rowId, field, initialValue, save, onError, }: InlineEditOptions<string>): InlineTextResult;
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ import { useCallback, useState } from "react";
3
+ export function useInlineToggle({ rowId, field, initialValue, save, onError, }) {
4
+ const [value, setValue] = useState(initialValue);
5
+ const [isSaving, setIsSaving] = useState(false);
6
+ const toggle = useCallback(async () => {
7
+ const previous = value;
8
+ const next = !previous;
9
+ setValue(next);
10
+ setIsSaving(true);
11
+ try {
12
+ await save(rowId, field, next);
13
+ }
14
+ catch (err) {
15
+ setValue(previous);
16
+ onError?.(err, previous);
17
+ }
18
+ finally {
19
+ setIsSaving(false);
20
+ }
21
+ }, [value, save, rowId, field, onError]);
22
+ return { value, isSaving, toggle };
23
+ }
24
+ export function useInlineTextEdit({ rowId, field, initialValue, save, onError, }) {
25
+ const [value, setValue] = useState(initialValue);
26
+ const [draft, setDraft] = useState(initialValue);
27
+ const [isEditing, setIsEditing] = useState(false);
28
+ const [isSaving, setIsSaving] = useState(false);
29
+ const startEdit = useCallback(() => {
30
+ setDraft(value);
31
+ setIsEditing(true);
32
+ }, [value]);
33
+ const cancelEdit = useCallback(() => {
34
+ setDraft(value);
35
+ setIsEditing(false);
36
+ }, [value]);
37
+ const commitEdit = useCallback(async () => {
38
+ if (draft === value) {
39
+ setIsEditing(false);
40
+ return;
41
+ }
42
+ const previous = value;
43
+ setValue(draft);
44
+ setIsEditing(false);
45
+ setIsSaving(true);
46
+ try {
47
+ await save(rowId, field, draft);
48
+ }
49
+ catch (err) {
50
+ setValue(previous);
51
+ setDraft(previous);
52
+ onError?.(err, previous);
53
+ }
54
+ finally {
55
+ setIsSaving(false);
56
+ }
57
+ }, [draft, value, save, rowId, field, onError]);
58
+ return {
59
+ value,
60
+ draft,
61
+ isEditing,
62
+ isSaving,
63
+ startEdit,
64
+ cancelEdit,
65
+ commitEdit,
66
+ setDraft,
67
+ };
68
+ }
@@ -30,6 +30,10 @@ export type { UseBulkSelectionOptions, UseBulkSelectionReturn, } from "./hooks/u
30
30
  export { useSyncManager } from "../core/hooks/useSyncManager";
31
31
  export { useUrlTable } from "./hooks/useUrlTable";
32
32
  export type { UseUrlTableOptions } from "./hooks/useUrlTable";
33
+ export { useInlineToggle, useInlineTextEdit, } from "./hooks/useInlineRowEdit";
34
+ export type { InlineEditOptions, InlineToggleResult, InlineTextResult, } from "./hooks/useInlineRowEdit";
35
+ export { useFormStatePreservation } from "./hooks/useFormStatePreservation";
36
+ export type { FormStatePreservationOptions } from "./hooks/useFormStatePreservation";
33
37
  export { usePendingFilters } from "./hooks/usePendingFilters";
34
38
  export type { UsePendingFiltersOptions, UsePendingFiltersReturn, } from "./hooks/usePendingFilters";
35
39
  export { usePendingTable } from "./hooks/usePendingTable";
@@ -28,6 +28,10 @@ export { useBulkSelection } from "./hooks/useBulkSelection";
28
28
  export { useSyncManager } from "../core/hooks/useSyncManager";
29
29
  // URL-driven table / list state
30
30
  export { useUrlTable } from "./hooks/useUrlTable";
31
+ // Inline row editing (S-STORE-CROSS-B)
32
+ export { useInlineToggle, useInlineTextEdit, } from "./hooks/useInlineRowEdit";
33
+ // Form state preservation in URL (S-STORE-CROSS-C)
34
+ export { useFormStatePreservation } from "./hooks/useFormStatePreservation";
31
35
  // Staged (pending) filter management
32
36
  export { usePendingFilters } from "./hooks/usePendingFilters";
33
37
  export { usePendingTable } from "./hooks/usePendingTable";
@@ -24,9 +24,13 @@ export { carouselsRepository, CarouselsRepository } from "../features/homepage/r
24
24
  export { homepageSectionsRepository } from "../features/homepage/repository/homepage-sections.repository";
25
25
  export { CategoriesRepository, categoriesRepository, } from "../features/categories/repository/categories.repository";
26
26
  export { couponsRepository } from "../features/promotions/repository/coupons.repository";
27
+ export { ClaimedCouponsRepository, claimedCouponsRepository, } from "../features/promotions/repository/claimed-coupons.repository";
28
+ export type { ClaimedCouponCreateInput } from "../features/promotions/repository/claimed-coupons.repository";
27
29
  export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
28
30
  export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
29
31
  export { payoutRepository } from "../features/payments/repository/payout.repository";
32
+ export { payoutMethodsRepository, shippingConfigsRepository, analyticsCardsRepository, analyticsAlertsRepository, storeCategoriesRepository, listingTemplatesRepository, moderationQueueRepository, reportsRepository, itemRequestsRepository, storeWhatsAppConfigRepository, storeGoogleConfigRepository, PayoutMethodsRepository, ShippingConfigsRepository, AnalyticsCardsRepository, AnalyticsAlertsRepository, StoreCategoriesRepository, ListingTemplatesRepository, ModerationQueueRepository, ReportsRepository, ItemRequestsRepository, StoreWhatsAppConfigRepository, StoreGoogleConfigRepository, } from "../features/store-extensions/repository/store-extensions.repositories";
33
+ export { roleOverridesRepository, customRolesRepository, adminNotificationsRepository, RoleOverridesRepository, CustomRolesRepository, AdminNotificationsRepository, } from "../features/store-extensions/repository/rbac.repositories";
30
34
  export { OfferRepository, offerRepository, } from "../features/seller/repository/offer.repository";
31
35
  export { wishlistRepository, type UserWishlistItem as WishlistItem, WishlistFullError, } from "../features/wishlist/repository/user-wishlist.repository";
32
36
  export { historyRepository, type UserHistoryItem, type HistoryProductType, } from "../features/history/repository/user-history.repository";
@@ -31,9 +31,14 @@ export { carouselsRepository, CarouselsRepository } from "../features/homepage/r
31
31
  export { homepageSectionsRepository } from "../features/homepage/repository/homepage-sections.repository";
32
32
  export { CategoriesRepository, categoriesRepository, } from "../features/categories/repository/categories.repository";
33
33
  export { couponsRepository } from "../features/promotions/repository/coupons.repository";
34
+ export { ClaimedCouponsRepository, claimedCouponsRepository, } from "../features/promotions/repository/claimed-coupons.repository";
34
35
  export { FAQsRepository, FirebaseFAQsRepository, faqsRepository, } from "../features/faq/repository/faqs.repository";
35
36
  export { BlogRepository, blogRepository, } from "../features/blog/repository/blog.repository";
36
37
  export { payoutRepository } from "../features/payments/repository/payout.repository";
38
+ // S-STORE-CROSS — 11 new collection repositories
39
+ export { payoutMethodsRepository, shippingConfigsRepository, analyticsCardsRepository, analyticsAlertsRepository, storeCategoriesRepository, listingTemplatesRepository, moderationQueueRepository, reportsRepository, itemRequestsRepository, storeWhatsAppConfigRepository, storeGoogleConfigRepository, PayoutMethodsRepository, ShippingConfigsRepository, AnalyticsCardsRepository, AnalyticsAlertsRepository, StoreCategoriesRepository, ListingTemplatesRepository, ModerationQueueRepository, ReportsRepository, ItemRequestsRepository, StoreWhatsAppConfigRepository, StoreGoogleConfigRepository, } from "../features/store-extensions/repository/store-extensions.repositories";
40
+ // S-STORE RBAC + admin notifications
41
+ export { roleOverridesRepository, customRolesRepository, adminNotificationsRepository, RoleOverridesRepository, CustomRolesRepository, AdminNotificationsRepository, } from "../features/store-extensions/repository/rbac.repositories";
37
42
  export { OfferRepository, offerRepository, } from "../features/seller/repository/offer.repository";
38
43
  export { wishlistRepository, WishlistFullError, } from "../features/wishlist/repository/user-wishlist.repository";
39
44
  export { historyRepository, } from "../features/history/repository/user-history.repository";
@@ -6,7 +6,7 @@
6
6
  * the actual collection-specific seeding logic (800+ lines with PII encryption,
7
7
  * Auth user creation, subcollection handling, etc.).
8
8
  */
9
- export type SeedCollectionName = "users" | "addresses" | "categories" | "stores" | "products" | "orders" | "reviews" | "bids" | "coupons" | "carousels" | "carouselSlides" | "homepageSections" | "siteSettings" | "faqs" | "notifications" | "payouts" | "blogPosts" | "events" | "eventEntries" | "sessions" | "carts" | "wishlists" | "history" | "conversations" | "groupedListings" | "scammerProfiles" | "supportTickets" | "productFeatures" | "offers";
9
+ export type SeedCollectionName = "users" | "addresses" | "categories" | "stores" | "products" | "orders" | "reviews" | "bids" | "coupons" | "carousels" | "carouselSlides" | "homepageSections" | "siteSettings" | "faqs" | "notifications" | "payouts" | "blogPosts" | "events" | "eventEntries" | "sessions" | "carts" | "wishlists" | "history" | "conversations" | "groupedListings" | "scammerProfiles" | "supportTickets" | "productFeatures" | "offers" | "payoutMethods" | "shippingConfigs" | "analyticsCards" | "analyticsAlerts" | "storeCategories" | "listingTemplates" | "moderationQueue" | "reports" | "itemRequests" | "storeWhatsAppConfig" | "storeGoogleConfig" | "roleOverrides" | "customRoles" | "adminNotifications";
10
10
  export interface SeedOperationResult {
11
11
  success?: boolean;
12
12
  message: string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Claimed Coupons Seed Data — plan §10.
3
+ *
4
+ * Top-level `claimedCoupons` collection (one doc per user × coupon). These
5
+ * rows populate the /user/coupons wallet with one example per status so the
6
+ * tabs (Active / Expired / Used) all have something to render in demo.
7
+ *
8
+ * Coupon snapshots mirror coupons-seed-data.ts (WELCOME10, POKEMON25,
9
+ * FREESHIP999) so the discount badge labels render correctly. Seed user is
10
+ * `user-mohsin-c` to match the dev-account convention used elsewhere.
11
+ */
12
+ import type { ClaimedCouponDocument } from "../features/promotions/schemas";
13
+ export declare const claimedCouponsSeedData: ClaimedCouponDocument[];