@mohasinac/appkit 4.9.5 → 4.11.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.d.ts +6 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +4 -1
- package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +1 -1
- package/dist/_internal/client/features/lottery/LotteryPullForm.js +2 -2
- package/dist/_internal/server/features/admin/daily-digest-actions.d.ts +18 -0
- package/dist/_internal/server/features/admin/daily-digest-actions.js +37 -0
- 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/audit-log/actions.d.ts +25 -0
- package/dist/_internal/server/features/audit-log/actions.js +38 -0
- package/dist/_internal/server/features/brands/actions.js +0 -2
- package/dist/_internal/server/features/brands/og.d.ts +4 -1
- package/dist/_internal/server/features/brands/og.js +1 -1
- 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 +16 -0
- package/dist/_internal/server/features/grouped/data.js +50 -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/orders/actions.js +9 -0
- package/dist/_internal/server/features/orders/adapters.js +25 -0
- 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/server/functions/scheduled.d.ts +3 -1
- package/dist/_internal/server/functions/scheduled.js +17 -1
- package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +40 -0
- package/dist/_internal/server/jobs/core/dailyStatusDigest.js +164 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +11 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
- package/dist/_internal/server/jobs/core/testerSandboxRefresh.d.ts +12 -0
- package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +85 -0
- package/dist/_internal/server/jobs/core/whatsappNotify.js +16 -0
- package/dist/_internal/server/jobs/handlers/dailyStatusDigest.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/dailyStatusDigest.js +4 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/index.js +3 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.js +2 -0
- package/dist/_internal/server/notifications/channel-health.d.ts +27 -0
- package/dist/_internal/server/notifications/channel-health.js +101 -0
- 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/features/brands/schema.d.ts +0 -6
- package/dist/_internal/shared/features/brands/schema.js +0 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +7 -0
- package/dist/_internal/shared/features/categories/bundle-schemas.js +3 -0
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- 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 +21 -12
- package/dist/client.js +14 -7
- package/dist/constants/api-endpoints.d.ts +9 -9
- package/dist/constants/api-endpoints.js +3 -3
- package/dist/contracts/client-auth.d.ts +3 -7
- package/dist/contracts/email.d.ts +1 -0
- package/dist/features/account/components/AddressForm.js +24 -2
- package/dist/features/account/components/BecomeSellerView.d.ts +1 -2
- package/dist/features/account/components/BecomeSellerView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +1 -1
- package/dist/features/account/components/UserBidsView.d.ts +1 -0
- package/dist/features/account/components/UserBidsView.js +47 -0
- package/dist/features/account/components/UserOrdersView.d.ts +4 -11
- package/dist/features/account/components/UserOrdersView.js +54 -4
- package/dist/features/account/components/UserReturnsView.d.ts +4 -9
- package/dist/features/account/components/UserReturnsView.js +37 -3
- package/dist/features/account/components/index.d.ts +3 -2
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/admin/actions/admin-actions.js +22 -0
- package/dist/features/admin/actions/admin-coupon-actions.js +10 -0
- package/dist/features/admin/actions/notification-actions.js +4 -3
- package/dist/features/admin/components/AdminAdsView.d.ts +2 -3
- package/dist/features/admin/components/AdminAdsView.js +86 -89
- package/dist/features/admin/components/AdminAllEventEntriesView.js +18 -3
- package/dist/features/admin/components/AdminAuditLogView.d.ts +11 -0
- package/dist/features/admin/components/AdminAuditLogView.js +95 -0
- package/dist/features/admin/components/AdminBlogEditorView.js +37 -3
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -6
- package/dist/features/admin/components/AdminBundleEditorView.js +18 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +2 -2
- package/dist/features/admin/components/AdminCarouselGroupEditorView.js +2 -2
- package/dist/features/admin/components/AdminCartsView.js +34 -4
- package/dist/features/admin/components/AdminCategoryEditorView.js +5 -4
- package/dist/features/admin/components/AdminCouponEditorView.js +2 -2
- package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
- package/dist/features/admin/components/AdminHistoryView.js +11 -1
- package/dist/features/admin/components/AdminNotificationsView.js +27 -1
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
- package/dist/features/admin/components/AdminOrdersView.js +92 -24
- package/dist/features/admin/components/AdminPayoutMarkPaidModal.d.ts +7 -0
- package/dist/features/admin/components/AdminPayoutMarkPaidModal.js +47 -0
- package/dist/features/admin/components/AdminPayoutsView.js +15 -31
- package/dist/features/admin/components/AdminProductEditorView.js +26 -3
- package/dist/features/admin/components/AdminSiteSettingsView.js +31 -4
- package/dist/features/admin/components/AdminStoreAddressesView.js +22 -2
- package/dist/features/admin/components/AdminStoresView.js +7 -0
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +2 -2
- package/dist/features/admin/components/AdminUserEditorView.d.ts +2 -2
- package/dist/features/admin/components/AdminUserEditorView.js +4 -2
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/AdminWishlistsView.js +14 -1
- package/dist/features/admin/components/DataListingView.d.ts +2 -2
- package/dist/features/admin/components/ViewAuditLogEntryModal.d.ts +19 -0
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +22 -0
- package/dist/features/admin/components/ViewNotificationModal.d.ts +21 -0
- package/dist/features/admin/components/ViewNotificationModal.js +15 -0
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +4 -7
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +56 -36
- package/dist/features/admin/components/index.d.ts +8 -1
- package/dist/features/admin/components/index.js +4 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +49 -0
- package/dist/features/admin/constants/filter-tabs.js +27 -0
- package/dist/features/admin/hooks/useAdminListing.d.ts +6 -0
- package/dist/features/admin/hooks/useAdminListing.js +3 -1
- package/dist/features/admin/hooks/useAdminListingData.d.ts +9 -1
- package/dist/features/admin/hooks/useAdminListingData.js +9 -2
- package/dist/features/admin/repository/site-settings.repository.d.ts +5 -0
- package/dist/features/admin/schemas/firestore.d.ts +21 -0
- package/dist/features/admin/schemas/firestore.js +6 -0
- package/dist/features/analytics/types.d.ts +1 -1
- package/dist/features/analytics/types.js +8 -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/auctions/schemas/index.d.ts +5 -0
- package/dist/features/audit-log/repository/audit-log.repository.d.ts +45 -0
- package/dist/features/audit-log/repository/audit-log.repository.js +30 -0
- package/dist/features/audit-log/schemas/firestore.d.ts +59 -0
- package/dist/features/audit-log/schemas/firestore.js +35 -0
- package/dist/features/auth/actions/index.d.ts +0 -1
- package/dist/features/auth/actions/index.js +0 -1
- package/dist/features/auth/hooks/useAuth.d.ts +8 -35
- package/dist/features/auth/hooks/useAuth.js +21 -37
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +2 -0
- package/dist/features/blog/schemas/index.d.ts +32 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +31 -3
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +2 -1
- 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/BrandDetailPageView.js +14 -12
- package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
- package/dist/features/categories/components/BundleDetailView.js +3 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +7 -3
- package/dist/features/categories/components/CategoryHighlightsAndFaqSection.d.ts +14 -0
- package/dist/features/categories/components/CategoryHighlightsAndFaqSection.js +22 -0
- package/dist/features/categories/components/CategoryProductsView.d.ts +1 -5
- package/dist/features/categories/components/CategoryProductsView.js +1 -1
- package/dist/features/categories/components/CategorySelectorCreate.js +16 -2
- package/dist/features/categories/schemas/firestore.d.ts +19 -2
- package/dist/features/categories/schemas/index.d.ts +24 -3
- package/dist/features/categories/schemas/index.js +3 -1
- package/dist/features/categories/types/index.d.ts +7 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +17 -3
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +101 -22
- 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/ContactForm.js +17 -4
- package/dist/features/contact/components/ContactPageView.js +8 -2
- package/dist/features/contact/email.d.ts +1 -0
- package/dist/features/contact/email.js +3 -0
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
- package/dist/features/events/components/AdminEventEditorView.js +54 -2
- package/dist/features/events/components/AdminEventEntriesView.d.ts +2 -16
- package/dist/features/events/components/AdminEventEntriesView.js +56 -89
- package/dist/features/events/components/EventFormDrawer.js +5 -1
- package/dist/features/events/components/EventRaffleEntryForm.d.ts +1 -3
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/schemas/index.d.ts +22 -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 +12 -0
- package/dist/features/grouped/repository/grouped-listings.repository.js +34 -0
- package/dist/features/homepage/components/CharacterHotspotForm.js +202 -187
- package/dist/features/homepage/components/SectionCarousel.d.ts +1 -7
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- 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/TitleBarLayout.d.ts +1 -1
- package/dist/features/layout/TitleBarLayout.js +3 -3
- 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/MediaImage.js +39 -3
- package/dist/features/media/MediaVideo.js +17 -1
- package/dist/features/media/types/index.d.ts +10 -0
- package/dist/features/media/types/index.js +1 -0
- package/dist/features/media/upload/MediaUploadField.d.ts +7 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -7
- package/dist/features/media/upload/video-poster.d.ts +2 -0
- package/dist/features/media/upload/video-poster.js +16 -1
- package/dist/features/media/upload/video-poster.test.js +1 -1
- package/dist/features/orders/components/OrderStatusTimeline.d.ts +12 -0
- package/dist/features/orders/components/OrderStatusTimeline.js +55 -0
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/constants/payment-window.d.ts +25 -0
- package/dist/features/orders/constants/payment-window.js +25 -0
- package/dist/features/orders/repository/orders.repository.d.ts +32 -0
- package/dist/features/orders/repository/orders.repository.js +56 -0
- package/dist/features/orders/schemas/index.d.ts +24 -24
- package/dist/features/orders/types/index.d.ts +33 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
- package/dist/features/pre-orders/schemas/index.d.ts +5 -0
- package/dist/features/products/components/BidHistory.js +9 -1
- package/dist/features/products/components/GroupSettingsPanel.js +25 -3
- package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
- package/dist/features/products/components/PrizeDrawEntryActions.d.ts +1 -4
- package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
- package/dist/features/products/components/ProductDetailActions.d.ts +1 -2
- package/dist/features/products/components/ProductDetailActions.js +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +11 -116
- package/dist/features/products/components/ProductGrid.js +15 -1
- package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
- package/dist/features/products/components/RelatedItemsSection.js +17 -0
- package/dist/features/products/constants/action-defs.d.ts +1 -0
- package/dist/features/products/constants/action-defs.js +1 -0
- package/dist/features/products/schemas/index.d.ts +5 -0
- package/dist/features/promotions/components/CouponsIndexListing.d.ts +1 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
- package/dist/features/search/components/SearchView.d.ts +1 -3
- package/dist/features/search/components/SearchView.js +1 -1
- package/dist/features/seller/components/QuickProductForm.js +2 -1
- package/dist/features/seller/components/SellerBidsView.js +66 -107
- package/dist/features/seller/components/SellerGoogleReviewsView.js +17 -1
- package/dist/features/seller/components/SellerOrdersView.d.ts +15 -3
- package/dist/features/seller/components/SellerOrdersView.js +134 -163
- package/dist/features/seller/components/SellerPayoutMethodsView.js +60 -48
- package/dist/features/seller/components/SellerPayoutSettingsView.js +69 -4
- package/dist/features/seller/components/SellerPayoutsView.d.ts +12 -0
- package/dist/features/seller/components/SellerPayoutsView.js +25 -5
- package/dist/features/seller/components/SellerProductShell.d.ts +10 -3
- package/dist/features/seller/components/SellerProductShell.js +90 -37
- package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +2 -7
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +4 -4
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -4
- package/dist/features/seller/components/SellerProductsView.js +131 -189
- package/dist/features/seller/components/SellerReviewsView.js +95 -133
- package/dist/features/seller/components/SellerShippingConfigsView.js +47 -67
- package/dist/features/seller/components/SellerShippingView.js +41 -4
- package/dist/features/seller/components/SellerStoreCategoriesView.js +51 -59
- package/dist/features/seller/components/SellerStorefrontView.d.ts +6 -1
- package/dist/features/seller/components/SellerStorefrontView.js +42 -5
- package/dist/features/seller/components/index.d.ts +2 -2
- package/dist/features/seller/components/index.js +2 -2
- package/dist/features/shell/FormShell.d.ts +24 -4
- package/dist/features/shell/FormShell.js +12 -6
- package/dist/features/shell/QuickFormDrawer.js +67 -12
- package/dist/features/shell/StepForm.d.ts +30 -1
- package/dist/features/shell/StepForm.js +47 -4
- package/dist/features/shell/index.d.ts +1 -1
- package/dist/features/shell/index.js +1 -1
- package/dist/features/shipments/components/AdminShipmentEditorView.js +2 -2
- package/dist/features/shipments/schemas/validation.d.ts +14 -4
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +23 -2
- package/dist/features/tester/components/TesterChecklistStepRow.js +1 -1
- package/dist/features/tester/components/TesterHubView.js +3 -2
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +9 -1
- package/dist/features/tester/seed-data/products-tester-seed-data.js +43 -32
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +487 -18
- package/dist/index.d.ts +17 -3
- package/dist/index.js +23 -5
- package/dist/next/routing/route-map.d.ts +13 -0
- package/dist/next/routing/route-map.js +12 -0
- package/dist/providers/email-resend/provider.js +1 -0
- package/dist/providers/firebase-client/auth.d.ts +1 -0
- package/dist/providers/firebase-client/auth.js +7 -1
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.js +1 -0
- package/dist/schemas/registry.d.ts +61 -25
- package/dist/security/pii-mask.js +1 -1
- package/dist/seed/bids-seed-data.js +48 -3
- package/dist/seed/categories-seed-data.js +69 -0
- 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 +226 -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 +234 -4
- package/dist/seed/products-stickers-seed-data.js +178 -5
- package/dist/seed/site-settings-seed-data.js +23 -30
- package/dist/seed/store-extensions-seed-data.js +2 -2
- package/dist/server-entry.d.ts +6 -2
- package/dist/server-entry.js +24 -3
- package/dist/server.d.ts +10 -3
- package/dist/server.js +11 -4
- package/dist/styles.css +29 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Form.d.ts +11 -2
- package/dist/ui/components/Form.js +4 -3
- package/dist/ui/components/FormField.d.ts +3 -1
- package/dist/ui/components/FormField.js +22 -4
- package/dist/ui/components/ImageLightbox.js +37 -3
- package/dist/ui/components/ImageLightbox.style.css +28 -0
- package/dist/ui/components/ListingLayout.d.ts +1 -2
- package/dist/ui/components/ListingLayout.js +1 -1
- package/dist/ui/components/RecordDetailModal.d.ts +68 -0
- package/dist/ui/components/RecordDetailModal.js +8 -0
- package/dist/ui/components/SlottedListingView.js +9 -1
- package/dist/ui/forms/FormErrorSummary.d.ts +25 -0
- package/dist/ui/forms/FormErrorSummary.js +37 -0
- package/dist/ui/forms/FormShell.d.ts +37 -2
- package/dist/ui/forms/FormShell.js +37 -7
- package/dist/ui/forms/FormShell.style.css +17 -0
- package/dist/ui/forms/index.d.ts +2 -0
- package/dist/ui/forms/index.js +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +5 -0
- package/dist/utils/media-url.d.ts +12 -1
- package/dist/utils/media-url.js +59 -1
- package/dist/validation/schemas.d.ts +4 -4
- package/package.json +1 -1
- package/dist/_internal/client/features/classified/ClassifiedDetailView.d.ts +0 -9
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +0 -55
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.d.ts +0 -18
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +0 -21
- package/dist/_internal/client/features/live/LiveItemDetailView.d.ts +0 -9
- package/dist/_internal/client/features/live/LiveItemDetailView.js +0 -25
- package/dist/_internal/server/jobs/core/prizeRevealClose.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealClose.js +0 -28
- package/dist/_internal/server/jobs/core/prizeRevealExpiry.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +0 -61
- package/dist/_internal/server/jobs/core/prizeRevealOpen.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealOpen.js +0 -68
- package/dist/_internal/server/jobs/core/prizeRevealReminder.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealReminder.js +0 -49
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +0 -2
- package/dist/features/auth/consent-otp.d.ts +0 -57
- package/dist/features/auth/consent-otp.js +0 -127
- package/dist/features/cart/components/CheckoutOtpModal.d.ts +0 -15
- package/dist/features/cart/components/CheckoutOtpModal.js +0 -12
- package/dist/features/checkout/actions/checkout-actions.d.ts +0 -31
- package/dist/features/checkout/actions/checkout-actions.js +0 -124
- package/dist/features/classified/components/ClassifiedIndexListing.d.ts +0 -5
- package/dist/features/classified/components/ClassifiedIndexListing.js +0 -123
- package/dist/features/classified/components/ClassifiedListView.d.ts +0 -6
- package/dist/features/classified/components/ClassifiedListView.js +0 -44
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +0 -5
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +0 -114
- package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +0 -6
- package/dist/features/digital-codes/components/DigitalCodesListView.js +0 -38
- package/dist/features/live/components/LiveItemsIndexListing.d.ts +0 -5
- package/dist/features/live/components/LiveItemsIndexListing.js +0 -115
- package/dist/features/live/components/LiveItemsListView.d.ts +0 -6
- package/dist/features/live/components/LiveItemsListView.js +0 -44
- package/dist/features/seller/components/SellerTemplatesView.d.ts +0 -12
- package/dist/features/seller/components/SellerTemplatesView.js +0 -276
- package/dist/react/hooks/useVisibleItems.d.ts +0 -37
- package/dist/react/hooks/useVisibleItems.js +0 -59
- package/dist/ui/components/TabStrip.d.ts +0 -34
- package/dist/ui/components/TabStrip.js +0 -56
- package/dist/ui/components/TabStrip.style.css +0 -97
|
@@ -35,7 +35,12 @@ export interface DashboardLayoutClientProps {
|
|
|
35
35
|
permissions?: string[] | null;
|
|
36
36
|
/** Override active-link highlight. Defaults to usePathname(). */
|
|
37
37
|
activeHref?: string;
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Responsive controls — accepted for interface parity with the generic
|
|
40
|
+
* `SectionResponsive` shape used elsewhere, but not currently honoured by
|
|
41
|
+
* this component (no caller passes it today). Wire `hideAt`/`showAt`/
|
|
42
|
+
* `compactAt` to real chrome behaviour before relying on this prop.
|
|
43
|
+
*/
|
|
39
44
|
responsive?: SectionResponsive;
|
|
40
45
|
/**
|
|
41
46
|
* Cross-dashboard nav links shown in the sidebar footer. Plain hrefs
|
|
@@ -155,7 +155,10 @@ function DashboardBottomNav({ items, activeHref }) {
|
|
|
155
155
|
const DEFAULT_CONTENT_PADDING_RIGHT = "px-[var(--appkit-space-5)] py-[var(--appkit-space-8)] lg:pl-14 lg:pr-6 xl:pl-16 xl:pr-10";
|
|
156
156
|
const DEFAULT_CONTENT_PADDING_LEFT = "px-[var(--appkit-space-5)] py-[var(--appkit-space-8)] lg:pr-14 lg:pl-6 xl:pr-16 xl:pl-10";
|
|
157
157
|
const DEFAULT_CONTENT_MAX_WIDTH = "max-w-screen-2xl";
|
|
158
|
-
export function DashboardLayoutClient({ variant, groups, permissions, activeHref: explicitActiveHref,
|
|
158
|
+
export function DashboardLayoutClient({ variant, groups, permissions, activeHref: explicitActiveHref,
|
|
159
|
+
// audit-dead-underscore-prop-ok: accepted for interface parity, not yet
|
|
160
|
+
// wired — see the doc comment on `responsive` above; no caller passes it.
|
|
161
|
+
responsive: _responsive, crossNav, className, contentPadding, contentSurface, contentMaxWidth, lightBackground, darkBackground, children, }) {
|
|
159
162
|
const pathname = usePathname();
|
|
160
163
|
const activeHref = explicitActiveHref ?? pathname ?? "";
|
|
161
164
|
const storageKey = `appkit:sidebar-open:${variant}`;
|
|
@@ -16,5 +16,5 @@ interface LotteryPullFormProps {
|
|
|
16
16
|
* Submits TX ID + phone + payment time + item number.
|
|
17
17
|
* On success, shows the user their lottery number and assigned prize slot.
|
|
18
18
|
*/
|
|
19
|
-
export declare function LotteryPullForm({ sourceType, eventId, productId, totalSlots, maxPullsPerUser
|
|
19
|
+
export declare function LotteryPullForm({ sourceType, eventId, productId, totalSlots, maxPullsPerUser, onSuccess, }: LotteryPullFormProps): React.JSX.Element;
|
|
20
20
|
export {};
|
|
@@ -10,7 +10,7 @@ import { apiClient } from "../../../../http";
|
|
|
10
10
|
* Submits TX ID + phone + payment time + item number.
|
|
11
11
|
* On success, shows the user their lottery number and assigned prize slot.
|
|
12
12
|
*/
|
|
13
|
-
export function LotteryPullForm({ sourceType, eventId, productId, totalSlots, maxPullsPerUser
|
|
13
|
+
export function LotteryPullForm({ sourceType, eventId, productId, totalSlots, maxPullsPerUser, onSuccess, }) {
|
|
14
14
|
const [result, setResult] = useState(null);
|
|
15
15
|
const [transactionId, setTransactionId] = useState("");
|
|
16
16
|
const [paymentTime, setPaymentTime] = useState("");
|
|
@@ -39,7 +39,7 @@ export function LotteryPullForm({ sourceType, eventId, productId, totalSlots, ma
|
|
|
39
39
|
if (result) {
|
|
40
40
|
return (_jsxs(Stack, { gap: "sm", padding: "md", rounded: "2xl", surface: "success-surface", className: "border border-success/20", children: [_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Span, { layout: "inline-flex", color: "inverse", weight: "semibold", className: "bg-success text-[11px] tracking-wide", padding: "pill-sm", rounded: "full", transform: "uppercase", children: "Entry Confirmed" }), _jsxs(Heading, { level: 2, className: "text-success", size: "lg", weight: "bold", children: ["You're #", result.userLotteryNumber, "!"] })] }), _jsxs(Text, { className: "text-success", size: "sm", children: ["You've been assigned", " ", _jsxs(Span, { weight: "bold", children: ["Slot #", result.assignedPrizeSlotNumber] }), result.slotName ? ` — ${result.slotName}` : "", ". Good luck!"] })] }));
|
|
41
41
|
}
|
|
42
|
-
return (_jsx(Form, { onSubmit: (e) => e.preventDefault(), className: "space-y-4", children: ({ setFieldError, clearErrors }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, size: "lg", weight: "semibold", children: "Submit Your Entry" }),
|
|
42
|
+
return (_jsx(Form, { onSubmit: (e) => e.preventDefault(), className: "space-y-4", children: ({ setFieldError, clearErrors }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, size: "lg", weight: "semibold", children: "Submit Your Entry" }), _jsxs(Text, { size: "sm", color: "muted", children: ["Enter your UPI Transaction ID and payment details to claim your slot.", " ", "You may enter up to ", maxPullsPerUser, " time", maxPullsPerUser === 1 ? "" : "s", "."] }), _jsx(FieldInput, { name: "transactionId", label: "Transaction ID (UPI Ref / Payment Ref)", placeholder: "e.g. 123456789012", required: true, value: transactionId, onChange: (v) => { setTransactionId(v); clearErrors(); } }), _jsx(FieldInput, { name: "paymentTime", label: "Payment Date & Time", type: "datetime-local", required: true, value: paymentTime, onChange: (v) => { setPaymentTime(v); clearErrors(); } }), _jsx(FieldInput, { name: "itemNumber", label: `Slot Number (1 – ${totalSlots})`, type: "number", placeholder: `Enter a number between 1 and ${totalSlots}`, required: true, value: itemNumber, onChange: (v) => { setItemNumber(v); clearErrors(); } }), _jsx(FieldInput, { name: "userPhone", label: "Your Phone Number", type: "tel", placeholder: "e.g. 9876543210", required: true, value: userPhone, onChange: (v) => { setUserPhone(v); clearErrors(); } }), _jsx(Button, { type: "submit", variant: "primary", isLoading: mutation.isPending, onClick: () => {
|
|
43
43
|
clearErrors();
|
|
44
44
|
const num = parseInt(itemNumber, 10);
|
|
45
45
|
let valid = true;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual trigger for the daily status digest.
|
|
3
|
+
*
|
|
4
|
+
* The digest normally runs from the `dailyStatusDigest` scheduled Firebase
|
|
5
|
+
* Function (10:00 IST). Firebase has no "run on first deploy" trigger, so
|
|
6
|
+
* this exists to fire the exact same core function on demand — e.g. right
|
|
7
|
+
* after a fresh deploy, to confirm the whole chain works without waiting
|
|
8
|
+
* for the next morning. Both paths share one implementation; there is no
|
|
9
|
+
* second copy of the digest logic.
|
|
10
|
+
*/
|
|
11
|
+
import { type DailyStatusDigestResult } from "../../jobs/core/dailyStatusDigest";
|
|
12
|
+
export declare function triggerDailyStatusDigest(): Promise<DailyStatusDigestResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Fires the digest once per deployment version, from server startup.
|
|
15
|
+
* Safe to call on every cold start — `runDeploymentDigest` claims the
|
|
16
|
+
* version in a Firestore transaction and no-ops if it's already been sent.
|
|
17
|
+
*/
|
|
18
|
+
export declare function triggerDeploymentDigest(version: string): Promise<DailyStatusDigestResult>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manual trigger for the daily status digest.
|
|
3
|
+
*
|
|
4
|
+
* The digest normally runs from the `dailyStatusDigest` scheduled Firebase
|
|
5
|
+
* Function (10:00 IST). Firebase has no "run on first deploy" trigger, so
|
|
6
|
+
* this exists to fire the exact same core function on demand — e.g. right
|
|
7
|
+
* after a fresh deploy, to confirm the whole chain works without waiting
|
|
8
|
+
* for the next morning. Both paths share one implementation; there is no
|
|
9
|
+
* second copy of the digest logic.
|
|
10
|
+
*/
|
|
11
|
+
import { getAdminDb } from "../../../../providers/db-firebase";
|
|
12
|
+
import { serverLogger } from "../../../../monitoring";
|
|
13
|
+
import { runDailyStatusDigest, runDeploymentDigest, } from "../../jobs/core/dailyStatusDigest";
|
|
14
|
+
function buildManualJobContext(job) {
|
|
15
|
+
return {
|
|
16
|
+
job,
|
|
17
|
+
db: getAdminDb(),
|
|
18
|
+
logger: {
|
|
19
|
+
info: (message, meta) => serverLogger.info(message, meta),
|
|
20
|
+
warn: (message, meta) => serverLogger.warn(message, meta),
|
|
21
|
+
error: (message, err, meta) => serverLogger.error(message, { err, ...(meta ?? {}) }),
|
|
22
|
+
},
|
|
23
|
+
env: (key) => process.env[key],
|
|
24
|
+
now: new Date(),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export async function triggerDailyStatusDigest() {
|
|
28
|
+
return runDailyStatusDigest(buildManualJobContext("dailyStatusDigest:manual"));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fires the digest once per deployment version, from server startup.
|
|
32
|
+
* Safe to call on every cold start — `runDeploymentDigest` claims the
|
|
33
|
+
* version in a Firestore transaction and no-ops if it's already been sent.
|
|
34
|
+
*/
|
|
35
|
+
export async function triggerDeploymentDigest(version) {
|
|
36
|
+
return runDeploymentDigest(buildManualJobContext("dailyStatusDigest:deploy"), version);
|
|
37
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
import { wrapAction } from "@mohasinac/appkit/server";
|
|
3
|
-
import { bidRepository, productRepository, userRepository } from "../../../../repositories";
|
|
3
|
+
import { bidRepository, productRepository, userRepository, siteSettingsRepository } from "../../../../repositories";
|
|
4
4
|
import { requireRoleUser } from "../../../../providers/auth-firebase/helpers";
|
|
5
5
|
import { placeBidSchema } from "../../../shared/features/auctions/schema";
|
|
6
6
|
import { assertAuctionActive, assertBidAmount, assertNotAuctionOwner, shouldAutoExtend, computeExtendedEndDate, } from "./service";
|
|
@@ -14,7 +14,8 @@ export async function placeBidAction(input) {
|
|
|
14
14
|
const { auctionId, amount } = parsed.data;
|
|
15
15
|
const product = await assertAuctionActive(auctionId);
|
|
16
16
|
assertNotAuctionOwner(product, user.uid);
|
|
17
|
-
|
|
17
|
+
const settings = await siteSettingsRepository.getSingleton();
|
|
18
|
+
assertBidAmount(product, amount, settings.auctionConfig?.bidIncrementTiers ?? []);
|
|
18
19
|
const profile = await userRepository.findById(user.uid).catch(() => null);
|
|
19
20
|
const userName = profile?.displayName ?? user.name ?? "Anonymous";
|
|
20
21
|
// Mark all current bids for this auction as outbid, then set new winning bid
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type BidIncrementTier } from "../../../shared/features/auctions/config";
|
|
1
2
|
import type { ProductDocument } from "../../../shared/features/products/types";
|
|
2
3
|
/** Assert an auction exists, is published, and is still active. Returns the product. */
|
|
3
4
|
export declare function assertAuctionActive(auctionId: string): Promise<ProductDocument>;
|
|
4
|
-
/** Compute the minimum valid bid given the current state. */
|
|
5
|
-
export declare function computeMinBid(product: ProductDocument): number;
|
|
5
|
+
/** Compute the minimum valid bid given the current state and the admin's tier table. */
|
|
6
|
+
export declare function computeMinBid(product: ProductDocument, tiers: BidIncrementTier[]): number;
|
|
6
7
|
/** Assert a bid amount is valid against the current auction state. */
|
|
7
|
-
export declare function assertBidAmount(product: ProductDocument, amount: number): void;
|
|
8
|
+
export declare function assertBidAmount(product: ProductDocument, amount: number, tiers: BidIncrementTier[]): void;
|
|
8
9
|
/** Assert the bidder is not the auction owner. */
|
|
9
10
|
export declare function assertNotAuctionOwner(product: ProductDocument, bidderId: string): void;
|
|
10
11
|
/** Return true if the bid was placed within the sniping window and the auction should auto-extend. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { productRepository } from "../../../../repositories";
|
|
2
2
|
import { isAuctionListing } from "../../../../features/products/utils/listing-type";
|
|
3
3
|
import { AuctionNotFoundError, AuctionEndedError, BidTooLowError, BidOnOwnAuctionError, } from "../../../shared/features/auctions/errors";
|
|
4
|
-
import {
|
|
4
|
+
import { AUCTION_SNIPING_WINDOW_SECONDS, AUCTION_DEFAULT_EXTENSION_MINUTES, resolveMinBidIncrement, } from "../../../shared/features/auctions/config";
|
|
5
5
|
/** Assert an auction exists, is published, and is still active. Returns the product. */
|
|
6
6
|
export async function assertAuctionActive(auctionId) {
|
|
7
7
|
const product = await productRepository.findByIdOrSlug(auctionId).catch(() => null);
|
|
@@ -16,15 +16,15 @@ export async function assertAuctionActive(auctionId) {
|
|
|
16
16
|
throw new AuctionEndedError(auctionId);
|
|
17
17
|
return product;
|
|
18
18
|
}
|
|
19
|
-
/** Compute the minimum valid bid given the current state. */
|
|
20
|
-
export function computeMinBid(product) {
|
|
19
|
+
/** Compute the minimum valid bid given the current state and the admin's tier table. */
|
|
20
|
+
export function computeMinBid(product, tiers) {
|
|
21
21
|
const current = product.currentBid ?? product.startingBid ?? 0;
|
|
22
|
-
const increment = product.minBidIncrement
|
|
22
|
+
const increment = resolveMinBidIncrement(current, tiers, product.minBidIncrement);
|
|
23
23
|
return current + increment;
|
|
24
24
|
}
|
|
25
25
|
/** Assert a bid amount is valid against the current auction state. */
|
|
26
|
-
export function assertBidAmount(product, amount) {
|
|
27
|
-
const minBid = computeMinBid(product);
|
|
26
|
+
export function assertBidAmount(product, amount, tiers) {
|
|
27
|
+
const minBid = computeMinBid(product, tiers);
|
|
28
28
|
if (amount < minBid)
|
|
29
29
|
throw new BidTooLowError(minBid);
|
|
30
30
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recordAdminAction — the single write-site for the admin audit trail.
|
|
3
|
+
*
|
|
4
|
+
* MVP scope: instruments the highest-value already-privileged admin actions
|
|
5
|
+
* (bans, checkout bypass, coupon edits, payout mark-paid, store status
|
|
6
|
+
* changes, role changes) rather than sweeping every write path in the app —
|
|
7
|
+
* see CLAUDE.md's "Admin Audit Log" section for the full instrumented-action
|
|
8
|
+
* list and rationale.
|
|
9
|
+
*
|
|
10
|
+
* Callers should treat this as best-effort/non-blocking — a failure to write
|
|
11
|
+
* an audit entry must never fail the underlying privileged action itself.
|
|
12
|
+
*/
|
|
13
|
+
import type { AdminAuditAction } from "../../../../features/audit-log/schemas/firestore";
|
|
14
|
+
import type { JsonValue } from "../../../../schemas/types";
|
|
15
|
+
export interface RecordAdminActionInput {
|
|
16
|
+
actorUid: string;
|
|
17
|
+
actorName?: string;
|
|
18
|
+
action: AdminAuditAction;
|
|
19
|
+
targetType: string;
|
|
20
|
+
targetId: string;
|
|
21
|
+
targetLabel?: string;
|
|
22
|
+
reason?: string;
|
|
23
|
+
metadata?: Record<string, JsonValue>;
|
|
24
|
+
}
|
|
25
|
+
export declare function recordAdminAction(input: RecordAdminActionInput): Promise<void>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* recordAdminAction — the single write-site for the admin audit trail.
|
|
3
|
+
*
|
|
4
|
+
* MVP scope: instruments the highest-value already-privileged admin actions
|
|
5
|
+
* (bans, checkout bypass, coupon edits, payout mark-paid, store status
|
|
6
|
+
* changes, role changes) rather than sweeping every write path in the app —
|
|
7
|
+
* see CLAUDE.md's "Admin Audit Log" section for the full instrumented-action
|
|
8
|
+
* list and rationale.
|
|
9
|
+
*
|
|
10
|
+
* Callers should treat this as best-effort/non-blocking — a failure to write
|
|
11
|
+
* an audit entry must never fail the underlying privileged action itself.
|
|
12
|
+
*/
|
|
13
|
+
import { adminAuditLogRepository } from "../../../../features/audit-log/repository/audit-log.repository";
|
|
14
|
+
import { normalizeError } from "../../../../errors/normalize";
|
|
15
|
+
import { serverLogger } from "../../../../monitoring";
|
|
16
|
+
export async function recordAdminAction(input) {
|
|
17
|
+
try {
|
|
18
|
+
await adminAuditLogRepository.create({
|
|
19
|
+
actorUid: input.actorUid,
|
|
20
|
+
actorName: input.actorName,
|
|
21
|
+
action: input.action,
|
|
22
|
+
targetType: input.targetType,
|
|
23
|
+
targetId: input.targetId,
|
|
24
|
+
targetLabel: input.targetLabel,
|
|
25
|
+
reason: input.reason,
|
|
26
|
+
metadata: input.metadata,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const normalized = normalizeError(err);
|
|
31
|
+
serverLogger.warn("recordAdminAction failed (non-critical)", {
|
|
32
|
+
action: input.action,
|
|
33
|
+
targetType: input.targetType,
|
|
34
|
+
targetId: input.targetId,
|
|
35
|
+
error: normalized.message,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -26,8 +26,6 @@ function brandInputToCategoryFields(input) {
|
|
|
26
26
|
out.brandCountry = input.country;
|
|
27
27
|
if (input.founded !== undefined)
|
|
28
28
|
out.brandFounded = input.founded;
|
|
29
|
-
if (input.bannerURL !== undefined)
|
|
30
|
-
out.brandBannerImage = input.bannerURL;
|
|
31
29
|
if (input.logoURL !== undefined) {
|
|
32
30
|
out.display = { coverImage: input.logoURL, showInMenu: false, showInFooter: false };
|
|
33
31
|
}
|
|
@@ -7,7 +7,10 @@ export interface BrandOgData {
|
|
|
7
7
|
interface BrandDocLike {
|
|
8
8
|
name?: string | null;
|
|
9
9
|
description?: string | null;
|
|
10
|
-
logoURL
|
|
10
|
+
/** CategoryDocument has no `logoURL` field — the brand's image lives at `display.coverImage`, the same field the hero banner and generateMetadata's OG meta tag already use. */
|
|
11
|
+
display?: {
|
|
12
|
+
coverImage?: string | null;
|
|
13
|
+
} | null;
|
|
11
14
|
}
|
|
12
15
|
/** High-level OG renderer — accepts the raw brand document from `getBrandForDetail`. */
|
|
13
16
|
export declare function renderBrandOg(doc: BrandDocLike | null | undefined, opts: {
|
|
@@ -7,7 +7,7 @@ export function renderBrandOg(doc, opts) {
|
|
|
7
7
|
name,
|
|
8
8
|
description: doc?.description?.slice(0, 120) ??
|
|
9
9
|
`Shop authentic ${name} collectibles on ${opts.siteName}.`,
|
|
10
|
-
logoUrl: resolveOgImageUrl(doc?.
|
|
10
|
+
logoUrl: resolveOgImageUrl(doc?.display?.coverImage ?? null, opts.baseUrl),
|
|
11
11
|
}, opts.siteName);
|
|
12
12
|
}
|
|
13
13
|
export function renderBrandOgImage(data, siteName) {
|
|
@@ -45,3 +45,12 @@ export declare function resolveBundleOriginalTotal(productIds: string[]): Promis
|
|
|
45
45
|
* `limit` (default 8) and filtered to `isActive: true` server-side.
|
|
46
46
|
*/
|
|
47
47
|
export declare const listFeaturedBundles: (limit?: number, _opts?: BundleDataOptions) => Promise<CategoryDocument[]>;
|
|
48
|
+
/**
|
|
49
|
+
* "Related Bundles" for the bundle detail page — every other active bundle,
|
|
50
|
+
* excluding the current one. Bundles are a CategoryDocument, not a
|
|
51
|
+
* ProductDocument, so this mirrors BrandDetailPageView's "Related Brands"
|
|
52
|
+
* pattern (all active siblings of the same categoryType) rather than the
|
|
53
|
+
* product-based 4-signal computeRelatedItems() used elsewhere — bundle
|
|
54
|
+
* detail pages had no related section at all before this.
|
|
55
|
+
*/
|
|
56
|
+
export declare const getRelatedBundles: (bundle: Pick<CategoryDocument, "id">, limit?: number) => Promise<CategoryDocument[]>;
|
|
@@ -79,3 +79,17 @@ export const listFeaturedBundles = cache(async (limit = 8, _opts) => {
|
|
|
79
79
|
.catch(() => []);
|
|
80
80
|
return all;
|
|
81
81
|
});
|
|
82
|
+
/**
|
|
83
|
+
* "Related Bundles" for the bundle detail page — every other active bundle,
|
|
84
|
+
* excluding the current one. Bundles are a CategoryDocument, not a
|
|
85
|
+
* ProductDocument, so this mirrors BrandDetailPageView's "Related Brands"
|
|
86
|
+
* pattern (all active siblings of the same categoryType) rather than the
|
|
87
|
+
* product-based 4-signal computeRelatedItems() used elsewhere — bundle
|
|
88
|
+
* detail pages had no related section at all before this.
|
|
89
|
+
*/
|
|
90
|
+
export const getRelatedBundles = cache(async (bundle, limit = 8) => {
|
|
91
|
+
const all = await categoriesRepository
|
|
92
|
+
.listByType("bundle", { activeOnly: true, limit: limit + 1 })
|
|
93
|
+
.catch(() => []);
|
|
94
|
+
return all.filter((b) => b.id !== bundle.id).slice(0, limit);
|
|
95
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, type BundleDataOptions, } from "./data";
|
|
1
|
+
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, 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, resolveBundleMemberIds, resolveBundleOriginalTotal, } from "./data";
|
|
1
|
+
export { getBundleForDetail, listBundleMembers, listFeaturedBundles, getRelatedBundles, resolveBundleMemberIds, resolveBundleOriginalTotal, } 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";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
export interface CatalogueItemOgData {
|
|
3
|
+
title: string;
|
|
4
|
+
ownerName?: string | null;
|
|
5
|
+
priceLabel?: string | null;
|
|
6
|
+
imageUrl?: string | null;
|
|
7
|
+
}
|
|
8
|
+
interface CatalogueItemDocLike {
|
|
9
|
+
title?: string | null;
|
|
10
|
+
price?: number | null;
|
|
11
|
+
mainImage?: string | null;
|
|
12
|
+
images?: (string | null | undefined)[] | null;
|
|
13
|
+
}
|
|
14
|
+
export declare function renderCatalogueItemOg(doc: CatalogueItemDocLike | null | undefined, opts: {
|
|
15
|
+
siteName: string;
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
ownerName?: string | null;
|
|
18
|
+
}): ReactElement;
|
|
19
|
+
export declare function renderCatalogueItemOgImage(data: CatalogueItemOgData, siteName: string): ReactElement;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { renderOgLayout } from "../seo/og-layout";
|
|
2
|
+
import { resolveOgImageUrl } from "../seo/og";
|
|
3
|
+
export function renderCatalogueItemOg(doc, opts) {
|
|
4
|
+
const priceLabel = doc?.price != null && doc.price > 0
|
|
5
|
+
? new Intl.NumberFormat("en-IN", {
|
|
6
|
+
style: "currency",
|
|
7
|
+
currency: "INR",
|
|
8
|
+
maximumFractionDigits: 0,
|
|
9
|
+
}).format(doc.price)
|
|
10
|
+
: null;
|
|
11
|
+
return renderCatalogueItemOgImage({
|
|
12
|
+
title: doc?.title ?? "Catalogue Item",
|
|
13
|
+
ownerName: opts.ownerName,
|
|
14
|
+
priceLabel,
|
|
15
|
+
imageUrl: resolveOgImageUrl(doc?.mainImage || doc?.images?.[0] || null, opts.baseUrl),
|
|
16
|
+
}, opts.siteName);
|
|
17
|
+
}
|
|
18
|
+
export function renderCatalogueItemOgImage(data, siteName) {
|
|
19
|
+
return renderOgLayout({
|
|
20
|
+
title: data.title,
|
|
21
|
+
subtitle: data.ownerName ? `Owned by ${data.ownerName}` : undefined,
|
|
22
|
+
imageUrl: data.imageUrl,
|
|
23
|
+
siteName: `${siteName} · Catalogue`,
|
|
24
|
+
accentSlot: data.priceLabel,
|
|
25
|
+
theme: { accentColor: "#a78bfa" },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -18,6 +18,22 @@ export interface ListGroupedListingsParams {
|
|
|
18
18
|
export declare function listGroupedListings(params?: ListGroupedListingsParams): Promise<GroupedListingDocument[]>;
|
|
19
19
|
/** Featured grouped listings for homepage strips. */
|
|
20
20
|
export declare const listFeaturedGroupedListings: (limit?: number) => Promise<GroupedListingDocument[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Groups a product belongs to that are eligible to render publicly —
|
|
23
|
+
* powers the "You might also like" / "Same character" / etc. carousel
|
|
24
|
+
* on product-based listing detail pages. Deduped per request.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getGroupsForProduct: (productId: string) => Promise<GroupedListingDocument[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Groups a product belongs to, each hydrated with its OTHER member products
|
|
29
|
+
* (the current product is excluded from its own group's item list) — ready
|
|
30
|
+
* to render directly as a public GroupedListingsCarousel section.
|
|
31
|
+
*/
|
|
32
|
+
export declare const getGroupsWithItemsForProduct: (productId: string) => Promise<GroupedListingWithItems[]>;
|
|
33
|
+
/** Groups tagged to a category, hydrated with all member products — for the category detail page's GroupedListingsCarousel. */
|
|
34
|
+
export declare const getGroupsForCategory: (categorySlug: string) => Promise<GroupedListingWithItems[]>;
|
|
35
|
+
/** Groups tagged to a brand, hydrated with all member products — for the brand detail page's GroupedListingsCarousel. */
|
|
36
|
+
export declare const getGroupsForBrand: (brandSlug: string) => Promise<GroupedListingWithItems[]>;
|
|
21
37
|
export interface SitemapGroupedListing {
|
|
22
38
|
slug: string;
|
|
23
39
|
updatedAt: Date;
|
|
@@ -3,7 +3,7 @@ import { getAdminDb } from "../../../../providers/db-firebase";
|
|
|
3
3
|
import { normalizeError } from "../../../../errors/normalize";
|
|
4
4
|
import { serverLogger } from "../../../../monitoring/server-logger";
|
|
5
5
|
import { GROUPED_LISTINGS_COLLECTION, } from "../../../../features/grouped/schemas/firestore";
|
|
6
|
-
import { productRepository } from "../../../../repositories";
|
|
6
|
+
import { productRepository, groupedListingsRepository } from "../../../../repositories";
|
|
7
7
|
import { PRODUCT_FIELDS, CATEGORY_FIELDS } from "../../../../constants/field-names";
|
|
8
8
|
import { GROUPED_LISTINGS_FEATURED_LIMIT, GROUPED_LISTINGS_PAGE_SIZE, GROUPED_LISTINGS_SITEMAP_LIMIT, } from "../../../shared/features/grouped/config";
|
|
9
9
|
function mapDoc(doc) {
|
|
@@ -107,6 +107,55 @@ export async function listGroupedListings(params = {}) {
|
|
|
107
107
|
export const listFeaturedGroupedListings = cache(async (limit = GROUPED_LISTINGS_FEATURED_LIMIT) => {
|
|
108
108
|
return listGroupedListings({ featuredOnly: true, limit });
|
|
109
109
|
});
|
|
110
|
+
/**
|
|
111
|
+
* Groups a product belongs to that are eligible to render publicly —
|
|
112
|
+
* powers the "You might also like" / "Same character" / etc. carousel
|
|
113
|
+
* on product-based listing detail pages. Deduped per request.
|
|
114
|
+
*/
|
|
115
|
+
export const getGroupsForProduct = cache(async (productId) => {
|
|
116
|
+
return groupedListingsRepository.findByProductId(productId).catch((err) => {
|
|
117
|
+
void normalizeError(err);
|
|
118
|
+
serverLogger.warn("grouped-data: getGroupsForProduct failed — returning empty", { productId, error: err instanceof Error ? err.message : String(err) });
|
|
119
|
+
return [];
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
/**
|
|
123
|
+
* Groups a product belongs to, each hydrated with its OTHER member products
|
|
124
|
+
* (the current product is excluded from its own group's item list) — ready
|
|
125
|
+
* to render directly as a public GroupedListingsCarousel section.
|
|
126
|
+
*/
|
|
127
|
+
export const getGroupsWithItemsForProduct = cache(async (productId) => {
|
|
128
|
+
const groups = await getGroupsForProduct(productId);
|
|
129
|
+
return Promise.all(groups.map(async (group) => {
|
|
130
|
+
const otherIds = group.productIds.filter((id) => id !== productId);
|
|
131
|
+
const items = await Promise.all(otherIds.map((id) => productRepository.findByIdOrSlug(id).catch(() => null)));
|
|
132
|
+
return { ...group, items: items.filter((p) => p !== null) };
|
|
133
|
+
}));
|
|
134
|
+
});
|
|
135
|
+
/** Groups tagged to a category, hydrated with all member products — for the category detail page's GroupedListingsCarousel. */
|
|
136
|
+
export const getGroupsForCategory = cache(async (categorySlug) => {
|
|
137
|
+
const groups = await groupedListingsRepository.findByCategorySlug(categorySlug).catch((err) => {
|
|
138
|
+
void normalizeError(err);
|
|
139
|
+
serverLogger.warn("grouped-data: getGroupsForCategory failed — returning empty", { categorySlug, error: err instanceof Error ? err.message : String(err) });
|
|
140
|
+
return [];
|
|
141
|
+
});
|
|
142
|
+
return Promise.all(groups.map(async (group) => {
|
|
143
|
+
const items = await Promise.all(group.productIds.map((id) => productRepository.findByIdOrSlug(id).catch(() => null)));
|
|
144
|
+
return { ...group, items: items.filter((p) => p !== null) };
|
|
145
|
+
}));
|
|
146
|
+
});
|
|
147
|
+
/** Groups tagged to a brand, hydrated with all member products — for the brand detail page's GroupedListingsCarousel. */
|
|
148
|
+
export const getGroupsForBrand = cache(async (brandSlug) => {
|
|
149
|
+
const groups = await groupedListingsRepository.findByBrandSlug(brandSlug).catch((err) => {
|
|
150
|
+
void normalizeError(err);
|
|
151
|
+
serverLogger.warn("grouped-data: getGroupsForBrand failed — returning empty", { brandSlug, error: err instanceof Error ? err.message : String(err) });
|
|
152
|
+
return [];
|
|
153
|
+
});
|
|
154
|
+
return Promise.all(groups.map(async (group) => {
|
|
155
|
+
const items = await Promise.all(group.productIds.map((id) => productRepository.findByIdOrSlug(id).catch(() => null)));
|
|
156
|
+
return { ...group, items: items.filter((p) => p !== null) };
|
|
157
|
+
}));
|
|
158
|
+
});
|
|
110
159
|
export async function listSitemapGroupedListings() {
|
|
111
160
|
try {
|
|
112
161
|
const db = getAdminDb();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedListings, listFeaturedGroupedListings, listSitemapGroupedListings, type GroupedListingWithItems, type ListGroupedListingsParams, type SitemapGroupedListing, } from "./data";
|
|
1
|
+
export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedListings, listFeaturedGroupedListings, listSitemapGroupedListings, getGroupsForProduct, getGroupsWithItemsForProduct, getGroupsForCategory, getGroupsForBrand, type GroupedListingWithItems, type ListGroupedListingsParams, type SitemapGroupedListing, } from "./data";
|
|
2
2
|
export { GROUPED_LISTINGS_PAGE_SIZE, GROUPED_LISTINGS_FEATURED_LIMIT, GROUPED_LISTINGS_SITEMAP_LIMIT, } from "../../../shared/features/grouped/config";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedListings, listFeaturedGroupedListings, listSitemapGroupedListings, } from "./data";
|
|
1
|
+
export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedListings, listFeaturedGroupedListings, listSitemapGroupedListings, getGroupsForProduct, getGroupsWithItemsForProduct, getGroupsForCategory, getGroupsForBrand, } from "./data";
|
|
2
2
|
export { GROUPED_LISTINGS_PAGE_SIZE, GROUPED_LISTINGS_FEATURED_LIMIT, GROUPED_LISTINGS_SITEMAP_LIMIT, } from "../../../shared/features/grouped/config";
|
|
@@ -161,6 +161,15 @@ export async function attachPaymentProofAction(orderId, proof) {
|
|
|
161
161
|
buyerFraudAgreementAcceptedAt: new Date(),
|
|
162
162
|
buyerReportedUpiId: proof.buyerReportedUpiId,
|
|
163
163
|
paymentUpiMismatch,
|
|
164
|
+
// A re-upload after `adminRequestProofReuploadAction` must clear the
|
|
165
|
+
// stale `reupload_requested` outcome. Both the 2-hour auto-approve
|
|
166
|
+
// sweep (`getUnreviewedProofPastDeadline`) and the admin
|
|
167
|
+
// "Awaiting verification" queue treat *any* set outcome as "already
|
|
168
|
+
// decided" — leaving it set meant a corrected proof was invisible to
|
|
169
|
+
// both: never auto-approved, never surfaced for manual review.
|
|
170
|
+
paymentReviewOutcome: null,
|
|
171
|
+
paymentReviewedBy: null,
|
|
172
|
+
paymentReviewedAt: null,
|
|
164
173
|
});
|
|
165
174
|
notifyAdminsOfPaymentProof({
|
|
166
175
|
id: orderId,
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
function toIsoOrUndefined(value) {
|
|
2
|
+
return value instanceof Date ? value.toISOString() : undefined;
|
|
3
|
+
}
|
|
1
4
|
export function orderDocumentToOrder(doc) {
|
|
2
5
|
const items = doc.items?.length
|
|
3
6
|
? doc.items.map((item) => ({
|
|
@@ -55,10 +58,32 @@ export function orderDocumentToOrder(doc) {
|
|
|
55
58
|
couponCode: doc.couponCode,
|
|
56
59
|
trackingNumber: doc.trackingNumber,
|
|
57
60
|
shippingCarrier: doc.shippingCarrier,
|
|
61
|
+
trackingUrl: doc.trackingUrl,
|
|
58
62
|
notes: doc.notes,
|
|
63
|
+
orderDate: toIsoOrUndefined(doc.orderDate),
|
|
64
|
+
shippingDate: toIsoOrUndefined(doc.shippingDate),
|
|
65
|
+
deliveryDate: toIsoOrUndefined(doc.deliveryDate),
|
|
66
|
+
cancellationDate: toIsoOrUndefined(doc.cancellationDate),
|
|
59
67
|
autoApproved: doc.autoApproved,
|
|
60
68
|
disputeRaised: doc.disputeRaised,
|
|
61
69
|
disputeStatus: doc.disputeStatus,
|
|
70
|
+
// Manual-payment (cash / UPI / EMI) passthrough. These were previously
|
|
71
|
+
// dropped here, which silently disabled the entire buyer proof-upload
|
|
72
|
+
// flow: `/user/orders/[id]/payment` branches on `paymentMethod` and so
|
|
73
|
+
// rendered "this order does not require manual payment upload" for every
|
|
74
|
+
// order, with no UPI ID and no countdown.
|
|
75
|
+
paymentMethod: doc.paymentMethod,
|
|
76
|
+
displayedUpiId: doc.displayedUpiId,
|
|
77
|
+
paymentDeadline: toIsoOrUndefined(doc.paymentDeadline),
|
|
78
|
+
paymentProofUrl: doc.paymentProofUrl,
|
|
79
|
+
paymentProofUploadedAt: toIsoOrUndefined(doc.paymentProofUploadedAt),
|
|
80
|
+
paymentTransactionId: doc.paymentTransactionId,
|
|
81
|
+
buyerReportedUpiId: doc.buyerReportedUpiId,
|
|
82
|
+
buyerMarkedPaid: doc.buyerMarkedPaid,
|
|
83
|
+
paymentUpiMismatch: doc.paymentUpiMismatch,
|
|
84
|
+
paymentReviewOutcome: doc.paymentReviewOutcome,
|
|
85
|
+
paymentReviewNote: doc.paymentReviewNote,
|
|
86
|
+
cancellationReason: doc.cancellationReason,
|
|
62
87
|
createdAt: doc.createdAt instanceof Date
|
|
63
88
|
? doc.createdAt.toISOString()
|
|
64
89
|
: String(doc.createdAt),
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
2
2
|
import type { ListingType } from "../../../../features/products/types";
|
|
3
|
+
import type { ProductItem } from "../../../../features/products/types";
|
|
4
|
+
import type { FirestoreDocument } from "../../../../schemas/types";
|
|
5
|
+
import type { Review } from "../../../../features/reviews/types";
|
|
3
6
|
/** Fetch a single product by slug or id, deduped per request. */
|
|
4
7
|
export declare const getProductForDetail: (slugOrId: string) => Promise<ProductDocument | null>;
|
|
5
8
|
/** Fetch the first page of approved reviews for a product, deduped per request. */
|
|
6
9
|
export declare const getReviewsForProduct: (productId: string) => Promise<unknown[]>;
|
|
10
|
+
/** Firestore review doc → client Review shape. Shared by every listing-type detail page's reviews tab. */
|
|
11
|
+
export declare function toReview(doc: FirestoreDocument): Review;
|
|
12
|
+
/** Fetch + map approved reviews for a product straight to the client Review shape, deduped per request. */
|
|
13
|
+
export declare const getReviewItemsForProduct: (productId: string) => Promise<Review[]>;
|
|
7
14
|
/** Minimal product fields needed for sitemap generation. */
|
|
8
15
|
export interface SitemapProduct {
|
|
9
16
|
slugOrId: string;
|
|
@@ -13,3 +20,19 @@ export interface SitemapProduct {
|
|
|
13
20
|
}
|
|
14
21
|
/** List all published products for sitemap generation. */
|
|
15
22
|
export declare function listSitemapProducts(): Promise<SitemapProduct[]>;
|
|
23
|
+
export interface RelatedItemsResult {
|
|
24
|
+
relatedItems: ProductItem[];
|
|
25
|
+
relatedByBrand: ProductItem[];
|
|
26
|
+
relatedByTags: ProductItem[];
|
|
27
|
+
relatedByStore: ProductItem[];
|
|
28
|
+
}
|
|
29
|
+
/** Firestore doc → card-grid shape. Shared by every related/similar-items carousel. */
|
|
30
|
+
export declare function toProductItem(doc: FirestoreDocument): ProductItem;
|
|
31
|
+
/**
|
|
32
|
+
* Same 4-signal related-items computation used across every listing-type
|
|
33
|
+
* detail page (category / brand / tag-overlap / same-store), each excluding
|
|
34
|
+
* invalid states for that item's own listing type. Extracted from
|
|
35
|
+
* ProductDetailPageView so pre-order/prize-draw/classified/digital-code/live
|
|
36
|
+
* pages can reuse it instead of having no related section at all.
|
|
37
|
+
*/
|
|
38
|
+
export declare const computeRelatedItems: (product: ProductDocument) => Promise<RelatedItemsResult>;
|