@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
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { sieveFilter, sieveAnd, SIEVE_OP, sortBy, PRODUCT_FIELDS } from "@mohasinac/appkit";
3
+ import { productRepository } from "../../../repositories";
4
+ import { getStoreBySlug } from "./StoreDetailLayoutView";
5
+ import { StoreClassifiedsListing } from "./StoreClassifiedsListing";
6
+ export async function StoreClassifiedsPageView({ storeSlug }) {
7
+ const store = await getStoreBySlug(storeSlug);
8
+ const storeId = store?.id;
9
+ if (!storeId)
10
+ return null;
11
+ const result = await productRepository
12
+ .list({
13
+ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "classified")),
14
+ sorts: sortBy(PRODUCT_FIELDS.CREATED_AT),
15
+ page: 1,
16
+ pageSize: 24,
17
+ })
18
+ .catch(() => null);
19
+ return _jsx(StoreClassifiedsListing, { storeId: storeId, initialData: result ?? undefined });
20
+ }
@@ -14,6 +14,9 @@ const STORE_LISTING_HREF = {
14
14
  "pre-orders": (slug) => String(ROUTES.PUBLIC.STORE_PRE_ORDERS(slug)),
15
15
  "prize-draws": (slug) => String(ROUTES.PUBLIC.STORE_PRIZE_DRAWS(slug)),
16
16
  bundles: (slug) => String(ROUTES.PUBLIC.STORE_BUNDLES(slug)),
17
+ classifieds: (slug) => String(ROUTES.PUBLIC.STORE_CLASSIFIEDS(slug)),
18
+ "digital-codes": (slug) => String(ROUTES.PUBLIC.STORE_DIGITAL_CODES(slug)),
19
+ live: (slug) => String(ROUTES.PUBLIC.STORE_LIVE(slug)),
17
20
  };
18
21
  export const getStoreBySlug = cache((slug) => storeRepository.findBySlug(slug).catch(() => undefined));
19
22
  function tabLabel(base, count) {
@@ -28,7 +31,7 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
28
31
  }
29
32
  const storeId = store?.id;
30
33
  const settings = await siteSettingsRepository.findById("global").catch(() => null);
31
- const [productsCount, auctionsCount, preOrdersCount, prizeDrawsCount, bundlesCount, couponsCount, reviewsCount] = storeId
34
+ const [productsCount, auctionsCount, preOrdersCount, prizeDrawsCount, bundlesCount, classifiedsCount, digitalCodesCount, liveCount, couponsCount, reviewsCount] = storeId
32
35
  ? await Promise.all([
33
36
  productRepository
34
37
  .list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "standard")), page: 1, pageSize: 1 })
@@ -52,6 +55,18 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
52
55
  .listByType("bundle", { activeOnly: true, limit: 100 })
53
56
  .then((rows) => rows.filter((c) => c.createdByStoreId === storeId).length)
54
57
  .catch(() => 0),
58
+ productRepository
59
+ .list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "classified")), page: 1, pageSize: 1 })
60
+ .then((r) => r.total)
61
+ .catch(() => 0),
62
+ productRepository
63
+ .list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "digital-code")), page: 1, pageSize: 1 })
64
+ .then((r) => r.total)
65
+ .catch(() => 0),
66
+ productRepository
67
+ .list({ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "live")), page: 1, pageSize: 1 })
68
+ .then((r) => r.total)
69
+ .catch(() => 0),
55
70
  couponsRepository
56
71
  .list({ filters: sieveAnd(sieveFilter("sellerId", SIEVE_OP.EQ, storeId), sieveFilter("validity.isActive", SIEVE_OP.EQ, "true")), page: 1, pageSize: 1 })
57
72
  .then((r) => r.total)
@@ -61,19 +76,25 @@ export async function StoreDetailLayoutView({ storeSlug, activeTab, children, })
61
76
  .then((r) => r.total)
62
77
  .catch(() => 0),
63
78
  ])
