@mohasinac/appkit 4.9.5 → 4.10.0

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 (108) hide show
  1. package/dist/_internal/server/features/auctions/actions.js +3 -2
  2. package/dist/_internal/server/features/auctions/service.d.ts +4 -3
  3. package/dist/_internal/server/features/auctions/service.js +6 -6
  4. package/dist/_internal/server/features/bundles/data.d.ts +9 -0
  5. package/dist/_internal/server/features/bundles/data.js +14 -0
  6. package/dist/_internal/server/features/bundles/index.d.ts +1 -1
  7. package/dist/_internal/server/features/bundles/index.js +1 -1
  8. package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
  9. package/dist/_internal/server/features/catalogue/og.js +27 -0
  10. package/dist/_internal/server/features/grouped/data.d.ts +12 -0
  11. package/dist/_internal/server/features/grouped/data.js +26 -1
  12. package/dist/_internal/server/features/grouped/index.d.ts +1 -1
  13. package/dist/_internal/server/features/grouped/index.js +1 -1
  14. package/dist/_internal/server/features/products/data.d.ts +23 -0
  15. package/dist/_internal/server/features/products/data.js +159 -0
  16. package/dist/_internal/server/features/products/index.d.ts +1 -1
  17. package/dist/_internal/server/features/products/index.js +1 -1
  18. package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
  19. package/dist/_internal/shared/features/auctions/config.js +31 -1
  20. package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
  21. package/dist/_internal/shared/listing-types/art/config.js +1 -1
  22. package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
  23. package/dist/_internal/shared/listing-types/classified/config.js +1 -1
  24. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
  25. package/dist/_internal/shared/listing-types/digital-code/config.js +1 -1
  26. package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
  27. package/dist/_internal/shared/listing-types/live/config.js +1 -1
  28. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
  29. package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
  30. package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
  31. package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
  32. package/dist/client.d.ts +0 -6
  33. package/dist/client.js +1 -4
  34. package/dist/constants/api-endpoints.d.ts +3 -0
  35. package/dist/constants/api-endpoints.js +1 -0
  36. package/dist/features/admin/components/AdminSiteSettingsView.js +12 -4
  37. package/dist/features/admin/schemas/firestore.d.ts +9 -0
  38. package/dist/features/admin/schemas/firestore.js +6 -0
  39. package/dist/features/auctions/actions/bid-actions.js +4 -1
  40. package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
  41. package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
  42. package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
  43. package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
  44. package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
  45. package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
  46. package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
  47. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
  48. package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
  49. package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
  50. package/dist/features/catalogue/index.d.ts +2 -0
  51. package/dist/features/catalogue/index.js +1 -0
  52. package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
  53. package/dist/features/categories/components/BundleDetailView.js +3 -2
  54. package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
  55. package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
  56. package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
  57. package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
  58. package/dist/features/contact/components/ContactPageView.js +8 -2
  59. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
  60. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
  61. package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
  62. package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
  63. package/dist/features/grouped/repository/grouped-listings.repository.d.ts +8 -0
  64. package/dist/features/grouped/repository/grouped-listings.repository.js +16 -0
  65. package/dist/features/layout/BottomActions.js +4 -3
  66. package/dist/features/layout/BottomActionsContext.d.ts +10 -0
  67. package/dist/features/layout/BottomActionsContext.js +5 -1
  68. package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
  69. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  70. package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
  71. package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
  72. package/dist/features/media/MediaVideo.js +17 -1
  73. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
  74. package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
  75. package/dist/features/products/components/ProductDetailPageView.js +11 -116
  76. package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
  77. package/dist/features/products/components/RelatedItemsSection.js +17 -0
  78. package/dist/features/seller/components/SellerProductShell.js +1 -1
  79. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +83 -3
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.js +1 -0
  82. package/dist/next/routing/route-map.d.ts +2 -0
  83. package/dist/next/routing/route-map.js +7 -0
  84. package/dist/seed/bids-seed-data.js +48 -3
  85. package/dist/seed/grouped-listings-seed-data.js +167 -0
  86. package/dist/seed/payouts-seed-data.js +4 -4
  87. package/dist/seed/products-art-seed-data.js +188 -5
  88. package/dist/seed/products-auctions-seed-data.js +215 -6
  89. package/dist/seed/products-classifieds-seed-data.js +255 -8
  90. package/dist/seed/products-digital-codes-seed-data.js +258 -19
  91. package/dist/seed/products-live-items-seed-data.js +143 -10
  92. package/dist/seed/products-preorders-seed-data.js +213 -8
  93. package/dist/seed/products-prize-draws-seed-data.js +198 -0
  94. package/dist/seed/products-standard-seed-data.js +141 -0
  95. package/dist/seed/products-stickers-seed-data.js +178 -5
  96. package/dist/seed/site-settings-seed-data.js +10 -29
  97. package/dist/seed/store-extensions-seed-data.js +1 -1
  98. package/dist/server-entry.d.ts +4 -1
  99. package/dist/server-entry.js +4 -1
  100. package/dist/server.d.ts +4 -2
  101. package/dist/server.js +4 -2
  102. package/dist/styles.css +29 -1
  103. package/dist/tailwind-utilities.css +1 -1
  104. package/dist/ui/components/ImageLightbox.js +37 -3
  105. package/dist/ui/components/ImageLightbox.style.css +28 -0
  106. package/dist/utils/media-url.d.ts +9 -0
  107. package/dist/utils/media-url.js +39 -0
  108. package/package.json +1 -1
