@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
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/*
|
|
3
|
+
* WHY: A signed-in viewer's own records belong in the same box as the public
|
|
4
|
+
* catalogue — but they cost real reads and must not be fetched the way
|
|
5
|
+
* the free tier is.
|
|
6
|
+
* WHAT: Tier 2's client half, plus the merge with Tier 1.
|
|
7
|
+
*
|
|
8
|
+
* ## 🛑 ON SUBMIT, never per keystroke
|
|
9
|
+
*
|
|
10
|
+
* Tier 1 is a local scan and costs nothing, so it runs on every character.
|
|
11
|
+
* This one is a bounded Firestore fan-out — up to ~320 documents for an
|
|
12
|
+
* admin — so it runs when the user commits to a query. A debounced
|
|
13
|
+
* per-keystroke version of this endpoint is how a 50k/day read tier
|
|
14
|
+
* disappears in an afternoon.
|
|
15
|
+
*
|
|
16
|
+
* ## 🛑 A guest issues ZERO requests
|
|
17
|
+
*
|
|
18
|
+
* Gated on `enabled`, which the caller sets from the session. The server
|
|
19
|
+
* refuses too (`auth: true`, and `scopedSourcesFor(null)` is `[]`), but the
|
|
20
|
+
* client gate is what makes "signed out = no authenticated request in the
|
|
21
|
+
* Network panel" true, which is the only form of that claim anyone can
|
|
22
|
+
* verify.
|
|
23
|
+
*
|
|
24
|
+
* @tag domain:search
|
|
25
|
+
* @tag layer:feature
|
|
26
|
+
* @tag pattern:hook
|
|
27
|
+
* @tag access:client
|
|
28
|
+
* @tag consumers:SearchResultsClient
|
|
29
|
+
* @tag sideEffects:network
|
|
30
|
+
*/
|
|
31
|
+
import * as React from "react";
|
|
32
|
+
import { apiClient } from "../../../http/index.js";
|
|
33
|
+
import { normalizeError } from "../../../errors/normalize.js";
|
|
34
|
+
import { SEARCH_ENDPOINTS } from "../../../constants/api-endpoints.js";
|
|
35
|
+
/** Matches the server-side gate, so the two cannot disagree about what is worth asking. */
|
|
36
|
+
const MIN_CHARS = 3;
|
|
37
|
+
export function useScopedSearch({ enabled, submittedQuery, }) {
|
|
38
|
+
const [status, setStatus] = React.useState("idle");
|
|
39
|
+
const [groups, setGroups] = React.useState([]);
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
const q = submittedQuery.trim();
|
|
42
|
+
if (!enabled || q.length < MIN_CHARS) {
|
|
43
|
+
setStatus("idle");
|
|
44
|
+
setGroups([]);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
/*
|
|
48
|
+
* An `AbortController` per query, mirroring `useNavSuggestions`. Without
|
|
49
|
+
* it, a slow response to an earlier query can land after a faster
|
|
50
|
+
* response to a later one and overwrite it — the user sees results for
|
|
51
|
+
* something they already moved on from, which looks like the search
|
|
52
|
+
* returning the wrong thing rather than like a race.
|
|
53
|
+
*/
|
|
54
|
+
const controller = new AbortController();
|
|
55
|
+
setStatus("loading");
|
|
56
|
+
apiClient
|
|
57
|
+
.get(SEARCH_ENDPOINTS.SCOPED(q), { signal: controller.signal })
|
|
58
|
+
.then((res) => {
|
|
59
|
+
if (controller.signal.aborted)
|
|
60
|
+
return;
|
|
61
|
+
setGroups(res?.data?.groups ?? []);
|
|
62
|
+
setStatus("ready");
|
|
63
|
+
})
|
|
64
|
+
.catch((err) => {
|
|
65
|
+
if (controller.signal.aborted)
|
|
66
|
+
return;
|
|
67
|
+
const e = normalizeError(err);
|
|
68
|
+
/*
|
|
69
|
+
* `failed`, and the CALLER must say so out loud.
|
|
70
|
+
* `searchEverything`'s own header records that a degraded source "is
|
|
71
|
+
* indistinguishable from 'nothing matched'" — and on a page where
|
|
72
|
+
* the public half rendered fine, silence tells a seller their draft
|
|
73
|
+
* does not exist.
|
|
74
|
+
*/
|
|
75
|
+
void e;
|
|
76
|
+
setGroups([]);
|
|
77
|
+
setStatus("failed");
|
|
78
|
+
});
|
|
79
|
+
return () => controller.abort();
|
|
80
|
+
}, [enabled, submittedQuery]);
|
|
81
|
+
return { status, groups };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Merge the two tiers.
|
|
85
|
+
*
|
|
86
|
+
* ## 🛑 Dedupe by DESTINATION, and local wins
|
|
87
|
+
*
|
|
88
|
+
* The tiers are NOT disjoint: a seller's published listing is in the public
|
|
89
|
+
* artifact AND in `my-listings`. Showing both is a duplicate-results bug;
|
|
90
|
+
* dropping the public one would lose the row a buyer would see.
|
|
91
|
+
*
|
|
92
|
+
* Local wins, so what survives in the scoped group is precisely the rows the
|
|
93
|
+
* artifact does not have — a seller's DRAFTS. Labelling that group "Your
|
|
94
|
+
* listings (incl. drafts)" is what makes the dedupe legible rather than
|
|
95
|
+
* mysterious.
|
|
96
|
+
*
|
|
97
|
+
* 🛑 The key is the HREF, not `${typeKey}:${id}`. The artifact keys products
|
|
98
|
+
* by SLUG and Firestore by document id, so a composite key would never
|
|
99
|
+
* collide and the dedupe would silently do nothing — the failure mode being
|
|
100
|
+
* a page that looks fine and shows everything twice. Both tiers already
|
|
101
|
+
* agree on where a row goes, which is the only identity they share.
|
|
102
|
+
*/
|
|
103
|
+
export function mergeSearchTiers(local, scoped) {
|
|
104
|
+
const seen = new Set();
|
|
105
|
+
for (const g of local)
|
|
106
|
+
for (const h of g.hits)
|
|
107
|
+
seen.add(h.href);
|
|
108
|
+
const deduped = scoped
|
|
109
|
+
.map((g) => ({ ...g, hits: g.hits.filter((h) => !seen.has(h.href)) }))
|
|
110
|
+
// A scoped group that is now empty is dropped entirely rather than
|
|
111
|
+
// rendered as a heading over nothing, which reads as a broken section.
|
|
112
|
+
.filter((g) => g.hits.length > 0);
|
|
113
|
+
return [...local, ...deduped];
|
|
114
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type FacetCount } from "../../../_internal/shared/search/to-groups";
|
|
2
|
+
import { type SearchIndexStatus } from "./useSearchIndex";
|
|
3
|
+
import type { SearchEverythingResult } from "../../../_internal/server/features/search/search-everything";
|
|
4
|
+
import type { NavSuggestionRecord } from "./useNavSuggestions";
|
|
5
|
+
export interface UseSiteSearchOptions {
|
|
6
|
+
/** Flip true on focus or first keypress. Gates the artifact fetch. */
|
|
7
|
+
active: boolean;
|
|
8
|
+
/** `siteSettings.search?.indexEnabled` — read as `!== false`. */
|
|
9
|
+
indexEnabled?: boolean;
|
|
10
|
+
/** Restrict to these index type keys. Absent means every type. */
|
|
11
|
+
types?: readonly string[];
|
|
12
|
+
/** Require every one of these `k:v` pairs. The facet rail's selection. */
|
|
13
|
+
facets?: readonly string[];
|
|
14
|
+
/** `typeKey` -> heading. See `ToGroupsOptions.label`. */
|
|
15
|
+
label: (typeKey: string) => string;
|
|
16
|
+
}
|
|
17
|
+
export interface UseSiteSearchResult {
|
|
18
|
+
readonly status: SearchIndexStatus;
|
|
19
|
+
/** Null until the index is ready; never a fabricated empty result. */
|
|
20
|
+
readonly result: SearchEverythingResult | null;
|
|
21
|
+
readonly suggestions: readonly NavSuggestionRecord[];
|
|
22
|
+
readonly facets: readonly FacetCount[];
|
|
23
|
+
/** The index build this answered from, for a "results as of" line. */
|
|
24
|
+
readonly builtAt: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function useSiteSearch(query: string, { active, indexEnabled, types, facets, label }: UseSiteSearchOptions): UseSiteSearchResult;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/*
|
|
3
|
+
* WHY: One query, one matcher, two surfaces — the header dropdown and
|
|
4
|
+
* `/search` must not grow separate notions of what matches.
|
|
5
|
+
* WHAT: The client search hook. Runs the browser matcher over the loaded
|
|
6
|
+
* artifact and returns BOTH shapes: grouped results for the page and
|
|
7
|
+
* flat suggestion rows for the typeahead.
|
|
8
|
+
*
|
|
9
|
+
* ## 🛑 Synchronous per keystroke, and no debounce
|
|
10
|
+
*
|
|
11
|
+
* There is nothing to debounce — a debounce exists to avoid spending a
|
|
12
|
+
* network round trip per character, and this spends none. `searchIndex` is a
|
|
13
|
+
* linear scan over ~3,700 prepared records, measured sub-millisecond by
|
|
14
|
+
* `verify-search-local.mjs`. Adding a 250 ms debounce here would make the box
|
|
15
|
+
* feel SLOWER than the thing it replaced while costing nothing less.
|
|
16
|
+
*
|
|
17
|
+
* The one thing that is async is loading the artifact, once, and `active`
|
|
18
|
+
* gates that (see `useSearchIndex`).
|
|
19
|
+
*
|
|
20
|
+
* ## 🛑 No minimum query length either
|
|
21
|
+
*
|
|
22
|
+
* `useNavSuggestions` gates at 3 characters because each query is a real
|
|
23
|
+
* Firestore round trip and below that the result is dominated by whatever
|
|
24
|
+
* sorts first. Neither clause holds here: a one-character query costs the
|
|
25
|
+
* same nothing, and the matcher ranks rather than truncates. Typing "d" and
|
|
26
|
+
* seeing something is the behaviour a local index is FOR.
|
|
27
|
+
*
|
|
28
|
+
* ## It returns a result even when the index is not in play
|
|
29
|
+
*
|
|
30
|
+
* `status` distinguishes `idle` / `loading` / `ready` / `failed` / `disabled`,
|
|
31
|
+
* and the last two mean *the caller should fall back*, not *show nothing*.
|
|
32
|
+
* A caller that renders an empty state on `loading` is saying "nothing
|
|
33
|
+
* matched" about a question that has not been asked yet.
|
|
34
|
+
*
|
|
35
|
+
* @tag domain:search
|
|
36
|
+
* @tag layer:feature
|
|
37
|
+
* @tag pattern:hook
|
|
38
|
+
* @tag access:client
|
|
39
|
+
* @tag consumers:Search,SearchResultsClient
|
|
40
|
+
* @tag sideEffects:none
|
|
41
|
+
*/
|
|
42
|
+
import * as React from "react";
|
|
43
|
+
import { searchIndex } from "../../../_internal/shared/search/match.js";
|
|
44
|
+
import { countFacets, moreHrefResolver, toSearchResult, } from "../../../_internal/shared/search/to-groups.js";
|
|
45
|
+
import { parseSearchTxtQuery } from "../../../utils/search-txt.js";
|
|
46
|
+
import { useSearchIndex } from "./useSearchIndex.js";
|
|
47
|
+
/**
|
|
48
|
+
* How many hits the matcher is asked for.
|
|
49
|
+
*
|
|
50
|
+
* Generous because grouping happens AFTER: a cap of 20 on a query matching
|
|
51
|
+
* 400 products would starve every other group, since the list is
|
|
52
|
+
* score-ordered and products would fill it. 200 keeps the long tail of types
|
|
53
|
+
* reachable while staying trivial to sort.
|
|
54
|
+
*/
|
|
55
|
+
const MATCH_LIMIT = 200;
|
|
56
|
+
/**
|
|
57
|
+
* `typeKey` -> the five values the header dropdown's icon and badge maps
|
|
58
|
+
* understand.
|
|
59
|
+
*
|
|
60
|
+
* 🛑 A MAPPING rather than a widening of `NavSuggestionRecord["type"]`.
|
|
61
|
+
* That union is public API and is switched on by the dropdown's
|
|
62
|
+
* `DEFAULT_TYPE_ICONS` / `DEFAULT_TYPE_BADGES`; widening it to `string` would
|
|
63
|
+
* compile everywhere and silently render unstyled rows for the 16 index types
|
|
64
|
+
* those maps have never heard of (Root Cause #20). The real key travels
|
|
65
|
+
* alongside, in `typeKey`, for anything that wants it.
|
|
66
|
+
*/
|
|
67
|
+
function suggestionTypeFor(typeKey) {
|
|
68
|
+
switch (typeKey) {
|
|
69
|
+
case "blog":
|
|
70
|
+
return "blog";
|
|
71
|
+
case "event":
|
|
72
|
+
return "event";
|
|
73
|
+
case "category":
|
|
74
|
+
case "brand":
|
|
75
|
+
case "franchise":
|
|
76
|
+
case "bundle":
|
|
77
|
+
case "model":
|
|
78
|
+
case "part":
|
|
79
|
+
return "category";
|
|
80
|
+
case "store":
|
|
81
|
+
case "faq":
|
|
82
|
+
case "review":
|
|
83
|
+
case "scammer":
|
|
84
|
+
case "coupon":
|
|
85
|
+
case "group":
|
|
86
|
+
return "page";
|
|
87
|
+
default:
|
|
88
|
+
// Every listing type — product, auction, pre-order, … — plus anything
|
|
89
|
+
// added to the index later. A listing is the commonest row and the
|
|
90
|
+
// product icon is the right default for an unknown one.
|
|
91
|
+
return "product";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function useSiteSearch(query, { active, indexEnabled, types, facets, label }) {
|
|
95
|
+
const { status, index } = useSearchIndex({ active, indexEnabled });
|
|
96
|
+
/*
|
|
97
|
+
* 🛑 `types` and `facets` are arrays, so a caller passing a literal creates
|
|
98
|
+
* a new identity every render and would re-run the scan on every keystroke
|
|
99
|
+
* of an UNCHANGED filter. Keying the memo on the joined strings makes the
|
|
100
|
+
* dependency structural rather than referential.
|
|
101
|
+
*/
|
|
102
|
+
const typeKey = types ? types.join(",") : "";
|
|
103
|
+
const facetKey = facets ? facets.join(",") : "";
|
|
104
|
+
return React.useMemo(() => {
|
|
105
|
+
if (!index) {
|
|
106
|
+
return { status, result: null, suggestions: [], facets: [], builtAt: null };
|
|
107
|
+
}
|
|
108
|
+
const q = query.trim();
|
|
109
|
+
if (!q) {
|
|
110
|
+
return {
|
|
111
|
+
status,
|
|
112
|
+
result: null,
|
|
113
|
+
suggestions: [],
|
|
114
|
+
facets: [],
|
|
115
|
+
builtAt: index.builtAt,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const hits = searchIndex(index.artifact, index.prepared, q, {
|
|
119
|
+
limit: MATCH_LIMIT,
|
|
120
|
+
types: typeKey ? typeKey.split(",") : undefined,
|
|
121
|
+
facets: facetKey ? facetKey.split(",") : undefined,
|
|
122
|
+
});
|
|
123
|
+
/*
|
|
124
|
+
* Terms come from the SAME parser the matcher used, so a query that
|
|
125
|
+
* normalises away ("!!!") reports zero terms and the page can render its
|
|
126
|
+
* "no searchable words" state — which is a different thing from "nothing
|
|
127
|
+
* matched", and the distinction the server tier also draws via
|
|
128
|
+
* `plan.empty`.
|
|
129
|
+
*/
|
|
130
|
+
const terms = parseSearchTxtQuery(q);
|
|
131
|
+
return {
|
|
132
|
+
status,
|
|
133
|
+
result: toSearchResult(q, terms, hits, {
|
|
134
|
+
label,
|
|
135
|
+
moreHref: moreHrefResolver(index.artifact),
|
|
136
|
+
}),
|
|
137
|
+
suggestions: hits.slice(0, 8).map((h) => ({
|
|
138
|
+
objectID: h.href,
|
|
139
|
+
type: suggestionTypeFor(h.typeKey),
|
|
140
|
+
typeKey: h.typeKey,
|
|
141
|
+
title: h.title,
|
|
142
|
+
subtitle: h.detail || undefined,
|
|
143
|
+
url: h.href,
|
|
144
|
+
})),
|
|
145
|
+
facets: countFacets(hits),
|
|
146
|
+
builtAt: index.builtAt,
|
|
147
|
+
};
|
|
148
|
+
}, [index, status, query, typeKey, facetKey, label]);
|
|
149
|
+
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export * from "./types/index.js";
|
|
2
|
-
export * from "./schemas/index.js";
|
|
3
|
-
export * from "./columns/index.js";
|
|
4
|
-
export * from "./hooks/useSearch.js";
|
|
5
1
|
export * from "./hooks/useNavSuggestions.js";
|
|
6
2
|
export * from "./components/index.js";
|
|
7
3
|
export { manifest } from "./manifest.js";
|
|
@@ -1,2 +1,14 @@
|
|
|
1
1
|
import type { FeatureManifest } from "../../contracts";
|
|
2
|
+
/**
|
|
3
|
+
* `default` is `SearchResultsClient`, which is what `[locale]/search/page.tsx`
|
|
4
|
+
* actually renders. It used to say `SearchView` — a component the route has
|
|
5
|
+
* never rendered, from the dead legacy `feat-search` subsystem — and A7
|
|
6
|
+
* (`audit-feature-manifest-routes`) is what this file is the fixed example
|
|
7
|
+
* for.
|
|
8
|
+
*
|
|
9
|
+
* `api/search` (the dead `SearchRepository`-backed GET handler) was removed
|
|
10
|
+
* from `apiRoutes` in the same Wave 10 commit that deleted the route itself
|
|
11
|
+
* — the manifest and the filesystem go empty together, not one claiming the
|
|
12
|
+
* other vanished a week early.
|
|
13
|
+
*/
|
|
2
14
|
export declare const manifest: FeatureManifest;
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `default` is `SearchResultsClient`, which is what `[locale]/search/page.tsx`
|
|
3
|
+
* actually renders. It used to say `SearchView` — a component the route has
|
|
4
|
+
* never rendered, from the dead legacy `feat-search` subsystem — and A7
|
|
5
|
+
* (`audit-feature-manifest-routes`) is what this file is the fixed example
|
|
6
|
+
* for.
|
|
7
|
+
*
|
|
8
|
+
* `api/search` (the dead `SearchRepository`-backed GET handler) was removed
|
|
9
|
+
* from `apiRoutes` in the same Wave 10 commit that deleted the route itself
|
|
10
|
+
* — the manifest and the filesystem go empty together, not one claiming the
|
|
11
|
+
* other vanished a week early.
|
|
12
|
+
*/
|
|
1
13
|
export const manifest = {
|
|
2
14
|
name: "search",
|
|
3
15
|
i18nNamespace: "search",
|
|
4
16
|
envKeys: [],
|
|
5
|
-
routes: [
|
|
17
|
+
routes: [
|
|
18
|
+
{ segment: "[locale]/search", exports: { default: "SearchResultsClient" } },
|
|
19
|
+
],
|
|
6
20
|
apiRoutes: [
|
|
7
|
-
{ segment: "api/search", methods: ["GET"] },
|
|
21
|
+
{ segment: "api/search/scoped", methods: ["GET"] },
|
|
22
|
+
{ segment: "api/search/suggestions", methods: ["GET"] },
|
|
8
23
|
{ segment: "api/categories/flat", methods: ["GET"] },
|
|
9
24
|
],
|
|
10
25
|
};
|
|
@@ -53,7 +53,7 @@ export interface SellerListingTypeSpec {
|
|
|
53
53
|
* because standard / auction / pre-order / prize-draw do NOT have one — their
|
|
54
54
|
* store routes redirect into the multi-type `SellerProductsView`.
|
|
55
55
|
*/
|
|
56
|
-
export type SellerListingTypeKey = "art" | "stickers" | "classified" | "digital-code" | "live";
|
|
56
|
+
export type SellerListingTypeKey = "art" | "stickers" | "classified" | "digital-code" | "live" | "spares";
|
|
57
57
|
export declare const SELLER_LISTING_TYPE_SPECS: Record<SellerListingTypeKey, SellerListingTypeSpec>;
|
|
58
58
|
export interface SellerListingTypeViewProps {
|
|
59
59
|
onCreateClick?: () => void;
|
|
@@ -87,6 +87,26 @@ export const SELLER_LISTING_TYPE_SPECS = {
|
|
|
87
87
|
}),
|
|
88
88
|
extraColumns: [textCell("size", "Size")],
|
|
89
89
|
},
|
|
90
|
+
spares: {
|
|
91
|
+
editRoute: (id) => String(ROUTES.STORE.SPARES_EDIT(id)),
|
|
92
|
+
newRoute: String(ROUTES.STORE.SPARES_NEW),
|
|
93
|
+
createLabel: "List a Spare",
|
|
94
|
+
bulkKey: "spares",
|
|
95
|
+
deleteLabel: "Spare Listing",
|
|
96
|
+
searchPlaceholder: "Search spares by part or colour...",
|
|
97
|
+
emptyLabel: "No spares listed yet — list a part you have going spare",
|
|
98
|
+
/*
|
|
99
|
+
* Colourway, not size. Two listings of the same part code are told apart by
|
|
100
|
+
* COLOUR here — a red Cross Dranzer and a navy one are different objects to
|
|
101
|
+
* a buyer rebuilding a specific top, which is the user's own framing
|
|
102
|
+
* ("sell it to someone who wants it in the same colour"). `printMeta.size`
|
|
103
|
+
* is meaningless on a moulded component.
|
|
104
|
+
*/
|
|
105
|
+
extraFields: (item) => ({
|
|
106
|
+
colourway: toStringValue(item.colourway, ""),
|
|
107
|
+
}),
|
|
108
|
+
extraColumns: [textCell("colourway", "Colourway")],
|
|
109
|
+
},
|
|
90
110
|
classified: {
|
|
91
111
|
editRoute: (id) => String(ROUTES.STORE.CLASSIFIED_EDIT(id)),
|
|
92
112
|
newRoute: String(ROUTES.STORE.CLASSIFIED_NEW),
|
|
@@ -46,9 +46,17 @@ const payoutSettingsDraftSchema = z.object({
|
|
|
46
46
|
ifscCode: annotate(z.string(), { section: "method", quick: true, order: 5, row: "pair" }),
|
|
47
47
|
bankName: annotate(z.string(), { section: "method", quick: true, order: 6, row: "pair" }),
|
|
48
48
|
accountType: annotate(z.enum(["savings", "current"]), { section: "method", quick: true, order: 7, row: "pair" }),
|
|
49
|
+
// The three fields that identify the SUPPLIER OF RECORD on this store's
|
|
50
|
+
// invoices. A seller with a GSTIN invoices under it; one without
|
|
51
|
+
// invoices under LetItRip's (resolveSupplierIdentity).
|
|
52
|
+
//
|
|
53
|
+
// `pan` and `businessType` were removed 2026-10-19: neither exists on
|
|
54
|
+
// StoreDocument or UserDocument and the route stripped them, so a
|
|
55
|
+
// seller who entered a PAN was told it saved and it went nowhere.
|
|
56
|
+
// An input that provably cannot persist is worse than no input.
|
|
49
57
|
gstin: annotate(z.string(), { section: "tax", sectionLabel: "Tax Info", order: 1, row: "pair" }),
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
legalName: annotate(z.string(), { section: "tax", order: 2, row: "pair" }),
|
|
59
|
+
registeredAddress: annotate(z.string(), { section: "tax", order: 3, row: "full" }),
|
|
52
60
|
autoPayout: annotate(z.boolean(), {
|
|
53
61
|
section: "preferences", sectionLabel: "Preferences", order: 1, row: "quarter",
|
|
54
62
|
}),
|
|
@@ -110,8 +118,8 @@ const DEFAULT_DRAFT = {
|
|
|
110
118
|
bankName: "",
|
|
111
119
|
accountType: "savings",
|
|
112
120
|
gstin: "",
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
legalName: "",
|
|
122
|
+
registeredAddress: "",
|
|
115
123
|
autoPayout: true,
|
|
116
124
|
minimumThreshold: "",
|
|
117
125
|
emiEnabled: false,
|
|
@@ -142,9 +150,22 @@ export function SellerPayoutSettingsView({ apiBase = SELLER_ENDPOINTS.PAYOUT_SET
|
|
|
142
150
|
ifscCode: details.bankAccount?.ifscCode ?? "",
|
|
143
151
|
bankName: details.bankAccount?.bankName ?? "",
|
|
144
152
|
accountType: details.bankAccount?.accountType ?? "savings",
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
153
|
+
/*
|
|
154
|
+
* 🛑 Flat fields, NOT `res.data.taxInfo.*`.
|
|
155
|
+
*
|
|
156
|
+
* `taxInfo` is a key the route has never returned, so these three
|
|
157
|
+
* inputs were ALWAYS blank on load no matter what had been saved —
|
|
158
|
+
* and the save side posted a `taxInfo` object that the route's
|
|
159
|
+
* `z.object()` schema silently stripped. A seller could type their
|
|
160
|
+
* GSTIN, get a success toast, reload, and find it gone.
|
|
161
|
+
*
|
|
162
|
+
* The route now declares and persists `gstin` / `legalName` /
|
|
163
|
+
* `registeredAddress` on the STORE, because the GSTIN decides who
|
|
164
|
+
* is the supplier of record on that store's invoices.
|
|
165
|
+
*/
|
|
166
|
+
gstin: res?.data?.gstin ?? "",
|
|
167
|
+
legalName: res?.data?.legalName ?? "",
|
|
168
|
+
registeredAddress: res?.data?.registeredAddress ?? "",
|
|
148
169
|
autoPayout: res?.data?.preferences?.autoPayout ?? true,
|
|
149
170
|
minimumThreshold: res?.data?.preferences?.minimumThreshold
|
|
150
171
|
? String(res.data.preferences.minimumThreshold)
|
|
@@ -184,11 +205,11 @@ export function SellerPayoutSettingsView({ apiBase = SELLER_ENDPOINTS.PAYOUT_SET
|
|
|
184
205
|
pricesIncludeGst: draft.pricesIncludeGst,
|
|
185
206
|
supportsShippingProtection: draft.supportsShippingProtection,
|
|
186
207
|
supportsSaleProtection: draft.supportsSaleProtection,
|
|
187
|
-
taxInfo
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
208
|
+
// Flat, matching the route's schema. A nested `taxInfo` object was
|
|
209
|
+
// stripped by `z.object()` and never reached Firestore.
|
|
210
|
+
gstin: draft.gstin.trim(),
|
|
211
|
+
legalName: draft.legalName.trim(),
|
|
212
|
+
registeredAddress: draft.registeredAddress.trim(),
|
|
192
213
|
preferences: {
|
|
193
214
|
autoPayout: draft.autoPayout,
|
|
194
215
|
minimumThreshold: Math.round(parseFloat(draft.minimumThreshold || "0") * 100) / 100,
|
|
@@ -244,8 +265,8 @@ export function SellerPayoutSettingsView({ apiBase = SELLER_ENDPOINTS.PAYOUT_SET
|
|
|
244
265
|
{
|
|
245
266
|
id: "tax",
|
|
246
267
|
label: "Tax Info",
|
|
247
|
-
fields: ["gstin", "
|
|
248
|
-
render: ({ values, onChange }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, className: "mb-2", children: "Tax Information" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Optional
|
|
268
|
+
fields: ["gstin", "legalName", "registeredAddress"],
|
|
269
|
+
render: ({ values, onChange }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, className: "mb-2", children: "Tax Information" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Optional. Enter a GSTIN and your orders are invoiced under your own registration; leave it blank and they are invoiced under LetItRip's." }), _jsx(FormField, { name: "gstin", label: "GSTIN (optional)", type: "text", value: values.gstin, onChange: (v) => onChange({ gstin: v.toUpperCase() }), placeholder: "e.g. 22AAAAA0000A1Z5", helpText: "15-character Goods and Services Tax Identification Number.", disabled: busy }), _jsx(FormField, { name: "legalName", label: "Registered legal name (optional)", type: "text", value: values.legalName, onChange: (v) => onChange({ legalName: v }), placeholder: "e.g. Arena Collectibles Pvt Ltd", helpText: "The entity name that appears on the invoice. Leave blank to use your store name.", disabled: busy }), _jsx(FormField, { name: "registeredAddress", label: "Registered address (optional)", type: "text", value: values.registeredAddress, onChange: (v) => onChange({ registeredAddress: v }), placeholder: "Address as registered against your GSTIN", helpText: "Printed on invoices issued under your GSTIN.", disabled: busy })] })),
|
|
249
270
|
},
|
|
250
271
|
{
|
|
251
272
|
id: "preferences",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { MediaField } from "../../media/types";
|
|
3
|
-
export type ProductListingMode = "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | "classified" | "digital-code" | "live" | "art" | "stickers";
|
|
3
|
+
export type ProductListingMode = "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | "classified" | "digital-code" | "live" | "art" | "stickers" | "spares";
|
|
4
4
|
export interface SellerProductDraft {
|
|
5
5
|
title?: string;
|
|
6
6
|
slug?: string;
|
|
@@ -8,6 +8,7 @@ import { FormShellContext, useFormShellState, applyZodIssues, FormErrorSummary }
|
|
|
8
8
|
import { Alert, Button, Div, FormField, FormGroup, Heading, Section, Stack, TagInput, Text, Toggle, useToast, Row } from "../../../ui/index.js";
|
|
9
9
|
import { ImageUpload, MediaUploadField, MediaUploadList, useMediaUpload } from "../../media/index.js";
|
|
10
10
|
import { StoreAddressSelectorCreate } from "../../stores/components/StoreAddressSelectorCreate.js";
|
|
11
|
+
import { PriceGuidanceHint } from "../../categories/components/PriceGuidanceHint.js";
|
|
11
12
|
import { QuickProductForm } from "./QuickProductForm.js";
|
|
12
13
|
import { BarcodeField } from "./BarcodeField.js";
|
|
13
14
|
import { pluginFor } from "../../../_internal/shared/listing-types/_registry.js";
|
|
@@ -388,7 +389,7 @@ const TYPE_SPECIFIC_SECTIONS = {
|
|
|
388
389
|
function StepPricing({ values, onChange, listingType, }) {
|
|
389
390
|
const listingPlugin = pluginForMode(listingType);
|
|
390
391
|
const priceLabel = listingPlugin.priceLabel;
|
|
391
|
-
return (_jsxs(Stack, { gap: "md", children: [_jsx(Alert, { variant: "info", children: "All prices in Indian Rupees (\u20B9)." }), _jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "price", label: priceLabel, type: "number", value: toRupeesString(values.price), onChange: (v) => onChange({ price: fromRupeesString(v) }), placeholder: "999" }), _jsx(FormField, { name: "originalPrice", label: "Compare-at Price (\u20B9, optional)", type: "number", value: toRupeesString(values.originalPrice), onChange: (v) => onChange({ originalPrice: v ? fromRupeesString(v) : undefined }), placeholder: "1299", helpText: "Original price shown as strikethrough" })] }), listingPlugin.showsStockQuantity && (_jsx(FormField, { name: "stockQuantity", label: "Stock Quantity", type: "number", value: String(values.stockQuantity ?? ""), onChange: (v) => onChange({ stockQuantity: Number(v) }), placeholder: "1" })), _jsxs(FormGroup, { columns: 2, children: [_jsx(Toggle, { checked: !!values.featured, onChange: (checked) => onChange({ featured: checked }), label: "Mark as Featured" }), _jsx(Toggle, { checked: !!values.isNew, onChange: (checked) => onChange({ isNew: checked }), label: "Mark as New Arrival" })] }), _jsx(Toggle, { checked: !!values.allowOffers, onChange: (checked) => onChange({
|
|
392
|
+
return (_jsxs(Stack, { gap: "md", children: [_jsx(Alert, { variant: "info", children: "All prices in Indian Rupees (\u20B9)." }), _jsxs(FormGroup, { columns: 2, children: [_jsx(FormField, { name: "price", label: priceLabel, type: "number", value: toRupeesString(values.price), onChange: (v) => onChange({ price: fromRupeesString(v) }), placeholder: "999" }), _jsx(FormField, { name: "originalPrice", label: "Compare-at Price (\u20B9, optional)", type: "number", value: toRupeesString(values.originalPrice), onChange: (v) => onChange({ originalPrice: v ? fromRupeesString(v) : undefined }), placeholder: "1299", helpText: "Original price shown as strikethrough" })] }), (values.categoryIds?.[0] ?? values.category) && (_jsx(PriceGuidanceHint, { categoryId: (values.categoryIds?.[0] ?? values.category) })), listingPlugin.showsStockQuantity && (_jsx(FormField, { name: "stockQuantity", label: "Stock Quantity", type: "number", value: String(values.stockQuantity ?? ""), onChange: (v) => onChange({ stockQuantity: Number(v) }), placeholder: "1" })), _jsxs(FormGroup, { columns: 2, children: [_jsx(Toggle, { checked: !!values.featured, onChange: (checked) => onChange({ featured: checked }), label: "Mark as Featured" }), _jsx(Toggle, { checked: !!values.isNew, onChange: (checked) => onChange({ isNew: checked }), label: "Mark as New Arrival" })] }), _jsx(Toggle, { checked: !!values.allowOffers, onChange: (checked) => onChange({
|
|
392
393
|
allowOffers: checked,
|
|
393
394
|
minOfferPercent: checked
|
|
394
395
|
? values.minOfferPercent ?? DEFAULT_MIN_OFFER_PERCENT
|
|
@@ -24,7 +24,7 @@ const CLS_NAV_ICON_ACTIVE = "text-warning dark:text-warning";
|
|
|
24
24
|
function NavLink({ item, isActive, onClick }) {
|
|
25
25
|
return (_jsxs(Link, { href: item.href, onClick: onClick, className: `flex items-center justify-end gap-[var(--appkit-space-2-5)] rounded-lg px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[0.8125rem] font-medium leading-tight transition-colors ${isActive
|
|
26
26
|
? CLS_NAV_ACTIVE
|
|
27
|
-
: "text-[var(--appkit-color-text-muted)] hover:bg-surface-hover hover:text-
|
|
27
|
+
: "text-[var(--appkit-color-text-muted)] hover:bg-surface-hover hover:text-[var(--appkit-color-text)]"}`, children: [item.icon && _jsx(Span, { size: "base", className: "shrink-0 opacity-60", children: item.icon }), _jsx(Span, { className: "truncate", children: item.label }), item.badge != null && item.badge > 0 && (_jsx(Span, { weight: "bold", className: CLS_NAV_BADGE, children: item.badge }))] }));
|
|
28
28
|
}
|
|
29
29
|
function FlatContent({ items, activeHref, storeName, storeLogoURL, onItemClick, }) {
|
|
30
30
|
const activeItem = findActiveNavItem(items, activeHref);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SellerSparesView — seller browse/manage of spares listings.
|
|
3
|
+
*
|
|
4
|
+
* A named wrapper, matching its five siblings exactly: all behaviour is
|
|
5
|
+
* `SellerListingTypeView`, and everything this type does differently is one
|
|
6
|
+
* entry in `SELLER_LISTING_TYPE_SPECS` (a colourway column instead of a size
|
|
7
|
+
* column, and its own routes and copy).
|
|
8
|
+
*
|
|
9
|
+
* Written as a wrapper rather than as a sixth copy of the component on purpose
|
|
10
|
+
* — see `SellerListingTypeView`'s header for what the five hand-written copies
|
|
11
|
+
* cost, and note that the factory it adopts had existed with zero seller
|
|
12
|
+
* callers the whole time.
|
|
13
|
+
*/
|
|
14
|
+
import React from "react";
|
|
15
|
+
import { type SellerListingTypeViewProps } from "./SellerListingTypeView";
|
|
16
|
+
export type SellerSparesViewProps = SellerListingTypeViewProps;
|
|
17
|
+
export declare function SellerSparesView(props: SellerSparesViewProps): React.JSX.Element;
|
|
@@ -114,6 +114,8 @@ export { SellerArtView } from "./SellerArtView";
|
|
|
114
114
|
export type { SellerArtViewProps } from "./SellerArtView";
|
|
115
115
|
export { SellerStickersView } from "./SellerStickersView";
|
|
116
116
|
export type { SellerStickersViewProps } from "./SellerStickersView";
|
|
117
|
+
export { SellerSparesView } from "./SellerSparesView";
|
|
118
|
+
export type { SellerSparesViewProps } from "./SellerSparesView";
|
|
117
119
|
export { SellerDigitalCodesView } from "./SellerDigitalCodesView";
|
|
118
120
|
export type { SellerDigitalCodesViewProps } from "./SellerDigitalCodesView";
|
|
119
121
|
export { SellerLiveView } from "./SellerLiveView";
|
|
@@ -60,6 +60,7 @@ export { SellerBundlesView } from "./SellerBundlesView.js";
|
|
|
60
60
|
export { SellerClassifiedView } from "./SellerClassifiedView.js";
|
|
61
61
|
export { SellerArtView } from "./SellerArtView.js";
|
|
62
62
|
export { SellerStickersView } from "./SellerStickersView.js";
|
|
63
|
+
export { SellerSparesView } from "./SellerSparesView.js";
|
|
63
64
|
export { SellerDigitalCodesView } from "./SellerDigitalCodesView.js";
|
|
64
65
|
export { SellerLiveView } from "./SellerLiveView.js";
|
|
65
66
|
export { BarcodeField } from "./BarcodeField.js";
|
|
@@ -60,7 +60,7 @@ export function CommandPalette({ isOpen, onClose, groups, placeholder = "Jump to
|
|
|
60
60
|
if (target)
|
|
61
61
|
navigate(target.href);
|
|
62
62
|
}, [results, activeIndex, navigate, onClose]);
|
|
63
|
-
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, size: "lg", showCloseButton: false,
|
|
63
|
+
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, size: "lg", showCloseButton: false, children: _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Input, { ref: inputRef, value: query, onChange: (e) => setQuery(e.target.value), onKeyDown: handleKeyDown, placeholder: placeholder, "aria-label": placeholder, className: "flex-1", autoFocus: true }), _jsx(Kbd, { size: "sm", tone: "brand", children: "Esc" })] }), _jsx(Div, { className: "max-h-96", overflow: "y-auto", children: results.length === 0 ? (_jsxs(Text, { size: "sm", color: "muted", align: "center", paddingY: "lg", children: ["No matches for \u201C", query, "\u201D."] })) : (_jsx(Stack, { gap: "none", children: results.map((item, idx) => (_jsxs(Button, { variant: "ghost", type: "button", onClick: () => navigate(item.href), onMouseEnter: () => setActiveIndex(idx), justify: "between", rounded: "md", paddingX: "sm", paddingY: "xs", className: [
|
|
64
64
|
"w-full text-left",
|
|
65
65
|
idx === activeIndex
|
|
66
66
|
? "bg-[var(--appkit-color-primary-50)] text-[var(--appkit-color-primary-700)]"
|
|
@@ -116,6 +116,25 @@ export interface SheetPart {
|
|
|
116
116
|
* on these sheets.
|
|
117
117
|
*/
|
|
118
118
|
duplicateOf?: number;
|
|
119
|
+
/**
|
|
120
|
+
* The `/media/{shortId}` slug of this part's PUBLIC, WATERMARKED copy.
|
|
121
|
+
*
|
|
122
|
+
* 🛑 ZERO BYTES ARE DUPLICATED. The `mediaAssets` row points at the SAME
|
|
123
|
+
* `assetPath` above — the clean original under `private/sticker-sheets/` —
|
|
124
|
+
* and is written with `watermarkedAt` deliberately ABSENT, so
|
|
125
|
+
* `/api/media/[...slug]` composites the mark on read. Clean original for the
|
|
126
|
+
* cut file, watermarked copy for the marketplace, one object.
|
|
127
|
+
*
|
|
128
|
+
* Object COUNT is metered separately from bytes (that is the whole reason the
|
|
129
|
+
* thumb atlas exists), so a second uploaded copy per part would spend Class A
|
|
130
|
+
* writes 60× faster per sheet for pixels we already have.
|
|
131
|
+
*
|
|
132
|
+
* Stored back here so re-promoting a sheet REUSES the row rather than minting
|
|
133
|
+
* a second slug for the same object and orphaning the first.
|
|
134
|
+
*
|
|
135
|
+
* Absent until the sheet has been promoted to listings.
|
|
136
|
+
*/
|
|
137
|
+
mediaShortId?: string;
|
|
119
138
|
}
|
|
120
139
|
/**
|
|
121
140
|
* One progress transition, mirrored from RTDB so history survives the prune.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
|
-
export declare const getStoreBySlug: (slug: string) => Promise<import("
|
|
3
|
+
export declare const getStoreBySlug: (slug: string) => Promise<import("..").StoreDocument | null>;
|
|
4
4
|
export interface StoreDetailLayoutViewProps {
|
|
5
5
|
storeSlug: string;
|
|
6
6
|
/** The current active tab value: "products" | "auctions" | "reviews" | "about" */
|