64
- : [0, 0, 0, 0, 0, 0, 0];
79
+ : [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
65
80
  const listingCounts = {
66
81
  products: productsCount,
67
82
  auctions: auctionsCount,
68
83
  "pre-orders": preOrdersCount,
69
84
  "prize-draws": prizeDrawsCount,
70
85
  bundles: bundlesCount,
86
+ classifieds: classifiedsCount,
87
+ "digital-codes": digitalCodesCount,
88
+ live: liveCount,
71
89
  };
72
90
  const TAB_LISTING_TYPE = {
73
91
  products: "standard",
74
92
  auctions: "auction",
75
93
  "pre-orders": "pre-order",
76
94
  "prize-draws": "prize-draw",
95
+ classifieds: "classified",
96
+ "digital-codes": "digital-code",
97
+ live: "live",
77
98
  };
78
99
  const visibleStoreTabs = STORE_PAGE_TABS.filter((tab) => {
79
100
  if (tab.id === "bundles")
@@ -0,0 +1,5 @@
1
+ export interface StoreDigitalCodesListingProps {
2
+ storeId?: string;
3
+ initialData?: any;
4
+ }
5
+ export declare function StoreDigitalCodesListing({ storeId, initialData }: StoreDigitalCodesListingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,48 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
+ import { usePendingTable } from "../../../react/hooks/usePendingTable";
6
+ import { useProducts } from "../../products/hooks/useProducts";
7
+ import { Div, FilterDrawer, ListingToolbar, Pagination, Row, Text } from "../../../ui";
8
+ import { DigitalCodeFilters } from "../../digital-codes/components/DigitalCodeFilters";
9
+ import { InteractiveProductCard } from "../../products/components/InteractiveProductCard";
10
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
11
+ import { TABLE_KEYS } from "../../../constants/table-keys";
12
+ import { sortBy } from "../../../constants/sort";
13
+ import { ROUTES } from "../../../next";
14
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
15
+ const SORT_OPTIONS = [
16
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
17
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
18
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
19
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
20
+ ];
21
+ const FILTER_KEYS = [TABLE_KEYS.MIN_PRICE, TABLE_KEYS.MAX_PRICE];
22
+ export function StoreDigitalCodesListing({ storeId, initialData }) {
23
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
24
+ const [searchInput, setSearchInput] = useState(table.get("q") || "");
25
+ const [filterOpen, setFilterOpen] = useState(false);
26
+ const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onResetAll, onFilterReset } = usePendingTable(table, FILTER_KEYS);
27
+ const openFilters = useCallback(() => { onFilterReset(); setFilterOpen(true); }, [onFilterReset]);
28
+ const applyFilters = useCallback(() => { onFilterApply(); setFilterOpen(false); }, [onFilterApply]);
29
+ const resetAll = useCallback(() => { onResetAll({ q: "", sort: "" }); setSearchInput(""); }, [onResetAll]);
30
+ const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || filterActiveCount > 0;
31
+ const params = {
32
+ q: table.get("q") || undefined,
33
+ minPrice: table.get(TABLE_KEYS.MIN_PRICE) ? Number(table.get(TABLE_KEYS.MIN_PRICE)) : undefined,
34
+ maxPrice: table.get(TABLE_KEYS.MAX_PRICE) ? Number(table.get(TABLE_KEYS.MAX_PRICE)) : undefined,
35
+ sort: table.get("sort") || DEFAULT_SORT,
36
+ page: table.getNumber("page", 1),
37
+ perPage: table.getNumber("pageSize", 24),
38
+ storeId: storeId || undefined,
39
+ listingType: "digital-code",
40
+ };
41
+ const { products, totalPages, page, isLoading } = useProducts(params, { initialData });
42
+ const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4";
43
+ return (_jsxs(Div, { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search digital codes\u2026", onSearchChange: setSearchInput, onSearchCommit: () => table.set("q", searchInput.trim()), sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => table.set("sort", v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: _jsx(Div, { className: gridClass, children: isLoading
44
+ ? Array.from({ length: 8 }).map((_, i) => _jsx(Div, { surface: "muted", rounded: "xl", className: "aspect-square animate-pulse" }, i))
45
+ : products.length === 0
46
+ ? _jsx(Div, { paddingY: "y-4xl", className: "col-span-full text-center", children: _jsx(Text, { color: "muted", children: "No digital codes in this store yet." }) })
47
+ : products.map((p) => (_jsx(InteractiveProductCard, { product: p, href: String(ROUTES.PUBLIC.DIGITAL_CODE_DETAIL(p.slug ?? p.id)) }, p.id))) }) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(DigitalCodeFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) })] }));
48
+ }
@@ -0,0 +1,4 @@
1
+ export interface StoreDigitalCodesPageViewProps {
2
+ storeSlug: string;
3
+ }
4
+ export declare function StoreDigitalCodesPageView({ storeSlug }: StoreDigitalCodesPageViewProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { sieveFilter, sieveAnd, SIEVE_OP, sortBy, PRODUCT_FIELDS } from "@mohasinac/appkit";
3
+ import { productRepository } from "../../../repositories";
4
+ import { getStoreBySlug } from "./StoreDetailLayoutView";
5
+ import { StoreDigitalCodesListing } from "./StoreDigitalCodesListing";
6
+ export async function StoreDigitalCodesPageView({ storeSlug }) {
7
+ const store = await getStoreBySlug(storeSlug);
8
+ const storeId = store?.id;
9
+ if (!storeId)
10
+ return null;
11
+ const result = await productRepository
12
+ .list({
13
+ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "digital-code")),
14
+ sorts: sortBy(PRODUCT_FIELDS.CREATED_AT),
15
+ page: 1,
16
+ pageSize: 24,
17
+ })
18
+ .catch(() => null);
19
+ return _jsx(StoreDigitalCodesListing, { storeId: storeId, initialData: result ?? undefined });
20
+ }
@@ -0,0 +1,5 @@
1
+ export interface StoreLiveItemsListingProps {
2
+ storeId?: string;
3
+ initialData?: any;
4
+ }
5
+ export declare function StoreLiveItemsListing({ storeId, initialData }: StoreLiveItemsListingProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,48 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import { useUrlTable } from "../../../react/hooks/useUrlTable";
5
+ import { usePendingTable } from "../../../react/hooks/usePendingTable";
6
+ import { useProducts } from "../../products/hooks/useProducts";
7
+ import { Div, FilterDrawer, ListingToolbar, Pagination, Row, Text } from "../../../ui";
8
+ import { LiveItemFilters } from "../../live/components/LiveItemFilters";
9
+ import { InteractiveProductCard } from "../../products/components/InteractiveProductCard";
10
+ import { PRODUCT_FIELDS } from "../../../constants/field-names";
11
+ import { TABLE_KEYS } from "../../../constants/table-keys";
12
+ import { sortBy } from "../../../constants/sort";
13
+ import { ROUTES } from "../../../next";
14
+ const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
15
+ const SORT_OPTIONS = [
16
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
17
+ { value: sortBy(PRODUCT_FIELDS.CREATED_AT, "ASC"), label: "Oldest First" },
18
+ { value: sortBy(PRODUCT_FIELDS.PRICE, "ASC"), label: "Price: Low to High" },
19
+ { value: sortBy(PRODUCT_FIELDS.PRICE), label: "Price: High to Low" },
20
+ ];
21
+ const FILTER_KEYS = [TABLE_KEYS.MIN_PRICE, TABLE_KEYS.MAX_PRICE, TABLE_KEYS.SPECIES, "liveSex", "liveTransportMethod", "jurisdiction"];
22
+ export function StoreLiveItemsListing({ storeId, initialData }) {
23
+ const table = useUrlTable({ defaults: { pageSize: "24", sort: DEFAULT_SORT } });
24
+ const [searchInput, setSearchInput] = useState(table.get("q") || "");
25
+ const [filterOpen, setFilterOpen] = useState(false);
26
+ const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onResetAll, onFilterReset } = usePendingTable(table, FILTER_KEYS);
27
+ const openFilters = useCallback(() => { onFilterReset(); setFilterOpen(true); }, [onFilterReset]);
28
+ const applyFilters = useCallback(() => { onFilterApply(); setFilterOpen(false); }, [onFilterApply]);
29
+ const resetAll = useCallback(() => { onResetAll({ q: "", sort: "" }); setSearchInput(""); }, [onResetAll]);
30
+ const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || filterActiveCount > 0;
31
+ const params = {
32
+ q: table.get("q") || undefined,
33
+ minPrice: table.get(TABLE_KEYS.MIN_PRICE) ? Number(table.get(TABLE_KEYS.MIN_PRICE)) : undefined,
34
+ maxPrice: table.get(TABLE_KEYS.MAX_PRICE) ? Number(table.get(TABLE_KEYS.MAX_PRICE)) : undefined,
35
+ sort: table.get("sort") || DEFAULT_SORT,
36
+ page: table.getNumber("page", 1),
37
+ perPage: table.getNumber("pageSize", 24),
38
+ storeId: storeId || undefined,
39
+ listingType: "live",
40
+ };
41
+ const { products, totalPages, page, isLoading } = useProducts(params, { initialData });
42
+ const gridClass = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4";
43
+ return (_jsxs(Div, { className: "min-h-[200px]", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search live animals & plants\u2026", onSearchChange: setSearchInput, onSearchCommit: () => table.set("q", searchInput.trim()), sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => table.set("sort", v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: _jsx(Div, { className: gridClass, children: isLoading
44
+ ? Array.from({ length: 8 }).map((_, i) => _jsx(Div, { surface: "muted", rounded: "xl", className: "aspect-square animate-pulse" }, i))
45
+ : products.length === 0
46
+ ? _jsx(Div, { paddingY: "y-4xl", className: "col-span-full text-center", children: _jsx(Text, { color: "muted", children: "No live items in this store yet." }) })
47
+ : products.map((p) => (_jsx(InteractiveProductCard, { product: p, href: String(ROUTES.PUBLIC.LIVE_DETAIL(p.slug ?? p.id)) }, p.id))) }) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(LiveItemFilters, { table: pendingTable, currencyPrefix: "\u20B9" }) })] }));
48
+ }
@@ -0,0 +1,4 @@
1
+ export interface StoreLiveItemsPageViewProps {
2
+ storeSlug: string;
3
+ }
4
+ export declare function StoreLiveItemsPageView({ storeSlug }: StoreLiveItemsPageViewProps): Promise<import("react/jsx-runtime").JSX.Element | null>;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { sieveFilter, sieveAnd, SIEVE_OP, sortBy, PRODUCT_FIELDS } from "@mohasinac/appkit";
3
+ import { productRepository } from "../../../repositories";
4
+ import { getStoreBySlug } from "./StoreDetailLayoutView";
5
+ import { StoreLiveItemsListing } from "./StoreLiveItemsListing";
6
+ export async function StoreLiveItemsPageView({ storeSlug }) {
7
+ const store = await getStoreBySlug(storeSlug);
8
+ const storeId = store?.id;
9
+ if (!storeId)
10
+ return null;
11
+ const result = await productRepository
12
+ .list({
13
+ filters: sieveAnd(sieveFilter("storeId", SIEVE_OP.EQ, storeId), sieveFilter("status", SIEVE_OP.EQ, "published"), sieveFilter("listingType", SIEVE_OP.EQ, "live")),
14
+ sorts: sortBy(PRODUCT_FIELDS.CREATED_AT),
15
+ page: 1,
16
+ pageSize: 24,
17
+ })
18
+ .catch(() => null);
19
+ return _jsx(StoreLiveItemsListing, { storeId: storeId, initialData: result ?? undefined });
20
+ }
@@ -26,6 +26,15 @@ export type { StorePreOrdersListingProps } from "./StorePreOrdersListing";
26
26
  export type { StorePreOrdersPageViewProps } from "./StorePreOrdersPageView";