@@ -55,7 +55,29 @@ const rawTesterChecklistItems = [
55
55
  cases: [
56
56
  { key: "email-signup", label: "Sign up with email works", href: "/auth/register" },
57
57
  { key: "google-oauth", label: "Sign up / log in with Google works", href: "/auth/login" },
58
- { key: "google-link-existing", label: "Linking Google sign-in to an existing email/password account works" },
58
+ {
59
+ key: "google-link-existing",
60
+ label: "Signing in with Google using the SAME email as an existing password account logs into that same account automatically — no duplicate account, no explicit linking needed",
61
+ description: "This is the auto-merge path: register with email/password (email A), log out, then \"Sign in with Google\" using a Google account whose email is also A. You should land back in the same account (same orders/wishlist/etc.), and Settings > Account tab should now show Google as Connected.",
62
+ href: "/auth/login",
63
+ },
64
+ {
65
+ key: "google-link-different-email",
66
+ label: "Linking a Google account whose email differs from your original signup email requires the explicit \"Connect Google\" button (My Account dashboard or Settings > Account tab) — it does not happen automatically just by signing in with Google",
67
+ description: "Sign up/log in normally with email A (password). While logged in as A, use the \"Connect Google\" button and complete the popup with a Google account using a DIFFERENT email B. Afterward, Settings > Account tab should show Google as Connected with email B, while your account's primary login email is still A — the account now has two associated emails, not a second account.",
68
+ href: "/user/settings",
69
+ },
70
+ {
71
+ key: "google-link-confirmation-shown",
72
+ label: "After Google is connected, the My Account dashboard shows a \"Google account connected\" confirmation with a Connected badge and your linked email — it does not just silently stop showing the \"Connect Google\" prompt",
73
+ description: "Fixed 2026-08-20 — the /user dashboard only ever handled the unlinked case; once linked, the whole alert block disappeared with no confirmation, unlike Settings > Account tab which already showed a Connected badge. Link a Google account (or use an already-linked test account) and confirm the green confirmation alert appears on /user, not just an absence of the blue prompt.",
74
+ href: "/user",
75
+ },
76
+ {
77
+ key: "google-link-conflict-rejected",
78
+ label: "Trying to link a Google account whose email is already used by a DIFFERENT existing account is rejected with a clear error — it does not silently merge the two accounts or move the email over",
79
+ href: "/user/settings",
80
+ },
59
81
  { key: "google-popup-blocked-fallback", label: "If the Google sign-in popup is blocked, the fallback (RTDB signal + postMessage) still completes sign-in" },
60
82
  { key: "login", label: "Log in with email + password works", href: "/auth/login" },
61
83
  { key: "logout", label: "Log out works and clears the session" },
@@ -188,7 +210,11 @@ const rawTesterChecklistItems = [
188
210
  pageLabel: "Product / Auction / Pre-order Detail",
189
211
  cases: [
190
212
  { key: "standard-detail", label: "Standard product detail page loads correctly" },
191
- { key: "auction-detail", label: "Auction detail page shows current bid + countdown correctly" },
213
+ {
214
+ key: "auction-detail",
215
+ label: "Auction detail page shows current bid + a live, ticking countdown correctly",
216
+ description: "The countdown (\"Ends in 2d 5h 30m\", ticking every second — not a static date) must appear directly above every \"Place a bid\" button: the info panel, the desktop and mobile compact bid-summary cards, inside the \"Place your bid\" modal above the submit button, and in the mobile sticky bottom bar (as a row above the current-bid/bid-count line). It should switch to \"Ended\" once the end time passes.",
217
+ },
192
218
  { key: "preorder-detail", label: "Pre-order detail page shows expected ship date correctly" },
193
219
  {
194
220
  key: "image-gallery",
@@ -267,6 +293,24 @@ const rawTesterChecklistItems = [
267
293
  label: "Choosing manual payment (UPI/Cash) at checkout shows a how-it-works guide (payment steps, refund summary, what happens if an item sells out) and requires a consent checkbox before the \"Pay via UPI / Cash\" button becomes clickable",
268
294
  href: "/checkout",
269
295
  },
296
+ {
297
+ key: "checkout-cash-payment-no-validation-error",
298
+ label: "Checking the consent box and clicking \"Pay via UPI / Cash\" places the order successfully — no red \"Validation failed\" error appears",
299
+ description: "Fixed 2026-08-20 — the checkout API's schema only accepted paymentMethod \"cod\"/\"online\"/\"upi_manual\"/\"emi\"; the manual-payment button has always sent \"cash\", which was never in that list, so every attempt was rejected with a generic \"Validation failed\" message even with the out-of-stock policy and consent checkbox correctly filled in. Add items to cart, reach the payment step, check the consent box, and click \"Pay via UPI / Cash\" — confirm it succeeds and lands on the order confirmation / payment-proof page.",
300
+ href: "/checkout",
301
+ },
302
+ {
303
+ key: "checkout-order-summary-full-breakdown",
304
+ label: "The checkout Order Summary panel shows Shipping, COD handling fee (when COD is the likely method), the selected add-on fees (WhatsApp updates / gift wrap / shipment protection — only the ones checked), GST (when enabled), and Coupon discount as separate line items with icons before you pay — not just Subtotal and Total",
305
+ description: "Fixed 2026-08-20 — the Order Summary previously showed Total = Subtotal − coupon discount only; shipping and every fee were computed and charged server-side but never shown to the buyer beforehand. Reach the payment step with an address selected, toggle an add-on checkbox, and confirm the matching line appears in the summary a moment later and the Total updates to match — then confirm the same Total appears on the order confirmation page afterward.",
306
+ href: "/checkout",
307
+ },
308
+ {
309
+ key: "checkout-razorpay-charge-includes-shipping",
310
+ label: "When Razorpay online payment is enabled, the amount charged in the Razorpay checkout modal matches the order's recorded Total exactly, including shipping fee",
311
+ description: "Fixed 2026-08-20 — the Razorpay pre-charge amount (computed before opening the payment modal) omitted the seller's shipping fee entirely, while the order created afterward recorded a higher total that included it, so the buyer was silently charged less via the gateway than what got recorded as owed. Only testable when Site Settings → Payments → Razorpay is enabled and the seller has a configured shipping fee. Compare the amount shown in the Razorpay modal against the order's Total on the confirmation page — they should match exactly.",
312
+ href: "/checkout",
313
+ },
270
314
  ],
271
315
  },
272
316
  {
@@ -308,6 +352,20 @@ const rawTesterChecklistItems = [
308
352
  { key: "win-auction", label: "Winning an auction creates a payable order correctly" },
309
353
  { key: "bid-history", label: "My Bids page shows accurate bid history, paginated with the most recent bid first", href: "/user/bids" },
310
354
  { key: "bid-history-auction-detail-pagination", label: "An auction detail page's Bid History section shows the most recent bid first and paginates once there are more bids than fit on one page (try the L-Drago auction — 13 seeded bids)" },
355
+ {
356
+ key: "bid-increment-tiered",
357
+ label: "The \"min increment\" shown on an auction matches the admin-configured tier for the current bid amount, not a flat ₹1 — and a bid below that increment is rejected",
358
+ description: "Default tiers: current bid ≤₹100 → ₹10 increment, ≤₹1,000 → ₹100, ≤₹5,000 → ₹200, ≤₹10,000 → ₹500, above that → ₹1,000. On an auction with no per-listing \"Minimum Bid Increment\" set, confirm the displayed \"min increment\" matches the tier for its current bid, and that trying to bid only current+1 (below the tier) is rejected with a minimum-increment error, while current+tier (or more) is accepted.",
359
+ },
360
+ {
361
+ key: "bid-increment-override-floor-raising",
362
+ label: "A seller's per-listing \"Minimum Bid Increment\" can require MORE than the admin tier, but can never let a bid undercut the tier",
363
+ description: "Set a listing's \"Minimum Bid Increment\" below the current tier's value (e.g. 1) and confirm the effective minimum bid still enforces the tier, not the smaller override. Then set it above the tier (e.g. 500 when the tier is 100) and confirm the higher override is now enforced instead.",
364
+ },
365
+ {
366
+ key: "bid-increment-live-tier-change",
367
+ label: "The displayed \"min increment\" on an open auction updates live (without a page refresh) if another bidder's bid pushes the current bid across a tier boundary",
368
+ },
311
369
  ],
312
370
  },
313
371
  {
@@ -770,6 +828,12 @@ const rawTesterChecklistItems = [
770
828
  pageLabel: "Footer & Dark Mode",
771
829
  cases: [
772
830
  { key: "footer-dark-mode", label: "Footer background and all link/text colors switch correctly between light and dark mode", href: "/" },
831
+ {
832
+ key: "footer-github-icon",
833
+ label: "The footer's social icon row (brand column, bottom-left) shows a GitHub icon alongside Instagram/Twitter/WhatsApp, and clicking it opens the developer's real GitHub profile in a new tab",
834
+ description: "Added 2026-08-20 — GITHUB was a new socialUrls key with no footer icon before this. Confirm the icon renders (not a broken/missing glyph) and the link target is a real, working github.com profile, not a placeholder or dead link.",
835
+ href: "/",
836
+ },
773
837
  ],
774
838
  },
775
839
  {
@@ -807,7 +871,17 @@ const rawTesterChecklistItems = [
807
871
  cases: [
808
872
  { key: "homepage-loads", label: "The homepage loads without errors on both desktop and mobile", href: "/" },
809
873
  { key: "about-us-in-main-nav", label: "\"About Us\" appears as an item in the main public top navigation, not just the footer", href: "/about" },
810
- { key: "developer-page-loads", label: "The Developer page loads correctly and is linked from the footer's Support column next to About Us", href: "/developer" },
874
+ {
875
+ key: "about-team-real-founder",
876
+ label: "The About page's \"Who's Behind LetItRip\" team section shows the real founder's name (not a placeholder persona) and a working \"GitHub ↗\" link on their card",
877
+ description: "Updated 2026-08-20 — the founder card previously used a fictional placeholder name with no GitHub link. Confirm the founder card's name matches the real developer and the GitHub link opens their actual profile.",
878
+ href: "/about",
879
+ },
880
+ {
881
+ key: "developer-page-loads",
882
+ label: "The Developer page loads correctly, is linked from the footer's Support column next to About Us, shows the real developer's name, and its \"GitHub ↗\" link opens their actual GitHub profile",
883
+ href: "/developer",
884
+ },
811
885
  { key: "products-listing-page", label: "The products listing page loads and paginates correctly", href: "/products" },
812
886
  { key: "auctions-listing-page", label: "The auctions listing page loads correctly", href: "/auctions" },
813
887
  { key: "preorders-listing-page", label: "The pre-orders listing page loads correctly", href: "/pre-orders" },
@@ -1048,6 +1122,12 @@ const rawTesterChecklistItems = [
1048
1122
  pageLabel: "Site & System",
1049
1123
  cases: [
1050
1124
  { key: "site-settings-admin", label: "Admin site settings page saves correctly", href: "/admin/site" },
1125
+ {
1126
+ key: "auction-bid-tiers-admin",
1127
+ label: "Admin can add, edit, and remove bid-increment tiers in Site Settings → Auction Config, and the changes persist after saving and reloading the page",
1128
+ description: "Each tier row has an editable \"up to (₹)\" amount and \"increment (₹)\" amount; the last row is fixed as \"and above\" (open-ended) and can't have its threshold edited. Add a new tier, edit an existing increment, remove a tier, save, then reload the Site Settings page and confirm the tier list matches what was saved — not reverted to the old defaults.",
1129
+ href: "/admin/site",
1130
+ },
1051
1131
  { key: "admin-dashboard-widgets", label: "Admin dashboard widgets show accurate data", href: "/admin/dashboard" },
1052
1132
  { key: "analytics-admin", label: "Admin analytics dashboard shows accurate data", href: "/admin/analytics" },
1053
1133
  { key: "maintenance-pages-admin", label: "The maintenance pages (analysis, client-errors, cloud-logs, function-errors, payment-rollbacks, server-errors + detail) all load correctly", href: "/admin/maintenance" },
package/dist/index.d.ts CHANGED
@@ -2321,6 +2321,8 @@ export { CatalogueItemEditorView } from "./features/catalogue/index";
2321
2321
  export type { CatalogueItemEditorViewProps } from "./features/catalogue/index";
2322
2322
  export { PublicCatalogueView } from "./features/catalogue/index";
2323
2323
  export type { PublicCatalogueViewProps } from "./features/catalogue/index";
2324
+ export { PublicCatalogueItemDetailView } from "./features/catalogue/index";
2325
+ export type { PublicCatalogueItemDetailViewProps } from "./features/catalogue/index";
2324
2326
  export { AdminCatalogueApprovalsView } from "./features/catalogue/index";
2325
2327
  export { PAYOUT_FIELDS } from "./features/payments/index";
2326
2328
  export { PAYOUT_INDEXED_FIELDS } from "./features/payments/index";
package/dist/index.js CHANGED
@@ -4215,6 +4215,7 @@ export { approveCatalogueListingAction, rejectCatalogueListingAction, } from "./
4215
4215
  export { UserCatalogueView } from "./features/catalogue/index";
4216
4216
  export { CatalogueItemEditorView } from "./features/catalogue/index";
4217
4217
  export { PublicCatalogueView } from "./features/catalogue/index";
4218
+ export { PublicCatalogueItemDetailView } from "./features/catalogue/index";
4218
4219
  export { AdminCatalogueApprovalsView } from "./features/catalogue/index";
4219
4220
  // [SCHEMA]-Schema / data-shape constant â€" Zod validator, default-value object, or Firestore collection/field name constant.
4220
4221
  // PAYOUT_FIELDS - Constant used across modules.
@@ -105,6 +105,7 @@ export declare const DEFAULT_ROUTE_MAP: {
105
105
  readonly LIVE: "/live";
106
106
  readonly LIVE_DETAIL: (slug: string) => string;
107
107
  readonly ART: "/art";
108
+ readonly CATALOGUE_ITEM_DETAIL: (ownerSlug: string, itemId: string) => string;
108
109
  };
109
110
  readonly ERRORS: {
110
111
  readonly UNAUTHORIZED: "/unauthorized";
@@ -470,6 +471,7 @@ export declare const ROUTES: {
470
471
  readonly LIVE: "/live";
471
472
  readonly LIVE_DETAIL: (slug: string) => string;
472
473
  readonly ART: "/art";
474
+ readonly CATALOGUE_ITEM_DETAIL: (ownerSlug: string, itemId: string) => string;
473
475
  };
474
476
  readonly ERRORS: {
475
477
  readonly UNAUTHORIZED: "/unauthorized";
@@ -99,6 +99,13 @@ export const DEFAULT_ROUTE_MAP = {
99
99
  // detail page stays PRODUCT_DETAIL (`/products/{slug}`), already wired in
100
100
  // `_internal/shared/listing-types/{art,stickers}/config.ts`.
101
101
  ART: "/art",
102
+ // Personal catalogue (Feature B) — a user's own photo inventory of owned
103
+ // items, distinct from marketplace listings. Public when the owner sets
104
+ // an item's visibility to "public". The owner's full catalogue listing
105
+ // already exists at PROFILE(userId)/catalogue (PublicProfileView's
106
+ // "Catalogue" tab) — this is only the per-item detail route, which had
107
+ // no page at all before this.
108
+ CATALOGUE_ITEM_DETAIL: (ownerSlug, itemId) => `/catalogue/${ownerSlug}/${itemId}`,
102
109
  },
103
110
  ERRORS: {
104
111
  UNAUTHORIZED: "/unauthorized",
@@ -45,14 +45,19 @@ function withBidDefaults(b) {
45
45
  updatedAt: (b.createdAt ?? NOW),
46
46
  };
47
47
  }
48
- /** One ascending bid ladder per auction — last entry is "active", the rest "outbid". */
48
+ /**
49
+ * One ascending bid ladder per auction. By default the last entry is "active"
50
+ * and the rest "outbid" (a live auction). Pass `closed:true` for an ended
51
+ * auction — the last entry becomes "won" and the rest "lost".
52
+ */
49
53
  function buildLadder(params) {
50
- const { productId, productTitle, startingBid, currentBid, bidderIds } = params;
54
+ const { productId, productTitle, startingBid, currentBid, bidderIds, closed = false } = params;
51
55
  const steps = bidderIds.length;
52
56
  const range = currentBid - startingBid;
53
57
  return bidderIds.map((userId, i) => {
54
58
  const amount = i === steps - 1 ? currentBid : Math.round(startingBid + (range * (i + 1)) / (steps + 1));
55
59
  const daysBack = steps - i;
60
+ const isFinal = i === steps - 1;
56
61
  return {
57
62
  id: `bid-${productId.replace(/^auction-/, "")}-${userId.replace(/^user-/, "")}-20260601-${String(i).padStart(3, "0")}`,
58
63
  productId,
@@ -60,7 +65,7 @@ function buildLadder(params) {
60
65
  userId,
61
66
  userName: BIDDER_NAMES[userId] ?? userId,
62
67
  bidAmount: amount,
63
- status: i === steps - 1 ? "active" : "outbid",
68
+ status: isFinal ? (closed ? "won" : "active") : (closed ? "lost" : "outbid"),
64
69
  bidDate: daysAgo(daysBack),
65
70
  createdAt: daysAgo(daysBack),
66
71
  };
@@ -98,5 +103,45 @@ const _rawBidsSeedData = [
98
103
  "user-rohit-collector",
99
104
  ],
100
105
  }),
106
+ // auction-beyblade-original-seaborg — bidCount: 4, currentBid: 2200 (reserve 4000 not met)
107
+ ...buildLadder({
108
+ productId: "auction-beyblade-original-seaborg",
109
+ productTitle: "Beyblade Original — Seaborg 2000 (Reserve Auction)",
110
+ startingBid: 1499,
111
+ currentBid: 2200,
112
+ bidderIds: ["user-ananya-collector", "user-meera-bey", "user-rohit-collector", "user-ananya-collector"],
113
+ }),
114
+ // auction-beyblade-metal-diablo-nemesis — bidCount: 6, currentBid: 6200, CLOSED (won by user-rohit-collector)
115
+ ...buildLadder({
116
+ productId: "auction-beyblade-metal-diablo-nemesis",
117
+ productTitle: "Metal Fight Beyblade BB-122 Diablo Nemesis (Ended — Sold)",
118
+ startingBid: 3499,
119
+ currentBid: 6200,
120
+ bidderIds: [
121
+ "user-meera-bey",
122
+ "user-ananya-collector",
123
+ "user-meera-bey",
124
+ "user-ananya-collector",
125
+ "user-meera-bey",
126
+ "user-rohit-collector",
127
+ ],
128
+ closed: true,
129
+ }),
130
+ // auction-beyblade-burst-cho-z-achilles — bidCount: 2, currentBid: 1650
131
+ ...buildLadder({
132
+ productId: "auction-beyblade-burst-cho-z-achilles",
133
+ productTitle: "Beyblade Burst B-100 Cho-Z Achilles",
134
+ startingBid: 1199,
135
+ currentBid: 1650,
136
+ bidderIds: ["user-rohit-collector", "user-meera-bey"],
137
+ }),
138
+ // auction-beyblade-x-wizard-fafnir — bidCount: 3, currentBid: 1450
139
+ ...buildLadder({
140
+ productId: "auction-beyblade-x-wizard-fafnir",
141
+ productTitle: "Beyblade X BX-06 Wizard Fafnir (Long-Running Auction)",
142
+ startingBid: 999,
143
+ currentBid: 1450,
144
+ bidderIds: ["user-ananya-collector", "user-rohit-collector", "user-meera-bey"],
145
+ }),
101
146
  ];
102
147
  export const bidsSeedData = _rawBidsSeedData.map(withBidDefaults);
@@ -97,4 +97,171 @@ export const groupedListingsSeedData = [
97
97
  createdAt: daysAgo(15),
98
98
  updatedAt: daysAgo(3),
99
99
  },
100
+ // --- Coverage for every other listing type — previously only standard products had a
101
+ // group, so the public GroupedListingsCarousel (Phase 3) had nothing to render on
102
+ // any auction/pre-order/prize-draw/classified/digital-code/live/art/stickers page. ---
103
+ {
104
+ id: "group-beyblade-auction-highlights",
105
+ slug: "group-beyblade-auction-highlights",
106
+ title: "Auction Highlights",
107
+ description: "Two of the rarest pieces currently up for auction on Beyblade Arena.",
108
+ productIds: [
109
+ "auction-beyblade-original-dragoon-storm",
110
+ "auction-beyblade-metal-diablo-nemesis",
111
+ ],
112
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-auction-highlights-20260819/1200/900"),
113
+ groupTheme: "related",
114
+ minActiveMembers: 2,
115
+ activeMemberCount: 2,
116
+ visibilityStatus: "visible",
117
+ isActive: true,
118
+ isFeatured: false,
119
+ storeId: "store-beyblade-arena",
120
+ brandSlug: "brand-beyblade",
121
+ categorySlug: "category-spinning-tops",
122
+ createdBy: "user-admin-letitrip",
123
+ createdAt: daysAgo(6),
124
+ updatedAt: daysAgo(1),
125
+ },
126
+ {
127
+ id: "group-beyblade-x-preorder-wave",
128
+ slug: "group-beyblade-x-preorder-wave",
129
+ title: "Beyblade X Pre-Order Wave",
130
+ description: "Reserve your spot in the upcoming Beyblade X booster waves.",
131
+ productIds: [
132
+ "preorder-beyblade-x-bx-08-wave",
133
+ "preorder-beyblade-x-bx-09-glide-ring",
134
+ ],
135
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-x-preorder-wave-20260819/1200/900"),
136
+ groupTheme: "set",
137
+ minActiveMembers: 2,
138
+ activeMemberCount: 2,
139
+ visibilityStatus: "visible",
140
+ isActive: true,
141
+ isFeatured: false,
142
+ storeId: "store-beyblade-arena",
143
+ brandSlug: "brand-takara-tomy",
144
+ categorySlug: "category-beyblade-x",
145
+ createdBy: "user-admin-letitrip",
146
+ createdAt: daysAgo(5),
147
+ updatedAt: daysAgo(1),
148
+ },
149
+ {
150
+ id: "group-beyblade-mystery-draws",
151
+ slug: "group-beyblade-mystery-draws",
152
+ title: "Mystery Draws You Might Like",
153
+ description: "More prize draws with entries still open.",
154
+ productIds: [
155
+ "prizedraw-beyblade-mystery-box",
156
+ "prizedraw-beyblade-x-legendary-vault",
157
+ "prizedraw-beyblade-original-vintage-vault",
158
+ ],
159
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-mystery-draws-20260819/1200/900"),
160
+ groupTheme: "related",
161
+ minActiveMembers: 2,
162
+ activeMemberCount: 3,
163
+ visibilityStatus: "visible",
164
+ isActive: true,
165
+ isFeatured: true,
166
+ storeId: "store-letitrip-official",
167
+ brandSlug: "brand-beyblade",
168
+ categorySlug: "category-spinning-tops",
169
+ createdBy: "user-admin-letitrip",
170
+ createdAt: daysAgo(4),
171
+ updatedAt: daysAgo(1),
172
+ },
173
+ {
174
+ id: "group-beyblade-local-meetup-picks",
175
+ slug: "group-beyblade-local-meetup-picks",
176
+ title: "Local Meetup Picks",
177
+ description: "More classified listings from sellers open to meeting up.",
178
+ productIds: [
179
+ "classified-beyblade-stadium-set",
180
+ "classified-beyblade-burst-collection-bengaluru",
181
+ "classified-beyblade-x-starter-pune",
182
+ ],
183
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-local-meetup-picks-20260819/1200/900"),
184
+ groupTheme: "related",
185
+ minActiveMembers: 2,
186
+ activeMemberCount: 3,
187
+ visibilityStatus: "visible",
188
+ isActive: true,
189
+ isFeatured: false,
190
+ storeId: "store-beyblade-arena",
191
+ brandSlug: "brand-beyblade",
192
+ categorySlug: "category-spinning-tops",
193
+ createdBy: "user-admin-letitrip",
194
+ createdAt: daysAgo(3),
195
+ updatedAt: daysAgo(1),
196
+ },
197
+ {
198
+ id: "group-beyblade-app-unlock-codes",
199
+ slug: "group-beyblade-app-unlock-codes",
200
+ title: "App Unlock Codes",
201
+ description: "More companion-app digital codes to unlock tops, packs, and cosmetics.",
202
+ productIds: [
203
+ "digitalcode-beyblade-x-app-starter-pack",
204
+ "digitalcode-beyblade-metal-app-classic-pack",
205
+ "digitalcode-beyblade-burst-app-avatar-skins",
206
+ ],
207
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-app-unlock-codes-20260819/1200/900"),
208
+ groupTheme: "related",
209
+ minActiveMembers: 2,
210
+ activeMemberCount: 3,
211
+ visibilityStatus: "visible",
212
+ isActive: true,
213
+ isFeatured: false,
214
+ storeId: "store-beyblade-arena",
215
+ brandSlug: "brand-takara-tomy",
216
+ categorySlug: "category-spinning-tops",
217
+ createdBy: "user-admin-letitrip",
218
+ createdAt: daysAgo(3),
219
+ updatedAt: daysAgo(1),
220
+ },
221
+ {
222
+ id: "group-beyblade-fan-art-and-stickers",
223
+ slug: "group-beyblade-fan-art-and-stickers",
224
+ title: "Fan Art & Stickers",
225
+ description: "Prints and sticker sheets to go with your collection.",
226
+ productIds: [
227
+ "art-dranzer-phoenix-poster",
228
+ "art-valkyrie-holographic-print",
229
+ "stickers-beyblade-original-classic-sheet",
230
+ "stickers-beyblade-x-holographic-pack",
231
+ ],
232
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-fan-art-and-stickers-20260819/1200/900"),
233
+ groupTheme: "related",
234
+ minActiveMembers: 2,
235
+ activeMemberCount: 4,
236
+ visibilityStatus: "visible",
237
+ isActive: true,
238
+ isFeatured: false,
239
+ storeId: "store-beyblade-arena",
240
+ brandSlug: "brand-beyblade",
241
+ categorySlug: "category-spinning-tops",
242
+ createdBy: "user-admin-letitrip",
243
+ createdAt: daysAgo(2),
244
+ updatedAt: daysAgo(1),
245
+ },
246
+ {
247
+ id: "group-beyblade-arena-extras",
248
+ slug: "group-beyblade-arena-extras",
249
+ title: "Beyblade Arena Extras",
250
+ description: "A few off-catalog extras also listed by Beyblade Arena.",
251
+ productIds: [
252
+ "live-golden-retriever-puppy",
253
+ "live-bonsai-juniper-10yr",
254
+ ],
255
+ coverImage: seedExtMedia("https://picsum.photos/seed/group-beyblade-arena-extras-20260819/1200/900"),
256
+ groupTheme: "generic",
257
+ minActiveMembers: 2,
258
+ activeMemberCount: 2,
259
+ visibilityStatus: "visible",
260
+ isActive: true,
261
+ isFeatured: false,
262
+ storeId: "store-beyblade-arena",
263
+ createdBy: "user-admin-letitrip",
264
+ createdAt: daysAgo(2),
265
+ updatedAt: daysAgo(1),
266
+ },
100
267
  ];
@@ -65,7 +65,7 @@ export const payoutsSeedData = [
65
65
  currency: _CURRENCY,
66
66
  status: PAYOUT_FIELDS.STATUS_VALUES.PAID,
67
67
  paymentMethod: "upi",
68
- upiId: "letitrip@upi",
68
+ upiId: "mohsin0502@okicici",
69
69
  notes: "January 2026 payout — Mystery box + pre-order deposit orders",
70
70
  adminNote: "UPI credited. Ref: UPI-2026-01-9983",
71
71
  orderIds: ["order-2-20260120-d4e5f6"],
@@ -110,7 +110,7 @@ export const payoutsSeedData = [
110
110
  currency: _CURRENCY,
111
111
  status: PAYOUT_FIELDS.STATUS_VALUES.PAID,
112
112
  paymentMethod: "upi",
113
- upiId: "letitrip@upi",
113
+ upiId: "mohsin0502@okicici",
114
114
  notes: "March 2026 payout — Accessory orders",
115
115
  adminNote: "UPI credited. Ref: UPI-2026-03-7765",
116
116
  orderIds: ["order-4-20260315-j1k2l3"],
@@ -151,7 +151,7 @@ export const payoutsSeedData = [
151
151
  currency: _CURRENCY,
152
152
  status: PAYOUT_FIELDS.STATUS_VALUES.PROCESSING,
153
153
  paymentMethod: "upi",
154
- upiId: "letitrip@upi",
154
+ upiId: "mohsin0502@okicici",
155
155
  notes: "May 2026 payout — Mystery box sealed batch + accessories batch",
156
156
  adminNote: "UPI transfer queued. Processing batch run.",
157
157
  orderIds: ["order-6-20260510-p7q8r9"],
@@ -199,7 +199,7 @@ export const payoutsSeedData = [
199
199
  currency: _CURRENCY,
200
200
  status: PAYOUT_FIELDS.STATUS_VALUES.PENDING,
201
201
  paymentMethod: "upi",
202
- upiId: "letitrip@upi",
202
+ upiId: "mohsin0502@okicici",
203
203
  notes: "May 2026 payout — Pre-order deposits + accessories",
204
204
  orderIds: ["order-8-20260518-v4w5x6"],
205
205
  requestedAt: daysAgo(1),