@mohasinac/appkit 4.30.18 → 4.31.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/digital-code/CodeRevealPanel.js +5 -2
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -3
- package/dist/_internal/client/features/layout/useSidebarSearch.d.ts +21 -5
- package/dist/_internal/client/features/layout/useSidebarSearch.js +27 -6
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.d.ts +23 -3
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +106 -86
- package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +16 -5
- package/dist/_internal/client/features/lottery/LotteryPullForm.js +65 -40
- package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +5 -2
- package/dist/_internal/client/features/maintenance/views/CloudLogsListView.js +11 -3
- package/dist/_internal/client/hand-mode/HandModeProvider.js +2 -0
- package/dist/_internal/server/features/auctions/actions.js +14 -3
- package/dist/_internal/server/features/auctions/service.js +1 -1
- package/dist/_internal/server/features/auth/permissions.d.ts +2 -0
- package/dist/_internal/server/features/auth/permissions.js +3 -2
- package/dist/_internal/server/features/blog/data.js +2 -2
- package/dist/_internal/server/features/blog/service.js +3 -3
- package/dist/_internal/server/features/brands/data.js +1 -1
- package/dist/_internal/server/features/brands/service.js +3 -3
- package/dist/_internal/server/features/bundles/actions.js +6 -1
- package/dist/_internal/server/features/bundles/data.js +21 -4
- package/dist/_internal/server/features/cart/data.js +3 -1
- package/dist/_internal/server/features/cart/service.js +13 -2
- package/dist/_internal/server/features/categories/data.js +26 -6
- package/dist/_internal/server/features/classified/index.d.ts +0 -1
- package/dist/_internal/server/features/classified/index.js +0 -1
- package/dist/_internal/server/features/digital-code/index.d.ts +0 -1
- package/dist/_internal/server/features/digital-code/index.js +0 -1
- package/dist/_internal/server/features/events/actions.js +17 -4
- package/dist/_internal/server/features/events/data.js +1 -1
- package/dist/_internal/server/features/events/service.js +1 -1
- package/dist/_internal/server/features/grouped/data.js +7 -2
- package/dist/_internal/server/features/item-requests/data.js +1 -1
- package/dist/_internal/server/features/live/index.d.ts +0 -1
- package/dist/_internal/server/features/live/index.js +0 -1
- package/dist/_internal/server/features/lottery/actions.js +2 -2
- package/dist/_internal/server/features/lottery/data.js +1 -1
- package/dist/_internal/server/features/orders/actions.js +7 -7
- package/dist/_internal/server/features/orders/data.d.ts +1 -1
- package/dist/_internal/server/features/orders/data.js +14 -2
- package/dist/_internal/server/features/orders/service.js +1 -1
- package/dist/_internal/server/features/pre-orders/service.js +1 -1
- package/dist/_internal/server/features/prize-draws/actions.js +1 -1
- package/dist/_internal/server/features/products/data.js +21 -6
- package/dist/_internal/server/features/products/list-public.d.ts +9 -0
- package/dist/_internal/server/features/products/list-public.js +95 -7
- package/dist/_internal/server/features/products/service.js +1 -1
- package/dist/_internal/server/features/promotions/actions.js +1 -1
- package/dist/_internal/server/features/promotions/data.js +1 -1
- package/dist/_internal/server/features/promotions/service.js +1 -1
- package/dist/_internal/server/features/reviews/data.d.ts +1 -1
- package/dist/_internal/server/features/reviews/data.js +6 -1
- package/dist/_internal/server/features/reviews/og-data.js +1 -1
- package/dist/_internal/server/features/shared/listing-data-factory.js +7 -2
- package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
- package/dist/_internal/server/features/site-settings/adapters.js +8 -5
- package/dist/_internal/server/features/stores/data.js +1 -1
- package/dist/_internal/server/features/sublisting-categories/data.js +1 -1
- package/dist/_internal/server/features/tester/visibility.d.ts +2 -1
- package/dist/_internal/server/features/tester/visibility.js +2 -2
- package/dist/_internal/server/functions/scheduled.d.ts +3 -1
- package/dist/_internal/server/functions/scheduled.js +27 -1
- package/dist/_internal/server/jobs/core/auctionSettlement.js +6 -1
- package/dist/_internal/server/jobs/core/hardBanCascade.js +4 -0
- package/dist/_internal/server/jobs/core/index.d.ts +2 -0
- package/dist/_internal/server/jobs/core/index.js +2 -0
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +7 -15
- package/dist/_internal/server/jobs/core/pageViewPrune.d.ts +10 -0
- package/dist/_internal/server/jobs/core/pageViewPrune.js +44 -0
- package/dist/_internal/server/jobs/core/pageViewRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/core/pageViewRollup.js +87 -0
- package/dist/_internal/server/jobs/core/revenueRollup.js +7 -1
- package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/index.js +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewPrune.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewPrune.js +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/pageViewRollup.js +2 -0
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +69 -22
- package/dist/_internal/shared/checkout/rules/classified.rule.d.ts +9 -4
- package/dist/_internal/shared/checkout/rules/classified.rule.js +7 -2
- package/dist/_internal/shared/features/layout/matchesNavQuery.d.ts +14 -0
- package/dist/_internal/shared/features/layout/matchesNavQuery.js +72 -0
- package/dist/_internal/shared/features/layout/types.d.ts +37 -1
- package/dist/_internal/shared/features/layout/types.js +19 -1
- package/dist/_internal/shared/features/notifications/action-url.d.ts +9 -1
- package/dist/_internal/shared/features/notifications/action-url.js +47 -0
- package/dist/_internal/shared/features/offers/config.d.ts +65 -0
- package/dist/_internal/shared/features/offers/config.js +73 -2
- package/dist/_internal/shared/features/orders/schema.d.ts +19 -1
- package/dist/_internal/shared/features/orders/schema.js +22 -2
- package/dist/_internal/shared/features/site-settings/types.d.ts +12 -3
- package/dist/_internal/shared/listing-types/capabilities.d.ts +8 -2
- package/dist/_internal/shared/listing-types/capabilities.js +6 -1
- package/dist/_internal/shared/listing-types/classified/ctas.js +6 -1
- package/dist/_internal/shared/listing-types/feature-flags.d.ts +10 -5
- package/dist/_internal/shared/listing-types/feature-flags.js +11 -6
- package/dist/client/api/useApiQuery.js +17 -6
- package/dist/client.d.ts +38 -20
- package/dist/client.js +39 -14
- package/dist/configs/next.js +10 -2
- package/dist/constants/api-endpoints.d.ts +18 -54
- package/dist/constants/api-endpoints.js +6 -26
- package/dist/constants/field-names.d.ts +6 -24
- package/dist/constants/field-names.js +10 -27
- package/dist/constants/geo/countries.d.ts +50 -0
- package/dist/constants/geo/countries.js +129 -0
- package/dist/constants/geo/subdivisions.d.ts +13 -0
- package/dist/constants/geo/subdivisions.js +104 -0
- package/dist/constants/index.d.ts +2 -2
- package/dist/constants/index.js +2 -2
- package/dist/constants/table-keys.d.ts +24 -0
- package/dist/constants/table-keys.js +28 -0
- package/dist/contracts/client-realtime.d.ts +6 -0
- package/dist/contracts/extend.d.ts +0 -9
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/realtime-session.d.ts +12 -12
- package/dist/contracts/realtime-session.js +79 -77
- package/dist/core/browser.d.ts +1 -1
- package/dist/core/browser.js +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/site-config.d.ts +0 -3
- package/dist/core/site-config.js +0 -3
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/messages.d.ts +0 -8
- package/dist/errors/messages.js +0 -9
- package/dist/features/about/components/DeveloperView.js +7 -2
- package/dist/features/about/components/PolicyPageView.js +9 -1
- package/dist/features/about/components/PublicProfileView.js +23 -5
- package/dist/features/about/schemas/index.d.ts +8 -8
- package/dist/features/account/components/AddressFilters.js +32 -11
- package/dist/features/account/components/AddressForm.d.ts +26 -25
- package/dist/features/account/components/AddressForm.js +81 -103
- package/dist/features/account/components/AddressesIndexListing.js +8 -4
- package/dist/features/account/components/NotificationBell.js +4 -3
- package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
- package/dist/features/account/components/UserOffersPanel.js +1 -1
- package/dist/features/account/components/UserSidebar.d.ts +3 -4
- package/dist/features/account/components/UserSupportView.js +89 -58
- package/dist/features/account/components/index.d.ts +1 -7
- package/dist/features/account/components/index.js +0 -3
- package/dist/features/account/hooks/useAddresses.d.ts +4 -3
- package/dist/features/account/hooks/useAddresses.js +4 -6
- package/dist/features/account/hooks/useCollapsedSections.d.ts +51 -10
- package/dist/features/account/hooks/useCollapsedSections.js +211 -38
- package/dist/features/account/hooks/useProfile.d.ts +8 -0
- package/dist/features/account/index.d.ts +0 -3
- package/dist/features/account/index.js +0 -3
- package/dist/features/account/schemas/index.d.ts +0 -92
- package/dist/features/account/schemas/index.js +42 -20
- package/dist/features/addresses/components/AddressLocationFields.d.ts +13 -0
- package/dist/features/addresses/components/AddressLocationFields.js +41 -0
- package/dist/features/addresses/hooks/usePostalLookup.d.ts +17 -0
- package/dist/features/addresses/hooks/usePostalLookup.js +133 -0
- package/dist/features/addresses/schemas/address-form.d.ts +423 -0
- package/dist/features/addresses/schemas/address-form.js +212 -0
- package/dist/features/addresses/schemas/index.d.ts +1 -0
- package/dist/features/addresses/schemas/index.js +8 -0
- package/dist/features/admin/actions/admin-read-actions.d.ts +1 -1
- package/dist/features/admin/actions/index.d.ts +0 -1
- package/dist/features/admin/actions/index.js +0 -1
- package/dist/features/admin/actions/notification-actions.js +1 -41
- package/dist/features/admin/components/AdminActionIndexView.d.ts +32 -0
- package/dist/features/admin/components/AdminActionIndexView.js +128 -0
- package/dist/features/admin/components/AdminAdEditorView.js +159 -163
- package/dist/features/admin/components/AdminAddressEditorView.js +97 -55
- package/dist/features/admin/components/AdminBrandEditorView.d.ts +15 -0
- package/dist/features/admin/components/AdminBrandEditorView.js +113 -77
- package/dist/features/admin/components/AdminBundleEditorView.d.ts +19 -9
- package/dist/features/admin/components/AdminBundleEditorView.js +136 -168
- package/dist/features/admin/components/AdminCategoryEditorView.js +120 -43
- package/dist/features/admin/components/AdminCouponEditorView.js +145 -109
- package/dist/features/admin/components/AdminEmployeeEditorView.js +125 -56
- package/dist/features/admin/components/AdminFaqEditorView.js +112 -58
- package/dist/features/admin/components/AdminFeatureEditorView.js +108 -68
- package/dist/features/admin/components/AdminFulfillmentView.js +5 -2
- package/dist/features/admin/components/AdminMediaView.js +3 -3
- package/dist/features/admin/components/AdminNavEditorView.js +69 -44
- package/dist/features/admin/components/AdminOrderEditorView.js +47 -10
- package/dist/features/admin/components/AdminPrizeDrawsView.js +16 -2
- package/dist/features/admin/components/AdminSidebar.d.ts +11 -7
- package/dist/features/admin/components/AdminSiteSettingsView.js +37 -37
- package/dist/features/admin/components/AdminStoreEditorView.js +75 -52
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +71 -30
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +95 -65
- package/dist/features/admin/components/BrandQuickCreateForm.d.ts +10 -0
- package/dist/features/admin/components/BrandQuickCreateForm.js +49 -26
- package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +11 -0
- package/dist/features/admin/components/CategoryQuickCreateForm.js +48 -26
- package/dist/features/admin/components/index.d.ts +2 -2
- package/dist/features/admin/components/index.js +1 -1
- package/dist/features/admin/constants/site-settings-tabs.d.ts +120 -0
- package/dist/features/admin/constants/site-settings-tabs.js +152 -0
- package/dist/features/admin/index.d.ts +0 -3
- package/dist/features/admin/index.js +0 -2
- package/dist/features/admin/repository/analytics-rollup.repository.d.ts +35 -0
- package/dist/features/admin/repository/analytics-rollup.repository.js +30 -0
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +56 -57
- package/dist/features/admin/schemas/admin-editor-forms.js +97 -54
- package/dist/features/admin/schemas/admin-ops-forms.d.ts +57 -5
- package/dist/features/admin/schemas/admin-ops-forms.js +104 -20
- package/dist/features/admin/schemas/admin-user-form.js +7 -0
- package/dist/features/admin/schemas/firestore.d.ts +48 -95
- package/dist/features/admin/schemas/firestore.js +15 -151
- package/dist/features/admin/schemas/nav-item-form.js +9 -2
- package/dist/features/admin/server.d.ts +0 -4
- package/dist/features/admin/server.js +0 -2
- package/dist/features/admin/types/index.d.ts +0 -7
- package/dist/features/analytics/repository/page-views.repository.d.ts +14 -0
- package/dist/features/analytics/repository/page-views.repository.js +24 -0
- package/dist/features/analytics/types.d.ts +1 -1
- package/dist/features/analytics/types.js +13 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +6 -2
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -1
- package/dist/features/auth/actions/index.d.ts +0 -1
- package/dist/features/auth/actions/index.js +0 -1
- package/dist/features/auth/actions/profile-actions.js +4 -3
- package/dist/features/auth/actions/realtime-token-actions.js +1 -12
- package/dist/features/auth/auth-helpers.js +5 -7
- package/dist/features/auth/components/ForgotPasswordView.js +1 -1
- package/dist/features/auth/components/Guards.js +2 -1
- package/dist/features/auth/components/LoginForm.d.ts +0 -2
- package/dist/features/auth/components/LoginForm.js +2 -4
- package/dist/features/auth/components/RegisterForm.js +62 -19
- package/dist/features/auth/components/ResetPasswordView.js +1 -1
- package/dist/features/auth/hooks/useAuth.js +3 -0
- package/dist/features/auth/permissions/constants.d.ts +27 -1
- package/dist/features/auth/role-predicates.d.ts +75 -7
- package/dist/features/auth/role-predicates.js +28 -2
- package/dist/features/auth/schemas/firestore.d.ts +22 -0
- package/dist/features/auth/schemas/index.d.ts +1 -1
- package/dist/features/auth/schemas/index.js +44 -8
- package/dist/features/auth/types/index.d.ts +14 -1
- package/dist/features/blog/api/route.js +10 -2
- package/dist/features/blog/components/BlogIndexListing.js +1 -1
- package/dist/features/blog/hooks/useBlog.js +2 -2
- package/dist/features/blog/repository/blog.repository.js +3 -1
- package/dist/features/blog/schemas/index.d.ts +4 -0
- package/dist/features/blog/schemas/index.js +2 -0
- package/dist/features/blog/types/index.d.ts +1 -1
- package/dist/features/cart/actions/cart-actions.js +13 -4
- package/dist/features/cart/utils/pending-ops.js +1 -1
- package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +22 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +112 -52
- package/dist/features/catalogue/schemas/validation.d.ts +4 -4
- package/dist/features/catalogue/schemas/validation.js +47 -10
- package/dist/features/categories/components/BrandDetailPageView.js +28 -12
- package/dist/features/categories/components/CategoryDetailPageView.js +37 -20
- package/dist/features/categories/repository/categories.repository.js +3 -1
- package/dist/features/categories/schemas/bundle-form.d.ts +142 -0
- package/dist/features/categories/schemas/bundle-form.js +149 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +10 -1
- package/dist/features/classified/components/ClassifiedContactSellerPanel.js +1 -1
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +5 -4
- package/dist/features/classified/components/ClassifiedDetailPageView.js +47 -18
- package/dist/features/consultation/components/ConsultationForm.js +1 -1
- package/dist/features/consultation/schemas/index.js +34 -10
- package/dist/features/corporate/schemas/index.js +36 -15
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +4 -1
- package/dist/features/events/components/EventBanner.js +5 -2
- package/dist/features/events/components/EventOfferCard.js +3 -1
- package/dist/features/events/components/EventPollWidget.js +1 -1
- package/dist/features/events/components/SpinWheelView.js +3 -2
- package/dist/features/filters/FilterPanel.js +3 -3
- package/dist/features/filters/RangeFilter.d.ts +10 -0
- package/dist/features/filters/RangeFilter.js +41 -4
- package/dist/features/grouped/components/GroupedListingEditorView.js +2 -1
- package/dist/features/history/hooks/useHistory.js +29 -27
- package/dist/features/homepage/components/AdSlot.js +3 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +8 -2
- package/dist/features/homepage/components/MarketplaceHomepageView.js +58 -15
- package/dist/features/homepage/components/SocialFeedSection.js +4 -1
- package/dist/features/homepage/hooks/useBlogArticles.js +1 -1
- package/dist/features/homepage/lib/live-stats.js +8 -1
- package/dist/features/homepage/repository/carousel.repository.js +2 -1
- package/dist/features/layout/BottomActions.js +84 -11
- package/dist/features/layout/BottomActionsContext.d.ts +1 -6
- package/dist/features/layout/BottomActionsContext.js +1 -1
- package/dist/features/layout/hooks/useBottomActions.js +2 -2
- package/dist/features/layout/hooks/useFormBottomActions.d.ts +12 -1
- package/dist/features/layout/hooks/useFormBottomActions.js +12 -6
- package/dist/features/live/components/LiveItemDetailPageView.js +4 -1
- package/dist/features/lottery/schemas/config-write.d.ts +9 -5
- package/dist/features/lottery/schemas/config-write.js +69 -9
- package/dist/features/media/finalize.js +3 -1
- package/dist/features/media/modals/ImageEditor.js +1 -1
- package/dist/features/media/modals/VideoThumbnailSelector.js +5 -2
- package/dist/features/media/modals/VideoTrimModal.js +5 -2
- package/dist/features/media/upload/MediaUploadField.js +2 -2
- package/dist/features/messages/hooks/useConversation.js +18 -4
- package/dist/features/messages/hooks/useConversations.js +25 -8
- package/dist/features/orders/components/RefundRequestView.js +5 -2
- package/dist/features/orders/schemas/buyer-forms.d.ts +6 -3
- package/dist/features/orders/schemas/buyer-forms.js +31 -3
- package/dist/features/orders/schemas/index.d.ts +2 -2
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -1
- package/dist/features/products/components/GroupSettingsPanel.js +3 -1
- package/dist/features/products/components/MakeOfferButton.d.ts +13 -2
- package/dist/features/products/components/MakeOfferButton.js +33 -11
- package/dist/features/products/components/PrizeDrawDetailPageView.js +4 -1
- package/dist/features/products/components/ProductDetailActions.js +0 -1
- package/dist/features/products/components/ProductDetailPageView.d.ts +7 -3
- package/dist/features/products/components/ProductDetailPageView.js +16 -7
- package/dist/features/products/components/ShareButton.js +3 -1
- package/dist/features/products/constants/action-defs.d.ts +1 -2
- package/dist/features/products/constants/action-defs.js +40 -43
- package/dist/features/products/repository/loadProductFeatures.js +10 -2
- package/dist/features/products/repository/products.repository.d.ts +5 -1
- package/dist/features/products/repository/products.repository.js +25 -2
- package/dist/features/products/schemas/firestore.d.ts +7 -3
- package/dist/features/products/schemas/product-features.validators.js +3 -0
- package/dist/features/promotions/components/CouponCard.js +11 -8
- package/dist/features/reviews/actions/review-actions.js +8 -1
- package/dist/features/reviews/components/ReviewDetailPageView.js +13 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +3 -1
- package/dist/features/scams/actions/scam-actions.d.ts +9 -1
- package/dist/features/scams/actions/scam-actions.js +52 -12
- package/dist/features/scams/components/SellerTrustBadge.d.ts +1 -1
- package/dist/features/scams/components/SellerTrustBadge.js +13 -0
- package/dist/features/scams/repository/scammer.repository.js +2 -1
- package/dist/features/scams/schemas/firestore.d.ts +15 -1
- package/dist/features/scams/schemas/report-form.d.ts +5 -5
- package/dist/features/scams/schemas/report-form.js +18 -3
- package/dist/features/search/action-index/derive.d.ts +49 -0
- package/dist/features/search/action-index/derive.js +121 -0
- package/dist/features/search/action-index/repository.d.ts +42 -0
- package/dist/features/search/action-index/repository.js +100 -0
- package/dist/features/search/action-index/settings-entries.d.ts +41 -0
- package/dist/features/search/action-index/settings-entries.js +268 -0
- package/dist/features/search/action-index/types.d.ts +81 -0
- package/dist/features/search/action-index/types.js +102 -0
- package/dist/features/search/action-index/validate-entry.d.ts +34 -0
- package/dist/features/search/action-index/validate-entry.js +114 -0
- package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
- package/dist/features/search/hooks/useNavSuggestions.js +23 -3
- package/dist/features/search/repository/search.repository.js +3 -1
- package/dist/features/seller/actions/offer-actions.js +43 -19
- package/dist/features/seller/actions/seller-actions.js +29 -5
- package/dist/features/seller/components/CategoryChipPicker.d.ts +9 -0
- package/dist/features/seller/components/CategoryChipPicker.js +12 -0
- package/dist/features/seller/components/FulfillmentView.js +5 -2
- package/dist/features/seller/components/PhysicalLocationModal.js +1 -1
- package/dist/features/seller/components/PrintCenterView.js +3 -1
- package/dist/features/seller/components/SellerAddressesView.js +5 -1
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +83 -43
- package/dist/features/seller/components/SellerArtView.d.ts +14 -7
- package/dist/features/seller/components/SellerArtView.js +4 -119
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerClassifiedView.d.ts +14 -7
- package/dist/features/seller/components/SellerClassifiedView.js +4 -124
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +22 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +91 -45
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerDigitalCodesView.d.ts +14 -7
- package/dist/features/seller/components/SellerDigitalCodesView.js +4 -126
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
- package/dist/features/seller/components/SellerListingTypeView.d.ts +66 -0
- package/dist/features/seller/components/SellerListingTypeView.js +277 -0
- package/dist/features/seller/components/SellerLiveView.d.ts +14 -7
- package/dist/features/seller/components/SellerLiveView.js +4 -126
- package/dist/features/seller/components/SellerOrdersView.js +3 -3
- package/dist/features/seller/components/SellerPayoutMethodsView.js +2 -2
- package/dist/features/seller/components/SellerProductShell.d.ts +5 -0
- package/dist/features/seller/components/SellerProductShell.js +15 -5
- package/dist/features/seller/components/SellerProductsView.js +24 -10
- package/dist/features/seller/components/SellerReviewsView.js +47 -16
- package/dist/features/seller/components/SellerShippingConfigsView.js +5 -4
- package/dist/features/seller/components/SellerSidebar.d.ts +3 -6
- package/dist/features/seller/components/SellerStickersView.d.ts +14 -7
- package/dist/features/seller/components/SellerStickersView.js +4 -119
- package/dist/features/seller/components/SellerStoreCategoriesView.js +3 -2
- package/dist/features/seller/components/SellerSupportView.d.ts +31 -0
- package/dist/features/seller/components/SellerSupportView.js +100 -0
- package/dist/features/seller/components/index.d.ts +4 -8
- package/dist/features/seller/components/index.js +2 -4
- package/dist/features/seller/index.d.ts +0 -1
- package/dist/features/seller/index.js +0 -1
- package/dist/features/seller/schemas/coupon-form.d.ts +214 -0
- package/dist/features/seller/schemas/coupon-form.js +155 -23
- package/dist/features/seller/schemas/offer-forms.d.ts +16 -7
- package/dist/features/seller/schemas/offer-forms.js +28 -12
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +2 -2
- package/dist/features/shell/SectionForm.d.ts +19 -1
- package/dist/features/shell/SectionForm.js +104 -17
- package/dist/features/shell/build-sections.d.ts +23 -0
- package/dist/features/shell/build-sections.js +106 -8
- package/dist/features/shell/field-ui-meta.d.ts +44 -0
- package/dist/features/shell/field-ui-meta.js +14 -7
- package/dist/features/shell/form-sections.d.ts +46 -0
- package/dist/features/shell/form-sections.js +114 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.js +87 -64
- package/dist/features/shipments/schemas/validation.d.ts +2 -2
- package/dist/features/shipments/schemas/validation.js +44 -13
- package/dist/features/store-extensions/schemas/custom-role-form.js +6 -2
- package/dist/features/store-extensions/schemas/listing-template-form.d.ts +7 -7
- package/dist/features/store-extensions/schemas/payout-method-form.js +14 -0
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/api/[storeSlug]/auctions/route.js +3 -1
- package/dist/features/stores/api/[storeSlug]/products/route.js +3 -1
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +12 -3
- package/dist/features/support/repository/support.repository.d.ts +21 -0
- package/dist/features/support/repository/support.repository.js +63 -0
- package/dist/features/support/schemas/firestore.d.ts +27 -2
- package/dist/features/support/schemas/firestore.js +2 -0
- package/dist/features/support/schemas/ticket-create-form.js +7 -0
- package/dist/features/tester/schemas/checklist-item-form.d.ts +43 -0
- package/dist/features/tester/schemas/checklist-item-form.js +109 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/events-tester-seed-data.js +5 -5
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +2 -2
- package/dist/features/tester/seed-data/products-tester-seed-data.js +48 -49
- package/dist/features/tester/seed-data/stores-tester-seed-data.js +3 -3
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +291 -30
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +51 -14
- package/dist/features/wishlist/hooks/useWishlistToggle.js +8 -1
- package/dist/http/api-handler.js +2 -1
- package/dist/index.d.ts +25 -104
- package/dist/index.js +38 -143
- package/dist/jobs.d.ts +1 -1
- package/dist/jobs.js +1 -1
- package/dist/monitoring/browser.d.ts +0 -2
- package/dist/monitoring/browser.js +12 -1
- package/dist/monitoring/index.d.ts +0 -2
- package/dist/monitoring/index.js +0 -1
- package/dist/next/api/routeHandler.js +9 -4
- package/dist/next/index.d.ts +1 -2
- package/dist/next/index.js +0 -1
- package/dist/next/middleware/index.d.ts +0 -2
- package/dist/next/middleware/index.js +0 -1
- package/dist/next/routing/route-map.d.ts +8 -7
- package/dist/next/routing/route-map.js +10 -3
- package/dist/providers/auth-firebase/session.js +3 -1
- package/dist/providers/db-firebase/admin-app-lite.js +8 -8
- package/dist/providers/db-firebase/admin.js +27 -13
- package/dist/providers/db-firebase/browser-stub.d.ts +1 -11
- package/dist/providers/db-firebase/browser-stub.js +6 -11
- package/dist/providers/db-firebase/index.d.ts +0 -1
- package/dist/providers/db-firebase/index.js +0 -1
- package/dist/providers/db-firebase/rtdb-paths.d.ts +15 -6
- package/dist/providers/db-firebase/rtdb-paths.js +15 -6
- package/dist/providers/db-firebase/rtdb-url.d.ts +27 -0
- package/dist/providers/db-firebase/rtdb-url.js +50 -0
- package/dist/providers/db-firebase/sieve.d.ts +22 -0
- package/dist/providers/firebase-client/realtime.d.ts +20 -0
- package/dist/providers/firebase-client/realtime.js +34 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +1 -1
- package/dist/react/hooks/use-action-dispatch.js +8 -2
- package/dist/react/hooks/useFormStatePreservation.js +3 -1
- package/dist/react/hooks/useListingTypeFlags.d.ts +1 -1
- package/dist/react/hooks/useListingTypeFlags.js +1 -1
- package/dist/react/hooks/usePendingFilters.js +5 -3
- package/dist/react/hooks/usePendingTable.js +15 -3
- package/dist/react/hooks/useRealtimeEvent.js +20 -9
- package/dist/repositories/index.d.ts +0 -1
- package/dist/repositories/index.js +0 -1
- package/dist/schemas/registry.d.ts +197 -232
- package/dist/schemas/registry.js +5 -6
- package/dist/schemas/webhooks/razorpay.d.ts +50 -50
- package/dist/security/authorization.d.ts +9 -0
- package/dist/security/authorization.js +16 -2
- package/dist/security/browser.d.ts +1 -3
- package/dist/security/browser.js +5 -2
- package/dist/security/index.d.ts +1 -3
- package/dist/security/index.js +19 -2
- package/dist/security/pii-encrypt.js +16 -0
- package/dist/security/pii-schemas.d.ts +0 -14
- package/dist/security/pii-schemas.js +7 -15
- package/dist/seed/_helpers/category-forest.js +2 -2
- package/dist/seed/_helpers/media.d.ts +19 -0
- package/dist/seed/_helpers/media.js +75 -0
- package/dist/seed/blog-posts-seed-data.js +17 -17
- package/dist/seed/carousel-slides-seed-data.js +7 -7
- package/dist/seed/cart-seed-data.js +13 -13
- package/dist/seed/categories-seed-data.js +10 -10
- package/dist/seed/events-seed-data.js +24 -24
- package/dist/seed/factories/product.factory.js +4 -4
- package/dist/seed/factories/store.factory.js +3 -3
- package/dist/seed/factories/user.factory.js +2 -2
- package/dist/seed/grouped-listings-seed-data.js +11 -11
- package/dist/seed/homepage-sections-seed-data.js +2 -2
- package/dist/seed/index.d.ts +0 -1
- package/dist/seed/index.js +0 -1
- package/dist/seed/manifest.d.ts +1 -1
- package/dist/seed/manifest.js +0 -5
- package/dist/seed/notifications-seed-data.js +20 -1
- package/dist/seed/orders-seed-data.js +2 -2
- package/dist/seed/products-art-seed-data.js +16 -16
- package/dist/seed/products-auctions-seed-data.js +34 -34
- package/dist/seed/products-classifieds-seed-data.js +35 -37
- package/dist/seed/products-digital-codes-seed-data.js +20 -20
- package/dist/seed/products-live-items-seed-data.js +11 -11
- package/dist/seed/products-preorders-seed-data.js +13 -13
- package/dist/seed/products-prize-draws-seed-data.js +43 -43
- package/dist/seed/products-standard-seed-data.js +54 -54
- package/dist/seed/products-stickers-seed-data.js +15 -15
- package/dist/seed/reviews-seed-data.js +4 -4
- package/dist/seed/scammers-seed-data.js +3 -3
- package/dist/seed/site-settings-seed-data.js +11 -24
- package/dist/seed/store-extensions-seed-data.js +10 -10
- package/dist/seed/stores-seed-data.js +11 -11
- package/dist/seed/support-tickets-seed-data.d.ts +14 -0
- package/dist/seed/support-tickets-seed-data.js +20 -1
- package/dist/seed/users-seed-data.js +20 -20
- package/dist/server-entry.d.ts +0 -1
- package/dist/server-entry.js +0 -1
- package/dist/server.d.ts +9 -6
- package/dist/server.js +7 -13
- package/dist/styles.css +248 -68
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +2 -2
- package/dist/tokens/themes/default-light.js +2 -2
- package/dist/tokens/tokens.css +24 -4
- package/dist/ui/components/ActionRow.d.ts +50 -0
- package/dist/ui/components/ActionRow.js +53 -0
- package/dist/ui/components/ActionRow.style.css +145 -0
- package/dist/ui/components/Drawer.d.ts +10 -0
- package/dist/ui/components/Drawer.js +2 -1
- package/dist/ui/components/FilterDrawer.js +4 -1
- package/dist/ui/components/FilterDrawer.style.css +6 -12
- package/dist/ui/components/FormActionBar.js +14 -1
- package/dist/ui/components/FormActionBar.style.css +12 -11
- package/dist/ui/components/ListingLayout.js +8 -1
- package/dist/ui/components/ListingLayout.style.css +6 -13
- package/dist/ui/components/Modal.d.ts +15 -1
- package/dist/ui/components/Modal.js +17 -3
- package/dist/ui/components/QuickCreateModal.js +2 -2
- package/dist/ui/components/QuickCreateModal.style.css +78 -84
- package/dist/ui/components/RecordDetailModal.js +2 -2
- package/dist/ui/components/SideDrawer.d.ts +8 -0
- package/dist/ui/components/SideDrawer.js +2 -1
- package/dist/ui/components/SideDrawer.style.css +6 -3
- package/dist/ui/components/SideModal.d.ts +11 -1
- package/dist/ui/components/SideModal.js +3 -2
- package/dist/ui/components/SideModal.style.css +14 -0
- package/dist/ui/components/Typography.style.css +33 -24
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/components/toolbar-collapse.js +1 -2
- package/dist/ui/forms/FormShell.style.css +260 -311
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -1
- package/dist/validation/index.d.ts +1 -1
- package/dist/validation/index.js +1 -1
- package/dist/validation/schemas.d.ts +0 -19
- package/dist/validation/schemas.js +8 -19
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +3 -6
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: `pageViews` writes one document per entity per day and had NO prune.
|
|
3
|
+
* Twenty-seven scheduled functions existed — `cartPrune`,
|
|
4
|
+
* `notificationPrune`, `draftPrune`, `dailyDataCleanup` — and not one of
|
|
5
|
+
* them touched this collection, so it was the only unbounded writer in the
|
|
6
|
+
* system. Its size was capped by nothing except how many distinct pages
|
|
7
|
+
* the catalogue had, multiplied by how long the site had been running.
|
|
8
|
+
*
|
|
9
|
+
* WHAT: Delete day-buckets older than the retention window. Shaped after
|
|
10
|
+
* `notificationPrune`, which is the smallest correct prune in the repo.
|
|
11
|
+
*
|
|
12
|
+
* The daily rows are the raw material; `pageViewRollup` keeps the long-run
|
|
13
|
+
* totals, so deleting the buckets loses granularity past the window and not the
|
|
14
|
+
* history itself.
|
|
15
|
+
*
|
|
16
|
+
* EXPORTS: PAGE_VIEW_TTL_DAYS, runPageViewPrune
|
|
17
|
+
*
|
|
18
|
+
* @tag domain:analytics
|
|
19
|
+
* @tag layer:job
|
|
20
|
+
* @tag pattern:none
|
|
21
|
+
* @tag access:server-only
|
|
22
|
+
* @tag consumers:pageViewPrune scheduled function
|
|
23
|
+
* @tag sideEffects:deletes pageViews documents
|
|
24
|
+
*/
|
|
25
|
+
import { pageViewsRepository } from "../../../../features/analytics/repository/page-views.repository";
|
|
26
|
+
import { batchDelete } from "../handlers/_helpers";
|
|
27
|
+
/**
|
|
28
|
+
* 90 days.
|
|
29
|
+
*
|
|
30
|
+
* Long enough for a quarter-over-quarter comparison in the admin report, which
|
|
31
|
+
* is the longest range that screen offers, and short enough that the collection
|
|
32
|
+
* reaches a steady state instead of growing forever.
|
|
33
|
+
*/
|
|
34
|
+
export const PAGE_VIEW_TTL_DAYS = 90;
|
|
35
|
+
export async function runPageViewPrune(ctx) {
|
|
36
|
+
ctx.logger.info(`Pruning page-view buckets older than ${PAGE_VIEW_TTL_DAYS} days`);
|
|
37
|
+
const refs = await pageViewsRepository.getOlderThanRefs(PAGE_VIEW_TTL_DAYS);
|
|
38
|
+
if (refs.length === 0) {
|
|
39
|
+
ctx.logger.info("No stale page-view buckets found");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const deleted = await batchDelete(ctx, refs);
|
|
43
|
+
ctx.logger.info("Page-view prune complete", { deleted });
|
|
44
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: `pageViewPrune` deletes day-buckets past the retention window. Without a
|
|
3
|
+
* rollup that would also delete the only record that those views ever
|
|
4
|
+
* happened — the admin's lifetime total would silently walk backwards as
|
|
5
|
+
* the prune caught up with it.
|
|
6
|
+
*
|
|
7
|
+
* WHAT: Fold each new day-bucket into a singleton total before the prune can
|
|
8
|
+
* reach it. Modelled on `revenueRollup`: scan → one small doc → the API
|
|
9
|
+
* route reads a single document instead of the collection.
|
|
10
|
+
*
|
|
11
|
+
* EXPORTS: runPageViewRollup
|
|
12
|
+
*
|
|
13
|
+
* @tag domain:analytics
|
|
14
|
+
* @tag layer:job
|
|
15
|
+
* @tag pattern:none
|
|
16
|
+
* @tag access:server-only
|
|
17
|
+
* @tag consumers:pageViewRollup scheduled function
|
|
18
|
+
* @tag sideEffects:writes analytics/pageViewRollup
|
|
19
|
+
*/
|
|
20
|
+
import { pageViewsRepository } from "../../../../features/analytics/repository/page-views.repository";
|
|
21
|
+
import { pageViewRollupRepository } from "../../../../features/admin/repository/analytics-rollup.repository";
|
|
22
|
+
/** The earliest date this rollup will fold in on a cold start. */
|
|
23
|
+
const EPOCH_DATE = "2020-01-01";
|
|
24
|
+
function dayKey(offsetDays) {
|
|
25
|
+
const d = new Date();
|
|
26
|
+
d.setUTCDate(d.getUTCDate() + offsetDays);
|
|
27
|
+
return d.toISOString().slice(0, 10);
|
|
28
|
+
}
|
|
29
|
+
export async function runPageViewRollup(ctx) {
|
|
30
|
+
const existing = await pageViewRollupRepository.get();
|
|
31
|
+
/*
|
|
32
|
+
* 🛑 `throughDate` is what makes this job re-runnable.
|
|
33
|
+
*
|
|
34
|
+
* The rollup ACCUMULATES rather than recomputing — the day-buckets it has
|
|
35
|
+
* already folded in get deleted by `pageViewPrune`, so a recompute-from-
|
|
36
|
+
* scratch would produce a total that shrinks every time the prune runs. So it
|
|
37
|
+
* must only ever read buckets it has not seen, and `throughDate` is the
|
|
38
|
+
* boundary. Running this twice in one day is a no-op; running it after a
|
|
39
|
+
* missed day still catches up.
|
|
40
|
+
*/
|
|
41
|
+
const from = existing?.throughDate
|
|
42
|
+
? dayKey(0) === existing.throughDate
|
|
43
|
+
? null // already folded in today — nothing new to read
|
|
44
|
+
: nextDay(existing.throughDate)
|
|
45
|
+
: EPOCH_DATE;
|
|
46
|
+
if (from === null) {
|
|
47
|
+
ctx.logger.info("pageViewRollup: already current", {
|
|
48
|
+
throughDate: existing?.throughDate ?? "",
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Yesterday, not today: today's buckets are still being written to, and
|
|
53
|
+
// folding a partial day in would make it uncountable tomorrow.
|
|
54
|
+
const through = dayKey(-1);
|
|
55
|
+
if (from > through) {
|
|
56
|
+
ctx.logger.info("pageViewRollup: nothing to fold", { from, through });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
/*
|
|
60
|
+
* No `.catch(() => [])`. An empty range is a legitimate zero, so a swallowed
|
|
61
|
+
* query failure would write a confident "no views" the dashboard cannot tell
|
|
62
|
+
* from the real thing — and unlike `revenueRollup`, this one ACCUMULATES, so
|
|
63
|
+
* a bad read would also advance `throughDate` past days it never counted and
|
|
64
|
+
* lose them permanently. Let it throw; the runner records the failure and the
|
|
65
|
+
* stale-but-correct singleton stays.
|
|
66
|
+
*/
|
|
67
|
+
const buckets = await pageViewsRepository.listInRange(from, through);
|
|
68
|
+
const byEntityType = { ...(existing?.byEntityType ?? {}) };
|
|
69
|
+
let totalViews = existing?.totalViews ?? 0;
|
|
70
|
+
for (const b of buckets) {
|
|
71
|
+
const n = Number(b.count) || 0;
|
|
72
|
+
totalViews += n;
|
|
73
|
+
byEntityType[b.entityType] = (byEntityType[b.entityType] ?? 0) + n;
|
|
74
|
+
}
|
|
75
|
+
await pageViewRollupRepository.set({ totalViews, byEntityType, throughDate: through });
|
|
76
|
+
ctx.logger.info("pageViewRollup: complete", {
|
|
77
|
+
from,
|
|
78
|
+
through,
|
|
79
|
+
bucketsFolded: buckets.length,
|
|
80
|
+
totalViews,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function nextDay(dateKey) {
|
|
84
|
+
const d = new Date(`${dateKey}T00:00:00.000Z`);
|
|
85
|
+
d.setUTCDate(d.getUTCDate() + 1);
|
|
86
|
+
return d.toISOString().slice(0, 10);
|
|
87
|
+
}
|
|
@@ -12,7 +12,13 @@
|
|
|
12
12
|
import { orderRepository } from "../../../../repositories";
|
|
13
13
|
import { analyticsRollupRepository } from "../../../../repositories";
|
|
14
14
|
export async function runRevenueRollup(ctx) {
|
|
15
|
-
|
|
15
|
+
// No `.catch(() => [])` here on purpose: an empty list is a legitimate
|
|
16
|
+
// outcome that writes `totalRevenue: 0`, so swallowing a query failure would
|
|
17
|
+
// overwrite yesterday's correct rollup with a confident zero that the
|
|
18
|
+
// dashboard has no way to distinguish from "no delivered orders". Let it
|
|
19
|
+
// throw — the job runner records the failure and the stale-but-correct
|
|
20
|
+
// singleton stays put.
|
|
21
|
+
const deliveredOrders = await orderRepository.findByStatus("delivered");
|
|
16
22
|
const totalRevenue = deliveredOrders.reduce((sum, order) => sum + (Number(order.totalPrice ?? 0) || 0), 0);
|
|
17
23
|
await analyticsRollupRepository.setDashboardRollup({
|
|
18
24
|
totalRevenue,
|
|
@@ -28,6 +28,8 @@ export { hardBanReinstatementHandler } from "./hardBanReinstatement";
|
|
|
28
28
|
export { paymentReviewAutoApproveHandler } from "./paymentReviewAutoApprove";
|
|
29
29
|
export { productStatsSyncHandler } from "./productStatsSync";
|
|
30
30
|
export { revenueRollupHandler } from "./revenueRollup";
|
|
31
|
+
export { pageViewRollupHandler } from "./pageViewRollup";
|
|
32
|
+
export { pageViewPruneHandler } from "./pageViewPrune";
|
|
31
33
|
export { dailyStatusDigestHandler } from "./dailyStatusDigest";
|
|
32
34
|
export { positionsReconcileHandler } from "./positionsReconcile";
|
|
33
35
|
export { payoutBatchHandler } from "./payoutBatch";
|
|
@@ -28,6 +28,8 @@ export { hardBanReinstatementHandler } from "./hardBanReinstatement";
|
|
|
28
28
|
export { paymentReviewAutoApproveHandler } from "./paymentReviewAutoApprove";
|
|
29
29
|
export { productStatsSyncHandler } from "./productStatsSync";
|
|
30
30
|
export { revenueRollupHandler } from "./revenueRollup";
|
|
31
|
+
export { pageViewRollupHandler } from "./pageViewRollup";
|
|
32
|
+
export { pageViewPruneHandler } from "./pageViewPrune";
|
|
31
33
|
export { dailyStatusDigestHandler } from "./dailyStatusDigest";
|
|
32
34
|
export { positionsReconcileHandler } from "./positionsReconcile";
|
|
33
35
|
export { payoutBatchHandler } from "./payoutBatch";
|
|
@@ -29,7 +29,7 @@ import type { IconKey } from "../../../ui/icons/icon-registry";
|
|
|
29
29
|
/** What KIND of action — drives default UI affordance (link vs button vs danger). */
|
|
30
30
|
export type ActionKind = "primary" | "secondary" | "danger" | "ghost" | "link" | "chip";
|
|
31
31
|
/** Resource bucket — keyed top-level in the ACTIONS tree. */
|
|
32
|
-
export type ActionResource = "PRODUCT" | "AUCTION" | "PRE_ORDER" | "PRIZE_DRAW" | "
|
|
32
|
+
export type ActionResource = "PRODUCT" | "AUCTION" | "PRE_ORDER" | "PRIZE_DRAW" | "DIGITAL_CODE" | "BUNDLE" | "GROUP" | "CATEGORY" | "BRAND" | "SUBLISTING" | "STORE" | "BLOG" | "EVENT" | "SHIPMENT" | "CATALOGUE" | "USER" | "SELLER" | "ADMIN" | "CART" | "CHECKOUT" | "NAV" | "MEDIA" | "SUPPORT" | "LOTTERY" | "TESTER";
|
|
33
33
|
/** Confirmation modal config — when set, <Button action={...}> opens
|
|
34
34
|
* a confirm dialog before firing the actual handler. */
|
|
35
35
|
export interface ActionConfirmation {
|
|
@@ -172,9 +172,17 @@ export const ACTIONS = {
|
|
|
172
172
|
iconKey: "message",
|
|
173
173
|
id: "product.make-offer",
|
|
174
174
|
label: "Make an offer",
|
|
175
|
-
|
|
175
|
+
/*
|
|
176
|
+
* Scope corrected 2026-08-31: this was `["classified"]`, but the button it
|
|
177
|
+
* labels (`MakeOfferButton`) mounts on every type whose capability says
|
|
178
|
+
* `canMakeOffer` — which is standard, art and stickers as well. On
|
|
179
|
+
* classified specifically it is the ONLY purchase path, and a seller who
|
|
180
|
+
* has not opted into haggling receives a request to buy at the asking
|
|
181
|
+
* price rather than a lower offer.
|
|
182
|
+
*/
|
|
183
|
+
description: "Propose a price to the seller, or request to buy at the asking price.",
|
|
176
184
|
kind: "secondary",
|
|
177
|
-
listingTypeScope: ["classified"],
|
|
185
|
+
listingTypeScope: ["standard", "classified", "art", "stickers"],
|
|
178
186
|
},
|
|
179
187
|
},
|
|
180
188
|
AUCTION: {
|
|
@@ -271,16 +279,15 @@ export const ACTIONS = {
|
|
|
271
279
|
listingTypeScope: ["prize-draw"],
|
|
272
280
|
},
|
|
273
281
|
},
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
},
|
|
282
|
+
/*
|
|
283
|
+
* `CLASSIFIED` held one entry, "contact-seller", whose description read
|
|
284
|
+
* "Open a conversations thread with the seller". It had ZERO consumers — the
|
|
285
|
+
* button on the classified PDP was hand-written — and the feature it named was
|
|
286
|
+
* deleted 2026-08-31. `PRODUCT["make-offer"]` below is the action that is
|
|
287
|
+
* actually wired (`MakeOfferButton`), and on a classified it is now the only
|
|
288
|
+
* purchase path, so a second bucket duplicating it would be exactly the drift
|
|
289
|
+
* Rule #7 exists to prevent.
|
|
290
|
+
*/
|
|
284
291
|
DIGITAL_CODE: {
|
|
285
292
|
"claim-code": {
|
|
286
293
|
iconKey: "confirm",
|
|
@@ -291,16 +298,12 @@ export const ACTIONS = {
|
|
|
291
298
|
listingTypeScope: ["digital-code"],
|
|
292
299
|
},
|
|
293
300
|
},
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
kind: "primary",
|
|
301
|
-
listingTypeScope: ["live"],
|
|
302
|
-
},
|
|
303
|
-
},
|
|
301
|
+
/*
|
|
302
|
+
* `LIVE.inquire` ("Open a conversation with the seller about a live-item
|
|
303
|
+
* listing") went the same way and for the same two reasons: no consumer, and
|
|
304
|
+
* the conversations feature is gone. It was never needed either — a live item
|
|
305
|
+
* has `canAddToCart: true`, so unlike classified it has a real checkout.
|
|
306
|
+
*/
|
|
304
307
|
BUNDLE: {
|
|
305
308
|
"buy-now": {
|
|
306
309
|
iconKey: "cart",
|
|
@@ -879,6 +882,26 @@ export const ACTIONS = {
|
|
|
879
882
|
confirmKind: "danger",
|
|
880
883
|
},
|
|
881
884
|
},
|
|
885
|
+
/*
|
|
886
|
+
* The alerts list rendered a bare `<Button variant="ghost">Delete</Button>`
|
|
887
|
+
* with a raw onClick — no ActionDef, so no confirmation, so one misplaced
|
|
888
|
+
* click silently removed an alert with nothing to undo it (Rule #7).
|
|
889
|
+
*/
|
|
890
|
+
"delete-analytics-alert": {
|
|
891
|
+
iconKey: "delete",
|
|
892
|
+
id: "store.delete-analytics-alert",
|
|
893
|
+
label: "Delete",
|
|
894
|
+
ariaLabel: "Delete this analytics alert",
|
|
895
|
+
description: "Permanently removes this alert rule. Past notifications are unaffected.",
|
|
896
|
+
kind: "danger",
|
|
897
|
+
permissions: ["seller", "admin"],
|
|
898
|
+
confirmation: {
|
|
899
|
+
title: "Delete this alert?",
|
|
900
|
+
body: "You will stop being notified when this rule matches. Alerts already sent are unaffected. This cannot be undone.",
|
|
901
|
+
confirmLabel: "Delete alert",
|
|
902
|
+
confirmKind: "danger",
|
|
903
|
+
},
|
|
904
|
+
},
|
|
882
905
|
"cancel-form": {
|
|
883
906
|
iconKey: "cancel",
|
|
884
907
|
id: "store.cancel-form",
|
|
@@ -1197,6 +1220,30 @@ export const ACTIONS = {
|
|
|
1197
1220
|
confirmKind: "danger",
|
|
1198
1221
|
},
|
|
1199
1222
|
},
|
|
1223
|
+
/*
|
|
1224
|
+
* A LOT, not the whole shipment.
|
|
1225
|
+
*
|
|
1226
|
+
* The lot row's delete button used `shipment.delete`, so the dialog asked
|
|
1227
|
+
* "Delete this shipment?" and warned about removing every lot — while the
|
|
1228
|
+
* handler deleted one lot. A confirmation that names the wrong object is
|
|
1229
|
+
* worse than none: it is either ignored, or it stops someone doing
|
|
1230
|
+
* something harmless.
|
|
1231
|
+
*/
|
|
1232
|
+
"delete-lot": {
|
|
1233
|
+
iconKey: "delete",
|
|
1234
|
+
id: "shipment.delete-lot",
|
|
1235
|
+
label: "Delete",
|
|
1236
|
+
ariaLabel: "Delete this lot and its items",
|
|
1237
|
+
description: "Permanently deletes this lot and every item in it.",
|
|
1238
|
+
kind: "danger",
|
|
1239
|
+
permissions: ["admin"],
|
|
1240
|
+
confirmation: {
|
|
1241
|
+
title: "Delete this lot?",
|
|
1242
|
+
body: "This permanently removes the lot and every item in it. The rest of the shipment is untouched. Items still linked to a product must be unlinked first.",
|
|
1243
|
+
confirmLabel: "Delete lot",
|
|
1244
|
+
confirmKind: "danger",
|
|
1245
|
+
},
|
|
1246
|
+
},
|
|
1200
1247
|
},
|
|
1201
1248
|
CATALOGUE: {
|
|
1202
1249
|
"list-item": {
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Classified listing rule —
|
|
2
|
+
* Classified listing rule — no cart, no checkout; the offer IS the purchase path.
|
|
3
3
|
*
|
|
4
|
-
* Classified listings (OLX / Facebook Marketplace pattern)
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Classified listings (OLX / Facebook Marketplace pattern) never reach cart or
|
|
5
|
+
* order creation. The buyer transacts through Make-an-Offer: the seller accepts,
|
|
6
|
+
* which produces a locked cart line in the offer lane, and checkout proceeds
|
|
7
|
+
* from there like any other accepted offer.
|
|
8
|
+
*
|
|
9
|
+
* A seller who has not set `allowOffers` still receives requests to buy at their
|
|
10
|
+
* asking price — see `resolveOfferBounds` in the offers config. Without that,
|
|
11
|
+
* unchecking one flag would make the listing untransactable.
|
|
7
12
|
*/
|
|
8
13
|
import type { ListingCheckoutRule } from "./types";
|
|
9
14
|
export declare const classifiedRule: ListingCheckoutRule;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { DEFAULT_LISTING_RULE } from "./_defaults";
|
|
2
2
|
export const classifiedRule = {
|
|
3
3
|
...DEFAULT_LISTING_RULE,
|
|
4
|
-
orderType: "standard", // placeholder — classified
|
|
4
|
+
orderType: "standard", // placeholder — a classified reaches order creation only via an accepted offer
|
|
5
5
|
purchaseable: false,
|
|
6
6
|
cartEligible: false,
|
|
7
|
-
|
|
7
|
+
/*
|
|
8
|
+
* Names the control the page actually has. It read 'Use "Contact Seller" to
|
|
9
|
+
* arrange a meetup' until 2026-08-31, and that button opened a conversations
|
|
10
|
+
* thread which no longer exists.
|
|
11
|
+
*/
|
|
12
|
+
cartIneligibleHint: "Make an offer to buy this — classified listings are arranged with the seller.",
|
|
8
13
|
requiresShippingAddress: false,
|
|
9
14
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The fields the matcher reads. Everything is optional but `label`. */
|
|
2
|
+
export interface NavSearchable {
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
keywords?: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* How well `item` answers `query`. `0` when it does not.
|
|
9
|
+
*
|
|
10
|
+
* The query is matched whole rather than tokenised: "prize draws" should find
|
|
11
|
+
* Prize Draws, and splitting on spaces would also match anything containing
|
|
12
|
+
* "draws" on its own, which for a two-word query is nearly everything.
|
|
13
|
+
*/
|
|
14
|
+
export declare function matchesNavQuery(item: NavSearchable, query: string): number;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: The sidebar search was `item.label.toLowerCase().includes(q)` — so it
|
|
3
|
+
* could only ever find a screen by the name it already shows you. Typing
|
|
4
|
+
* "refund" found nothing, because the screen is called "Payouts"; typing
|
|
5
|
+
* "postcode" found nothing, because the field is called PIN code; typing
|
|
6
|
+
* "maintenance" found nothing, because the toggle lives inside "Site
|
|
7
|
+
* Settings". A search that only matches what is already on screen is a
|
|
8
|
+
* filter, not a search.
|
|
9
|
+
* WHAT: One matcher over label + description + keywords, shared by the sidebar
|
|
10
|
+
* search and (in W7) the action index.
|
|
11
|
+
*
|
|
12
|
+
* ## Ranking, not just filtering
|
|
13
|
+
*
|
|
14
|
+
* A label hit and a keyword hit are not equally good answers. "orders" should
|
|
15
|
+
* put **Orders** first and "Orders & Finance" (a guide that mentions orders)
|
|
16
|
+
* second — so the matcher returns a SCORE and the caller sorts by it. Without
|
|
17
|
+
* that, alphabetical order decides, and the exact match can land ninth.
|
|
18
|
+
*
|
|
19
|
+
* EXPORTS: matchesNavQuery, type NavSearchable
|
|
20
|
+
*
|
|
21
|
+
* @tag domain:layout
|
|
22
|
+
* @tag layer:shared
|
|
23
|
+
* @tag pattern:none
|
|
24
|
+
* @tag access:isomorphic
|
|
25
|
+
* @tag consumers:useSidebarSearch,action index
|
|
26
|
+
* @tag sideEffects:none
|
|
27
|
+
*/
|
|
28
|
+
/** Higher is a better answer. `0` means no match at all. */
|
|
29
|
+
const SCORE = {
|
|
30
|
+
labelExact: 100,
|
|
31
|
+
labelPrefix: 80,
|
|
32
|
+
labelSubstring: 60,
|
|
33
|
+
keywordExact: 50,
|
|
34
|
+
keywordSubstring: 30,
|
|
35
|
+
description: 10,
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* How well `item` answers `query`. `0` when it does not.
|
|
39
|
+
*
|
|
40
|
+
* The query is matched whole rather than tokenised: "prize draws" should find
|
|
41
|
+
* Prize Draws, and splitting on spaces would also match anything containing
|
|
42
|
+
* "draws" on its own, which for a two-word query is nearly everything.
|
|
43
|
+
*/
|
|
44
|
+
export function matchesNavQuery(item, query) {
|
|
45
|
+
const q = query.trim().toLowerCase();
|
|
46
|
+
if (!q)
|
|
47
|
+
return 0;
|
|
48
|
+
const label = item.label.toLowerCase();
|
|
49
|
+
if (label === q)
|
|
50
|
+
return SCORE.labelExact;
|
|
51
|
+
if (label.startsWith(q))
|
|
52
|
+
return SCORE.labelPrefix;
|
|
53
|
+
if (label.includes(q))
|
|
54
|
+
return SCORE.labelSubstring;
|
|
55
|
+
for (const keyword of item.keywords ?? []) {
|
|
56
|
+
const k = keyword.toLowerCase();
|
|
57
|
+
if (k === q)
|
|
58
|
+
return SCORE.keywordExact;
|
|
59
|
+
if (k.includes(q) || q.includes(k))
|
|
60
|
+
return SCORE.keywordSubstring;
|
|
61
|
+
}
|
|
62
|
+
/*
|
|
63
|
+
* The description is matched LAST and scores lowest on purpose: it is a
|
|
64
|
+
* sentence, so it contains common words, and letting it outrank a keyword
|
|
65
|
+
* would mean "shipping" surfaced every screen whose description happens to
|
|
66
|
+
* mention shipping ahead of the one actually called Shipping.
|
|
67
|
+
*/
|
|
68
|
+
if (item.description && item.description.toLowerCase().includes(q)) {
|
|
69
|
+
return SCORE.description;
|
|
70
|
+
}
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
@@ -25,12 +25,48 @@ export interface SidebarNavItem {
|
|
|
25
25
|
badge?: number;
|
|
26
26
|
/**
|
|
27
27
|
* Stable nav-* slug used as the key in siteSettings.navConfig.
|
|
28
|
-
*
|
|
28
|
+
*
|
|
29
|
+
* 🛑 **Derived from the href, never hand-written** — `navItemId(portal, href)`.
|
|
30
|
+
* A hand-written id drifts from the route it names, and because it is also
|
|
31
|
+
* the `navConfig` key, a drifted id silently un-toggles the item: the admin
|
|
32
|
+
* hides "Payouts", the toggle writes a key nothing reads, and the entry
|
|
33
|
+
* stays.
|
|
34
|
+
*
|
|
35
|
+
* If absent, the item is always visible — no admin toggle and **no
|
|
36
|
+
* permission check**, which is why every admin item having no id meant
|
|
37
|
+
* `requiredPermission` had never once been enforced.
|
|
29
38
|
*/
|
|
30
39
|
id?: string;
|
|
31
40
|
/** RBAC permission key — item only shows to users with this permission. */
|
|
32
41
|
requiredPermission?: string;
|
|
42
|
+
/**
|
|
43
|
+
* One sentence on what this screen is FOR, in the user's words rather than
|
|
44
|
+
* the entity's. "Refund a buyer, or check why a payout is late" finds its
|
|
45
|
+
* screen; "Payouts" only finds itself.
|
|
46
|
+
*
|
|
47
|
+
* Consumed by the sidebar search and, in W7, by the action index.
|
|
48
|
+
*/
|
|
49
|
+
description?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Words someone might search for that are not in the label — synonyms
|
|
52
|
+
* ("postcode" for PIN), the old name of a renamed screen, the noun the rest
|
|
53
|
+
* of the industry uses.
|
|
54
|
+
*/
|
|
55
|
+
keywords?: string[];
|
|
56
|
+
/** Which dashboard this belongs to. Set by the helper alongside `id`. */
|
|
57
|
+
portal?: NavPortal;
|
|
33
58
|
}
|
|
59
|
+
/** The three dashboards a sidebar item can belong to. */
|
|
60
|
+
export type NavPortal = "admin" | "store" | "user";
|
|
61
|
+
/**
|
|
62
|
+
* The `navConfig` key for a nav item: `nav-{portal}-{slug-of-href}`.
|
|
63
|
+
*
|
|
64
|
+
* Derived rather than authored so an id cannot disagree with the route it
|
|
65
|
+
* points at. Locale prefixes and dynamic segments are stripped, so
|
|
66
|
+
* `/en/admin/orders` and `/admin/orders` produce the same key — otherwise a
|
|
67
|
+
* localised build would write a second set of toggles nobody can find.
|
|
68
|
+
*/
|
|
69
|
+
export declare function navItemId(portal: NavPortal, href: string): string;
|
|
34
70
|
/** Sidebar group with title + items + default-open state. */
|
|
35
71
|
export interface SidebarNavGroup {
|
|
36
72
|
title: string;
|
|
@@ -10,4 +10,22 @@
|
|
|
10
10
|
* 2. render-prop slots on each section (defined on the section component itself).
|
|
11
11
|
* 3. Section replacement via AppShell named slots.
|
|
12
12
|
*/
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The `navConfig` key for a nav item: `nav-{portal}-{slug-of-href}`.
|
|
15
|
+
*
|
|
16
|
+
* Derived rather than authored so an id cannot disagree with the route it
|
|
17
|
+
* points at. Locale prefixes and dynamic segments are stripped, so
|
|
18
|
+
* `/en/admin/orders` and `/admin/orders` produce the same key — otherwise a
|
|
19
|
+
* localised build would write a second set of toggles nobody can find.
|
|
20
|
+
*/
|
|
21
|
+
export function navItemId(portal, href) {
|
|
22
|
+
const path = href
|
|
23
|
+
.replace(/^https?:\/\/[^/]+/, "")
|
|
24
|
+
.replace(/^\/[a-z]{2}(-[A-Z]{2})?(?=\/)/, "")
|
|
25
|
+
.replace(/[?#].*$/, "")
|
|
26
|
+
.replace(/^\/+|\/+$/g, "")
|
|
27
|
+
.replace(/[^a-zA-Z0-9/-]+/g, "-")
|
|
28
|
+
.replace(/\//g, "-")
|
|
29
|
+
.toLowerCase();
|
|
30
|
+
return `nav-${portal}-${path || "root"}`;
|
|
31
|
+
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* When those pages are built, change the entry here and all 40 call sites
|
|
26
26
|
* follow. That is the whole point of the indirection.
|
|
27
27
|
*/
|
|
28
|
-
import type { NotificationRelatedType } from "../../../../features/admin/schemas/firestore";
|
|
28
|
+
import type { NotificationRelatedType, NotificationType } from "../../../../features/admin/schemas/firestore";
|
|
29
29
|
/**
|
|
30
30
|
* Which portal the recipient reads this in.
|
|
31
31
|
*
|
|
@@ -45,3 +45,11 @@ export type NotificationAudience = "buyer" | "seller" | "admin";
|
|
|
45
45
|
* looking at.
|
|
46
46
|
*/
|
|
47
47
|
export declare function resolveNotificationActionUrl(relatedType: NotificationRelatedType | undefined, relatedId: string | undefined, audience: NotificationAudience): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Which portal each notification type belongs to.
|
|
50
|
+
*
|
|
51
|
+
* `Record<NotificationType, …>`, so a new type cannot compile without an
|
|
52
|
+
* answer — the same discipline `typeToPrefsKey` needed after it silently
|
|
53
|
+
* omitted three types and ignored those users' opt-outs.
|
|
54
|
+
*/
|
|
55
|
+
export declare const TYPE_AUDIENCE: Record<NotificationType, NotificationAudience>;
|
|
@@ -109,3 +109,50 @@ export function resolveNotificationActionUrl(relatedType, relatedId, audience) {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
+
/*
|
|
113
|
+
* Moved here from `features/admin/actions/notification-actions.ts` 2026-08-31.
|
|
114
|
+
* It belongs beside the resolver it feeds, and being module-private in a
|
|
115
|
+
* `"use server"` file meant the SEED could not use it — so seeded notifications
|
|
116
|
+
* carried no `actionUrl` and rendered unclickable, the exact defect the central
|
|
117
|
+
* resolver was built to end.
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* Which portal each notification type belongs to.
|
|
121
|
+
*
|
|
122
|
+
* `Record<NotificationType, …>`, so a new type cannot compile without an
|
|
123
|
+
* answer — the same discipline `typeToPrefsKey` needed after it silently
|
|
124
|
+
* omitted three types and ignored those users' opt-outs.
|
|
125
|
+
*/
|
|
126
|
+
export const TYPE_AUDIENCE = {
|
|
127
|
+
// Buyer-facing: the order lifecycle they are waiting on.
|
|
128
|
+
order_placed: "buyer",
|
|
129
|
+
order_confirmed: "buyer",
|
|
130
|
+
order_shipped: "buyer",
|
|
131
|
+
order_delivered: "buyer",
|
|
132
|
+
order_cancelled: "buyer",
|
|
133
|
+
refund_initiated: "buyer",
|
|
134
|
+
payment_review: "buyer",
|
|
135
|
+
emi_installment_due_soon: "buyer",
|
|
136
|
+
emi_installment_overdue: "buyer",
|
|
137
|
+
prize_won: "buyer",
|
|
138
|
+
prize_reveal_expired: "buyer",
|
|
139
|
+
product_available: "buyer",
|
|
140
|
+
bid_placed: "buyer",
|
|
141
|
+
bid_outbid: "buyer",
|
|
142
|
+
bid_won: "buyer",
|
|
143
|
+
bid_lost: "buyer",
|
|
144
|
+
offer_responded: "buyer",
|
|
145
|
+
offer_counter_accepted: "buyer",
|
|
146
|
+
offer_expired: "buyer",
|
|
147
|
+
review_replied: "buyer",
|
|
148
|
+
catalogue_images_stale: "buyer",
|
|
149
|
+
// Seller-facing.
|
|
150
|
+
auction_ended: "seller", // "your auction closed with no winner"
|
|
151
|
+
offer_received: "seller",
|
|
152
|
+
review_approved: "seller",
|
|
153
|
+
// Account-level, which lives in the user portal for everyone.
|
|
154
|
+
welcome: "buyer",
|
|
155
|
+
account_action: "buyer",
|
|
156
|
+
system: "buyer",
|
|
157
|
+
promotion: "buyer",
|
|
158
|
+
};
|