27
27
  export type { StorePrizeDrawsPageViewProps } from "./StorePrizeDrawsPageView";
28
28
  export type { StoreBundlesPageViewProps } from "./StoreBundlesPageView";
29
+ export { StoreClassifiedsListing } from "./StoreClassifiedsListing";
30
+ export type { StoreClassifiedsListingProps } from "./StoreClassifiedsListing";
31
+ export type { StoreClassifiedsPageViewProps } from "./StoreClassifiedsPageView";
32
+ export { StoreDigitalCodesListing } from "./StoreDigitalCodesListing";
33
+ export type { StoreDigitalCodesListingProps } from "./StoreDigitalCodesListing";
34
+ export type { StoreDigitalCodesPageViewProps } from "./StoreDigitalCodesPageView";
35
+ export { StoreLiveItemsListing } from "./StoreLiveItemsListing";
36
+ export type { StoreLiveItemsListingProps } from "./StoreLiveItemsListing";
37
+ export type { StoreLiveItemsPageViewProps } from "./StoreLiveItemsPageView";
29
38
  export { StoreGuideHubView } from "./StoreGuideHubView";
30
39
  export type { StoreGuideHubViewProps } from "./StoreGuideHubView";
31
40
  export { StoreListingsGuideView } from "./StoreListingsGuideView";
