@mohasinac/appkit 4.13.1 → 4.15.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/client/features/layout/DashboardLayoutClient.js +14 -5
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +3 -0
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +6 -0
- package/dist/_internal/client/features/lottery/LotteryDetailView.d.ts +8 -0
- package/dist/_internal/client/features/lottery/LotteryDetailView.js +4 -1
- package/dist/_internal/client/features/lottery/LotteryListView.d.ts +7 -0
- package/dist/_internal/client/features/lottery/LotteryListView.js +1 -1
- package/dist/_internal/client/features/lottery/PrizeDrawLotteryDetailView.js +4 -1
- package/dist/_internal/client/features/lottery/slot-collage-items.d.ts +15 -0
- package/dist/_internal/client/features/lottery/slot-collage-items.js +13 -0
- package/dist/_internal/server/features/auctions/actions.js +8 -2
- package/dist/_internal/server/features/bundles/data.d.ts +16 -0
- package/dist/_internal/server/features/bundles/data.js +26 -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/cart/service.d.ts +3 -3
- package/dist/_internal/server/features/checkout/actions.js +25 -0
- package/dist/_internal/server/features/checkout/locked-lines.d.ts +38 -0
- package/dist/_internal/server/features/checkout/locked-lines.js +171 -0
- package/dist/_internal/server/features/checkout/source-context.d.ts +5 -0
- package/dist/_internal/server/features/checkout/source-context.js +157 -0
- package/dist/_internal/server/features/homepage/index.d.ts +0 -1
- package/dist/_internal/server/features/homepage/index.js +7 -1
- package/dist/_internal/server/features/lottery/adapters.js +4 -0
- package/dist/_internal/server/features/offers/adapters.d.ts +103 -0
- package/dist/_internal/server/features/offers/adapters.js +88 -0
- package/dist/_internal/server/features/offers/index.d.ts +2 -0
- package/dist/_internal/server/features/offers/index.js +1 -0
- package/dist/_internal/server/features/orders/adapters.js +24 -0
- package/dist/_internal/server/features/products/data.js +15 -37
- package/dist/_internal/server/features/products/index.d.ts +1 -1
- package/dist/_internal/server/features/products/index.js +1 -1
- package/dist/_internal/server/features/products/list-public.d.ts +46 -20
- package/dist/_internal/server/features/products/list-public.js +266 -90
- package/dist/_internal/server/features/products/listing-tab-counts.d.ts +44 -0
- package/dist/_internal/server/features/products/listing-tab-counts.js +97 -0
- package/dist/_internal/server/features/site-settings/adapters.d.ts +51 -0
- package/dist/_internal/server/features/site-settings/adapters.js +75 -0
- package/dist/_internal/server/features/site-settings/index.d.ts +1 -0
- package/dist/_internal/server/features/site-settings/index.js +1 -0
- package/dist/_internal/server/features/stores/adapters.d.ts +56 -0
- package/dist/_internal/server/features/stores/adapters.js +91 -0
- package/dist/_internal/server/features/stores/index.d.ts +1 -0
- package/dist/_internal/server/features/stores/index.js +1 -0
- package/dist/_internal/server/jobs/core/auctionSettlement.js +56 -2
- package/dist/_internal/server/jobs/core/offerExpiry.js +55 -19
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.d.ts +5 -0
- package/dist/_internal/server/jobs/core/paymentReviewAutoApprove.js +33 -1
- package/dist/_internal/server/jobs/handlers/messages.d.ts +7 -0
- package/dist/_internal/server/jobs/handlers/messages.js +10 -0
- package/dist/_internal/shared/actions/action-registry.js +17 -1
- package/dist/_internal/shared/checkout/lanes.d.ts +25 -0
- package/dist/_internal/shared/checkout/lanes.js +26 -0
- package/dist/_internal/shared/features/auctions/config.d.ts +27 -0
- package/dist/_internal/shared/features/auctions/config.js +27 -0
- package/dist/_internal/shared/features/auctions/schema.d.ts +14 -2
- package/dist/_internal/shared/features/auctions/schema.js +13 -1
- package/dist/_internal/shared/features/blog/schema.d.ts +2 -2
- package/dist/_internal/shared/features/cart/schema.d.ts +20 -15
- package/dist/_internal/shared/features/cart/schema.js +15 -0
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +32 -32
- package/dist/_internal/shared/features/emi/schedule.d.ts +24 -3
- package/dist/_internal/shared/features/emi/schedule.js +20 -5
- package/dist/_internal/shared/features/events/schema.d.ts +2 -2
- package/dist/_internal/shared/features/homepage/section-gate.d.ts +14 -0
- package/dist/_internal/shared/features/homepage/section-gate.js +51 -0
- package/dist/_internal/shared/features/offers/config.d.ts +30 -0
- package/dist/_internal/shared/features/offers/config.js +59 -0
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +30 -30
- package/dist/_internal/shared/features/products/to-product-item.js +6 -0
- package/dist/_internal/shared/features/reviews/schema.d.ts +2 -2
- package/dist/_internal/shared/features/site-settings/fees.d.ts +60 -0
- package/dist/_internal/shared/features/site-settings/fees.js +39 -0
- package/dist/_internal/shared/features/site-settings/types.d.ts +40 -0
- package/dist/_internal/shared/features/site-settings/types.js +1 -0
- package/dist/_internal/shared/history/history.d.ts +88 -0
- package/dist/_internal/shared/history/history.js +198 -0
- package/dist/_internal/shared/history/index.d.ts +4 -0
- package/dist/_internal/shared/history/index.js +2 -0
- package/dist/_internal/shared/history/types.d.ts +61 -0
- package/dist/_internal/shared/history/types.js +6 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +54 -1
- package/dist/_internal/shared/listing-types/_registry.js +67 -0
- package/dist/_internal/shared/listing-types/art/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/art/config.js +5 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +13 -0
- package/dist/_internal/shared/listing-types/auction/config.js +21 -0
- package/dist/_internal/shared/listing-types/availability.d.ts +79 -0
- package/dist/_internal/shared/listing-types/availability.js +104 -0
- package/dist/_internal/shared/listing-types/capabilities.d.ts +15 -0
- package/dist/_internal/shared/listing-types/capabilities.js +12 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/classified/config.js +5 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +11 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +22 -2
- package/dist/_internal/shared/listing-types/live/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/live/config.js +5 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +19 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +11 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +15 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/standard/config.js +5 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +3 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +5 -0
- package/dist/client.d.ts +20 -7
- package/dist/client.js +22 -4
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +57 -8
- package/dist/constants/field-names.js +101 -8
- package/dist/constants/table-keys.d.ts +17 -0
- package/dist/constants/table-keys.js +17 -0
- package/dist/errors/error-codes.d.ts +13 -1
- package/dist/errors/error-codes.js +13 -1
- package/dist/errors/error-display-map.js +12 -3
- package/dist/errors/messages.d.ts +10 -2
- package/dist/errors/messages.js +10 -2
- package/dist/features/about/components/AboutView.d.ts +3 -0
- package/dist/features/about/components/AboutView.js +3 -2
- package/dist/features/about/components/PolicyPageView.d.ts +2 -1
- package/dist/features/about/components/PolicyPageView.js +61 -23
- package/dist/features/about/components/PublicProfileView.js +5 -0
- package/dist/features/about/schemas/firestore.d.ts +3 -0
- package/dist/features/account/components/UserBidsView.js +12 -4
- package/dist/features/account/components/UserOrdersView.js +7 -0
- package/dist/features/account/components/UserReturnsView.d.ts +3 -0
- package/dist/features/account/components/UserReturnsView.js +17 -1
- package/dist/features/account/components/index.d.ts +0 -2
- package/dist/features/account/components/index.js +0 -1
- package/dist/features/account/schemas/index.d.ts +2 -2
- package/dist/features/account/types/index.d.ts +21 -2
- package/dist/features/addresses/schemas/index.d.ts +4 -4
- package/dist/features/admin/components/AdminArtView.js +8 -3
- package/dist/features/admin/components/AdminAuditLogView.js +1 -0
- package/dist/features/admin/components/AdminBidsView.js +15 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +65 -33
- package/dist/features/admin/components/AdminClassifiedView.js +8 -3
- package/dist/features/admin/components/AdminDigitalCodesView.js +8 -3
- package/dist/features/admin/components/AdminFeatureEditorView.js +35 -6
- package/dist/features/admin/components/AdminFeatureFlagsView.js +1 -0
- package/dist/features/admin/components/AdminLiveView.js +8 -3
- package/dist/features/admin/components/AdminNavEditorView.js +15 -5
- package/dist/features/admin/components/AdminNewsletterView.js +18 -2
- package/dist/features/admin/components/AdminOffersView.d.ts +4 -0
- package/dist/features/admin/components/AdminOffersView.js +230 -0
- package/dist/features/admin/components/AdminOrdersView.js +10 -1
- package/dist/features/admin/components/AdminPaymentMethodsView.js +24 -4
- package/dist/features/admin/components/AdminPrizeDrawsView.js +5 -0
- package/dist/features/admin/components/AdminProductsView.js +16 -29
- package/dist/features/admin/components/AdminScammerEditorView.d.ts +2 -1
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -13
- package/dist/features/admin/components/AdminScammersView.js +3 -8
- package/dist/features/admin/components/AdminSectionsView.js +32 -23
- package/dist/features/admin/components/AdminSessionsView.js +17 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +31 -13
- package/dist/features/admin/components/AdminSiteView.js +6 -2
- package/dist/features/admin/components/AdminStickersView.js +8 -3
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +1 -0
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +4 -2
- package/dist/features/admin/components/sections/adminSectionsTypes.js +45 -27
- package/dist/features/admin/constants/filter-tabs.d.ts +89 -0
- package/dist/features/admin/constants/filter-tabs.js +56 -0
- package/dist/features/admin/schemas/firestore.d.ts +122 -3
- package/dist/features/admin/schemas/firestore.js +1 -0
- package/dist/features/admin/schemas/homepage-section-form.d.ts +22 -0
- package/dist/features/admin/schemas/homepage-section-form.js +68 -0
- package/dist/features/admin/schemas/nav-item-form.d.ts +74 -0
- package/dist/features/admin/schemas/nav-item-form.js +72 -0
- package/dist/features/auctions/actions/bid-actions.d.ts +20 -5
- package/dist/features/auctions/actions/bid-actions.js +93 -20
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +10 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +22 -4
- package/dist/features/auctions/components/AuctionDetailPageView.js +11 -6
- package/dist/features/auctions/components/AuctionsListView.js +5 -6
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +7 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +19 -2
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +1 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +8 -4
- package/dist/features/auctions/components/bid-detail-fields.d.ts +29 -0
- package/dist/features/auctions/components/bid-detail-fields.js +103 -0
- package/dist/features/auctions/repository/bid.repository.d.ts +13 -0
- package/dist/features/auctions/repository/bid.repository.js +23 -0
- package/dist/features/auctions/schemas/firestore.d.ts +17 -0
- package/dist/features/auctions/schemas/index.d.ts +12 -12
- package/dist/features/audit-log/schemas/firestore.d.ts +14 -0
- package/dist/features/audit-log/schemas/firestore.js +7 -0
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +10 -1
- package/dist/features/blog/actions/blog-actions.d.ts +7 -7
- package/dist/features/blog/schemas/blog-form.d.ts +80 -0
- package/dist/features/blog/schemas/blog-form.js +100 -0
- package/dist/features/blog/schemas/index.d.ts +6 -6
- package/dist/features/cart/repository/cart.repository.js +1 -0
- package/dist/features/cart/schemas/firestore.d.ts +15 -0
- package/dist/features/catalogue/schemas/validation.d.ts +4 -4
- package/dist/features/categories/components/BrandDetailPageView.js +23 -40
- package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -7
- package/dist/features/categories/components/BrandDetailTabs.js +8 -12
- package/dist/features/categories/components/BundleCollage.js +1 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +53 -57
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +10 -8
- package/dist/features/categories/components/CategoryDetailTabs.js +11 -16
- package/dist/features/categories/components/CategoryProductsListing.js +11 -1
- package/dist/features/categories/components/ConcernCard.js +7 -1
- package/dist/features/categories/schemas/firestore.d.ts +13 -0
- package/dist/features/categories/schemas/index.d.ts +26 -26
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +16 -1
- package/dist/features/classified/components/ClassifiedDetailPageView.js +23 -3
- package/dist/features/events/components/AdminEventEditorView.js +32 -54
- package/dist/features/events/components/AdminEventEntriesView.js +22 -3
- package/dist/features/events/components/AdminEventsView.js +15 -11
- package/dist/features/events/components/EventFilters.d.ts +9 -1
- package/dist/features/events/components/EventFilters.js +45 -21
- package/dist/features/events/components/EventsIndexListing.d.ts +6 -1
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/components/EventsListPageView.js +13 -4
- package/dist/features/events/repository/events.repository.d.ts +17 -0
- package/dist/features/events/repository/events.repository.js +27 -0
- package/dist/features/events/schemas/event-form.d.ts +113 -0
- package/dist/features/events/schemas/event-form.js +82 -0
- package/dist/features/events/schemas/firestore.d.ts +12 -0
- package/dist/features/events/schemas/firestore.js +12 -0
- package/dist/features/events/schemas/index.d.ts +50 -50
- package/dist/features/events/types/index.d.ts +11 -0
- package/dist/features/events/types/index.js +57 -1
- package/dist/features/faq/actions/faq-actions.d.ts +12 -12
- package/dist/features/faq/schemas/index.d.ts +8 -8
- package/dist/features/filters/FilterFacetSection.d.ts +7 -1
- package/dist/features/filters/FilterFacetSection.js +11 -3
- package/dist/features/grouped/schemas/grouped-listing-form.d.ts +101 -0
- package/dist/features/grouped/schemas/grouped-listing-form.js +89 -0
- package/dist/features/grouped/schemas/index.d.ts +4 -4
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +11 -3
- package/dist/features/homepage/actions/homepage-section-actions.js +33 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +7 -1
- package/dist/features/homepage/components/AnnouncementBar.js +3 -3
- package/dist/features/homepage/components/MarketplaceHomepageView.js +20 -6
- package/dist/features/homepage/hooks/homepage-query.d.ts +16 -0
- package/dist/features/homepage/hooks/homepage-query.js +45 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +10 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.js +28 -8
- package/dist/features/homepage/hooks/useFeaturedPreOrders.js +17 -8
- package/dist/features/homepage/hooks/useFeaturedProducts.js +15 -8
- package/dist/features/homepage/schemas/index.d.ts +33 -2
- package/dist/features/homepage/schemas/index.js +24 -0
- package/dist/features/layout/AppLayoutShell.d.ts +11 -1
- package/dist/features/layout/AppLayoutShell.js +15 -14
- package/dist/features/layout/BackToTop.d.ts +9 -0
- package/dist/features/layout/BackToTop.js +10 -1
- package/dist/features/layout/BottomActions.js +28 -25
- package/dist/features/layout/BottomChrome.d.ts +34 -0
- package/dist/features/layout/BottomChrome.js +55 -0
- package/dist/features/layout/BottomNavLayout.d.ts +6 -0
- package/dist/features/layout/BottomNavLayout.js +7 -1
- package/dist/features/layout/BottomNavbar.js +15 -2
- package/dist/features/layout/FooterLayout.js +11 -1
- package/dist/features/layout/NavbarLayout.js +1 -1
- package/dist/features/layout/TitleBarLayout.d.ts +7 -0
- package/dist/features/layout/TitleBarLayout.js +28 -5
- package/dist/features/layout/index.d.ts +2 -0
- package/dist/features/layout/index.js +1 -0
- package/dist/features/lottery/types/index.d.ts +3 -0
- package/dist/features/media/MediaPickerModal.js +5 -1
- package/dist/features/messages/schemas/index.d.ts +2 -2
- package/dist/features/orders/components/OrderScopeTabs.d.ts +20 -0
- package/dist/features/orders/components/OrderScopeTabs.js +31 -0
- package/dist/features/orders/components/OrderStatusTimeline.d.ts +5 -1
- package/dist/features/orders/components/OrderStatusTimeline.js +39 -20
- package/dist/features/orders/constants/order-scope.d.ts +48 -0
- package/dist/features/orders/constants/order-scope.js +111 -0
- package/dist/features/orders/repository/orders.repository.d.ts +54 -7
- package/dist/features/orders/repository/orders.repository.js +121 -22
- package/dist/features/orders/schemas/firestore.d.ts +152 -0
- package/dist/features/orders/schemas/firestore.js +30 -0
- package/dist/features/orders/schemas/index.d.ts +18 -18
- package/dist/features/orders/types/index.d.ts +35 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +14 -9
- package/dist/features/pre-orders/components/PreOrdersListView.js +6 -5
- package/dist/features/pre-orders/schemas/index.d.ts +1 -1
- package/dist/features/products/actions/product-actions.d.ts +14 -0
- package/dist/features/products/actions/product-actions.js +49 -11
- package/dist/features/products/api/route.d.ts +12 -0
- package/dist/features/products/api/route.js +42 -100
- package/dist/features/products/components/ArtStickersListView.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +13 -11
- package/dist/features/products/components/AvailabilityTabs.d.ts +11 -0
- package/dist/features/products/components/AvailabilityTabs.js +47 -0
- package/dist/features/products/components/GroupSettingsPanel.js +5 -1
- package/dist/features/products/components/MakeOfferButton.js +48 -49
- package/dist/features/products/components/PrizeDrawCollage.d.ts +20 -4
- package/dist/features/products/components/PrizeDrawCollage.js +9 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +14 -12
- package/dist/features/products/components/PrizeDrawsListingView.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.d.ts +7 -1
- package/dist/features/products/components/PrizeDrawsSection.js +23 -18
- package/dist/features/products/components/ProductDetailPageView.d.ts +4 -1
- package/dist/features/products/components/ProductDetailPageView.js +18 -4
- package/dist/features/products/components/ProductForm.js +5 -2
- package/dist/features/products/components/ProductGrid.js +6 -1
- package/dist/features/products/components/ProductsIndexListing.js +22 -32
- package/dist/features/products/components/ProductsIndexPageView.js +6 -9
- package/dist/features/products/components/index.d.ts +2 -2
- package/dist/features/products/components/index.js +1 -1
- package/dist/features/products/config/listing-type-listing-config.d.ts +20 -0
- package/dist/features/products/config/listing-type-listing-config.js +22 -10
- package/dist/features/products/constants/action-defs.d.ts +2 -0
- package/dist/features/products/constants/action-defs.js +6 -0
- package/dist/features/products/hooks/useAvailabilityScope.d.ts +13 -0
- package/dist/features/products/hooks/useAvailabilityScope.js +19 -0
- package/dist/features/products/hooks/useProducts.d.ts +5 -0
- package/dist/features/products/hooks/useProducts.js +13 -2
- package/dist/features/products/repository/products.repository.d.ts +31 -2
- package/dist/features/products/repository/products.repository.js +53 -21
- package/dist/features/products/schemas/firestore.d.ts +17 -3
- package/dist/features/products/schemas/firestore.js +7 -2
- package/dist/features/products/schemas/index.d.ts +64 -64
- package/dist/features/products/schemas/product-features.validators.d.ts +79 -6
- package/dist/features/products/schemas/product-features.validators.js +63 -0
- package/dist/features/products/types/index.d.ts +16 -1
- package/dist/features/promotions/schemas/index.d.ts +2 -2
- package/dist/features/reviews/schemas/index.d.ts +16 -16
- package/dist/features/scams/constants/scammer-status-display.d.ts +28 -0
- package/dist/features/scams/constants/scammer-status-display.js +79 -0
- package/dist/features/search/schemas/index.d.ts +4 -4
- package/dist/features/seller/actions/offer-actions.js +57 -4
- package/dist/features/seller/components/OfferPhaseTimeline.d.ts +59 -0
- package/dist/features/seller/components/OfferPhaseTimeline.js +107 -0
- package/dist/features/seller/components/SellerArtView.js +5 -0
- package/dist/features/seller/components/SellerAuctionsView.js +13 -15
- package/dist/features/seller/components/SellerBidsView.js +11 -4
- package/dist/features/seller/components/SellerClassifiedView.js +5 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +17 -17
- package/dist/features/seller/components/SellerDigitalCodesView.js +5 -0
- package/dist/features/seller/components/SellerLiveView.js +5 -0
- package/dist/features/seller/components/SellerOffersView.js +2 -1
- package/dist/features/seller/components/SellerOrdersView.js +31 -9
- package/dist/features/seller/components/SellerPayoutSettingsView.js +56 -31
- package/dist/features/seller/components/SellerPreOrdersView.js +5 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.js +14 -16
- package/dist/features/seller/components/SellerProductShell.js +7 -1
- package/dist/features/seller/components/SellerProductsView.js +11 -8
- package/dist/features/seller/components/SellerStickersView.js +5 -0
- package/dist/features/seller/components/index.d.ts +0 -2
- package/dist/features/seller/components/index.js +0 -1
- package/dist/features/seller/repository/offer.repository.d.ts +142 -24
- package/dist/features/seller/repository/offer.repository.js +165 -26
- package/dist/features/seller/schemas/coupon-form.d.ts +72 -0
- package/dist/features/seller/schemas/coupon-form.js +116 -0
- package/dist/features/seller/schemas/firestore.d.ts +56 -2
- package/dist/features/seller/schemas/firestore.js +27 -0
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/seller/schemas/offer-forms.d.ts +46 -0
- package/dist/features/seller/schemas/offer-forms.js +42 -0
- package/dist/features/seller/server.d.ts +0 -1
- package/dist/features/seller/server.js +0 -1
- package/dist/features/shell/SectionForm.d.ts +99 -0
- package/dist/features/shell/SectionForm.js +128 -0
- package/dist/features/shell/build-sections.d.ts +63 -0
- package/dist/features/shell/build-sections.js +207 -0
- package/dist/features/shell/entity-form.d.ts +109 -0
- package/dist/features/shell/entity-form.js +96 -0
- package/dist/features/shell/field-ui-meta.d.ts +115 -0
- package/dist/features/shell/field-ui-meta.js +324 -0
- package/dist/features/shell/index.d.ts +8 -0
- package/dist/features/shell/index.js +4 -0
- package/dist/features/status-history/components/StatusTimeline.d.ts +74 -0
- package/dist/features/status-history/components/StatusTimeline.js +46 -0
- package/dist/features/status-history/index.d.ts +11 -0
- package/dist/features/status-history/index.js +10 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.d.ts +27 -0
- package/dist/features/store-extensions/components/ReviewDecisionModal.js +82 -0
- package/dist/features/store-extensions/index.d.ts +12 -0
- package/dist/features/store-extensions/index.js +12 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.d.ts +36 -0
- package/dist/features/store-extensions/schemas/admin-notification-form.js +114 -0
- package/dist/features/store-extensions/schemas/analytics-forms.d.ts +57 -0
- package/dist/features/store-extensions/schemas/analytics-forms.js +158 -0
- package/dist/features/store-extensions/schemas/custom-role-form.d.ts +85 -0
- package/dist/features/store-extensions/schemas/custom-role-form.js +118 -0
- package/dist/features/store-extensions/schemas/firestore.d.ts +21 -1
- package/dist/features/store-extensions/schemas/firestore.js +60 -0
- package/dist/features/store-extensions/schemas/google-config-form.d.ts +53 -0
- package/dist/features/store-extensions/schemas/google-config-form.js +105 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.d.ts +28 -0
- package/dist/features/store-extensions/schemas/item-request-create-form.js +80 -0
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +78 -0
- package/dist/features/store-extensions/schemas/listing-template-form.js +87 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.d.ts +49 -0
- package/dist/features/store-extensions/schemas/moderation-review-form.js +101 -0
- package/dist/features/store-extensions/schemas/payout-method-form.d.ts +153 -0
- package/dist/features/store-extensions/schemas/payout-method-form.js +155 -0
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +25 -0
- package/dist/features/store-extensions/schemas/report-create-form.js +79 -0
- package/dist/features/store-extensions/schemas/report-review-form.d.ts +47 -0
- package/dist/features/store-extensions/schemas/report-review-form.js +111 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +148 -0
- package/dist/features/store-extensions/schemas/shipping-config-form.js +104 -0
- package/dist/features/store-extensions/schemas/store-category-form.d.ts +54 -0
- package/dist/features/store-extensions/schemas/store-category-form.js +73 -0
- package/dist/features/stores/api/[storeSlug]/route.js +2 -25
- package/dist/features/stores/components/StoreAuctionsListing.js +15 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +12 -2
- package/dist/features/stores/components/StoreDetailLayoutView.js +24 -71
- package/dist/features/stores/components/StoreDigitalCodesListing.js +12 -2
- package/dist/features/stores/components/StoreLiveItemsListing.js +12 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +12 -1
- package/dist/features/stores/components/StoreProductsListing.js +11 -1
- package/dist/features/stores/repository/store.repository.js +6 -0
- package/dist/features/stores/schemas/index.d.ts +6 -6
- package/dist/features/support/schemas/index.d.ts +4 -4
- package/dist/features/tester/actions/checklist-item-actions.d.ts +4 -4
- package/dist/features/tester/seed-data/offers-tester-seed-data.js +119 -3
- package/dist/features/tester/seed-data/products-tester-seed-data.js +131 -1
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +431 -1
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +25 -12
- package/dist/index.js +26 -11
- package/dist/next/routing/route-map.d.ts +23 -3
- package/dist/next/routing/route-map.js +14 -2
- package/dist/providers/db-firebase/base.repository.d.ts +30 -0
- package/dist/providers/db-firebase/base.repository.js +50 -1
- package/dist/providers/db-firebase/index.d.ts +1 -1
- package/dist/providers/db-firebase/index.js +1 -1
- package/dist/providers/db-firebase/sieve.d.ts +25 -0
- package/dist/providers/db-firebase/sieve.js +52 -18
- package/dist/react/hooks/useUrlTable.js +10 -1
- package/dist/schemas/firestore-value.d.ts +8 -0
- package/dist/schemas/firestore-value.js +44 -0
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/registry.d.ts +702 -69
- package/dist/schemas/registry.js +64 -1
- package/dist/seed/_helpers/category-forest.d.ts +2 -0
- package/dist/seed/_helpers/category-forest.js +309 -0
- package/dist/seed/_helpers/category-tree.d.ts +27 -0
- package/dist/seed/_helpers/category-tree.js +103 -0
- package/dist/seed/bids-seed-data.js +30 -0
- package/dist/seed/catalogue-seed-data.js +12 -12
- package/dist/seed/categories-seed-data.js +177 -162
- package/dist/seed/events-seed-data.js +61 -10
- package/dist/seed/homepage-sections-seed-data.js +5 -1
- package/dist/seed/offers-seed-data.js +244 -34
- package/dist/seed/orders-seed-data.js +336 -1
- package/dist/seed/products-art-seed-data.js +50 -12
- package/dist/seed/products-auctions-seed-data.js +138 -18
- package/dist/seed/products-classifieds-seed-data.js +80 -16
- package/dist/seed/products-digital-codes-seed-data.js +66 -18
- package/dist/seed/products-live-items-seed-data.js +64 -13
- package/dist/seed/products-preorders-seed-data.d.ts +0 -1
- package/dist/seed/products-preorders-seed-data.js +52 -13
- package/dist/seed/products-prize-draws-seed-data.js +63 -14
- package/dist/seed/products-standard-seed-data.js +99 -26
- package/dist/seed/products-stickers-seed-data.js +47 -12
- package/dist/seed/reviews-seed-data.js +6 -1
- package/dist/seed/site-settings-seed-data.d.ts +1 -38
- package/dist/seed/site-settings-seed-data.js +38 -76
- package/dist/seed/stores-seed-data.js +71 -1
- package/dist/seed/users-seed-data.js +15 -5
- package/dist/server-entry.d.ts +1 -2
- package/dist/server-entry.js +4 -3
- package/dist/server.d.ts +6 -3
- package/dist/server.js +13 -4
- package/dist/styles.css +78 -12
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Button.style.css +19 -4
- package/dist/ui/components/CollapsibleSection.d.ts +17 -1
- package/dist/ui/components/CollapsibleSection.js +6 -2
- package/dist/ui/components/FilterChipGroup.d.ts +25 -1
- package/dist/ui/components/FilterChipGroup.js +21 -4
- package/dist/ui/components/HandMode.style.css +47 -0
- package/dist/ui/components/Layout.d.ts +9 -2
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/ListingLayout.js +8 -8
- package/dist/ui/components/ListingLayout.style.css +8 -7
- package/dist/ui/components/RecordDetailModal.d.ts +10 -1
- package/dist/ui/components/RecordDetailModal.js +2 -2
- package/dist/ui/components/StickyToolbar.d.ts +3 -1
- package/dist/ui/components/StickyToolbar.js +62 -20
- package/dist/ui/components/bottom-chrome-slot.d.ts +21 -0
- package/dist/ui/components/bottom-chrome-slot.js +29 -0
- package/dist/ui/components/index.style.css +3 -0
- package/dist/ui/forms/FormShell.d.ts +43 -13
- package/dist/ui/forms/FormShell.js +22 -11
- package/dist/ui/forms/index.d.ts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +2 -1
- package/scripts/node-esm-loader.mjs +65 -0
- package/scripts/seed-cli-loader.mjs +6 -49
- package/scripts/seed-cli.mjs +1 -1
|
@@ -34,9 +34,9 @@ import { filterNavItems } from "./filterNavItems";
|
|
|
34
34
|
import { useSiteSettings } from "../../../../core/hooks/useSiteSettings";
|
|
35
35
|
import { useTheme } from "../../theme";
|
|
36
36
|
import { useHandMode } from "../../hand-mode";
|
|
37
|
-
import { BackgroundRenderer, Div, Nav, Span } from "../../../../ui";
|
|
37
|
+
import { BackgroundRenderer, Div, Li, Nav, Span } from "../../../../ui";
|
|
38
|
+
import { BottomNavLayout } from "../../../../features/layout/BottomNavLayout";
|
|
38
39
|
import { useToast } from "../../../../ui/components/Toast";
|
|
39
|
-
import { useVisualViewportInset } from "../../../../react/hooks/useVisualViewportInset";
|
|
40
40
|
import { useSession } from "../../../../react/contexts/SessionContext";
|
|
41
41
|
import { ROUTES } from "../../../../next/routing/route-map";
|
|
42
42
|
/**
|
|
@@ -140,14 +140,23 @@ const MAX_BOTTOM_NAV_ITEMS = 5;
|
|
|
140
140
|
* behind a hamburger toggle). Pattern lifted from the unused
|
|
141
141
|
* `DashboardScaffold` scaffold, which has since been retired in favour of
|
|
142
142
|
* wiring it directly here where the sidebars already live.
|
|
143
|
+
*
|
|
144
|
+
* Renders through the shared `<BottomNavLayout>` rather than hand-rolling its
|
|
145
|
+
* own `fixed bottom-0` chrome. That is not cosmetic: `BottomNavLayout` is what
|
|
146
|
+
* publishes `--bottom-nav-height`, which every bottom-anchored surface above it
|
|
147
|
+
* (the CTA tier, the pagination bar, BackToTop, the footer's clearance) offsets
|
|
148
|
+
* against. The hand-rolled version published nothing, so on dashboard routes
|
|
149
|
+
* that whole stack was positioned against the PUBLIC nav's height instead —
|
|
150
|
+
* which was itself a bug, since both bars were rendering on the same pixels.
|
|
151
|
+
* `AppLayoutShell` is now told to suppress the public one here via
|
|
152
|
+
* `showBottomNav={!isDashboard}`; exactly one nav must be mounted at a time.
|
|
143
153
|
*/
|
|
144
154
|
function DashboardBottomNav({ items, activeHref }) {
|
|
145
|
-
const isKeyboardOpen = useVisualViewportInset();
|
|
146
155
|
if (items.length === 0)
|
|
147
156
|
return null;
|
|
148
|
-
return (_jsx(
|
|
157
|
+
return (_jsx(BottomNavLayout, { id: "dashboard-bottom-navbar", ariaLabel: "Dashboard bottom navigation", children: items.slice(0, MAX_BOTTOM_NAV_ITEMS).map((item) => {
|
|
149
158
|
const isActive = activeHref === item.href || activeHref.startsWith(`${item.href}/`);
|
|
150
|
-
return (_jsxs(Link, { href: item.href, className: `flex
|
|
159
|
+
return (_jsx(Li, { className: "flex-1", children: _jsxs(Link, { href: item.href, className: `flex h-full flex-col items-center justify-center gap-[var(--appkit-space-0-5)] py-[var(--appkit-space-2)] ${isActive ? "text-[var(--appkit-color-primary)]" : "text-[var(--appkit-color-text-muted)]"}`, "aria-current": isActive ? "page" : undefined, children: [item.icon && _jsx(Span, { size: "base", children: item.icon }), _jsx(Span, { size: "xs", className: "max-w-full truncate", children: item.label })] }) }, item.href));
|
|
151
160
|
}) }));
|
|
152
161
|
}
|
|
153
162
|
// Asymmetric padding clears the persistent sidebar rail — right-heavy by
|
|
@@ -3,6 +3,8 @@ interface LotterySlotRow {
|
|
|
3
3
|
slotNumber: number;
|
|
4
4
|
name: string;
|
|
5
5
|
price: number;
|
|
6
|
+
/** Prize photo — rendered publicly in the prize collage on the detail page. */
|
|
7
|
+
image?: string;
|
|
6
8
|
}
|
|
7
9
|
interface LotteryEventFormData {
|
|
8
10
|
title: string;
|
|
@@ -12,6 +14,7 @@ interface LotteryEventFormData {
|
|
|
12
14
|
slots: Array<{
|
|
13
15
|
slotNumber: number;
|
|
14
16
|
name: string;
|
|
17
|
+
image?: string;
|
|
15
18
|
price: number;
|
|
16
19
|
weight: number;
|
|
17
20
|
isBooked: boolean;
|
|
@@ -37,6 +37,7 @@ export function LotteryAdminEditView({ eventId, initialData, onSubmit, }) {
|
|
|
37
37
|
slots: slots.map((s) => ({
|
|
38
38
|
slotNumber: s.slotNumber,
|
|
39
39
|
name: s.name,
|
|
40
|
+
image: s.image?.trim() || undefined,
|
|
40
41
|
price: s.price,
|
|
41
42
|
weight: 0,
|
|
42
43
|
isBooked: false,
|
|
@@ -68,6 +69,11 @@ export function LotteryAdminEditView({ eventId, initialData, onSubmit, }) {
|
|
|
68
69
|
header: "Prize Name",
|
|
69
70
|
render: (s) => (_jsx(Input, { type: "text", className: "w-full", placeholder: `Prize for slot ${s.slotNumber}`, value: s.name, onChange: (e) => updateSlot(s._idx, "name", e.target.value), "aria-label": `Slot ${s.slotNumber} prize name` })),
|
|
70
71
|
},
|
|
72
|
+
{
|
|
73
|
+
key: "image",
|
|
74
|
+
header: "Image",
|
|
75
|
+
render: (s) => (_jsx(Input, { type: "text", className: "w-full", placeholder: "/media/\u2026 or https://\u2026", value: s.image ?? "", onChange: (e) => updateSlot(s._idx, "image", e.target.value), "aria-label": `Slot ${s.slotNumber} prize image URL` })),
|
|
76
|
+
},
|
|
71
77
|
...(pricingMode === "variable"
|
|
72
78
|
? [
|
|
73
79
|
{
|
|
@@ -6,7 +6,15 @@ interface ClientLotteryEvent {
|
|
|
6
6
|
description?: string;
|
|
7
7
|
status: string;
|
|
8
8
|
endsAt?: string | Date | null;
|
|
9
|
+
/**
|
|
10
|
+
* Two spellings exist on EventDocument and only `coverImage.url` is ever
|
|
11
|
+
* populated — by seed data or the admin editor. Reading `coverImageUrl`
|
|
12
|
+
* alone is why this page showed the 🎰 placeholder for every lottery.
|
|
13
|
+
*/
|
|
9
14
|
coverImageUrl?: string;
|
|
15
|
+
coverImage?: {
|
|
16
|
+
url?: string;
|
|
17
|
+
} | null;
|
|
10
18
|
lotteryConfig?: ClientLotteryConfig;
|
|
11
19
|
}
|
|
12
20
|
interface LotteryDetailViewProps {
|
|
@@ -6,6 +6,8 @@ import { MediaImage } from "../../../../features/media/MediaImage";
|
|
|
6
6
|
import { ROUTES } from "../../../../next/routing/route-map";
|
|
7
7
|
import { LotterySlotGrid } from "./LotterySlotGrid";
|
|
8
8
|
import { LotteryPullForm } from "./LotteryPullForm";
|
|
9
|
+
import { PrizeDrawCollage } from "../../../../features/products/components/PrizeDrawCollage";
|
|
10
|
+
import { slotsToCollageItems } from "./slot-collage-items";
|
|
9
11
|
/**
|
|
10
12
|
* Full lottery detail page view.
|
|
11
13
|
* Shows cover + description + slot grid + pull form (if active + logged in).
|
|
@@ -13,7 +15,8 @@ import { LotteryPullForm } from "./LotteryPullForm";
|
|
|
13
15
|
export function LotteryDetailView({ event, user, currentEntry }) {
|
|
14
16
|
const [pulledEntry, setPulledEntry] = useState(currentEntry?.assignedPrizeSlotNumber != null ? currentEntry : null);
|
|
15
17
|
const config = event.lotteryConfig;
|
|
18
|
+
const prizeItems = slotsToCollageItems(config?.slots ?? []);
|
|
16
19
|
const isActive = event.status === "active";
|
|
17
20
|
const isEnded = event.status === "ended" || event.status === "cancelled";
|
|
18
|
-
return (_jsx(Container, { children: _jsx(Section, { children: _jsxs(Stack, { gap: "xl", children: [event.coverImageUrl ? (_jsx(Div, { rounded: "2xl", className: "relative overflow-hidden", style: { aspectRatio: "16/9", maxHeight: "16rem" }, children: _jsx(MediaImage, { src: event.coverImageUrl, alt: event.title, size: "hero" }) })) : (_jsx(Div, { rounded: "2xl", surface: "subtle", padding: "xl", align: "center", justify: "center", children: _jsx(Text, { size: "5xl", children: "\uD83C\uDFB0" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: isActive ? "success" : isEnded ? "danger" : "warning", children: event.status }), config && (_jsxs(Badge, { variant: "info", children: [config.slots.filter((s) => s.isBooked).length, "/", config.totalSlots, " slots claimed"] }))] }), _jsx(Heading, { level: 1, size: "3xl", weight: "bold", children: event.title }), event.description ? (_jsx(Text, { color: "muted", size: "sm", children: event.description.replace(/<[^>]+>/g, "").slice(0, 200) })) : null, event.endsAt ? (_jsxs(Text, { size: "sm", color: "muted", children: ["Ends: ", new Date(event.endsAt).toLocaleDateString("en-IN", { dateStyle: "long" })] })) : null] }), config && config.slots.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Slots" }), _jsx(LotterySlotGrid, { slots: config.slots, totalSlots: config.totalSlots })] })) : null, isActive && config && (_jsx(Div, { padding: "md", rounded: "2xl", surface: "card", className: "border border-[var(--appkit-color-border)]", children: !user ? (_jsxs(Stack, { gap: "md", className: "text-center", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Want to Participate?" }), _jsx(Text, { color: "muted", children: "Log in to submit your lottery entry." }), _jsx(Anchor, { href: String(ROUTES.AUTH.LOGIN), tone: "brand", children: "Log In to Enter" })] })) : pulledEntry ? (_jsxs(Stack, { gap: "sm", surface: "success-surface", padding: "md", rounded: "xl", className: "border border-success/20", children: [_jsxs(Heading, { level: 2, size: "lg", weight: "bold", className: "text-success", children: ["You're Lottery #", pulledEntry.userLotteryNumber, "!"] }), _jsxs(Text, { className: "text-success", size: "sm", children: ["Assigned to Slot #", pulledEntry.assignedPrizeSlotNumber, pulledEntry.slotName ? ` — ${pulledEntry.slotName}` : "", "."] })] })) : (_jsx(LotteryPullForm, { sourceType: "event", eventId: event.id, totalSlots: config.totalSlots, maxPullsPerUser: config.maxPullsPerUser, onSuccess: (res) => setPulledEntry(res) })) })), isEnded && !pulledEntry && (_jsx(Stack, { gap: "sm", surface: "muted", padding: "md", rounded: "xl", children: _jsx(Text, { color: "muted", weight: "semibold", children: "This lottery has ended." }) }))] }) }) }));
|
|
21
|
+
return (_jsx(Container, { children: _jsx(Section, { children: _jsxs(Stack, { gap: "xl", children: [event.coverImageUrl || event.coverImage?.url ? (_jsx(Div, { rounded: "2xl", className: "relative overflow-hidden", style: { aspectRatio: "16/9", maxHeight: "16rem" }, children: _jsx(MediaImage, { src: event.coverImageUrl || event.coverImage?.url || "", alt: event.title, size: "hero" }) })) : (_jsx(Div, { rounded: "2xl", surface: "subtle", padding: "xl", align: "center", justify: "center", children: _jsx(Text, { size: "5xl", children: "\uD83C\uDFB0" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: isActive ? "success" : isEnded ? "danger" : "warning", children: event.status }), config && (_jsxs(Badge, { variant: "info", children: [config.slots.filter((s) => s.isBooked).length, "/", config.totalSlots, " slots claimed"] }))] }), _jsx(Heading, { level: 1, size: "3xl", weight: "bold", children: event.title }), event.description ? (_jsx(Text, { color: "muted", size: "sm", children: event.description.replace(/<[^>]+>/g, "").slice(0, 200) })) : null, event.endsAt ? (_jsxs(Text, { size: "sm", color: "muted", children: ["Ends: ", new Date(event.endsAt).toLocaleDateString("en-IN", { dateStyle: "long" })] })) : null] }), prizeItems.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Prizes" }), _jsx(PrizeDrawCollage, { items: prizeItems, wonLabel: "Claimed" })] })) : null, config && config.slots.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Slots" }), _jsx(LotterySlotGrid, { slots: config.slots, totalSlots: config.totalSlots })] })) : null, isActive && config && (_jsx(Div, { padding: "md", rounded: "2xl", surface: "card", className: "border border-[var(--appkit-color-border)]", children: !user ? (_jsxs(Stack, { gap: "md", className: "text-center", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Want to Participate?" }), _jsx(Text, { color: "muted", children: "Log in to submit your lottery entry." }), _jsx(Anchor, { href: String(ROUTES.AUTH.LOGIN), tone: "brand", children: "Log In to Enter" })] })) : pulledEntry ? (_jsxs(Stack, { gap: "sm", surface: "success-surface", padding: "md", rounded: "xl", className: "border border-success/20", children: [_jsxs(Heading, { level: 2, size: "lg", weight: "bold", className: "text-success", children: ["You're Lottery #", pulledEntry.userLotteryNumber, "!"] }), _jsxs(Text, { className: "text-success", size: "sm", children: ["Assigned to Slot #", pulledEntry.assignedPrizeSlotNumber, pulledEntry.slotName ? ` — ${pulledEntry.slotName}` : "", "."] })] })) : (_jsx(LotteryPullForm, { sourceType: "event", eventId: event.id, totalSlots: config.totalSlots, maxPullsPerUser: config.maxPullsPerUser, onSuccess: (res) => setPulledEntry(res) })) })), isEnded && !pulledEntry && (_jsx(Stack, { gap: "sm", surface: "muted", padding: "md", rounded: "xl", children: _jsx(Text, { color: "muted", weight: "semibold", children: "This lottery has ended." }) }))] }) }) }));
|
|
19
22
|
}
|
|
@@ -7,7 +7,14 @@ interface ClientLotteryEvent {
|
|
|
7
7
|
status: string;
|
|
8
8
|
startsAt?: string | Date;
|
|
9
9
|
endsAt?: string | Date;
|
|
10
|
+
/**
|
|
11
|
+
* Only `coverImage.url` is ever populated on EventDocument — reading
|
|
12
|
+
* `coverImageUrl` alone showed the 🎰 placeholder on every card.
|
|
13
|
+
*/
|
|
10
14
|
coverImageUrl?: string;
|
|
15
|
+
coverImage?: {
|
|
16
|
+
url?: string;
|
|
17
|
+
} | null;
|
|
11
18
|
lotteryConfig?: ClientLotteryConfig;
|
|
12
19
|
}
|
|
13
20
|
interface LotteryListViewProps {
|
|
@@ -17,7 +17,7 @@ export function LotteryListView({ items, adminMode = false }) {
|
|
|
17
17
|
const claimed = event.lotteryConfig?.slots.filter((s) => s.isBooked).length ?? 0;
|
|
18
18
|
const total = event.lotteryConfig?.totalSlots ?? 0;
|
|
19
19
|
const slotsLeft = total - claimed;
|
|
20
|
-
return (_jsx(Anchor, { href: `/lottery/${event.id}`, tone: "brand", rounded: "2xl", className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-primary", "aria-label": `${event.title} lottery`, children: _jsxs(Card, { variant: "default", padding: "none", animate: "hoverLift", className: "overflow-hidden", children: [event.coverImageUrl ? (_jsx(Div, { className: "relative aspect-video overflow-hidden", children: _jsx(MediaImage, { src: event.coverImageUrl, alt: event.title, size: "card" }) })) : (_jsx(Div, { className: "aspect-video", surface: "muted", align: "center", justify: "center", children: _jsx(Text, { size: "3xl", children: "\uD83C\uDFB0" }) })), _jsxs(Stack, { gap: "xs", padding: "md", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: event.status === "active"
|
|
20
|
+
return (_jsx(Anchor, { href: `/lottery/${event.id}`, tone: "brand", rounded: "2xl", className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-primary", "aria-label": `${event.title} lottery`, children: _jsxs(Card, { variant: "default", padding: "none", animate: "hoverLift", className: "overflow-hidden", children: [event.coverImageUrl || event.coverImage?.url ? (_jsx(Div, { className: "relative aspect-video overflow-hidden", children: _jsx(MediaImage, { src: event.coverImageUrl || event.coverImage?.url || "", alt: event.title, size: "card" }) })) : (_jsx(Div, { className: "aspect-video", surface: "muted", align: "center", justify: "center", children: _jsx(Text, { size: "3xl", children: "\uD83C\uDFB0" }) })), _jsxs(Stack, { gap: "xs", padding: "md", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: event.status === "active"
|
|
21
21
|
? "success"
|
|
22
22
|
: event.status === "ended"
|
|
23
23
|
? "danger"
|
|
@@ -6,6 +6,8 @@ import { MediaImage } from "../../../../features/media/MediaImage";
|
|
|
6
6
|
import { ROUTES } from "../../../../next/routing/route-map";
|
|
7
7
|
import { LotterySlotGrid } from "./LotterySlotGrid";
|
|
8
8
|
import { LotteryPullForm } from "./LotteryPullForm";
|
|
9
|
+
import { PrizeDrawCollage } from "../../../../features/products/components/PrizeDrawCollage";
|
|
10
|
+
import { slotsToCollageItems } from "./slot-collage-items";
|
|
9
11
|
/**
|
|
10
12
|
* Prize-draw product detail view for lottery mode.
|
|
11
13
|
* Same flow as LotteryDetailView but sourced from a product.
|
|
@@ -15,6 +17,7 @@ export function PrizeDrawLotteryDetailView({ product, user, currentEntry, }) {
|
|
|
15
17
|
? currentEntry
|
|
16
18
|
: null);
|
|
17
19
|
const config = product.lotteryConfig;
|
|
20
|
+
const prizeItems = slotsToCollageItems(config?.slots ?? []);
|
|
18
21
|
const isActive = product.status === "published";
|
|
19
|
-
return (_jsx(Container, { children: _jsx(Section, { children: _jsxs(Stack, { gap: "xl", children: [product.mainImage ? (_jsx(Div, { rounded: "2xl", className: "relative overflow-hidden", style: { aspectRatio: "16/9", maxHeight: "16rem" }, children: _jsx(MediaImage, { src: product.mainImage, alt: product.title, size: "hero" }) })) : (_jsx(Div, { rounded: "2xl", surface: "muted", padding: "xl", align: "center", justify: "center", children: _jsx(Text, { size: "5xl", children: "\uD83C\uDF81" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: "info", children: "Lottery Prize Draw" }), config && (_jsxs(Badge, { variant: isActive ? "success" : "secondary", children: [config.slots.filter((s) => s.isBooked).length, "/", config.totalSlots, " claimed"] }))] }), _jsx(Heading, { level: 1, size: "3xl", weight: "bold", children: product.title }), product.description ? (_jsx(Text, { color: "muted", children: product.description })) : null] }), config && config.slots.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Slots" }), _jsx(LotterySlotGrid, { slots: config.slots, totalSlots: config.totalSlots })] })) : null, isActive && config && (_jsx(Div, { padding: "md", rounded: "2xl", surface: "card", className: "border border-[var(--appkit-color-border)]", children: !user ? (_jsxs(Stack, { gap: "md", className: "text-center", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Want to Enter?" }), _jsx(Text, { color: "muted", children: "Log in to submit your entry." }), _jsx(Anchor, { href: String(ROUTES.AUTH.LOGIN), tone: "brand", children: "Log In to Enter" })] })) : pulledEntry ? (_jsxs(Stack, { gap: "sm", surface: "success-surface", padding: "md", rounded: "xl", className: "border border-success/20", children: [_jsxs(Heading, { level: 2, size: "lg", weight: "bold", className: "text-success", children: ["You're Entry #", pulledEntry.userLotteryNumber, "!"] }), _jsxs(Text, { className: "text-success", size: "sm", children: ["Assigned to Slot #", pulledEntry.assignedPrizeSlotNumber, pulledEntry.slotName ? ` — ${pulledEntry.slotName}` : "", "."] })] })) : (_jsx(LotteryPullForm, { sourceType: "product", productId: product.id, totalSlots: config.totalSlots, maxPullsPerUser: config.maxPullsPerUser, onSuccess: (res) => setPulledEntry(res) })) }))] }) }) }));
|
|
22
|
+
return (_jsx(Container, { children: _jsx(Section, { children: _jsxs(Stack, { gap: "xl", children: [product.mainImage ? (_jsx(Div, { rounded: "2xl", className: "relative overflow-hidden", style: { aspectRatio: "16/9", maxHeight: "16rem" }, children: _jsx(MediaImage, { src: product.mainImage, alt: product.title, size: "hero" }) })) : (_jsx(Div, { rounded: "2xl", surface: "muted", padding: "xl", align: "center", justify: "center", children: _jsx(Text, { size: "5xl", children: "\uD83C\uDF81" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "xs", align: "center", wrap: true, children: [_jsx(Badge, { variant: "info", children: "Lottery Prize Draw" }), config && (_jsxs(Badge, { variant: isActive ? "success" : "secondary", children: [config.slots.filter((s) => s.isBooked).length, "/", config.totalSlots, " claimed"] }))] }), _jsx(Heading, { level: 1, size: "3xl", weight: "bold", children: product.title }), product.description ? (_jsx(Text, { color: "muted", children: product.description })) : null] }), prizeItems.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Prizes" }), _jsx(PrizeDrawCollage, { items: prizeItems, wonLabel: "Claimed" })] })) : null, config && config.slots.length > 0 ? (_jsxs(Stack, { gap: "sm", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Slots" }), _jsx(LotterySlotGrid, { slots: config.slots, totalSlots: config.totalSlots })] })) : null, isActive && config && (_jsx(Div, { padding: "md", rounded: "2xl", surface: "card", className: "border border-[var(--appkit-color-border)]", children: !user ? (_jsxs(Stack, { gap: "md", className: "text-center", children: [_jsx(Heading, { level: 2, size: "xl", weight: "semibold", children: "Want to Enter?" }), _jsx(Text, { color: "muted", children: "Log in to submit your entry." }), _jsx(Anchor, { href: String(ROUTES.AUTH.LOGIN), tone: "brand", children: "Log In to Enter" })] })) : pulledEntry ? (_jsxs(Stack, { gap: "sm", surface: "success-surface", padding: "md", rounded: "xl", className: "border border-success/20", children: [_jsxs(Heading, { level: 2, size: "lg", weight: "bold", className: "text-success", children: ["You're Entry #", pulledEntry.userLotteryNumber, "!"] }), _jsxs(Text, { className: "text-success", size: "sm", children: ["Assigned to Slot #", pulledEntry.assignedPrizeSlotNumber, pulledEntry.slotName ? ` — ${pulledEntry.slotName}` : "", "."] })] })) : (_jsx(LotteryPullForm, { sourceType: "product", productId: product.id, totalSlots: config.totalSlots, maxPullsPerUser: config.maxPullsPerUser, onSuccess: (res) => setPulledEntry(res) })) }))] }) }) }));
|
|
20
23
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map lottery slots onto the shape `PrizeDrawCollage` renders.
|
|
3
|
+
*
|
|
4
|
+
* Shared by all three lottery surfaces (event lottery detail, prize-draw-mode
|
|
5
|
+
* lottery detail, and any future one) so the "which slots get a tile" rule
|
|
6
|
+
* cannot drift between them.
|
|
7
|
+
*
|
|
8
|
+
* Slots with no image are dropped rather than rendered as empty tiles: a
|
|
9
|
+
* lottery may have 200 slots and only a handful of photographed prizes, and a
|
|
10
|
+
* collage of placeholders communicates nothing. The numbered `LotterySlotGrid`
|
|
11
|
+
* below it is still the complete, authoritative slot map.
|
|
12
|
+
*/
|
|
13
|
+
import type { ClientLotterySlot } from "../../../../features/lottery/types";
|
|
14
|
+
import type { CollagePrizeItem } from "../../../../features/products/components/PrizeDrawCollage";
|
|
15
|
+
export declare function slotsToCollageItems(slots: readonly ClientLotterySlot[]): CollagePrizeItem[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function slotsToCollageItems(slots) {
|
|
2
|
+
return slots
|
|
3
|
+
.filter((slot) => Boolean(slot.image))
|
|
4
|
+
.map((slot) => ({
|
|
5
|
+
itemNumber: slot.slotNumber,
|
|
6
|
+
title: slot.name,
|
|
7
|
+
images: slot.image ? [slot.image] : [],
|
|
8
|
+
// `isBooked` is the lottery's equivalent of a prize being taken. The
|
|
9
|
+
// collage's own label prop renames the stamp to "Claimed" at the call
|
|
10
|
+
// site — price and weight never reach the client at all.
|
|
11
|
+
isWon: slot.isBooked,
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { wrapAction } from "@mohasinac/appkit/server";
|
|
3
3
|
import { bidRepository, productRepository, userRepository, siteSettingsRepository } from "../../../../repositories";
|
|
4
4
|
import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
|
|
5
|
-
import {
|
|
5
|
+
import { placeBidActionSchema } from "../../../shared/features/auctions/schema";
|
|
6
6
|
import { assertAuctionActive, assertBidAmount, assertNotAuctionOwner, shouldAutoExtend, computeExtendedEndDate, } from "./service";
|
|
7
7
|
import { ValidationError } from "../../../shared/errors/index";
|
|
8
8
|
export async function placeBidAction(input) {
|
|
9
9
|
return wrapAction(async () => {
|
|
10
10
|
const user = await requireRoleUser(["buyer", "seller", "admin"]);
|
|
11
|
-
const parsed =
|
|
11
|
+
const parsed = placeBidActionSchema.safeParse(input);
|
|
12
12
|
if (!parsed.success)
|
|
13
13
|
throw new ValidationError(parsed.error.issues[0]?.message ?? "Invalid bid input");
|
|
14
14
|
const { auctionId, amount } = parsed.data;
|
|
@@ -32,9 +32,15 @@ export async function placeBidAction(input) {
|
|
|
32
32
|
});
|
|
33
33
|
// Now set this new bid as the winning bid
|
|
34
34
|
await bidRepository.setWinningBid(bid.id, auctionId);
|
|
35
|
+
// `bidsHaveStarted` and `leadingBidderId` are set by the primary bid path
|
|
36
|
+
// (`features/auctions/actions/bid-actions.ts`) but were missing here, so a
|
|
37
|
+
// bid placed through this legacy entrypoint left both mirrors stale —
|
|
38
|
+
// CLAUDE.md Root Cause #42.
|
|
35
39
|
const updates = {
|
|
36
40
|
currentBid: amount,
|
|
37
41
|
bidCount: (product.bidCount ?? 0) + 1,
|
|
42
|
+
leadingBidderId: user.uid,
|
|
43
|
+
bidsHaveStarted: true,
|
|
38
44
|
};
|
|
39
45
|
if (shouldAutoExtend(product)) {
|
|
40
46
|
updates.auctionEndDate = computeExtendedEndDate(product);
|
|
@@ -40,6 +40,22 @@ export declare const listBundleMembers: (bundle: Pick<CategoryDocument, "bundleP
|
|
|
40
40
|
* displayed discount.
|
|
41
41
|
*/
|
|
42
42
|
export declare function resolveBundleOriginalTotal(productIds: string[]): Promise<number | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* Union of the member products' `categorySlugs` — the `bundleCategorySlugs`
|
|
45
|
+
* mirror that lets a category page scope its Bundles tab.
|
|
46
|
+
*
|
|
47
|
+
* A bundle row has no category field of its own, which is why the category page
|
|
48
|
+
* counted every active bundle site-wide before this existed. Maintained at the
|
|
49
|
+
* same call sites as `resolveBundleOriginalTotal` so the two mirrors cannot
|
|
50
|
+
* drift apart.
|
|
51
|
+
*
|
|
52
|
+
* Unlike the price total, a partially-resolvable member set still yields a
|
|
53
|
+
* useful answer: over-inclusion (a bundle appearing under one category too many)
|
|
54
|
+
* is a far smaller error than a bundle vanishing from the category it belongs
|
|
55
|
+
* to, and readers already treat an ABSENT mirror as "unscoped" rather than
|
|
56
|
+
* "belongs nowhere" (Root Cause #42).
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveBundleCategorySlugs(productIds: string[]): Promise<string[]>;
|
|
43
59
|
/**
|
|
44
60
|
* List the most recent active bundles for homepage placement. Bounded to
|
|
45
61
|
* `limit` (default 8) and filtered to `isActive: true` server-side.
|
|
@@ -68,6 +68,32 @@ export async function resolveBundleOriginalTotal(productIds) {
|
|
|
68
68
|
const total = prices.reduce((sum, p) => sum + p, 0);
|
|
69
69
|
return Math.round(total * 100) / 100;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Union of the member products' `categorySlugs` — the `bundleCategorySlugs`
|
|
73
|
+
* mirror that lets a category page scope its Bundles tab.
|
|
74
|
+
*
|
|
75
|
+
* A bundle row has no category field of its own, which is why the category page
|
|
76
|
+
* counted every active bundle site-wide before this existed. Maintained at the
|
|
77
|
+
* same call sites as `resolveBundleOriginalTotal` so the two mirrors cannot
|
|
78
|
+
* drift apart.
|
|
79
|
+
*
|
|
80
|
+
* Unlike the price total, a partially-resolvable member set still yields a
|
|
81
|
+
* useful answer: over-inclusion (a bundle appearing under one category too many)
|
|
82
|
+
* is a far smaller error than a bundle vanishing from the category it belongs
|
|
83
|
+
* to, and readers already treat an ABSENT mirror as "unscoped" rather than
|
|
84
|
+
* "belongs nowhere" (Root Cause #42).
|
|
85
|
+
*/
|
|
86
|
+
export async function resolveBundleCategorySlugs(productIds) {
|
|
87
|
+
if (productIds.length === 0)
|
|
88
|
+
return [];
|
|
89
|
+
const results = await Promise.all(productIds.map((id) => productRepository.findById(id).catch(() => null)));
|
|
90
|
+
const slugs = new Set();
|
|
91
|
+
for (const p of results) {
|
|
92
|
+
for (const slug of p?.categorySlugs ?? [])
|
|
93
|
+
slugs.add(slug);
|
|
94
|
+
}
|
|
95
|
+
return [...slugs];
|
|
96
|
+
}
|
|
71
97
|
/**
|
|
72
98
|
* List the most recent active bundles for homepage placement. Bounded to
|
|
73
99
|
* `limit` (default 8) and filtered to `isActive: true` server-side.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, type BundleDataOptions, } from "./data";
|
|
1
|
+
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, resolveBundleCategorySlugs, type BundleDataOptions, } from "./data";
|
|
2
2
|
export { buildBundleMetadata, type BundleMetadataOptions } from "./metadata";
|
|
3
3
|
export { renderBundleOg, renderBundleOgImage, type BundleOgData, } from "./og";
|
|
4
4
|
export { addBundleToCartAction } from "./actions";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, } from "./data";
|
|
1
|
+
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, resolveBundleCategorySlugs, } from "./data";
|
|
2
2
|
export { buildBundleMetadata } from "./metadata";
|
|
3
3
|
// S-SBUNI-4 2026-05-13 — bundle OG renderer.
|
|
4
4
|
export { renderBundleOg, renderBundleOgImage, } from "./og";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
2
|
import type { addToCartSchema } from "../../../shared/features/cart/schema";
|
|
3
|
-
type
|
|
3
|
+
type AddToCartActionInput = z.infer<typeof addToCartSchema>;
|
|
4
4
|
export declare function assertCartCapacity(userId: string, addingQty: number): Promise<void>;
|
|
5
5
|
export declare function assertValidQuantity(quantity: number): void;
|
|
6
|
-
export declare function upsertCartItem(userId: string, item:
|
|
7
|
-
export declare function mergeGuestItems(userId: string, guestItems:
|
|
6
|
+
export declare function upsertCartItem(userId: string, item: AddToCartActionInput): Promise<void>;
|
|
7
|
+
export declare function mergeGuestItems(userId: string, guestItems: AddToCartActionInput[]): Promise<void>;
|
|
8
8
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { normalizeError } from "../../../../errors/normalize";
|
|
2
|
+
import { buildOrderSourceContext } from "./source-context";
|
|
2
3
|
import { roundRupees } from "../../../../utils/number.formatter";
|
|
3
4
|
/**
|
|
4
5
|
* Checkout server actions (appkit).
|
|
@@ -488,6 +489,10 @@ async function createOrderForGroup(group, orderType, ctx) {
|
|
|
488
489
|
const displayedUpiId = hasPaymentWindow
|
|
489
490
|
? await resolveDisplayedUpiId(firstItem.storeId, siteContactUpiVpa)
|
|
490
491
|
: undefined;
|
|
492
|
+
// Both creation paths call the SAME builder — two hand-written copies is the
|
|
493
|
+
// create-vs-create axis of Root Cause #39, and these two functions have
|
|
494
|
+
// already drifted once before (add-on fees, Root Cause #65).
|
|
495
|
+
const sourceContext = await buildOrderSourceContext(firstItem, firstProduct, orderType);
|
|
491
496
|
const order = await unitOfWork.orders.create({
|
|
492
497
|
productId: firstItem.productId,
|
|
493
498
|
productTitle: firstItem.productTitle,
|
|
@@ -502,7 +507,15 @@ async function createOrderForGroup(group, orderType, ctx) {
|
|
|
502
507
|
storeName: firstItem.storeName || undefined,
|
|
503
508
|
items: orderItems,
|
|
504
509
|
orderType,
|
|
510
|
+
// How the buyer earned the right to buy at this price. `orderType` cannot
|
|
511
|
+
// answer that — it has five values, and both a settled win and a buyout
|
|
512
|
+
// are "auction". Written ONCE here and never recomputed: the auction and
|
|
513
|
+
// offer documents it summarises are mutable and eventually archived.
|
|
514
|
+
sourceContext,
|
|
505
515
|
offerId: firstItem.offerId ?? undefined,
|
|
516
|
+
// Distinguishes a Buy Now purchase from a settled auction win. Both are
|
|
517
|
+
// orderType "auction"; only this one gets the 24h admin-review window.
|
|
518
|
+
isBuyout: firstItem.isBuyout ? true : undefined,
|
|
506
519
|
status: adminBypass ? OrderStatusValues.PROCESSING : OrderStatusValues.PENDING,
|
|
507
520
|
paymentStatus: adminBypass ? PaymentStatusValues.PAID : PaymentStatusValues.PENDING,
|
|
508
521
|
paymentMethod: adminBypass ? PaymentMethodValues.ADMIN_BYPASS : paymentMethod,
|
|
@@ -1201,6 +1214,10 @@ async function createRazorpayGroupOrder(group, orderType, ctx) {
|
|
|
1201
1214
|
const extraOrderFields = {
|
|
1202
1215
|
...groupRuleRzp.decorateOrderDoc(group[0].item, group[0].product),
|
|
1203
1216
|
};
|
|
1217
|
+
// Both creation paths call the SAME builder — two hand-written copies is the
|
|
1218
|
+
// create-vs-create axis of Root Cause #39, and these two functions have
|
|
1219
|
+
// already drifted once before (add-on fees, Root Cause #65).
|
|
1220
|
+
const sourceContext = await buildOrderSourceContext(firstItem, group[0].product, orderType);
|
|
1204
1221
|
const order = await unitOfWork.orders.create({
|
|
1205
1222
|
productId: firstItem.productId,
|
|
1206
1223
|
productTitle: firstItem.productTitle,
|
|
@@ -1215,7 +1232,15 @@ async function createRazorpayGroupOrder(group, orderType, ctx) {
|
|
|
1215
1232
|
storeName: firstItem.storeName || undefined,
|
|
1216
1233
|
items: orderItems,
|
|
1217
1234
|
orderType,
|
|
1235
|
+
// How the buyer earned the right to buy at this price. `orderType` cannot
|
|
1236
|
+
// answer that — it has five values, and both a settled win and a buyout
|
|
1237
|
+
// are "auction". Written ONCE here and never recomputed: the auction and
|
|
1238
|
+
// offer documents it summarises are mutable and eventually archived.
|
|
1239
|
+
sourceContext,
|
|
1218
1240
|
offerId: firstItem.offerId ?? undefined,
|
|
1241
|
+
// Distinguishes a Buy Now purchase from a settled auction win. Both are
|
|
1242
|
+
// orderType "auction"; only this one gets the 24h admin-review window.
|
|
1243
|
+
isBuyout: firstItem.isBuyout ? true : undefined,
|
|
1219
1244
|
status: OrderStatusValues.CONFIRMED,
|
|
1220
1245
|
paymentStatus: PaymentStatusValues.PAID,
|
|
1221
1246
|
paymentMethod: PaymentMethodValues.ONLINE,
|
|
@@ -11,6 +11,38 @@ import type { CartItemDocument } from "../../../../features/cart/schemas/firesto
|
|
|
11
11
|
export declare function assertCheckoutLane(allCartItems: readonly CartItemDocument[], selectedItems: readonly CartItemDocument[]): void;
|
|
12
12
|
/** Error code the client maps to a lane-aware message. */
|
|
13
13
|
export declare const CHECKOUT_LANE_BLOCKED = "CHECKOUT_LANE_BLOCKED";
|
|
14
|
+
/** Why a buyout claim could not be converted into a sale. */
|
|
15
|
+
type ClaimFailure = "NOT_FOUND" | "ALREADY_SOLD" | "AUCTION_ENDED" | "LAPSED" | "OUTBID" | "WRONG_BUYER";
|
|
16
|
+
/**
|
|
17
|
+
* Convert a pending Buy Now claim into an actual sale, atomically.
|
|
18
|
+
*
|
|
19
|
+
* This is where a buyout is decided, and it is the ONLY place the auction is
|
|
20
|
+
* closed. `buyNowAuction` deliberately leaves the listing untouched: the auction
|
|
21
|
+
* keeps running, keeps taking bids, and keeps accepting other buyers' buyouts.
|
|
22
|
+
* That means several people can be holding a claim on the same auction at once,
|
|
23
|
+
* which is intentional — whoever reaches this transaction first gets the item,
|
|
24
|
+
* and everyone else is refused HERE, before their order is written and before
|
|
25
|
+
* any payment is captured.
|
|
26
|
+
*
|
|
27
|
+
* Four ways to lose, all of them checked inside the transaction against freshly
|
|
28
|
+
* read documents rather than against the caller's stale cart line:
|
|
29
|
+
* - the auction is already sold (another buyout committed first);
|
|
30
|
+
* - its clock ran out (settlement will award it to a real bidder — the user's
|
|
31
|
+
* explicit rule: an unfinished buyout at auction end fails);
|
|
32
|
+
* - the claim's own bid is no longer `active` (the deadline sweep cancelled it);
|
|
33
|
+
* - bidding passed the buyout price, so buying out is no longer the better deal.
|
|
34
|
+
*
|
|
35
|
+
* Returns a discriminated result rather than throwing out of the transaction
|
|
36
|
+
* body, so each of these precise, buyer-readable refusals survives as itself
|
|
37
|
+
* instead of being reshaped by the transaction wrapper. The caller throws.
|
|
38
|
+
*/
|
|
39
|
+
export declare function claimAuctionForCheckout(item: CartItemDocument, buyerUid: string): Promise<{
|
|
40
|
+
ok: true;
|
|
41
|
+
bidAmount: number;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
reason: ClaimFailure;
|
|
45
|
+
}>;
|
|
14
46
|
/**
|
|
15
47
|
* Re-validate every locked line immediately before the order is written.
|
|
16
48
|
*
|
|
@@ -18,6 +50,11 @@ export declare const CHECKOUT_LANE_BLOCKED = "CHECKOUT_LANE_BLOCKED";
|
|
|
18
50
|
* to the cart, but nothing re-checked at order time — so a buyer could add an
|
|
19
51
|
* accepted offer, wait out the 48h window, and still be charged the locked
|
|
20
52
|
* price. Throws on the first invalid line; the caller's transaction aborts.
|
|
53
|
+
*
|
|
54
|
+
* Auction lines were skipped entirely until 2026-08-24 (`if (!item.offerId)
|
|
55
|
+
* continue`), so a won auction's own `checkoutDeadline` had never been checked
|
|
56
|
+
* at order time at all — and a buyout claim, which is decided here, had nowhere
|
|
57
|
+
* to be decided.
|
|
21
58
|
*/
|
|
22
59
|
export declare function assertLockedLinesStillValid(items: readonly CartItemDocument[], buyerUid: string): Promise<void>;
|
|
23
60
|
/**
|
|
@@ -28,3 +65,4 @@ export declare function assertLockedLinesStillValid(items: readonly CartItemDocu
|
|
|
28
65
|
* bookkeeping problem, refusing a completed order is a customer-facing one.
|
|
29
66
|
*/
|
|
30
67
|
export declare function finalizeLockedLines(items: readonly CartItemDocument[], orderId: string): Promise<void>;
|
|
68
|
+
export {};
|