@mohasinac/appkit 4.53.0 → 4.53.1
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/.build-stamp.json +3 -3
- package/dist/_internal/client/scaffolds/AppShell.js +1 -1
- package/dist/_internal/server/features/auctions/og.d.ts +3 -1
- package/dist/_internal/server/features/auctions/og.js +3 -1
- package/dist/_internal/server/features/bundles/actions.js +1 -1
- package/dist/_internal/server/features/business-documents/download.d.ts +41 -0
- package/dist/_internal/server/features/business-documents/download.js +91 -0
- package/dist/_internal/server/features/categories/adapters.d.ts +1 -1
- package/dist/_internal/server/features/categories/adapters.js +10 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +14 -0
- package/dist/_internal/server/features/checkout/actions.js +106 -12
- package/dist/_internal/server/features/checkout/bundle-expansion.js +17 -0
- package/dist/_internal/server/features/checkout/data.d.ts +22 -0
- package/dist/_internal/server/features/checkout/group-rule-revalidation.d.ts +34 -0
- package/dist/_internal/server/features/checkout/group-rule-revalidation.js +124 -0
- package/dist/_internal/server/features/checkout/supplier-identity.d.ts +55 -0
- package/dist/_internal/server/features/checkout/supplier-identity.js +81 -0
- package/dist/_internal/server/features/classified/metadata.js +1 -1
- package/dist/_internal/server/features/classified/og.d.ts +3 -1
- package/dist/_internal/server/features/classified/og.js +3 -1
- package/dist/_internal/server/features/digital-code/metadata.js +1 -1
- package/dist/_internal/server/features/digital-code/og.d.ts +3 -1
- package/dist/_internal/server/features/digital-code/og.js +3 -1
- package/dist/_internal/server/features/digital-code/pool.d.ts +19 -4
- package/dist/_internal/server/features/digital-code/pool.js +19 -4
- package/dist/_internal/server/features/live/metadata.js +1 -1
- package/dist/_internal/server/features/live/og.d.ts +3 -1
- package/dist/_internal/server/features/live/og.js +3 -1
- package/dist/_internal/server/features/messages/actions.js +1 -1
- package/dist/_internal/server/features/parts/og.js +1 -1
- package/dist/_internal/server/features/pre-orders/og.d.ts +3 -1
- package/dist/_internal/server/features/pre-orders/og.js +3 -1
- package/dist/_internal/server/features/price-index/search.d.ts +18 -0
- package/dist/_internal/server/features/price-index/search.js +47 -7
- package/dist/_internal/server/features/prize-draws/og.d.ts +3 -1
- package/dist/_internal/server/features/prize-draws/og.js +3 -1
- package/dist/_internal/server/features/products/group-members.d.ts +26 -0
- package/dist/_internal/server/features/products/group-members.js +7 -1
- package/dist/_internal/server/features/products/og.d.ts +3 -1
- package/dist/_internal/server/features/products/og.js +3 -1
- package/dist/_internal/server/features/search/scoped-sources.d.ts +26 -0
- package/dist/_internal/server/features/search/scoped-sources.js +252 -0
- package/dist/_internal/server/features/search/search-everything.d.ts +57 -0
- package/dist/_internal/server/features/search/search-everything.js +70 -20
- package/dist/_internal/server/features/seo/sitemap.js +6 -0
- package/dist/_internal/server/features/shared/listing-adapters.js +4 -2
- package/dist/_internal/server/features/sticker-trace/adapters.d.ts +11 -0
- package/dist/_internal/server/features/sticker-trace/adapters.js +1 -0
- package/dist/_internal/server/features/sticker-trace/promote-to-listings.d.ts +26 -0
- package/dist/_internal/server/features/sticker-trace/promote-to-listings.js +264 -0
- package/dist/_internal/server/features/sticker-trace/sheet-actions.d.ts +3 -1
- package/dist/_internal/server/features/sticker-trace/sheet-actions.js +32 -0
- package/dist/_internal/server/features/sticker-trace/storage.d.ts +20 -1
- package/dist/_internal/server/features/sticker-trace/storage.js +20 -1
- package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
- package/dist/_internal/server/features/stores/adapters.js +16 -0
- package/dist/_internal/server/features/stores/index.d.ts +1 -0
- package/dist/_internal/server/features/stores/index.js +1 -0
- package/dist/_internal/server/features/stores/tabs.d.ts +25 -0
- package/dist/_internal/server/features/stores/tabs.js +122 -0
- package/dist/_internal/shared/checkout/rules/_defaults.js +0 -2
- package/dist/_internal/shared/checkout/rules/_limits.d.ts +14 -1
- package/dist/_internal/shared/checkout/rules/_limits.js +14 -1
- package/dist/_internal/shared/checkout/rules/_registry.js +2 -0
- package/dist/_internal/shared/checkout/rules/auction.rule.js +9 -1
- package/dist/_internal/shared/checkout/rules/bundle.rule.js +13 -0
- package/dist/_internal/shared/checkout/rules/index.d.ts +2 -0
- package/dist/_internal/shared/checkout/rules/index.js +9 -0
- package/dist/_internal/shared/checkout/rules/offer.rule.js +0 -1
- package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +26 -0
- package/dist/_internal/shared/checkout/rules/payment-gate.js +133 -0
- package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +29 -8
- package/dist/_internal/shared/checkout/rules/spares.rule.d.ts +16 -0
- package/dist/_internal/shared/checkout/rules/spares.rule.js +5 -0
- package/dist/_internal/shared/checkout/rules/types.d.ts +26 -2
- package/dist/_internal/shared/config/schema.d.ts +122 -0
- package/dist/_internal/shared/features/cart/schema.js +3 -2
- package/dist/_internal/shared/features/products/group-rules.d.ts +75 -0
- package/dist/_internal/shared/features/products/group-rules.js +142 -0
- package/dist/_internal/shared/listing-types/_registry.d.ts +24 -0
- package/dist/_internal/shared/listing-types/_registry.js +39 -1
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/art/config.js +2 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/auction/config.js +2 -0
- package/dist/_internal/shared/listing-types/availability.js +48 -0
- package/dist/_internal/shared/listing-types/capabilities.js +19 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/classified/config.js +2 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +2 -0
- package/dist/_internal/shared/listing-types/feature-flags.js +1 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/live/config.js +2 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +2 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +2 -0
- package/dist/_internal/shared/listing-types/spares/config.d.ts +74 -0
- package/dist/_internal/shared/listing-types/spares/config.js +60 -0
- package/dist/_internal/shared/listing-types/spares/ctas.d.ts +1 -0
- package/dist/_internal/shared/listing-types/spares/ctas.js +4 -0
- package/dist/_internal/shared/listing-types/spares/og.js +1 -0
- package/dist/_internal/shared/listing-types/spares/schema.d.ts +2 -0
- package/dist/_internal/shared/listing-types/spares/schema.js +3 -0
- package/dist/_internal/shared/listing-types/spares/seed-factory.d.ts +1 -0
- package/dist/_internal/shared/listing-types/spares/seed-factory.js +1 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/standard/config.js +2 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +2 -0
- package/dist/_internal/shared/search/match.d.ts +11 -0
- package/dist/_internal/shared/search/match.js +2 -1
- package/dist/_internal/shared/search/to-groups.d.ts +52 -0
- package/dist/_internal/shared/search/to-groups.js +141 -0
- package/dist/client.d.ts +8 -2
- package/dist/client.js +4 -1
- package/dist/constants/api-endpoints.d.ts +39 -15
- package/dist/constants/api-endpoints.js +28 -5
- package/dist/constants/cache-invalidation.js +3 -1
- package/dist/constants/field-names.d.ts +6 -0
- package/dist/constants/field-names.js +6 -0
- package/dist/features/about/components/PolicyPageView.d.ts +22 -2
- package/dist/features/about/components/PolicyPageView.js +14 -2
- package/dist/features/about/components/PublicProfileView.js +2 -1
- package/dist/features/about/components/ShippingPolicyView.js +42 -2
- package/dist/features/account/components/NotificationBell.js +1 -1
- package/dist/features/account/hooks/useProfileStats.js +5 -1
- package/dist/features/addresses/repository/addresses.repository.d.ts +16 -0
- package/dist/features/addresses/repository/addresses.repository.js +21 -0
- package/dist/features/admin/actions/admin-actions.js +16 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +19 -2
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminPageHeader.js +1 -1
- package/dist/features/admin/components/AdminProductEditorView.js +17 -2
- package/dist/features/admin/components/AdminSidebar.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +39 -8
- package/dist/features/admin/components/AdminSparesView.d.ts +12 -0
- package/dist/features/admin/components/AdminSparesView.js +30 -0
- package/dist/features/admin/components/AdminUsersView.js +9 -7
- package/dist/features/admin/components/index.d.ts +2 -0
- package/dist/features/admin/components/index.js +1 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +7 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +3 -0
- package/dist/features/admin/constants/filter-tabs.js +1 -0
- package/dist/features/admin/schemas/firestore.d.ts +26 -2
- package/dist/features/auctions/components/AuctionDetailPageView.js +4 -11
- package/dist/features/auth/repository/user.repository.d.ts +13 -0
- package/dist/features/auth/repository/user.repository.js +28 -0
- package/dist/features/auth/schemas/firestore.d.ts +2 -0
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/business-documents/repository/business-documents.repository.d.ts +58 -0
- package/dist/features/business-documents/repository/business-documents.repository.js +54 -0
- package/dist/features/business-documents/schemas/firestore.d.ts +105 -0
- package/dist/features/business-documents/schemas/firestore.js +75 -0
- package/dist/features/cart/actions/cart-actions.js +83 -6
- package/dist/features/cart/repository/cart.repository.js +32 -4
- package/dist/features/cart/schemas/firestore.d.ts +20 -0
- package/dist/features/cart/schemas/index.d.ts +2 -2
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +1 -1
- package/dist/features/categories/api/[id]/price-guidance/route.d.ts +42 -0
- package/dist/features/categories/api/[id]/price-guidance/route.js +113 -0
- package/dist/features/categories/components/BrandDetailPageView.js +19 -3
- package/dist/features/categories/components/BrandDetailTabs.js +10 -0
- package/dist/features/categories/components/CategoriesIndexListing.js +23 -8
- package/dist/features/categories/components/CategoryDetailPageView.js +141 -14
- package/dist/features/categories/components/CategoryDetailTabs.js +12 -0
- package/dist/features/categories/components/CategoryGrid.js +10 -1
- package/dist/features/categories/components/PriceGuidanceHint.d.ts +29 -0
- package/dist/features/categories/components/PriceGuidanceHint.js +61 -0
- package/dist/features/categories/components/SubcategoryCardRow.d.ts +27 -0
- package/dist/features/categories/components/SubcategoryCardRow.js +98 -0
- package/dist/features/categories/constants/category-tabs.d.ts +20 -25
- package/dist/features/categories/constants/category-tabs.js +22 -39
- package/dist/features/categories/repository/categories.repository.d.ts +12 -0
- package/dist/features/categories/repository/categories.repository.js +20 -0
- package/dist/features/categories/schemas/firestore.d.ts +22 -1
- package/dist/features/categories/schemas/firestore.js +10 -0
- package/dist/features/categories/schemas/index.d.ts +6 -0
- package/dist/features/categories/schemas/index.js +2 -0
- package/dist/features/categories/types/index.d.ts +8 -0
- package/dist/features/categories/utils/taxonomy-visual.d.ts +16 -3
- package/dist/features/categories/utils/taxonomy-visual.js +26 -10
- package/dist/features/classified/components/ClassifiedDetailPageView.js +4 -9
- package/dist/features/contact/components/ContactPageView.d.ts +33 -1
- package/dist/features/contact/components/ContactPageView.js +58 -28
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +4 -9
- package/dist/features/grouped/components/GroupedListingDetailView.js +9 -1
- package/dist/features/grouped/schemas/firestore.d.ts +5 -0
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +3 -3
- package/dist/features/homepage/components/CollectionCardsSection.d.ts +28 -6
- package/dist/features/homepage/components/CollectionCardsSection.js +43 -8
- package/dist/features/homepage/components/HowItWorksSection.d.ts +23 -6
- package/dist/features/homepage/components/HowItWorksSection.js +4 -4
- package/dist/features/homepage/components/PromoGrid.d.ts +31 -2
- package/dist/features/homepage/components/PromoGrid.js +12 -3
- package/dist/features/homepage/components/TestimonialsCarousel.d.ts +34 -2
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/index.d.ts +0 -20
- package/dist/features/homepage/components/index.js +0 -11
- package/dist/features/homepage/index.d.ts +0 -2
- package/dist/features/homepage/index.js +0 -2
- package/dist/features/homepage/lib/section-renderer.d.ts +9 -0
- package/dist/features/homepage/lib/section-renderer.js +202 -58
- package/dist/features/homepage/repository/homepage-sections.repository.d.ts +35 -3
- package/dist/features/homepage/repository/homepage-sections.repository.js +58 -8
- package/dist/features/homepage/schemas/firestore.d.ts +106 -3
- package/dist/features/homepage/schemas/firestore.js +32 -2
- package/dist/features/homepage/schemas/index.d.ts +36 -7
- package/dist/features/homepage/schemas/index.js +39 -27
- package/dist/features/homepage/server.d.ts +0 -3
- package/dist/features/homepage/server.js +0 -3
- package/dist/features/homepage/types/index.d.ts +0 -47
- package/dist/features/homepage/types/index.js +49 -0
- package/dist/features/layout/AppLayoutShell.js +1 -1
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/TitleBarLayout.js +1 -1
- package/dist/features/live/components/LiveItemDetailPageView.js +4 -9
- package/dist/features/media/hooks/useMedia.js +17 -0
- package/dist/features/media/repository/media-assets.repository.d.ts +46 -0
- package/dist/features/media/repository/media-assets.repository.js +31 -0
- package/dist/features/media/trust-signals.d.ts +85 -0
- package/dist/features/media/trust-signals.js +126 -0
- package/dist/features/parts/components/PartDetailPageView.d.ts +14 -1
- package/dist/features/parts/components/PartDetailPageView.js +2 -2
- package/dist/features/parts/components/PartsIndexPageView.d.ts +11 -2
- package/dist/features/parts/components/PartsIndexPageView.js +2 -2
- package/dist/features/parts/components/PartsSearchBox.d.ts +9 -0
- package/dist/features/parts/components/PartsSearchBox.js +57 -0
- package/dist/features/parts/schemas/firestore.d.ts +149 -3
- package/dist/features/parts/schemas/firestore.js +184 -0
- package/dist/features/payments/repository/payout.repository.d.ts +15 -0
- package/dist/features/payments/repository/payout.repository.js +21 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -11
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +1 -1
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +3 -1
- package/dist/features/price-index/components/PriceIndexToolView.js +92 -13
- package/dist/features/products/components/CompareOverlay.d.ts +18 -1
- package/dist/features/products/components/CompareOverlay.js +21 -2
- package/dist/features/products/components/CustomSectionTabContent.d.ts +31 -0
- package/dist/features/products/components/CustomSectionTabContent.js +29 -3
- package/dist/features/products/components/GroupMemberPicker.d.ts +19 -1
- package/dist/features/products/components/GroupMemberPicker.js +46 -8
- package/dist/features/products/components/GroupSettingsPanel.d.ts +11 -1
- package/dist/features/products/components/GroupSettingsPanel.js +91 -3
- package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
- package/dist/features/products/components/PrizeDrawEntryActions.d.ts +15 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +70 -8
- package/dist/features/products/components/ProductDetailPageView.js +74 -15
- package/dist/features/products/components/ProductForm.d.ts +13 -1
- package/dist/features/products/components/ProductForm.js +16 -2
- package/dist/features/products/components/ProductsIndexListing.d.ts +16 -1
- package/dist/features/products/components/ProductsIndexListing.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +15 -2
- package/dist/features/products/components/SparesListView.d.ts +7 -0
- package/dist/features/products/components/SparesListView.js +39 -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/repository/products.repository.d.ts +98 -0
- package/dist/features/products/repository/products.repository.js +235 -17
- package/dist/features/products/schemas/firestore.d.ts +97 -4
- package/dist/features/products/schemas/firestore.js +104 -0
- package/dist/features/products/schemas/index.d.ts +10 -19
- package/dist/features/products/schemas/index.js +23 -6
- package/dist/features/products/types/index.d.ts +45 -1
- package/dist/features/products/utils/group-member-image.d.ts +39 -0
- package/dist/features/products/utils/group-member-image.js +3 -0
- package/dist/features/products/utils/listing-badge-variant.js +4 -0
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/components/ScamProfileView.js +1 -1
- package/dist/features/search/components/EntityTypeahead.d.ts +44 -0
- package/dist/features/search/components/EntityTypeahead.js +92 -0
- package/dist/features/search/components/Search.d.ts +12 -1
- package/dist/features/search/components/Search.js +47 -3
- package/dist/features/search/components/SearchFacetRail.d.ts +11 -0
- package/dist/features/search/components/SearchFacetRail.js +92 -0
- package/dist/features/search/components/SearchResultsClient.d.ts +33 -0
- package/dist/features/search/components/SearchResultsClient.js +103 -0
- package/dist/features/search/components/SearchResultsPageView.d.ts +15 -1
- package/dist/features/search/components/SearchResultsPageView.js +2 -2
- package/dist/features/search/components/index.d.ts +0 -6
- package/dist/features/search/components/index.js +0 -3
- package/dist/features/search/hooks/useNavSuggestions.d.ts +13 -0
- package/dist/features/search/hooks/useScopedSearch.d.ts +34 -0
- package/dist/features/search/hooks/useScopedSearch.js +114 -0
- package/dist/features/search/hooks/useSiteSearch.d.ts +26 -0
- package/dist/features/search/hooks/useSiteSearch.js +149 -0
- package/dist/features/search/index.d.ts +0 -4
- package/dist/features/search/index.js +0 -4
- package/dist/features/search/manifest.d.ts +12 -0
- package/dist/features/search/manifest.js +17 -2
- package/dist/features/search/server.d.ts +0 -3
- package/dist/features/search/server.js +0 -3
- package/dist/features/seller/components/SellerListingTypeView.d.ts +1 -1
- package/dist/features/seller/components/SellerListingTypeView.js +20 -0
- package/dist/features/seller/components/SellerPayoutSettingsView.js +35 -14
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductShell.js +2 -1
- package/dist/features/seller/components/SellerSidebar.js +1 -1
- package/dist/features/seller/components/SellerSparesView.d.ts +17 -0
- package/dist/features/seller/components/SellerSparesView.js +6 -0
- package/dist/features/seller/components/index.d.ts +2 -0
- package/dist/features/seller/components/index.js +1 -0
- package/dist/features/shell/CommandPalette.js +1 -1
- package/dist/features/sticker-trace/schemas/firestore.d.ts +19 -0
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -82
- package/dist/features/stores/components/StoreHeader.js +1 -2
- package/dist/features/stores/components/StoreSparesPageView.d.ts +27 -0
- package/dist/features/stores/components/StoreSparesPageView.js +48 -0
- package/dist/features/stores/schemas/firestore.d.ts +19 -0
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +96 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +280 -45
- package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +54 -32
- package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +3 -2
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +73 -0
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +340 -0
- package/dist/features/tester/seed-data/authored/index.js +16 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +1 -0
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +57 -0
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +77 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +2 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +58 -0
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +5 -4
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +372 -18
- package/dist/index.d.ts +17 -57
- package/dist/index.js +35 -96
- package/dist/next/routing/route-map.d.ts +42 -1
- package/dist/next/routing/route-map.js +45 -0
- package/dist/providers/db-firebase/base.repository.d.ts +22 -0
- package/dist/providers/db-firebase/base.repository.js +36 -0
- package/dist/schemas/registry.d.ts +15 -6
- package/dist/security/blind-index-tokens.d.ts +54 -0
- package/dist/security/blind-index-tokens.js +152 -0
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/settings-encryption.d.ts +35 -0
- package/dist/security/settings-encryption.js +91 -0
- package/dist/seed/_helpers/brand-rows.js +38 -14
- package/dist/seed/_helpers/category-forest.js +73 -7
- package/dist/seed/_helpers/category-images-generated.d.ts +25 -6
- package/dist/seed/_helpers/category-images-generated.js +81 -6
- package/dist/seed/_helpers/category-models.d.ts +1 -1
- package/dist/seed/_helpers/category-models.js +7 -1
- package/dist/seed/_helpers/category-parts-glossary-map.js +8 -0
- package/dist/seed/_helpers/category-parts.d.ts +1 -1
- package/dist/seed/_helpers/category-parts.js +50 -2
- package/dist/seed/_helpers/character-features.d.ts +1 -1
- package/dist/seed/_helpers/character-features.js +2 -1
- package/dist/seed/_helpers/franchise-rows.js +10 -2
- package/dist/seed/_helpers/media.d.ts +47 -0
- package/dist/seed/_helpers/media.js +34 -0
- package/dist/seed/authenticity-knowledge-seed-data.d.ts +49 -5
- package/dist/seed/authenticity-knowledge-seed-data.js +10001 -549
- package/dist/seed/categories-seed-data.js +124 -20
- package/dist/seed/grouped-listings-seed-data.js +16 -0
- package/dist/seed/homepage-sections-seed-data.js +94 -5
- package/dist/seed/index.d.ts +2 -3
- package/dist/seed/index.js +2 -2
- package/dist/seed/manifest.js +3 -0
- package/dist/seed/media-assets-seed-data.d.ts +1 -1
- package/dist/seed/media-assets-seed-data.js +746 -196
- package/dist/seed/model-composition-seed-data.js +122 -6
- package/dist/seed/part-glossary-seed-data.d.ts +1 -1
- package/dist/seed/part-glossary-seed-data.js +37219 -463
- package/dist/seed/products-art-seed-data.js +7 -18
- package/dist/seed/products-auctions-seed-data.js +56 -47
- package/dist/seed/products-beyblade-x-seed-data.d.ts +2 -0
- package/dist/seed/products-beyblade-x-seed-data.js +441 -0
- package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
- package/dist/seed/products-catalogue-seed-data.js +1500 -1240
- package/dist/seed/products-classifieds-seed-data.js +9 -27
- package/dist/seed/products-digital-codes-seed-data.js +9 -18
- package/dist/seed/products-live-items-seed-data.js +5 -13
- package/dist/seed/products-preorders-seed-data.js +67 -33
- package/dist/seed/products-prize-draws-seed-data.js +8 -17
- package/dist/seed/products-spares-seed-data.d.ts +2 -0
- package/dist/seed/products-spares-seed-data.js +368 -0
- package/dist/seed/products-standard-seed-data.js +39 -126
- package/dist/seed/products-stickers-seed-data.js +59 -15
- package/dist/seed/site-settings-seed-data.js +8 -0
- package/dist/seo/json-ld.d.ts +25 -0
- package/dist/seo/json-ld.js +28 -0
- package/dist/server-entry.d.ts +3 -1
- package/dist/server-entry.js +2 -2
- package/dist/server.d.ts +9 -9
- package/dist/server.js +27 -25
- package/dist/styles.css +202 -1
- package/dist/tailwind-input.css +31 -17
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Accordion.js +1 -1
- package/dist/ui/components/Breadcrumb.js +1 -1
- package/dist/ui/components/DetailPageGallery.js +0 -2
- package/dist/ui/components/DetailPageHero.js +0 -1
- package/dist/ui/components/DetailPageTabs.js +1 -1
- package/dist/ui/components/Divider.js +3 -3
- package/dist/ui/components/GatedPrice.js +5 -1
- package/dist/ui/components/HorizontalScroller.js +1 -1
- package/dist/ui/components/ListingLayout.js +3 -3
- package/dist/ui/components/MediaTabs.style.css +81 -0
- package/dist/ui/components/Pagination.js +1 -1
- package/dist/ui/components/PendingValue.d.ts +45 -0
- package/dist/ui/components/PendingValue.js +7 -0
- package/dist/ui/components/Radio.style.css +119 -0
- package/dist/ui/components/RatingDisplay.js +2 -2
- package/dist/ui/components/SettingsSection.js +0 -2
- package/dist/ui/components/SiteLogo.js +3 -0
- package/dist/ui/components/SiteMark.js +3 -0
- package/dist/ui/components/SortDropdown.js +1 -1
- package/dist/ui/components/SpecTable.d.ts +58 -0
- package/dist/ui/components/SpecTable.js +8 -0
- package/dist/ui/components/StarRating.js +1 -3
- package/dist/ui/components/SummaryCard.js +1 -1
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/icons/icon-registry.d.ts +1 -0
- package/dist/ui/icons/icon-registry.js +9 -1
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +2 -0
- package/dist/utils/search-txt-query.d.ts +12 -0
- package/dist/utils/search-txt-query.js +12 -0
- package/package.json +1 -1
- package/scripts/dedupe-peer-deps.mjs +18 -0
- package/scripts/seed-cli.mjs +135 -26
- package/scripts/verify-css-build.mjs +118 -37
- package/dist/_internal/server/features/search/actions.d.ts +0 -7
- package/dist/_internal/server/features/search/actions.js +0 -21
- package/dist/_internal/server/features/search/data.d.ts +0 -15
- package/dist/_internal/server/features/search/data.js +0 -18
- package/dist/_internal/server/features/search/index.d.ts +0 -3
- package/dist/_internal/server/features/search/index.js +0 -2
- package/dist/features/homepage/api/[id]/route.d.ts +0 -23
- package/dist/features/homepage/api/[id]/route.js +0 -103
- package/dist/features/homepage/api/route.d.ts +0 -14
- package/dist/features/homepage/api/route.js +0 -140
- package/dist/features/homepage/api/sections/[id]/route.d.ts +0 -26
- package/dist/features/homepage/api/sections/[id]/route.js +0 -95
- package/dist/features/homepage/api/sections/route.d.ts +0 -13
- package/dist/features/homepage/api/sections/route.js +0 -82
- package/dist/features/homepage/components/AdvertisementBanner.d.ts +0 -14
- package/dist/features/homepage/components/AdvertisementBanner.js +0 -35
- package/dist/features/homepage/components/BeforeAfterCard.d.ts +0 -9
- package/dist/features/homepage/components/BeforeAfterCard.js +0 -73
- package/dist/features/homepage/components/FeaturedResultsSection.d.ts +0 -17
- package/dist/features/homepage/components/FeaturedResultsSection.js +0 -17
- package/dist/features/homepage/components/HeroBanner.d.ts +0 -7
- package/dist/features/homepage/components/HeroBanner.js +0 -43
- package/dist/features/homepage/components/HeroSection.d.ts +0 -7
- package/dist/features/homepage/components/HeroSection.js +0 -6
- package/dist/features/homepage/components/HomepageSkeleton.d.ts +0 -2
- package/dist/features/homepage/components/HomepageSkeleton.js +0 -21
- package/dist/features/homepage/components/HomepageView.d.ts +0 -25
- package/dist/features/homepage/components/HomepageView.js +0 -5
- package/dist/features/homepage/components/NewsletterBanner.d.ts +0 -23
- package/dist/features/homepage/components/NewsletterBanner.js +0 -37
- package/dist/features/homepage/components/SiteFeaturesSection.d.ts +0 -14
- package/dist/features/homepage/components/SiteFeaturesSection.js +0 -11
- package/dist/features/homepage/components/TrustBadges.d.ts +0 -6
- package/dist/features/homepage/components/TrustBadges.js +0 -46
- package/dist/features/homepage/components/TrustIndicatorsSection.d.ts +0 -12
- package/dist/features/homepage/components/TrustIndicatorsSection.js +0 -11
- package/dist/features/homepage/hooks/useHomepage.d.ts +0 -11
- package/dist/features/homepage/hooks/useHomepage.js +0 -17
- package/dist/features/homepage/hooks/useHomepageSections.d.ts +0 -2
- package/dist/features/homepage/hooks/useHomepageSections.js +0 -10
- package/dist/features/homepage/repository/homepage.repository.d.ts +0 -11
- package/dist/features/homepage/repository/homepage.repository.js +0 -25
- package/dist/features/search/actions/index.d.ts +0 -1
- package/dist/features/search/actions/index.js +0 -1
- package/dist/features/search/actions/search-actions.d.ts +0 -18
- package/dist/features/search/actions/search-actions.js +0 -43
- package/dist/features/search/api/route.d.ts +0 -22
- package/dist/features/search/api/route.js +0 -128
- package/dist/features/search/columns/index.d.ts +0 -17
- package/dist/features/search/columns/index.js +0 -49
- package/dist/features/search/components/SearchFiltersRow.d.ts +0 -22
- package/dist/features/search/components/SearchFiltersRow.js +0 -21
- package/dist/features/search/components/SearchResultsSection.d.ts +0 -53
- package/dist/features/search/components/SearchResultsSection.js +0 -35
- package/dist/features/search/components/SearchView.d.ts +0 -27
- package/dist/features/search/components/SearchView.js +0 -8
- package/dist/features/search/hooks/useSearch.d.ts +0 -21
- package/dist/features/search/hooks/useSearch.js +0 -33
- package/dist/features/search/repository/search.repository.d.ts +0 -14
- package/dist/features/search/repository/search.repository.js +0 -59
- package/dist/features/search/schemas/index.d.ts +0 -70
- package/dist/features/search/schemas/index.js +0 -36
- package/dist/features/search/types/index.d.ts +0 -48
- package/dist/features/stores/components/StoreScopedSearch.d.ts +0 -17
- package/dist/features/stores/components/StoreScopedSearch.js +0 -27
- package/dist/seed/defaults/homepage-sections.d.ts +0 -2
- package/dist/seed/defaults/homepage-sections.js +0 -60
- package/dist/seed/factories/homepage-section.factory.d.ts +0 -10
- package/dist/seed/factories/homepage-section.factory.js +0 -13
- /package/dist/{features/search/types/index.js → _internal/shared/listing-types/spares/og.d.ts} +0 -0
|
@@ -22,6 +22,8 @@ export const config = {
|
|
|
22
22
|
browseRoute: String(ROUTES.PUBLIC.ART),
|
|
23
23
|
// /art ("Art & Stickers") is in MAIN_NAV_ITEMS and spans art + stickers.
|
|
24
24
|
inGeneralCatalogue: false,
|
|
25
|
+
// THE case this exists for: a sheet plus its individual cut-out stickers
|
|
26
|
+
canJoinProductGroup: true,
|
|
25
27
|
iconKey: "stickers",
|
|
26
28
|
hideDefault: "sold",
|
|
27
29
|
// Runs out rather than ending — no time dimension, so the shared
|
|
@@ -7,6 +7,17 @@ export interface ResolvedEntity {
|
|
|
7
7
|
readonly detail: string;
|
|
8
8
|
readonly href: string;
|
|
9
9
|
readonly score: number;
|
|
10
|
+
/**
|
|
11
|
+
* The record's raw compact facet string (`"lt:auction|br:takara-tomy"`), or
|
|
12
|
+
* `""`. Carried on the hit so a facet rail can count what the CURRENT result
|
|
13
|
+
* set contains without going back to the artifact and re-finding each row.
|
|
14
|
+
*
|
|
15
|
+
* 🛑 Raw rather than parsed, on purpose. Parsing is `facetsOf(rec)` and it
|
|
16
|
+
* allocates an array per record; a rail counts over every hit on every
|
|
17
|
+
* keystroke, and most queries never render one. The consumer parses the
|
|
18
|
+
* handful it actually needs.
|
|
19
|
+
*/
|
|
20
|
+
readonly facets: string;
|
|
10
21
|
}
|
|
11
22
|
export interface ResolveOptions {
|
|
12
23
|
readonly limit?: number;
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
import { normalizeSearchText, parseSearchTxtQuery } from "../../../utils/search-txt.js";
|
|
58
58
|
import { aliasVariantsForName } from "./alias-variants.js";
|
|
59
59
|
import { partAliasTokens } from "./part-aliases.js";
|
|
60
|
-
import { facetsOf, hrefFor, REC_DETAIL, REC_TITLE, REC_TYPE, } from "./index-record.js";
|
|
60
|
+
import { facetsOf, hrefFor, REC_DETAIL, REC_FACETS, REC_TITLE, REC_TYPE, } from "./index-record.js";
|
|
61
61
|
/** Field weights. Title dominates; a detail match is corroboration. */
|
|
62
62
|
const W_TITLE = 3;
|
|
63
63
|
const W_DETAIL = 1;
|
|
@@ -198,6 +198,7 @@ export function searchIndex(artifact, prepared, query, opts = {}) {
|
|
|
198
198
|
title: p.rec[REC_TITLE],
|
|
199
199
|
detail: p.rec[REC_DETAIL],
|
|
200
200
|
href: hrefFor(artifact, p.rec),
|
|
201
|
+
facets: p.rec[REC_FACETS] ?? "",
|
|
201
202
|
// An alias hit is a weaker signal than a direct one and must not
|
|
202
203
|
// outrank it when both are present in a later, wider query.
|
|
203
204
|
score: aliasPass ? score - S_ALIAS : score,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SearchEverythingResult, SearchGroup } from "../../server/features/search/search-everything";
|
|
2
|
+
import type { ResolvedEntity } from "./match";
|
|
3
|
+
import type { SearchIndexArtifact } from "./index-record";
|
|
4
|
+
/** Rows shown per group before "see all". Matches the server tier's PER_GROUP. */
|
|
5
|
+
export declare const LOCAL_PER_GROUP = 6;
|
|
6
|
+
export interface ToGroupsOptions {
|
|
7
|
+
readonly perGroup?: number;
|
|
8
|
+
/**
|
|
9
|
+
* `typeKey` -> human heading. REQUIRED, and the artifact deliberately does
|
|
10
|
+
* not carry it: a label baked into a shared immutable artifact cannot be
|
|
11
|
+
* translated, and this app is `[locale]`-routed. The caller resolves it
|
|
12
|
+
* through the label system at render time.
|
|
13
|
+
*/
|
|
14
|
+
readonly label: (typeKey: string) => string;
|
|
15
|
+
/** `typeKey` -> the type's browse page, from the artifact's type table. */
|
|
16
|
+
readonly moreHref: (typeKey: string) => string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Group score-ordered hits by type, preserving the order the types first
|
|
20
|
+
* appear in.
|
|
21
|
+
*
|
|
22
|
+
* 🛑 Group ORDER follows the best hit in each group, not the type table's
|
|
23
|
+
* `weight`. Weight already biased the scores; applying it again as an
|
|
24
|
+
* ordering key would double-count it, and a query that matched one FAQ
|
|
25
|
+
* exactly would still rank a weak product match above it.
|
|
26
|
+
*/
|
|
27
|
+
export declare function toSearchGroups(hits: readonly ResolvedEntity[], opts: ToGroupsOptions): SearchGroup[];
|
|
28
|
+
/** Assemble the full result envelope the page component expects. */
|
|
29
|
+
export declare function toSearchResult(q: string, terms: readonly string[], hits: readonly ResolvedEntity[], opts: ToGroupsOptions): SearchEverythingResult;
|
|
30
|
+
export interface FacetCount {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly value: string;
|
|
33
|
+
readonly count: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Count facet values across a result set.
|
|
37
|
+
*
|
|
38
|
+
* ## 🛑 This is the thing the server tier structurally cannot afford
|
|
39
|
+
*
|
|
40
|
+
* `BaseRepository.facetCounts` runs ONE aggregation query per facet value,
|
|
41
|
+
* each needing its own composite index, and on a missing index it logs and
|
|
42
|
+
* returns `undefined` so the facet "stays visible" with no count. Here it is
|
|
43
|
+
* a `reduce` over an array already in memory: zero queries, zero indexes, and
|
|
44
|
+
* a count that cannot silently fail.
|
|
45
|
+
*
|
|
46
|
+
* Counts are over the hits the CURRENT query produced, so ticking one facet
|
|
47
|
+
* and watching the others shrink is truthful rather than an approximation of
|
|
48
|
+
* the whole catalogue.
|
|
49
|
+
*/
|
|
50
|
+
export declare function countFacets(hits: readonly ResolvedEntity[]): FacetCount[];
|
|
51
|
+
/** Look up a type's `moreHref` from the artifact's own table. */
|
|
52
|
+
export declare function moreHrefResolver(artifact: Pick<SearchIndexArtifact, "types">): (typeKey: string) => string;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: Tier 1 and Tier 2 must render through the SAME component, or the page
|
|
3
|
+
* grows two layouts that drift.
|
|
4
|
+
* WHAT: `ResolvedEntity[]` (browser matcher) -> `SearchGroup[]` (the shape
|
|
5
|
+
* `SearchResultsPageView` already renders), plus facet counting.
|
|
6
|
+
*
|
|
7
|
+
* ## 🛑 Written against the server's types, not beside them
|
|
8
|
+
*
|
|
9
|
+
* `SearchGroup` / `SearchHit` / `SearchEverythingResult` are declared in
|
|
10
|
+
* `_internal/server/features/search/search-everything.ts` and imported here
|
|
11
|
+
* as TYPES ONLY — erased at runtime, so nothing of the server reaches a
|
|
12
|
+
* browser bundle. `SearchResultsPageView` already does exactly this, so the
|
|
13
|
+
* boundary is established rather than invented here.
|
|
14
|
+
*
|
|
15
|
+
* Defining a parallel `LocalSearchGroup` would have been the easy call and
|
|
16
|
+
* the wrong one: two near-identical result shapes is how a page ends up with
|
|
17
|
+
* two renderers, and then a fix to one of them (Root Cause #59's shape).
|
|
18
|
+
*
|
|
19
|
+
* ## 🛑 `truncated` is FALSE here, and that is a real difference
|
|
20
|
+
*
|
|
21
|
+
* The server tier reads a bounded window per collection, so a saturated fetch
|
|
22
|
+
* makes its count a FLOOR and it must render "6+". Tier 1 holds the entire
|
|
23
|
+
* corpus in memory, so the count is EXACT — there is no window to saturate.
|
|
24
|
+
* Reporting `truncated: true` because a group was capped for DISPLAY would be
|
|
25
|
+
* a different claim ("there may be more we could not see") and a false one.
|
|
26
|
+
* `total` carries the real figure; `hits` is the slice shown.
|
|
27
|
+
*
|
|
28
|
+
* @tag domain:search
|
|
29
|
+
* @tag layer:shared
|
|
30
|
+
* @tag pattern:none
|
|
31
|
+
* @tag access:isomorphic
|
|
32
|
+
* @tag consumers:useSiteSearch,SearchResultsClient
|
|
33
|
+
* @tag sideEffects:none
|
|
34
|
+
*/
|
|
35
|
+
/** Rows shown per group before "see all". Matches the server tier's PER_GROUP. */
|
|
36
|
+
export const LOCAL_PER_GROUP = 6;
|
|
37
|
+
/**
|
|
38
|
+
* Group score-ordered hits by type, preserving the order the types first
|
|
39
|
+
* appear in.
|
|
40
|
+
*
|
|
41
|
+
* 🛑 Group ORDER follows the best hit in each group, not the type table's
|
|
42
|
+
* `weight`. Weight already biased the scores; applying it again as an
|
|
43
|
+
* ordering key would double-count it, and a query that matched one FAQ
|
|
44
|
+
* exactly would still rank a weak product match above it.
|
|
45
|
+
*/
|
|
46
|
+
export function toSearchGroups(hits, opts) {
|
|
47
|
+
const perGroup = opts.perGroup ?? LOCAL_PER_GROUP;
|
|
48
|
+
const order = [];
|
|
49
|
+
const byType = new Map();
|
|
50
|
+
for (const hit of hits) {
|
|
51
|
+
let bucket = byType.get(hit.typeKey);
|
|
52
|
+
if (!bucket) {
|
|
53
|
+
bucket = [];
|
|
54
|
+
byType.set(hit.typeKey, bucket);
|
|
55
|
+
order.push(hit.typeKey);
|
|
56
|
+
}
|
|
57
|
+
bucket.push(hit);
|
|
58
|
+
}
|
|
59
|
+
return order.map((typeKey) => {
|
|
60
|
+
const bucket = byType.get(typeKey) ?? [];
|
|
61
|
+
const groupHits = bucket.slice(0, perGroup).map((h) => ({
|
|
62
|
+
/*
|
|
63
|
+
* The href IS the identity here. The artifact has no document id — it
|
|
64
|
+
* carries a slug, and two types can share a destination (a model
|
|
65
|
+
* composition and its category leaf both render `/categories/{s}`),
|
|
66
|
+
* which the matcher already dedupes on. Using the same key keeps the
|
|
67
|
+
* two consistent; inventing `${typeKey}:${slug}` would give the same
|
|
68
|
+
* row two identities depending on which layer you asked.
|
|
69
|
+
*/
|
|
70
|
+
id: h.href,
|
|
71
|
+
title: h.title,
|
|
72
|
+
href: h.href,
|
|
73
|
+
detail: h.detail || undefined,
|
|
74
|
+
}));
|
|
75
|
+
return {
|
|
76
|
+
key: typeKey,
|
|
77
|
+
label: opts.label(typeKey),
|
|
78
|
+
hits: groupHits,
|
|
79
|
+
truncated: false, // see the header — the count is exact, not a floor
|
|
80
|
+
moreHref: opts.moreHref(typeKey),
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/** Assemble the full result envelope the page component expects. */
|
|
85
|
+
export function toSearchResult(q, terms, hits, opts) {
|
|
86
|
+
const groups = toSearchGroups(hits, opts);
|
|
87
|
+
return {
|
|
88
|
+
q,
|
|
89
|
+
terms: [...terms],
|
|
90
|
+
groups,
|
|
91
|
+
/*
|
|
92
|
+
* The TOTAL matched, not the total shown. A page that says "24 results"
|
|
93
|
+
* and renders 12 because each group capped at 6 is lying in the direction
|
|
94
|
+
* that matters least; one that says "12" when 24 matched hides half the
|
|
95
|
+
* corpus from someone deciding whether to refine.
|
|
96
|
+
*/
|
|
97
|
+
totalHits: hits.length,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Count facet values across a result set.
|
|
102
|
+
*
|
|
103
|
+
* ## 🛑 This is the thing the server tier structurally cannot afford
|
|
104
|
+
*
|
|
105
|
+
* `BaseRepository.facetCounts` runs ONE aggregation query per facet value,
|
|
106
|
+
* each needing its own composite index, and on a missing index it logs and
|
|
107
|
+
* returns `undefined` so the facet "stays visible" with no count. Here it is
|
|
108
|
+
* a `reduce` over an array already in memory: zero queries, zero indexes, and
|
|
109
|
+
* a count that cannot silently fail.
|
|
110
|
+
*
|
|
111
|
+
* Counts are over the hits the CURRENT query produced, so ticking one facet
|
|
112
|
+
* and watching the others shrink is truthful rather than an approximation of
|
|
113
|
+
* the whole catalogue.
|
|
114
|
+
*/
|
|
115
|
+
export function countFacets(hits) {
|
|
116
|
+
const tally = new Map();
|
|
117
|
+
for (const hit of hits) {
|
|
118
|
+
if (!hit.facets)
|
|
119
|
+
continue;
|
|
120
|
+
for (const pair of hit.facets.split("|")) {
|
|
121
|
+
// Guard the shape rather than trusting it: a malformed pair is one
|
|
122
|
+
// record's problem, not a reason to drop the whole rail.
|
|
123
|
+
if (pair.indexOf(":") > 0)
|
|
124
|
+
tally.set(pair, (tally.get(pair) ?? 0) + 1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const out = [];
|
|
128
|
+
for (const [pair, count] of tally) {
|
|
129
|
+
const i = pair.indexOf(":");
|
|
130
|
+
out.push({ key: pair.slice(0, i), value: pair.slice(i + 1), count });
|
|
131
|
+
}
|
|
132
|
+
// Commonest first within a key, then alphabetical — a rail ordered by raw
|
|
133
|
+
// string would bury the useful refinement below the rare ones.
|
|
134
|
+
out.sort((a, b) => a.key.localeCompare(b.key) || b.count - a.count || a.value.localeCompare(b.value));
|
|
135
|
+
return out;
|
|
136
|
+
}
|
|
137
|
+
/** Look up a type's `moreHref` from the artifact's own table. */
|
|
138
|
+
export function moreHrefResolver(artifact) {
|
|
139
|
+
const map = new Map(artifact.types.map((t) => [t.key, t.moreHref]));
|
|
140
|
+
return (typeKey) => map.get(typeKey) ?? "/";
|
|
141
|
+
}
|
package/dist/client.d.ts
CHANGED
|
@@ -292,9 +292,11 @@ export { StoreSidebar } from "./features/seller/components/SellerSidebar";
|
|
|
292
292
|
export type { StoreNavItem, StoreNavGroup } from "./features/seller/components/SellerSidebar";
|
|
293
293
|
export { StoreProductsView, StoreAboutView } from "./features/stores/index";
|
|
294
294
|
export type { StoreProductItem, StoreAboutViewProps, StoreDetail } from "./features/stores/index";
|
|
295
|
-
export { SearchView } from "./features/search/index";
|
|
296
|
-
export type { SearchViewProps } from "./features/search/index";
|
|
297
295
|
export { useSearchIndex, ensureSearchIndex } from "./features/search/hooks/useSearchIndex";
|
|
296
|
+
export { useSiteSearch } from "./features/search/hooks/useSiteSearch";
|
|
297
|
+
export { useScopedSearch, mergeSearchTiers } from "./features/search/hooks/useScopedSearch";
|
|
298
|
+
export type { UseScopedSearchResult } from "./features/search/hooks/useScopedSearch";
|
|
299
|
+
export type { UseSiteSearchOptions, UseSiteSearchResult } from "./features/search/hooks/useSiteSearch";
|
|
298
300
|
export type { SearchIndexState, SearchIndexStatus, LoadedSearchIndex, UseSearchIndexOptions, } from "./features/search/hooks/useSearchIndex";
|
|
299
301
|
export { AdSlot } from "./features/homepage/components/AdSlot";
|
|
300
302
|
export { useActiveAd } from "./features/homepage/hooks/useActiveAd";
|
|
@@ -456,6 +458,8 @@ export { SellerArtView } from "./features/seller/components/SellerArtView";
|
|
|
456
458
|
export type { SellerArtViewProps } from "./features/seller/components/SellerArtView";
|
|
457
459
|
export { SellerStickersView } from "./features/seller/components/SellerStickersView";
|
|
458
460
|
export type { SellerStickersViewProps } from "./features/seller/components/SellerStickersView";
|
|
461
|
+
export { SellerSparesView } from "./features/seller/components/SellerSparesView";
|
|
462
|
+
export type { SellerSparesViewProps } from "./features/seller/components/SellerSparesView";
|
|
459
463
|
export { SellerDigitalCodesView } from "./features/seller/components/SellerDigitalCodesView";
|
|
460
464
|
export type { SellerDigitalCodesViewProps } from "./features/seller/components/SellerDigitalCodesView";
|
|
461
465
|
export { SellerLiveView } from "./features/seller/components/SellerLiveView";
|
|
@@ -501,6 +505,8 @@ export type { FAQCategory, FAQCategoryItem, FAQSortOption } from "./features/faq
|
|
|
501
505
|
export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect";
|
|
502
506
|
export { CategoryTemplatePicker, variantForCondition } from "./features/categories/components/CategoryTemplatePicker";
|
|
503
507
|
export type { CategoryTemplatePickerProps, CategoryTemplateApply } from "./features/categories/components/CategoryTemplatePicker";
|
|
508
|
+
export { PriceGuidanceHint } from "./features/categories/components/PriceGuidanceHint";
|
|
509
|
+
export type { PriceGuidanceHintProps } from "./features/categories/components/PriceGuidanceHint";
|
|
504
510
|
export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect";
|
|
505
511
|
export { API_ENDPOINTS } from "./constants/index";
|
|
506
512
|
export { SELLER_LISTING_TABS, type SellerListingTabId, } from "./features/products/constants/listing-tabs";
|
package/dist/client.js
CHANGED
|
@@ -327,7 +327,6 @@ export { updateProfileSchema } from "./features/account/index.js";
|
|
|
327
327
|
export { MediaImage } from "./features/media/index.js";
|
|
328
328
|
export { StoreSidebar } from "./features/seller/components/SellerSidebar.js";
|
|
329
329
|
export { StoreProductsView, StoreAboutView } from "./features/stores/index.js";
|
|
330
|
-
export { SearchView } from "./features/search/index.js";
|
|
331
330
|
/*
|
|
332
331
|
* The browser-side search index. Exported from its DEFINING module rather
|
|
333
332
|
* than through `features/search/index` (Root Cause #18) — `ensureSearchIndex`
|
|
@@ -336,6 +335,8 @@ export { SearchView } from "./features/search/index.js";
|
|
|
336
335
|
* fetch per page session" guarantee quietly becomes two.
|
|
337
336
|
*/
|
|
338
337
|
export { useSearchIndex, ensureSearchIndex } from "./features/search/hooks/useSearchIndex.js";
|
|
338
|
+
export { useSiteSearch } from "./features/search/hooks/useSiteSearch.js";
|
|
339
|
+
export { useScopedSearch, mergeSearchTiers } from "./features/search/hooks/useScopedSearch.js";
|
|
339
340
|
export { AdSlot } from "./features/homepage/components/AdSlot.js";
|
|
340
341
|
export { useActiveAd } from "./features/homepage/hooks/useActiveAd.js";
|
|
341
342
|
export { registerAdSlot, registerAdSlots, unregisterAdSlot, clearAdRegistry, setAdConsentGranted, isAdConsentGranted, isAdSlotRenderable, } from "./features/homepage/ad-registry.js";
|
|
@@ -466,6 +467,7 @@ export { SellerBundlesView } from "./features/seller/components/SellerBundlesVie
|
|
|
466
467
|
export { SellerClassifiedView } from "./features/seller/components/SellerClassifiedView.js";
|
|
467
468
|
export { SellerArtView } from "./features/seller/components/SellerArtView.js";
|
|
468
469
|
export { SellerStickersView } from "./features/seller/components/SellerStickersView.js";
|
|
470
|
+
export { SellerSparesView } from "./features/seller/components/SellerSparesView.js";
|
|
469
471
|
export { SellerDigitalCodesView } from "./features/seller/components/SellerDigitalCodesView.js";
|
|
470
472
|
export { SellerLiveView } from "./features/seller/components/SellerLiveView.js";
|
|
471
473
|
// ── Central schema registry (W1) ──────────────────────────────────────────────
|
|
@@ -502,6 +504,7 @@ export { computeCodHandlingFee } from "./_internal/shared/fees/calculator.js"; /
|
|
|
502
504
|
export { FAQPageContent } from "./features/faq/index.js";
|
|
503
505
|
export { CategoryInlineSelect } from "./features/seller/components/CategoryInlineSelect.js";
|
|
504
506
|
export { CategoryTemplatePicker, variantForCondition } from "./features/categories/components/CategoryTemplatePicker.js";
|
|
507
|
+
export { PriceGuidanceHint } from "./features/categories/components/PriceGuidanceHint.js";
|
|
505
508
|
export { BrandInlineSelect } from "./features/seller/components/BrandInlineSelect.js";
|
|
506
509
|
export { API_ENDPOINTS } from "./constants/index.js";
|
|
507
510
|
// [CLIENT-SAFE] Pure, zero-import constant files — dashboard filter-tab
|
|
@@ -273,6 +273,15 @@ export declare const CATEGORY_ENDPOINTS: {
|
|
|
273
273
|
* category change in the form costs zero function invocations on a hit.
|
|
274
274
|
*/
|
|
275
275
|
readonly DESCRIPTION_TEMPLATE: (id: string, variant?: string) => string;
|
|
276
|
+
/**
|
|
277
|
+
* The inherited `priceGuidance` band, restated on the calling seller's own
|
|
278
|
+
* tax basis — seller/admin/moderator only. Deliberately a SEPARATE
|
|
279
|
+
* endpoint from `DESCRIPTION_TEMPLATE`: that one is public and edge-cached
|
|
280
|
+
* so anyone can fetch it, and `priceGuidance` is withheld from that
|
|
281
|
+
* response for the same reason a listing's own price is hidden from guests
|
|
282
|
+
* (CLAUDE.md § "Guest price gating").
|
|
283
|
+
*/
|
|
284
|
+
readonly PRICE_GUIDANCE: (id: string) => string;
|
|
276
285
|
};
|
|
277
286
|
export declare const TOOL_ENDPOINTS: {
|
|
278
287
|
/**
|
|
@@ -286,6 +295,12 @@ export declare const TOOL_ENDPOINTS: {
|
|
|
286
295
|
* its invocation allowance.
|
|
287
296
|
*/
|
|
288
297
|
readonly PRICE_INDEX_SEARCH: (q: string) => string;
|
|
298
|
+
/**
|
|
299
|
+
* Tier 1 adoption — the client resolved these ids LOCALLY, from the
|
|
300
|
+
* public search artifact, at zero Firestore reads. This route's only job
|
|
301
|
+
* is the multi-get `searchPriceIndex` otherwise pays for every lookup.
|
|
302
|
+
*/
|
|
303
|
+
readonly PRICE_INDEX_BANDS: (ids: readonly string[]) => string;
|
|
289
304
|
};
|
|
290
305
|
/**
|
|
291
306
|
* The sticker-sheet kiss-cut tracer. Admin-only, every route behind
|
|
@@ -377,8 +392,6 @@ export declare const FAQ_ENDPOINTS: {
|
|
|
377
392
|
readonly VOTE: "/api/faqs/vote";
|
|
378
393
|
};
|
|
379
394
|
export declare const HOMEPAGE_ENDPOINTS: {
|
|
380
|
-
readonly GET: "/api/homepage";
|
|
381
|
-
readonly SECTIONS: "/api/homepage-sections";
|
|
382
395
|
readonly CAROUSEL: "/api/carousel";
|
|
383
396
|
readonly NEWSLETTER_SUBSCRIBE: "/api/newsletter/subscribe";
|
|
384
397
|
};
|
|
@@ -434,10 +447,9 @@ export declare const REVIEW_ENDPOINTS: {
|
|
|
434
447
|
readonly FEATURED: "/api/reviews?featured=true";
|
|
435
448
|
};
|
|
436
449
|
export declare const SEARCH_ENDPOINTS: {
|
|
437
|
-
readonly QUERY: (q: string, extra?: string) => string;
|
|
438
450
|
readonly SUGGESTIONS: "/api/search/suggestions";
|
|
439
|
-
/**
|
|
440
|
-
readonly
|
|
451
|
+
/** Tier 2 — the viewer's own orders/offers/drafts/addresses. `private, no-store`. */
|
|
452
|
+
readonly SCOPED: (q: string) => string;
|
|
441
453
|
};
|
|
442
454
|
export declare const SELLER_ENDPOINTS: {
|
|
443
455
|
readonly BECOME: "/api/seller/become";
|
|
@@ -816,6 +828,15 @@ export declare const API_ENDPOINTS: {
|
|
|
816
828
|
* category change in the form costs zero function invocations on a hit.
|
|
817
829
|
*/
|
|
818
830
|
readonly DESCRIPTION_TEMPLATE: (id: string, variant?: string) => string;
|
|
831
|
+
/**
|
|
832
|
+
* The inherited `priceGuidance` band, restated on the calling seller's own
|
|
833
|
+
* tax basis — seller/admin/moderator only. Deliberately a SEPARATE
|
|
834
|
+
* endpoint from `DESCRIPTION_TEMPLATE`: that one is public and edge-cached
|
|
835
|
+
* so anyone can fetch it, and `priceGuidance` is withheld from that
|
|
836
|
+
* response for the same reason a listing's own price is hidden from guests
|
|
837
|
+
* (CLAUDE.md § "Guest price gating").
|
|
838
|
+
*/
|
|
839
|
+
readonly PRICE_GUIDANCE: (id: string) => string;
|
|
819
840
|
};
|
|
820
841
|
readonly BEFORE_AFTER: {
|
|
821
842
|
readonly LIST: "/api/before-after";
|
|
@@ -880,8 +901,6 @@ export declare const API_ENDPOINTS: {
|
|
|
880
901
|
readonly VOTE: "/api/faqs/vote";
|
|
881
902
|
};
|
|
882
903
|
readonly HOMEPAGE: {
|
|
883
|
-
readonly GET: "/api/homepage";
|
|
884
|
-
readonly SECTIONS: "/api/homepage-sections";
|
|
885
904
|
readonly CAROUSEL: "/api/carousel";
|
|
886
905
|
readonly NEWSLETTER_SUBSCRIBE: "/api/newsletter/subscribe";
|
|
887
906
|
};
|
|
@@ -934,10 +953,9 @@ export declare const API_ENDPOINTS: {
|
|
|
934
953
|
readonly FEATURED: "/api/reviews?featured=true";
|
|
935
954
|
};
|
|
936
955
|
readonly SEARCH: {
|
|
937
|
-
readonly QUERY: (q: string, extra?: string) => string;
|
|
938
956
|
readonly SUGGESTIONS: "/api/search/suggestions";
|
|
939
|
-
/**
|
|
940
|
-
readonly
|
|
957
|
+
/** Tier 2 — the viewer's own orders/offers/drafts/addresses. `private, no-store`. */
|
|
958
|
+
readonly SCOPED: (q: string) => string;
|
|
941
959
|
};
|
|
942
960
|
readonly SELLER: {
|
|
943
961
|
readonly BECOME: "/api/seller/become";
|
|
@@ -1337,6 +1355,15 @@ export declare const API_ROUTES: {
|
|
|
1337
1355
|
* category change in the form costs zero function invocations on a hit.
|
|
1338
1356
|
*/
|
|
1339
1357
|
readonly DESCRIPTION_TEMPLATE: (id: string, variant?: string) => string;
|
|
1358
|
+
/**
|
|
1359
|
+
* The inherited `priceGuidance` band, restated on the calling seller's own
|
|
1360
|
+
* tax basis — seller/admin/moderator only. Deliberately a SEPARATE
|
|
1361
|
+
* endpoint from `DESCRIPTION_TEMPLATE`: that one is public and edge-cached
|
|
1362
|
+
* so anyone can fetch it, and `priceGuidance` is withheld from that
|
|
1363
|
+
* response for the same reason a listing's own price is hidden from guests
|
|
1364
|
+
* (CLAUDE.md § "Guest price gating").
|
|
1365
|
+
*/
|
|
1366
|
+
readonly PRICE_GUIDANCE: (id: string) => string;
|
|
1340
1367
|
};
|
|
1341
1368
|
readonly BEFORE_AFTER: {
|
|
1342
1369
|
readonly LIST: "/api/before-after";
|
|
@@ -1401,8 +1428,6 @@ export declare const API_ROUTES: {
|
|
|
1401
1428
|
readonly VOTE: "/api/faqs/vote";
|
|
1402
1429
|
};
|
|
1403
1430
|
readonly HOMEPAGE: {
|
|
1404
|
-
readonly GET: "/api/homepage";
|
|
1405
|
-
readonly SECTIONS: "/api/homepage-sections";
|
|
1406
1431
|
readonly CAROUSEL: "/api/carousel";
|
|
1407
1432
|
readonly NEWSLETTER_SUBSCRIBE: "/api/newsletter/subscribe";
|
|
1408
1433
|
};
|
|
@@ -1455,10 +1480,9 @@ export declare const API_ROUTES: {
|
|
|
1455
1480
|
readonly FEATURED: "/api/reviews?featured=true";
|
|
1456
1481
|
};
|
|
1457
1482
|
readonly SEARCH: {
|
|
1458
|
-
readonly QUERY: (q: string, extra?: string) => string;
|
|
1459
1483
|
readonly SUGGESTIONS: "/api/search/suggestions";
|
|
1460
|
-
/**
|
|
1461
|
-
readonly
|
|
1484
|
+
/** Tier 2 — the viewer's own orders/offers/drafts/addresses. `private, no-store`. */
|
|
1485
|
+
readonly SCOPED: (q: string) => string;
|
|
1462
1486
|
};
|
|
1463
1487
|
readonly SELLER: {
|
|
1464
1488
|
readonly BECOME: "/api/seller/become";
|
|
@@ -317,6 +317,15 @@ export const CATEGORY_ENDPOINTS = {
|
|
|
317
317
|
* category change in the form costs zero function invocations on a hit.
|
|
318
318
|
*/
|
|
319
319
|
DESCRIPTION_TEMPLATE: (id, variant) => `/api/categories/${id}/description-template${variant ? `?variant=${variant}` : ""}`,
|
|
320
|
+
/**
|
|
321
|
+
* The inherited `priceGuidance` band, restated on the calling seller's own
|
|
322
|
+
* tax basis — seller/admin/moderator only. Deliberately a SEPARATE
|
|
323
|
+
* endpoint from `DESCRIPTION_TEMPLATE`: that one is public and edge-cached
|
|
324
|
+
* so anyone can fetch it, and `priceGuidance` is withheld from that
|
|
325
|
+
* response for the same reason a listing's own price is hidden from guests
|
|
326
|
+
* (CLAUDE.md § "Guest price gating").
|
|
327
|
+
*/
|
|
328
|
+
PRICE_GUIDANCE: (id) => `/api/categories/${id}/price-guidance`,
|
|
320
329
|
};
|
|
321
330
|
// ---------------------------------------------------------------------------
|
|
322
331
|
// Tools — public surfaces that answer a question rather than sell something
|
|
@@ -333,6 +342,12 @@ export const TOOL_ENDPOINTS = {
|
|
|
333
342
|
* its invocation allowance.
|
|
334
343
|
*/
|
|
335
344
|
PRICE_INDEX_SEARCH: (q) => `/api/tools/price-index?q=${encodeURIComponent(q)}`,
|
|
345
|
+
/**
|
|
346
|
+
* Tier 1 adoption — the client resolved these ids LOCALLY, from the
|
|
347
|
+
* public search artifact, at zero Firestore reads. This route's only job
|
|
348
|
+
* is the multi-get `searchPriceIndex` otherwise pays for every lookup.
|
|
349
|
+
*/
|
|
350
|
+
PRICE_INDEX_BANDS: (ids) => `/api/tools/price-index/bands?ids=${ids.map(encodeURIComponent).join(",")}`,
|
|
336
351
|
};
|
|
337
352
|
/**
|
|
338
353
|
* The sticker-sheet kiss-cut tracer. Admin-only, every route behind
|
|
@@ -473,8 +488,17 @@ export const FAQ_ENDPOINTS = {
|
|
|
473
488
|
// Homepage
|
|
474
489
|
// ---------------------------------------------------------------------------
|
|
475
490
|
export const HOMEPAGE_ENDPOINTS = {
|
|
476
|
-
|
|
477
|
-
|
|
491
|
+
/*
|
|
492
|
+
* 🛑 `GET` and `SECTIONS` were both removed 2026-10-19 — `/api/homepage` was
|
|
493
|
+
* NEVER mounted (only a dead hook referenced it), and `/api/homepage-sections`
|
|
494
|
+
* was a mounted generic-starter-kit stub writing/reading the real
|
|
495
|
+
* `homepageSections` collection through an incompatible schema. See the
|
|
496
|
+
* deletion note in `features/homepage/types/index.ts` for the full writeup.
|
|
497
|
+
* The real, single section API is `/api/admin/sections` (admin CRUD);
|
|
498
|
+
* public rendering reads `homepageSectionsRepository` directly, server-side,
|
|
499
|
+
* in `MarketplaceHomepageView` — no public GET endpoint for sections exists
|
|
500
|
+
* or is needed.
|
|
501
|
+
*/
|
|
478
502
|
CAROUSEL: "/api/carousel",
|
|
479
503
|
NEWSLETTER_SUBSCRIBE: "/api/newsletter/subscribe",
|
|
480
504
|
};
|
|
@@ -566,10 +590,9 @@ export const REVIEW_ENDPOINTS = {
|
|
|
566
590
|
// Search
|
|
567
591
|
// ---------------------------------------------------------------------------
|
|
568
592
|
export const SEARCH_ENDPOINTS = {
|
|
569
|
-
QUERY: (q, extra) => `/api/search?q=${encodeURIComponent(q)}${extra ? `&${extra}` : ""}`,
|
|
570
593
|
SUGGESTIONS: "/api/search/suggestions",
|
|
571
|
-
/**
|
|
572
|
-
|
|
594
|
+
/** Tier 2 — the viewer's own orders/offers/drafts/addresses. `private, no-store`. */
|
|
595
|
+
SCOPED: (q) => `/api/search/scoped?q=${encodeURIComponent(q)}`,
|
|
573
596
|
};
|
|
574
597
|
// ---------------------------------------------------------------------------
|
|
575
598
|
// Seller
|
|
@@ -20,7 +20,9 @@ export const COLLECTION_CACHE_PATHS = {
|
|
|
20
20
|
categories: [CATEGORY_ENDPOINTS.LIST],
|
|
21
21
|
products: [PRODUCT_ENDPOINTS.LIST],
|
|
22
22
|
carouselSlides: [HOMEPAGE_ENDPOINTS.CAROUSEL],
|
|
23
|
-
homepageSections
|
|
23
|
+
// No public GET endpoint exists for homepageSections (removed 2026-10-19 —
|
|
24
|
+
// see HOMEPAGE_ENDPOINTS' own comment). Real-time freshness comes from
|
|
25
|
+
// `revalidatePath("/")`, which /api/admin/sections already calls on write.
|
|
24
26
|
siteSettings: [SITE_SETTINGS_ENDPOINTS.GET],
|
|
25
27
|
faqs: [FAQ_ENDPOINTS.LIST],
|
|
26
28
|
reviews: [REVIEW_ENDPOINTS.LIST],
|
|
@@ -49,6 +49,9 @@ export declare const PRODUCT_FIELDS: {
|
|
|
49
49
|
readonly STOCK_QUANTITY: "stockQuantity";
|
|
50
50
|
readonly AVAILABLE_QUANTITY: "availableQuantity";
|
|
51
51
|
readonly IS_SOLD: "isSold";
|
|
52
|
+
readonly MADE_TO_ORDER: "madeToOrder";
|
|
53
|
+
readonly PART_GLOSSARY_ID: "partGlossaryId";
|
|
54
|
+
readonly COLOURWAY: "colourway";
|
|
52
55
|
readonly MAIN_IMAGE: "mainImage";
|
|
53
56
|
readonly IMAGES: "images";
|
|
54
57
|
readonly VIDEO: "video";
|
|
@@ -181,6 +184,7 @@ export declare const PRODUCT_FIELDS: {
|
|
|
181
184
|
readonly LIVE: "live";
|
|
182
185
|
readonly ART: "art";
|
|
183
186
|
readonly STICKERS: "stickers";
|
|
187
|
+
readonly SPARES: "spares";
|
|
184
188
|
};
|
|
185
189
|
};
|
|
186
190
|
export declare const PRODUCT_STATUS_TRANSITIONS: Record<string, readonly string[]>;
|
|
@@ -853,6 +857,8 @@ export declare const HOMEPAGE_SECTION_FIELDS: {
|
|
|
853
857
|
readonly ORDER: "order";
|
|
854
858
|
readonly ENABLED: "enabled";
|
|
855
859
|
readonly CONFIG: "config";
|
|
860
|
+
/** Which page the row belongs to. Absent on a row means "homepage". */
|
|
861
|
+
readonly SURFACE: "surface";
|
|
856
862
|
readonly CREATED_AT: "createdAt";
|
|
857
863
|
readonly UPDATED_AT: "updatedAt";
|
|
858
864
|
readonly TYPE_VALUES: {
|
|
@@ -58,6 +58,9 @@ export const PRODUCT_FIELDS = {
|
|
|
58
58
|
STOCK_QUANTITY: "stockQuantity",
|
|
59
59
|
AVAILABLE_QUANTITY: "availableQuantity",
|
|
60
60
|
IS_SOLD: "isSold",
|
|
61
|
+
MADE_TO_ORDER: "madeToOrder",
|
|
62
|
+
PART_GLOSSARY_ID: "partGlossaryId",
|
|
63
|
+
COLOURWAY: "colourway",
|
|
61
64
|
MAIN_IMAGE: "mainImage",
|
|
62
65
|
IMAGES: "images",
|
|
63
66
|
VIDEO: "video",
|
|
@@ -201,6 +204,7 @@ export const PRODUCT_FIELDS = {
|
|
|
201
204
|
LIVE: "live",
|
|
202
205
|
ART: "art",
|
|
203
206
|
STICKERS: "stickers",
|
|
207
|
+
SPARES: "spares",
|
|
204
208
|
},
|
|
205
209
|
};
|
|
206
210
|
export const PRODUCT_STATUS_TRANSITIONS = {
|
|
@@ -1035,6 +1039,8 @@ export const HOMEPAGE_SECTION_FIELDS = {
|
|
|
1035
1039
|
ORDER: "order",
|
|
1036
1040
|
ENABLED: "enabled",
|
|
1037
1041
|
CONFIG: "config",
|
|
1042
|
+
/** Which page the row belongs to. Absent on a row means "homepage". */
|
|
1043
|
+
SURFACE: "surface",
|
|
1038
1044
|
CREATED_AT: "createdAt",
|
|
1039
1045
|
UPDATED_AT: "updatedAt",
|
|
1040
1046
|
TYPE_VALUES: {
|
|
@@ -1,6 +1,26 @@
|
|
|
1
|
-
export type PolicyKey = "privacy" | "terms" | "cookies" | "refund" | "ethics" | "conduct";
|
|
1
|
+
export type PolicyKey = "privacy" | "terms" | "cookies" | "refund" | "ethics" | "conduct" | "cancellation" | "grievance";
|
|
2
2
|
export interface PolicyPageViewProps {
|
|
3
3
|
/** Which policy to render */
|
|
4
4
|
policy: PolicyKey;
|
|
5
|
+
/**
|
|
6
|
+
* Rendered after the policy sections and before the related links.
|
|
7
|
+
*
|
|
8
|
+
* The slot exists for /grievance, whose officer block (name, designation,
|
|
9
|
+
* email, phone) comes from `appkit.config.js` → `business.grievance` rather
|
|
10
|
+
* than from i18n — those values are deployment-specific and some are still
|
|
11
|
+
* undecided, so they render through `<PendingValue>` as a visible
|
|
12
|
+
* `[to be confirmed]` marker.
|
|
13
|
+
*
|
|
14
|
+
* 🛑 Deliberately a `children` ReactNode and not a render prop: this is an
|
|
15
|
+
* async Server Component, and a function prop would have to cross the
|
|
16
|
+
* server/client boundary at the call site to be useful. The caller builds
|
|
17
|
+
* the node and passes it down, which needs nothing serialisable.
|
|
18
|
+
*
|
|
19
|
+
* Note it renders under the i18n sections but is SKIPPED when an admin HTML
|
|
20
|
+
* override is present — an override replaces the page's body, and silently
|
|
21
|
+
* appending a block the admin cannot see or edit would make the override a
|
|
22
|
+
* half-truth.
|
|
23
|
+
*/
|
|
24
|
+
children?: React.ReactNode;
|
|
5
25
|
}
|
|
6
|
-
export declare function PolicyPageView({ policy, }: PolicyPageViewProps): Promise<import("react").JSX.Element>;
|
|
26
|
+
export declare function PolicyPageView({ policy, children, }: PolicyPageViewProps): Promise<import("react").JSX.Element>;
|
|
@@ -58,9 +58,21 @@ const POLICY_META = {
|
|
|
58
58
|
firestoreField: "codeOfConduct",
|
|
59
59
|
relatedLabelKey: "relatedConduct",
|
|
60
60
|
},
|
|
61
|
+
cancellation: {
|
|
62
|
+
path: String(ROUTES.PUBLIC.CANCELLATION_POLICY),
|
|
63
|
+
namespace: "cancellationPolicy",
|
|
64
|
+
firestoreField: "cancellation",
|
|
65
|
+
relatedLabelKey: "relatedCancellation",
|
|
66
|
+
},
|
|
67
|
+
grievance: {
|
|
68
|
+
path: String(ROUTES.PUBLIC.GRIEVANCE),
|
|
69
|
+
namespace: "grievance",
|
|
70
|
+
firestoreField: "grievance",
|
|
71
|
+
relatedLabelKey: "relatedGrievance",
|
|
72
|
+
},
|
|
61
73
|
};
|
|
62
74
|
const POLICY_KEYS = Object.keys(POLICY_META);
|
|
63
|
-
export async function PolicyPageView({ policy, }) {
|
|
75
|
+
export async function PolicyPageView({ policy, children, }) {
|
|
64
76
|
const page = { container: PAGE_CONTAINER };
|
|
65
77
|
const meta = POLICY_META[policy];
|
|
66
78
|
const { getTranslations } = await import("next-intl/server");
|
|
@@ -93,5 +105,5 @@ export async function PolicyPageView({ policy, }) {
|
|
|
93
105
|
}));
|
|
94
106
|
return (_jsxs(Div, { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", children: [_jsx(Section, { color: "inverse", tone: "accent-banner", padding: "banner", children: _jsxs(Div, { className: `${page.container.sm}`, children: [_jsx(Heading, { color: "inverse", level: 1, variant: "none", className: "mb-3", children: t("title") }), _jsx(Text, { color: "inverse", variant: "none", className: "/80", size: "sm", children: t("lastUpdated") })] }) }), _jsxs(Div, { className: `${page.container.sm}`, padding: "content-banner", children: [adminHtml ? (
|
|
95
107
|
/* Admin-set HTML takes priority */
|
|
96
|
-
_jsx(Div, { className: "prose max-w-none", dangerouslySetInnerHTML: { __html: adminHtml } })) : (_jsxs(_Fragment, { children: [t.has("intro") && (_jsx(Text, { variant: "secondary", className: "mb-10 leading-relaxed", size: "base", children: t("intro") })), _jsx(Stack, { gap: "xl", children: sections.map((section, i) => (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-3", children: section.heading }), _jsx(Text, { variant: "secondary", className: "leading-relaxed whitespace-pre-line", children: section.body })] }, i))) })] })), relatedLinks.length > 0 && (_jsxs(Div, { className: `mt-14 border-t`, border: "default", padding: "t-xl", children: [_jsx(Heading, { level: 3, className: "mb-3 uppercase tracking-wide", color: "muted", size: "sm", weight: "semibold", children: t("relatedTitle") }), _jsx(Row, { wrap: true, gap: "md", children: relatedLinks.map((l) => (_jsx(TextLink, { href: l.href, variant: "muted", size: "sm", children: l.label }, l.href))) })] }))] })] }));
|
|
108
|
+
_jsx(Div, { className: "prose max-w-none", dangerouslySetInnerHTML: { __html: adminHtml } })) : (_jsxs(_Fragment, { children: [t.has("intro") && (_jsx(Text, { variant: "secondary", className: "mb-10 leading-relaxed", size: "base", children: t("intro") })), _jsx(Stack, { gap: "xl", children: sections.map((section, i) => (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-3", children: section.heading }), _jsx(Text, { variant: "secondary", className: "leading-relaxed whitespace-pre-line", children: section.body })] }, i))) }), children] })), relatedLinks.length > 0 && (_jsxs(Div, { className: `mt-14 border-t`, border: "default", padding: "t-xl", children: [_jsx(Heading, { level: 3, className: "mb-3 uppercase tracking-wide", color: "muted", size: "sm", weight: "semibold", children: t("relatedTitle") }), _jsx(Row, { wrap: true, gap: "md", children: relatedLinks.map((l) => (_jsx(TextLink, { href: l.href, variant: "muted", size: "sm", children: l.label }, l.href))) })] }))] })] }));
|
|
97
109
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import Link from "next/link.js";
|
|
3
|
+
import { productImageUrls } from "../../products/schemas/firestore.js";
|
|
3
4
|
import { getPublicUserProfile, getProfileStoreProducts, getReviewsAuthoredBy, getReviewsReceivedBy } from "../../auth/actions/profile-actions.js";
|
|
4
5
|
import { storeRepository } from "../../stores/repository/store.repository.js";
|
|
5
6
|
import { safeRead } from "../../../errors/safe-read.js";
|
|
@@ -37,7 +38,7 @@ function toProductItem(p) {
|
|
|
37
38
|
originalPrice: p.originalPrice,
|
|
38
39
|
currency: p.currency,
|
|
39
40
|
mainImage: p.mainImage,
|
|
40
|
-
images: p.images,
|
|
41
|
+
images: productImageUrls(p.images),
|
|
41
42
|
status: p.status,
|
|
42
43
|
condition: p.condition,
|
|
43
44
|
listingType: p.listingType,
|