@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.
- package/dist/_internal/server/features/auctions/actions.js +3 -2
- package/dist/_internal/server/features/auctions/service.d.ts +4 -3
- package/dist/_internal/server/features/auctions/service.js +6 -6
- package/dist/_internal/server/features/bundles/data.d.ts +9 -0
- package/dist/_internal/server/features/bundles/data.js +14 -0
- package/dist/_internal/server/features/bundles/index.d.ts +1 -1
- package/dist/_internal/server/features/bundles/index.js +1 -1
- package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
- package/dist/_internal/server/features/catalogue/og.js +27 -0
- package/dist/_internal/server/features/grouped/data.d.ts +12 -0
- package/dist/_internal/server/features/grouped/data.js +26 -1
- package/dist/_internal/server/features/grouped/index.d.ts +1 -1
- package/dist/_internal/server/features/grouped/index.js +1 -1
- package/dist/_internal/server/features/products/data.d.ts +23 -0
- package/dist/_internal/server/features/products/data.js +159 -0
- package/dist/_internal/server/features/products/index.d.ts +1 -1
- package/dist/_internal/server/features/products/index.js +1 -1
- package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
- package/dist/_internal/shared/features/auctions/config.js +31 -1
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/art/config.js +1 -1
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/classified/config.js +1 -1
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/digital-code/config.js +1 -1
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/live/config.js +1 -1
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
- package/dist/client.d.ts +0 -6
- package/dist/client.js +1 -4
- package/dist/constants/api-endpoints.d.ts +3 -0
- package/dist/constants/api-endpoints.js +1 -0
- package/dist/features/admin/components/AdminSiteSettingsView.js +12 -4
- package/dist/features/admin/schemas/firestore.d.ts +9 -0
- package/dist/features/admin/schemas/firestore.js +6 -0
- package/dist/features/auctions/actions/bid-actions.js +4 -1
- package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
- package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
- package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
- package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
- package/dist/features/catalogue/index.d.ts +2 -0
- package/dist/features/catalogue/index.js +1 -0
- package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
- package/dist/features/categories/components/BundleDetailView.js +3 -2
- package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
- package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
- package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
- package/dist/features/contact/components/ContactPageView.js +8 -2
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
- package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
- package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
- package/dist/features/grouped/repository/grouped-listings.repository.d.ts +8 -0
- package/dist/features/grouped/repository/grouped-listings.repository.js +16 -0
- package/dist/features/layout/BottomActions.js +4 -3
- package/dist/features/layout/BottomActionsContext.d.ts +10 -0
- package/dist/features/layout/BottomActionsContext.js +5 -1
- package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
- package/dist/features/layout/hooks/useBottomActions.js +4 -1
- package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
- package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
- package/dist/features/media/MediaVideo.js +17 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
- package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
- package/dist/features/products/components/ProductDetailPageView.js +11 -116
- package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
- package/dist/features/products/components/RelatedItemsSection.js +17 -0
- package/dist/features/seller/components/SellerProductShell.js +1 -1
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +83 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +7 -0
- package/dist/seed/bids-seed-data.js +48 -3
- package/dist/seed/grouped-listings-seed-data.js +167 -0
- package/dist/seed/payouts-seed-data.js +4 -4
- package/dist/seed/products-art-seed-data.js +188 -5
- package/dist/seed/products-auctions-seed-data.js +215 -6
- package/dist/seed/products-classifieds-seed-data.js +255 -8
- package/dist/seed/products-digital-codes-seed-data.js +258 -19
- package/dist/seed/products-live-items-seed-data.js +143 -10
- package/dist/seed/products-preorders-seed-data.js +213 -8
- package/dist/seed/products-prize-draws-seed-data.js +198 -0
- package/dist/seed/products-standard-seed-data.js +141 -0
- package/dist/seed/products-stickers-seed-data.js +178 -5
- package/dist/seed/site-settings-seed-data.js +10 -29
- package/dist/seed/store-extensions-seed-data.js +1 -1
- package/dist/server-entry.d.ts +4 -1
- package/dist/server-entry.js +4 -1
- package/dist/server.d.ts +4 -2
- package/dist/server.js +4 -2
- package/dist/styles.css +29 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/ImageLightbox.js +37 -3
- package/dist/ui/components/ImageLightbox.style.css +28 -0
- package/dist/utils/media-url.d.ts +9 -0
- package/dist/utils/media-url.js +39 -0
- 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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
{
|
|
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
|
-
/**
|
|
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:
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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),
|