@@ -11,6 +11,9 @@ export { StoreProductsListing } from "./StoreProductsListing";
11
11
  export { StoreAuctionsListing } from "./StoreAuctionsListing";
12
12
  export { StoreReviewsListing } from "./StoreReviewsListing";
13
13
  export { StorePreOrdersListing } from "./StorePreOrdersListing";
14
+ export { StoreClassifiedsListing } from "./StoreClassifiedsListing";
15
+ export { StoreDigitalCodesListing } from "./StoreDigitalCodesListing";
16
+ export { StoreLiveItemsListing } from "./StoreLiveItemsListing";
14
17
  export { StoreGuideHubView } from "./StoreGuideHubView";
15
18
  export { StoreListingsGuideView } from "./StoreListingsGuideView";
16
19
  export { StoreOrdersGuideView } from "./StoreOrdersGuideView";
@@ -5,6 +5,7 @@
5
5
  * and helpers for the stores feature.
6
6
  */
7
7
  import type { StoreCapability } from "../../auth/permissions/constants";
8
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
8
9
  export type ShippingProviderType = "shiprocket" | "self-courier" | "store-pickup" | "custom";
9
10
  export interface ShippingProviderConfig {
10
11
  /** Stable slug — never changes after creation. */
@@ -46,8 +47,7 @@ export declare const StoreStatusValues: {
46
47
  readonly REJECTED: "rejected";
47
48
  };
48
49
  export type StoreStatus = (typeof StoreStatusValues)[keyof typeof StoreStatusValues];
49
- export interface StoreDocument {
50
- id: string;
50
+ export interface StoreDocument extends BaseDocument {
51
51
  storeSlug: string;
52
52
  ownerId: string;
53
53
  storeName: string;
@@ -123,8 +123,6 @@ export interface StoreDocument {
123
123
  /** When the seller first connected their account */
124
124
  connectedAt?: Date;
125
125
  };
126
- createdAt: Date;
127
- updatedAt: Date;
128
126
  }
129
127
  export type { StoreCapability } from "../../auth/permissions/constants";
130
128
  export declare const STORE_COLLECTION: "stores";
@@ -405,8 +405,8 @@ export declare const storeFirestoreSchema: z.ZodObject<{
405
405
  createdAt: string | Date | z.objectOutputType<{
406
406
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
407
407
  }, z.ZodTypeAny, "passthrough">;
408
- id: string;
409
408
  storeName: string;
409
+ id: string;
410
410
  updatedAt: string | Date | z.objectOutputType<{
411
411
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
412
412
  }, z.ZodTypeAny, "passthrough">;
@@ -489,8 +489,8 @@ export declare const storeFirestoreSchema: z.ZodObject<{
489
489
  createdAt: string | Date | z.objectInputType<{
490
490
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
491
491
  }, z.ZodTypeAny, "passthrough">;
492
- id: string;
493
492
  storeName: string;
493
+ id: string;
494
494
  updatedAt: string | Date | z.objectInputType<{
495
495
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
496
496
  }, z.ZodTypeAny, "passthrough">;
@@ -603,8 +603,8 @@ export declare const storeListItemSchema: z.ZodObject<{
603
603
  createdAt: z.ZodOptional<z.ZodString>;
604
604
  }, "strip", z.ZodTypeAny, {
605
605
  status: string;
606
- id: string;
607
606
  storeName: string;
607
+ id: string;
608
608
  isPublic: boolean;
609
609
  storeSlug: string;
610
610
  ownerId: string;
@@ -619,8 +619,8 @@ export declare const storeListItemSchema: z.ZodObject<{
619
619
  averageRating?: number | undefined;
620
620
  }, {
621
621
  status: string;
622
- id: string;
623
622
  storeName: string;
623
+ id: string;
624
624
  isPublic: boolean;
625
625
  storeSlug: string;
626
626
  ownerId: string;
@@ -14,6 +14,7 @@
14
14
  * - No creation if user has create_support_tickets soft ban
15
15
  * - No new ticket in the same category while existing one is waiting_on_user
16
16
  */
17
+ import type { BaseDocument } from "../../../_internal/shared/types/base-document";
17
18
  export declare const TicketCategoryValues: {
18
19
  readonly ORDER_ISSUE: "order_issue";
19
20
  readonly BILLING_PAYMENT: "billing_payment";
@@ -70,8 +71,7 @@ export interface TicketRelatedParties {
70
71
  productId?: string;
71
72
  bidId?: string;
72
73
  }
73
- export interface SupportTicketDocument {
74
- id: string;
74
+ export interface SupportTicketDocument extends BaseDocument {
75
75
  userId: string;
76
76
  /** Denormalized — for admin table display. */
77
77
  userEmail: string;
@@ -103,8 +103,6 @@ export interface SupportTicketDocument {
103
103
  messages: TicketMessage[];
104
104
  resolvedAt?: Date;
105
105
  closedAt?: Date;
106
- createdAt: Date;
107
- updatedAt: Date;
108
106
  }
109
107
  export type SupportTicketCreateInput = Pick<SupportTicketDocument, "userId" | "userEmail" | "userDisplayName" | "category" | "subject" | "description" | "orderId">;
110
108
  export type SupportTicketUpdateInput = Partial<Pick<SupportTicketDocument, "status" | "priority" | "assignedTo" | "assignedToName" | "internalNotes" | "resolvedAt" | "closedAt" | "relatedParties">>;
@@ -154,8 +154,8 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
154
154
  createdAt: string | Date | z.objectOutputType<{
155
155
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
156
156
  }, z.ZodTypeAny, "passthrough">;
157
- id: string;
158
157
  description: string;
158
+ id: string;
159
159
  updatedAt: string | Date | z.objectOutputType<{
160
160
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
161
161
  }, z.ZodTypeAny, "passthrough">;
@@ -197,8 +197,8 @@ export declare const supportTicketFirestoreSchema: z.ZodObject<{
197
197
  createdAt: string | Date | z.objectInputType<{
198
198
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
199
199
  }, z.ZodTypeAny, "passthrough">;
200
- id: string;
201
200
  description: string;
201
+ id: string;
202
202
  updatedAt: string | Date | z.objectInputType<{
203
203
  toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
204
204
  }, z.ZodTypeAny, "passthrough">;
@@ -41,6 +41,9 @@ export declare const DEFAULT_ROUTE_MAP: {
41
41
  readonly STORE_REVIEWS: (storeSlug: string) => string;
42
42
  readonly STORE_ABOUT: (storeSlug: string) => string;
43
43
  readonly STORE_COUPONS: (storeSlug: string) => string;
44
+ readonly STORE_CLASSIFIEDS: (storeSlug: string) => string;
45
+ readonly STORE_DIGITAL_CODES: (storeSlug: string) => string;
46
+ readonly STORE_LIVE: (storeSlug: string) => string;
44
47
  readonly CATEGORIES: "/categories";
45
48
  readonly CATEGORY_DETAIL: (slug: string) => string;
46
49
  readonly BRANDS: "/brands";
@@ -196,6 +199,7 @@ export declare const DEFAULT_ROUTE_MAP: {
196
199
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
197
200
  readonly PRINT_CENTER: "/store/print-center";
198
201
  readonly INVENTORY_PRINT: "/store/inventory/print";
202
+ readonly FULFILLMENT: "/store/fulfillment";
199
203
  readonly PAYOUT_METHODS: "/store/payout-methods";
200
204
  readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
201
205
  readonly PAYOUT_METHODS_EDIT: (id: string) => string;
@@ -305,6 +309,7 @@ export declare const DEFAULT_ROUTE_MAP: {
305
309
  readonly SETTINGS_ACTIONS: "/admin/settings/actions";
306
310
  readonly SETTINGS_NAVIGATION: "/admin/settings/navigation";
307
311
  readonly PRINT_CENTER: "/admin/print-center";
312
+ readonly FULFILLMENT: "/admin/fulfillment";
308
313
  readonly MODERATION: "/admin/moderation";
309
314
  readonly MODERATION_DETAIL: (id: string) => string;
310
315
  readonly REPORTS: "/admin/reports";
@@ -366,6 +371,9 @@ export declare const ROUTES: {
366
371
  readonly STORE_REVIEWS: (storeSlug: string) => string;
367
372
  readonly STORE_ABOUT: (storeSlug: string) => string;
368
373
  readonly STORE_COUPONS: (storeSlug: string) => string;
374
+ readonly STORE_CLASSIFIEDS: (storeSlug: string) => string;
375
+ readonly STORE_DIGITAL_CODES: (storeSlug: string) => string;
376
+ readonly STORE_LIVE: (storeSlug: string) => string;
369
377
  readonly CATEGORIES: "/categories";
370
378
  readonly CATEGORY_DETAIL: (slug: string) => string;
371
379
  readonly BRANDS: "/brands";
@@ -521,6 +529,7 @@ export declare const ROUTES: {
521
529
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
522
530
  readonly PRINT_CENTER: "/store/print-center";
523
531
  readonly INVENTORY_PRINT: "/store/inventory/print";
532
+ readonly FULFILLMENT: "/store/fulfillment";
524
533
  readonly PAYOUT_METHODS: "/store/payout-methods";
525
534
  readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
526
535
  readonly PAYOUT_METHODS_EDIT: (id: string) => string;
@@ -630,6 +639,7 @@ export declare const ROUTES: {
630
639
  readonly SETTINGS_ACTIONS: "/admin/settings/actions";
631
640
  readonly SETTINGS_NAVIGATION: "/admin/settings/navigation";
632
641
  readonly PRINT_CENTER: "/admin/print-center";
642
+ readonly FULFILLMENT: "/admin/fulfillment";
633
643
  readonly MODERATION: "/admin/moderation";
634
644
  readonly MODERATION_DETAIL: (id: string) => string;
635
645
  readonly REPORTS: "/admin/reports";
@@ -715,6 +725,7 @@ export declare const SELLER_ROUTES: {
715
725
  readonly LIVE_ITEMS_EDIT: (id: string) => string;
716
726
  readonly PRINT_CENTER: "/store/print-center";
717
727
  readonly INVENTORY_PRINT: "/store/inventory/print";
728
+ readonly FULFILLMENT: "/store/fulfillment";
718
729
  readonly PAYOUT_METHODS: "/store/payout-methods";
719
730
  readonly PAYOUT_METHODS_NEW: "/store/payout-methods/new";
720
731
  readonly PAYOUT_METHODS_EDIT: (id: string) => string;
@@ -29,6 +29,9 @@ export const DEFAULT_ROUTE_MAP = {
29
29
  STORE_REVIEWS: (storeSlug) => `/stores/${storeSlug}/reviews`,
30
30
  STORE_ABOUT: (storeSlug) => `/stores/${storeSlug}/about`,
31
31
  STORE_COUPONS: (storeSlug) => `/stores/${storeSlug}/coupons`,
32
+ STORE_CLASSIFIEDS: (storeSlug) => `/stores/${storeSlug}/classified`,
33
+ STORE_DIGITAL_CODES: (storeSlug) => `/stores/${storeSlug}/digital-codes`,
34
+ STORE_LIVE: (storeSlug) => `/stores/${storeSlug}/live`,
32
35
  CATEGORIES: "/categories",
33
36
  CATEGORY_DETAIL: (slug) => `/categories/${slug}`,
34
37
  BRANDS: "/brands",
@@ -186,6 +189,7 @@ export const DEFAULT_ROUTE_MAP = {
186
189
  LIVE_ITEMS_EDIT: (id) => `/store/live/${id}/edit`,
187
190
  PRINT_CENTER: "/store/print-center",
188
191
  INVENTORY_PRINT: "/store/inventory/print",
192
+ FULFILLMENT: "/store/fulfillment",
189
193
  // S-STORE Tier — new extension routes
190
194
  PAYOUT_METHODS: "/store/payout-methods",
191
195
  PAYOUT_METHODS_NEW: "/store/payout-methods/new",
@@ -299,6 +303,7 @@ export const DEFAULT_ROUTE_MAP = {
299
303
  SETTINGS_ACTIONS: "/admin/settings/actions",
300
304
  SETTINGS_NAVIGATION: "/admin/settings/navigation",
301
305
  PRINT_CENTER: "/admin/print-center",
306
+ FULFILLMENT: "/admin/fulfillment",
302
307
  // S-STORE Tier — admin moderation + reports + item requests
303
308
  MODERATION: "/admin/moderation",
304
309
  MODERATION_DETAIL: (id) => `/admin/moderation/${id}`,