@mohasinac/appkit 2.7.58 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/filters/filter-load-options.d.ts +4 -5
- package/dist/_internal/server/features/auctions/og.js +8 -32
- package/dist/_internal/server/features/blog/og.js +10 -49
- package/dist/_internal/server/features/checkout/actions.js +6 -0
- package/dist/_internal/server/features/classified/og.js +9 -51
- package/dist/_internal/server/features/digital-code/actions.d.ts +11 -0
- package/dist/_internal/server/features/digital-code/actions.js +30 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +1 -0
- package/dist/_internal/server/features/digital-code/index.js +1 -0
- package/dist/_internal/server/features/digital-code/og.js +9 -51
- package/dist/_internal/server/features/events/og.js +10 -49
- package/dist/_internal/server/features/item-requests/data.d.ts +17 -0
- package/dist/_internal/server/features/item-requests/data.js +20 -0
- package/dist/_internal/server/features/item-requests/index.d.ts +2 -0
- package/dist/_internal/server/features/item-requests/index.js +2 -0
- package/dist/_internal/server/features/item-requests/og.d.ts +40 -0
- package/dist/_internal/server/features/item-requests/og.js +136 -0
- package/dist/_internal/server/features/live/actions.d.ts +5 -0
- package/dist/_internal/server/features/live/actions.js +24 -0
- package/dist/_internal/server/features/live/index.d.ts +1 -0
- package/dist/_internal/server/features/live/index.js +1 -0
- package/dist/_internal/server/features/live/og.js +9 -51
- package/dist/_internal/server/features/media/contextGuards.js +19 -8
- package/dist/_internal/server/features/pre-orders/og.js +8 -32
- package/dist/_internal/server/features/prize-draws/data.d.ts +17 -0
- package/dist/_internal/server/features/prize-draws/data.js +20 -0
- package/dist/_internal/server/features/prize-draws/index.d.ts +2 -0
- package/dist/_internal/server/features/prize-draws/index.js +2 -0
- package/dist/_internal/server/features/prize-draws/og.d.ts +30 -0
- package/dist/_internal/server/features/prize-draws/og.js +50 -0
- package/dist/_internal/server/features/products/og.js +8 -33
- package/dist/_internal/server/features/scams/og.js +1 -1
- package/dist/_internal/server/features/seo/og-layout.d.ts +42 -0
- package/dist/_internal/server/features/seo/og-layout.js +69 -0
- package/dist/_internal/server/features/stores/og.js +8 -41
- package/dist/_internal/server/features/sublisting-categories/og.js +11 -42
- package/dist/_internal/shared/actions/bulk-helpers.d.ts +3 -0
- package/dist/_internal/shared/actions/bulk-helpers.js +19 -0
- package/dist/_internal/shared/config/schema.d.ts +4 -4
- package/dist/client.d.ts +13 -6
- package/dist/client.js +9 -3
- package/dist/configs/next.js +11 -0
- package/dist/constants/index.d.ts +4 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/notification-types.d.ts +20 -0
- package/dist/constants/notification-types.js +37 -0
- package/dist/constants/pagination-presets.d.ts +39 -0
- package/dist/constants/pagination-presets.js +38 -0
- package/dist/errors/messages.d.ts +0 -4
- package/dist/errors/messages.js +0 -4
- package/dist/features/account/components/AddressesIndexListing.js +3 -4
- package/dist/features/account/components/UserOffersPanel.js +1 -1
- package/dist/features/account/components/UserSidebar.js +14 -10
- package/dist/features/account/components/UserSupportView.d.ts +1 -2
- package/dist/features/account/components/UserSupportView.js +9 -1
- package/dist/features/admin/actions/admin-actions.js +16 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +2 -3
- package/dist/features/admin/components/AdminAllEventEntriesView.js +50 -89
- package/dist/features/admin/components/AdminBidsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBidsView.js +64 -104
- package/dist/features/admin/components/AdminBlogView.d.ts +3 -7
- package/dist/features/admin/components/AdminBlogView.js +53 -88
- package/dist/features/admin/components/AdminBrandEditorView.js +14 -17
- package/dist/features/admin/components/AdminBrandsView.d.ts +2 -3
- package/dist/features/admin/components/AdminBrandsView.js +85 -89
- package/dist/features/admin/components/AdminBundlesView.js +68 -130
- package/dist/features/admin/components/AdminCarouselView.d.ts +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +22 -70
- package/dist/features/admin/components/AdminCartsView.d.ts +2 -3
- package/dist/features/admin/components/AdminCartsView.js +39 -89
- package/dist/features/admin/components/AdminCategoriesView.d.ts +3 -3
- package/dist/features/admin/components/AdminCategoriesView.js +97 -96
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -6
- package/dist/features/admin/components/AdminClassifiedView.d.ts +3 -0
- package/dist/features/admin/components/AdminClassifiedView.js +44 -0
- package/dist/features/admin/components/AdminContactView.d.ts +2 -2
- package/dist/features/admin/components/AdminContactView.js +105 -130
- package/dist/features/admin/components/AdminCouponEditorView.js +14 -17
- package/dist/features/admin/components/AdminCouponsView.d.ts +3 -6
- package/dist/features/admin/components/AdminCouponsView.js +69 -97
- package/dist/features/admin/components/AdminDigitalCodesView.d.ts +3 -0
- package/dist/features/admin/components/AdminDigitalCodesView.js +51 -0
- package/dist/features/admin/components/AdminFaqEditorView.js +14 -17
- package/dist/features/admin/components/AdminFaqsView.d.ts +4 -4
- package/dist/features/admin/components/AdminFaqsView.js +79 -86
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -9
- package/dist/features/admin/components/AdminFeaturesView.d.ts +2 -3
- package/dist/features/admin/components/AdminFeaturesView.js +57 -70
- package/dist/features/admin/components/AdminGroupedListingsView.d.ts +3 -0
- package/dist/features/admin/components/AdminGroupedListingsView.js +43 -0
- package/dist/features/admin/components/AdminHistoryView.d.ts +2 -3
- package/dist/features/admin/components/AdminHistoryView.js +35 -52
- package/dist/features/admin/components/AdminListingScaffold.d.ts +2 -2
- package/dist/features/admin/components/AdminListingScaffold.js +3 -3
- package/dist/features/admin/components/AdminLiveView.d.ts +3 -0
- package/dist/features/admin/components/AdminLiveView.js +50 -0
- package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -2
- package/dist/features/admin/components/AdminNewsletterView.js +68 -108
- package/dist/features/admin/components/AdminNotificationsView.d.ts +2 -3
- package/dist/features/admin/components/AdminNotificationsView.js +67 -99
- package/dist/features/admin/components/AdminOrderEditorView.js +10 -10
- package/dist/features/admin/components/AdminOrdersView.d.ts +2 -3
- package/dist/features/admin/components/AdminOrdersView.js +93 -113
- package/dist/features/admin/components/AdminPayoutsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPayoutsView.js +51 -97
- package/dist/features/admin/components/AdminPrizeDrawsView.d.ts +2 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +41 -83
- package/dist/features/admin/components/AdminProductEditorView.js +3 -7
- package/dist/features/admin/components/AdminProductsView.d.ts +4 -4
- package/dist/features/admin/components/AdminProductsView.js +166 -167
- package/dist/features/admin/components/AdminReturnRequestsView.d.ts +1 -1
- package/dist/features/admin/components/AdminReturnRequestsView.js +64 -66
- package/dist/features/admin/components/AdminReviewsView.d.ts +3 -7
- package/dist/features/admin/components/AdminReviewsView.js +94 -116
- package/dist/features/admin/components/AdminScammersView.d.ts +2 -3
- package/dist/features/admin/components/AdminScammersView.js +53 -103
- package/dist/features/admin/components/AdminSectionsView.js +1 -1
- package/dist/features/admin/components/AdminSessionsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSessionsView.js +62 -95
- package/dist/features/admin/components/AdminStoreAddressesView.d.ts +1 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +39 -53
- package/dist/features/admin/components/AdminStoreEditorView.js +21 -8
- package/dist/features/admin/components/AdminStoresView.d.ts +2 -3
- package/dist/features/admin/components/AdminStoresView.js +67 -105
- package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +1 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +29 -49
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +17 -20
- package/dist/features/admin/components/AdminSupportTicketDetailView.d.ts +10 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +191 -5
- package/dist/features/admin/components/AdminSupportTicketsView.d.ts +2 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +65 -102
- package/dist/features/admin/components/AdminTeamView.d.ts +2 -2
- package/dist/features/admin/components/AdminTeamView.js +42 -85
- package/dist/features/admin/components/AdminUserEditorView.d.ts +11 -1
- package/dist/features/admin/components/AdminUserEditorView.js +80 -6
- package/dist/features/admin/components/AdminUsersView.d.ts +2 -3
- package/dist/features/admin/components/AdminUsersView.js +108 -106
- package/dist/features/admin/components/AdminViewCards.d.ts +1 -1
- package/dist/features/admin/components/AdminWishlistsView.d.ts +2 -3
- package/dist/features/admin/components/AdminWishlistsView.js +36 -62
- package/dist/features/admin/components/DataListingView.d.ts +122 -0
- package/dist/features/admin/components/DataListingView.js +66 -0
- package/dist/features/admin/components/index.d.ts +10 -4
- package/dist/features/admin/components/index.js +6 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +23 -17
- package/dist/features/admin/constants/filter-tabs.js +21 -17
- package/dist/features/admin/hooks/useAdminListing.d.ts +59 -0
- package/dist/features/admin/hooks/useAdminListing.js +71 -0
- package/dist/features/admin/schemas/firestore.js +6 -7
- package/dist/features/auctions/server.d.ts +0 -1
- package/dist/features/auctions/server.js +0 -1
- package/dist/features/auth/actions/realtime-token-actions.js +1 -1
- package/dist/features/auth/repository/user.repository.js +1 -1
- package/dist/features/auth/schemas/firestore.d.ts +1 -0
- package/dist/features/blog/components/BlogIndexListing.js +3 -6
- package/dist/features/cart/repository/cart.repository.d.ts +4 -1
- package/dist/features/cart/repository/cart.repository.js +12 -0
- package/dist/features/categories/components/CategoriesIndexListing.js +3 -6
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -2
- package/dist/features/checkout/index.d.ts +1 -1
- package/dist/features/events/components/AdminEventsView.d.ts +3 -3
- package/dist/features/events/components/AdminEventsView.js +50 -86
- package/dist/features/events/components/EventOfferCard.d.ts +19 -0
- package/dist/features/events/components/EventOfferCard.js +29 -0
- package/dist/features/events/components/EventRaffleEntryForm.d.ts +25 -0
- package/dist/features/events/components/EventRaffleEntryForm.js +37 -0
- package/dist/features/events/components/EventRafflesSection.d.ts +1 -4
- package/dist/features/events/components/EventRafflesSection.js +17 -6
- package/dist/features/events/components/EventSaleBanner.d.ts +21 -0
- package/dist/features/events/components/EventSaleBanner.js +18 -0
- package/dist/features/events/components/EventsIndexListing.js +3 -4
- package/dist/features/events/components/index.d.ts +6 -0
- package/dist/features/events/components/index.js +4 -0
- package/dist/features/events/repository/event-entry.repository.d.ts +5 -0
- package/dist/features/events/repository/event-entry.repository.js +7 -0
- package/dist/features/filters/AsyncFacetSection.d.ts +1 -1
- package/dist/features/homepage/components/AnnouncementBar.d.ts +4 -1
- package/dist/features/homepage/components/AnnouncementBar.js +51 -4
- package/dist/features/homepage/components/FAQSection.d.ts +0 -5
- package/dist/features/homepage/components/MarketplaceHomepageView.d.ts +3 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
- package/dist/features/homepage/components/index.d.ts +1 -1
- package/dist/features/homepage/components/index.js +1 -1
- package/dist/features/homepage/lib/live-stats.js +1 -1
- package/dist/features/homepage/lib/section-renderer.d.ts +2 -2
- package/dist/features/homepage/lib/section-renderer.js +2 -2
- package/dist/features/homepage/schemas/firestore.d.ts +0 -2
- package/dist/features/layout/index.d.ts +0 -2
- package/dist/features/layout/index.js +0 -1
- package/dist/features/orders/repository/orders.repository.d.ts +0 -1
- package/dist/features/orders/repository/orders.repository.js +0 -1
- package/dist/features/orders/server.d.ts +1 -1
- package/dist/features/orders/server.js +1 -1
- package/dist/features/pre-orders/server.d.ts +0 -1
- package/dist/features/pre-orders/server.js +0 -1
- package/dist/features/products/components/GroupSettingsPanel.js +65 -49
- package/dist/features/products/components/PrizeDrawItemsEditor.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.d.ts +1 -4
- package/dist/features/products/components/PrizeDrawsSection.js +17 -6
- package/dist/features/products/components/PrizeRevealModal.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.d.ts +11 -0
- package/dist/features/products/components/ProductCardMetadataSection.js +25 -0
- package/dist/features/products/components/ProductDetailPageView.js +3 -1
- package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
- package/dist/features/products/components/ProductGradingTab.d.ts +13 -0
- package/dist/features/products/components/ProductGradingTab.js +25 -0
- package/dist/features/products/components/ProductGrid.js +14 -2
- package/dist/features/products/components/ProductTabsShell.d.ts +5 -1
- package/dist/features/products/components/ProductTabsShell.js +6 -1
- package/dist/features/products/components/index.d.ts +4 -0
- package/dist/features/products/components/index.js +3 -0
- package/dist/features/products/constants/action-defs.d.ts +5 -0
- package/dist/features/products/constants/action-defs.js +52 -32
- package/dist/features/products/constants/sieve.d.ts +24 -4
- package/dist/features/products/constants/sieve.js +20 -11
- package/dist/features/products/repository/products.repository.d.ts +0 -2
- package/dist/features/products/repository/products.repository.js +0 -2
- package/dist/features/products/schemas/firestore.d.ts +17 -0
- package/dist/features/products/schemas/product-features.validators.d.ts +2 -2
- package/dist/features/products/schemas/product-templates.d.ts +2 -4
- package/dist/features/products/server.d.ts +1 -1
- package/dist/features/products/server.js +1 -1
- package/dist/features/products/types/index.d.ts +4 -0
- package/dist/features/promotions/components/CouponCard.js +5 -5
- package/dist/features/promotions/components/CouponsIndexListing.js +3 -2
- package/dist/features/promotions/server.d.ts +0 -1
- package/dist/features/promotions/server.js +0 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +3 -4
- package/dist/features/reviews/repository/reviews.repository.d.ts +0 -1
- package/dist/features/reviews/repository/reviews.repository.js +0 -1
- package/dist/features/reviews/server.d.ts +1 -1
- package/dist/features/reviews/server.js +1 -1
- package/dist/features/search/api/route.js +44 -1
- package/dist/features/search/components/Search.js +2 -0
- package/dist/features/search/hooks/useNavSuggestions.d.ts +5 -1
- package/dist/features/search/hooks/useNavSuggestions.js +31 -4
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/SellerAddressesView.js +10 -20
- package/dist/features/seller/components/SellerAuctionsView.d.ts +3 -3
- package/dist/features/seller/components/SellerAuctionsView.js +67 -106
- package/dist/features/seller/components/SellerBidsView.js +6 -6
- package/dist/features/seller/components/SellerBundlesView.js +72 -105
- package/dist/features/seller/components/SellerClassifiedView.js +74 -105
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerCouponsView.d.ts +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +51 -96
- package/dist/features/seller/components/SellerDigitalCodesView.js +70 -103
- package/dist/features/seller/components/SellerGroupedListingsView.js +34 -54
- package/dist/features/seller/components/SellerLiveView.js +70 -99
- package/dist/features/seller/components/SellerOffersPanel.js +1 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOffersView.js +37 -70
- package/dist/features/seller/components/SellerOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +10 -24
- package/dist/features/seller/components/SellerPayoutMethodsView.js +12 -24
- package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPayoutsView.js +34 -69
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -2
- package/dist/features/seller/components/SellerPreOrdersView.js +55 -97
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -2
- package/dist/features/seller/components/SellerPrizeDrawsView.js +55 -97
- package/dist/features/seller/components/SellerProductShell.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +1 -1
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +3 -6
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -2
- package/dist/features/seller/components/SellerProductsView.js +24 -32
- package/dist/features/seller/components/SellerShippingConfigsView.js +12 -24
- package/dist/features/seller/components/SellerSidebar.d.ts +0 -4
- package/dist/features/seller/components/SellerSidebar.js +0 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +15 -34
- package/dist/features/seller/components/SellerTemplatesView.js +27 -43
- package/dist/features/seller/components/SellersListView.d.ts +1 -2
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.d.ts +5 -0
- package/dist/features/seller/components/analytics/SellerAnalyticsStats.js +2 -8
- package/dist/features/seller/components/index.d.ts +0 -3
- package/dist/features/seller/components/index.js +0 -2
- package/dist/features/seller/server.d.ts +0 -1
- package/dist/features/seller/server.js +0 -1
- package/dist/features/shell/FormShell.d.ts +1 -1
- package/dist/features/shell/FormShell.js +4 -1
- package/dist/features/shell/field-groups/ImageFieldGroup.d.ts +18 -0
- package/dist/features/shell/field-groups/ImageFieldGroup.js +15 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.d.ts +22 -0
- package/dist/features/shell/field-groups/SeoFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.d.ts +35 -0
- package/dist/features/shell/field-groups/StatusFieldGroup.js +16 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.d.ts +40 -0
- package/dist/features/shell/field-groups/TitleDescriptionGroup.js +16 -0
- package/dist/features/shell/field-groups/index.d.ts +13 -0
- package/dist/features/shell/field-groups/index.js +9 -0
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/stores/components/StoreCapabilitiesGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreFinanceGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreHeader.js +2 -1
- package/dist/features/stores/components/StoreListingsGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreOrdersGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoreReviewsListing.js +3 -4
- package/dist/features/stores/components/StoreScopedSearch.d.ts +16 -0
- package/dist/features/stores/components/StoreScopedSearch.js +27 -0
- package/dist/features/stores/components/StoreSettingsGuideView.d.ts +1 -2
- package/dist/features/stores/components/StoresIndexListing.js +3 -4
- package/dist/features/stores/server.d.ts +0 -1
- package/dist/features/stores/server.js +0 -1
- package/dist/features/support/schemas/firestore.d.ts +22 -1
- package/dist/features/support/schemas/firestore.js +10 -0
- package/dist/features/wishlist/server.d.ts +0 -1
- package/dist/features/wishlist/server.js +0 -1
- package/dist/index.d.ts +11 -33
- package/dist/index.js +17 -62
- package/dist/next/routing/route-map.d.ts +8 -0
- package/dist/next/routing/route-map.js +4 -0
- package/dist/react/contexts/SessionContext.d.ts +2 -0
- package/dist/react/contexts/SessionContext.js +2 -0
- package/dist/react/hooks/useEntityDelete.d.ts +15 -0
- package/dist/react/hooks/useEntityDelete.js +39 -0
- package/dist/react/hooks/useListingTypeFlags.d.ts +32 -0
- package/dist/react/hooks/useListingTypeFlags.js +19 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/repositories/index.d.ts +3 -3
- package/dist/repositories/index.js +3 -3
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/pii-redact.d.ts +8 -0
- package/dist/security/pii-redact.js +10 -1
- package/dist/seed/grouped-listings-seed-data.d.ts +4 -0
- package/dist/seed/products-preorders-seed-data.d.ts +4 -0
- package/dist/seed/products-prize-draws-seed-data.js +3 -0
- package/dist/seed/site-settings-seed-data.js +5 -5
- package/dist/seed/sub-listings-seed-data.d.ts +4 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +4 -0
- package/dist/styles.css +54 -395
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/BaseListingCard.d.ts +10 -0
- package/dist/ui/components/BaseListingCard.js +17 -1
- package/dist/ui/components/DetailPageGallery.d.ts +32 -0
- package/dist/ui/components/DetailPageGallery.js +47 -0
- package/dist/ui/components/DetailPageHero.d.ts +30 -0
- package/dist/ui/components/DetailPageHero.js +22 -0
- package/dist/ui/components/DetailPageTabs.d.ts +34 -0
- package/dist/ui/components/DetailPageTabs.js +38 -0
- package/dist/ui/components/HorizontalScroller.style.css +15 -2
- package/dist/ui/components/ListingFilterDrawer.d.ts +10 -0
- package/dist/ui/components/ListingFilterDrawer.js +8 -0
- package/dist/ui/components/ListingLayout.d.ts +11 -2
- package/dist/ui/components/ListingLayout.js +12 -6
- package/dist/ui/components/PaginatedSelect.d.ts +66 -0
- package/dist/ui/components/PaginatedSelect.js +201 -0
- package/dist/ui/components/PaginatedSelect.style.css +254 -0
- package/dist/ui/components/Semantic.d.ts +0 -4
- package/dist/ui/components/Semantic.js +0 -2
- package/dist/ui/components/SettingsSection.d.ts +47 -0
- package/dist/ui/components/SettingsSection.js +38 -0
- package/dist/ui/components/index.style.css +1 -4
- package/dist/ui/index.d.ts +14 -14
- package/dist/ui/index.js +7 -7
- package/dist/utils/id-generators.d.ts +1 -18
- package/dist/utils/id-generators.js +51 -18
- package/dist/validation/schemas.d.ts +25 -0
- package/dist/validation/schemas.js +28 -0
- package/package.json +1 -1
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
import React
|
|
4
|
-
import {
|
|
5
|
-
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
|
-
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
|
-
import { AdminViewCards } from "../../admin/components/AdminViewCards";
|
|
8
|
-
import { usePanelUrlSync } from "../../../react/hooks/use-panel-url-sync";
|
|
9
|
-
import { BulkActionBar, Button, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, SideDrawer } from "../../../ui";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { FilterChipGroup, ListingLayout } from "../../../ui";
|
|
10
5
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
11
6
|
import { ADMIN_EVENT_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
12
|
-
import { toRecordArray, toRelativeDate, toStringValue,
|
|
13
|
-
import {
|
|
7
|
+
import { toRecordArray, toRelativeDate, toStringValue, } from "../../admin/hooks/useAdminListingData";
|
|
8
|
+
import { DataListingView } from "../../admin/components/DataListingView";
|
|
14
9
|
import { AdminEventEditorView } from "./AdminEventEditorView";
|
|
15
|
-
import { useBottomActions } from "../../layout";
|
|
16
|
-
const PAGE_SIZE = 25;
|
|
17
|
-
const FILTER_KEYS = ["status", "type"];
|
|
18
|
-
const DEFAULT_SORT = "-startsAt";
|
|
19
|
-
const SORT_OPTIONS = [
|
|
20
|
-
{ value: "-startsAt", label: "Starting soonest" },
|
|
21
|
-
{ value: "startsAt", label: "Starting latest" },
|
|
22
|
-
{ value: "-createdAt", label: "Newest" },
|
|
23
|
-
{ value: "title", label: "Title A–Z" },
|
|
24
|
-
];
|
|
25
|
-
const STATUS_OPTIONS = ADMIN_EVENT_STATUS_TABS;
|
|
26
10
|
// TODO(events): TYPE_OPTIONS list pre-dates the SB9 EventType union refresh
|
|
27
11
|
// (sale|offer|poll|survey|feedback|raffle|spin_wheel). Keep current values to
|
|
28
12
|
// avoid silently breaking saved-filter URLs — sync in a dedicated follow-up.
|
|
@@ -35,78 +19,58 @@ const TYPE_OPTIONS = [
|
|
|
35
19
|
{ id: "survey", label: "Survey" },
|
|
36
20
|
{ id: "flash-sale", label: "Flash Sale" },
|
|
37
21
|
];
|
|
38
|
-
export function AdminEventsView({ children,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}, [table]);
|
|
50
|
-
const applyFilters = useCallback(() => {
|
|
51
|
-
const updates = { page: "1" };
|
|
52
|
-
for (const k of FILTER_KEYS)
|
|
53
|
-
updates[k] = pendingFilters[k] ?? "";
|
|
54
|
-
table.setMany(updates);
|
|
55
|
-
setFilterOpen(false);
|
|
56
|
-
}, [pendingFilters, table]);
|
|
57
|
-
const clearFilters = useCallback(() => {
|
|
58
|
-
setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
|
|
59
|
-
}, []);
|
|
60
|
-
const resetAll = useCallback(() => {
|
|
61
|
-
const updates = { q: "", sort: "" };
|
|
62
|
-
for (const k of FILTER_KEYS)
|
|
63
|
-
updates[k] = "";
|
|
64
|
-
table.setMany(updates);
|
|
65
|
-
setSearchInput("");
|
|
66
|
-
}, [table]);
|
|
67
|
-
const commitSearch = useCallback(() => {
|
|
68
|
-
table.set("q", searchInput.trim());
|
|
69
|
-
}, [searchInput, table]);
|
|
70
|
-
const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
|
|
71
|
-
const hasActiveState = !!table.get("q") || table.get("sort") !== DEFAULT_SORT || activeFilterCount > 0;
|
|
72
|
-
const filterParts = [];
|
|
73
|
-
const statusRaw = table.get("status");
|
|
74
|
-
if (statusRaw && statusRaw !== "All")
|
|
75
|
-
filterParts.push(`status==${statusRaw}`);
|
|
76
|
-
const typeRaw = table.get("type");
|
|
77
|
-
if (typeRaw && typeRaw !== "All")
|
|
78
|
-
filterParts.push(`type==${typeRaw}`);
|
|
79
|
-
const filters = filterParts.join(",") || undefined;
|
|
80
|
-
const { rows, total, isLoading, errorMessage } = useAdminListingData({
|
|
22
|
+
export function AdminEventsView({ children, ...props }) {
|
|
23
|
+
if (React.Children.count(children) > 0) {
|
|
24
|
+
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
25
|
+
}
|
|
26
|
+
const config = {
|
|
27
|
+
portal: "admin",
|
|
28
|
+
title: "Events",
|
|
29
|
+
searchPlaceholder: "Search events by title or type",
|
|
30
|
+
emptyLabel: "No events found",
|
|
31
|
+
filterKeys: ["status", "type"],
|
|
32
|
+
defaultSort: "-startsAt",
|
|
81
33
|
queryKey: ["admin", "events", "listing"],
|
|
82
34
|
endpoint: ADMIN_ENDPOINTS.EVENTS,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
35
|
+
sortOptions: [
|
|
36
|
+
{ value: "-startsAt", label: "Starting soonest" },
|
|
37
|
+
{ value: "startsAt", label: "Starting latest" },
|
|
38
|
+
{ value: "-createdAt", label: "Newest" },
|
|
39
|
+
{ value: "title", label: "Title A–Z" },
|
|
40
|
+
],
|
|
88
41
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
89
42
|
id: toStringValue(item.id, `event-${index}`),
|
|
90
43
|
primary: toStringValue(item.title, "Untitled event"),
|
|
91
|
-
secondary: [
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
].filter(Boolean).join(" · "),
|
|
44
|
+
secondary: [toStringValue(item.type, "event"), toStringValue(item.startsAt, "")]
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.join(" · "),
|
|
95
47
|
status: toStringValue(item.status, "active"),
|
|
96
48
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
97
49
|
})),
|
|
98
50
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
51
|
+
buildFilters: (state) => {
|
|
52
|
+
const parts = [];
|
|
53
|
+
if (state.status && state.status !== "All")
|
|
54
|
+
parts.push(`status==${state.status}`);
|
|
55
|
+
if (state.type && state.type !== "All")
|
|
56
|
+
parts.push(`type==${state.type}`);
|
|
57
|
+
return parts.join(",") || undefined;
|
|
58
|
+
},
|
|
59
|
+
primaryAction: {
|
|
60
|
+
label: "Add Event",
|
|
61
|
+
onClick: ({ openCreatePanel }) => openCreatePanel(),
|
|
62
|
+
},
|
|
63
|
+
buildBulkActions: (selection) => [
|
|
64
|
+
{
|
|
65
|
+
id: "delete",
|
|
66
|
+
label: "Delete Selected",
|
|
67
|
+
variant: "secondary",
|
|
68
|
+
onClick: () => selection.clearSelection(),
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(_Fragment, { children: [_jsx(FilterChipGroup, { label: "Status", tabs: ADMIN_EVENT_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }), _jsx(FilterChipGroup, { label: "Type", tabs: TYPE_OPTIONS, value: pendingFilters.type ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, type: id })) })] })),
|
|
72
|
+
renderEditor: ({ editId, closePanel }) => (_jsx(AdminEventEditorView, { eventId: editId ?? undefined, onSaved: closePanel, embedded: true })),
|
|
73
|
+
resolveEditorTitle: ({ isCreate }) => (isCreate ? "Add Event" : "Edit Event"),
|
|
74
|
+
};
|
|
75
|
+
return _jsx(DataListingView, { config: config });
|
|
112
76
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface EventOfferCardProps {
|
|
2
|
+
/** Coupon code to copy. */
|
|
3
|
+
couponCode: string;
|
|
4
|
+
/** Description of what the coupon does. */
|
|
5
|
+
offerDescription?: string;
|
|
6
|
+
/** Headline. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Optional filter param for the CTA — e.g. {key: "category", value: "trading-cards"}. */
|
|
9
|
+
filterParam?: {
|
|
10
|
+
key: string;
|
|
11
|
+
value: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* `EventOfferCard` — W1-18 — offer event UI noted as missing in the plan.
|
|
16
|
+
* Renders a coupon code with copy-to-clipboard + a CTA to the filtered
|
|
17
|
+
* products page.
|
|
18
|
+
*/
|
|
19
|
+
export declare function EventOfferCard({ couponCode, offerDescription, title, filterParam, }: EventOfferCardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import { Div, Heading, Stack, Text } from "../../../ui";
|
|
6
|
+
import { Button } from "../../../ui/components/Button";
|
|
7
|
+
import { ROUTES } from "../../../next/routing/route-map";
|
|
8
|
+
/**
|
|
9
|
+
* `EventOfferCard` — W1-18 — offer event UI noted as missing in the plan.
|
|
10
|
+
* Renders a coupon code with copy-to-clipboard + a CTA to the filtered
|
|
11
|
+
* products page.
|
|
12
|
+
*/
|
|
13
|
+
export function EventOfferCard({ couponCode, offerDescription, title = "Exclusive offer", filterParam, }) {
|
|
14
|
+
const [copied, setCopied] = useState(false);
|
|
15
|
+
const href = filterParam
|
|
16
|
+
? `${ROUTES.PUBLIC.PRODUCTS}?${encodeURIComponent(filterParam.key)}=${encodeURIComponent(filterParam.value)}`
|
|
17
|
+
: String(ROUTES.PUBLIC.PRODUCTS);
|
|
18
|
+
const copyCode = async () => {
|
|
19
|
+
try {
|
|
20
|
+
await navigator.clipboard.writeText(couponCode);
|
|
21
|
+
setCopied(true);
|
|
22
|
+
setTimeout(() => setCopied(false), 2000);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* clipboard unavailable — leave button as-is */
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (_jsx(Div, { className: "rounded-2xl border border-zinc-200 dark:border-zinc-700 p-6", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-2xl font-semibold", children: title }), offerDescription ? (_jsx(Text, { className: "text-sm text-zinc-600 dark:text-zinc-400", children: offerDescription })) : null] }), _jsxs(Div, { className: "flex items-center gap-3 rounded-lg bg-zinc-50 dark:bg-zinc-900 px-4 py-3", children: [_jsx("code", { className: "flex-1 font-mono text-lg font-bold text-zinc-900 dark:text-zinc-100", children: couponCode }), _jsx(Button, { type: "button", variant: "outline", onClick: copyCode, children: copied ? "Copied!" : "Copy code" })] }), _jsx(Div, { children: _jsx(Link, { href: href, children: _jsx(Button, { variant: "primary", children: "Apply at checkout" }) }) })] }) }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface EventRaffleEntryFormProps {
|
|
2
|
+
/** Event id used for the entry POST. */
|
|
3
|
+
eventId: string;
|
|
4
|
+
/** Raffle prize label rendered prominently above the form. */
|
|
5
|
+
prizeLabel?: string;
|
|
6
|
+
/** Raffle type — drives the helper copy. */
|
|
7
|
+
raffleType?: "open_raffle" | "top_n_scorers" | "top_n_participants" | "spin_wheel";
|
|
8
|
+
/** Top-N value when raffleType supports it. */
|
|
9
|
+
topN?: number;
|
|
10
|
+
/** Max entries this user already has (drives the over-limit message). */
|
|
11
|
+
userEntryCount?: number;
|
|
12
|
+
/** Server-enforced max entries per user (defaults to 1). */
|
|
13
|
+
maxEntriesPerUser?: number;
|
|
14
|
+
/** When true, the form is in a submitted/locked state. */
|
|
15
|
+
submitted?: boolean;
|
|
16
|
+
/** Caller-provided submit handler. Receives the user's optional message. */
|
|
17
|
+
onSubmit: (message: string) => Promise<void> | void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* `EventRaffleEntryForm` — W1-18 — fills the gap noted in the plan ("Raffle
|
|
21
|
+
* entry form (71 LOC stub) — no entry form"). Renders the prize hero,
|
|
22
|
+
* eligibility status, an optional message field, and a submit button. Server
|
|
23
|
+
* action wiring stays with the caller via the `onSubmit` prop.
|
|
24
|
+
*/
|
|
25
|
+
export declare function EventRaffleEntryForm({ eventId: _eventId, prizeLabel, raffleType, topN, userEntryCount, maxEntriesPerUser, submitted, onSubmit, }: EventRaffleEntryFormProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Button } from "../../../ui/components/Button";
|
|
5
|
+
import { Div, Heading, Stack, Text } from "../../../ui";
|
|
6
|
+
import { Badge } from "../../../ui/components/Badge";
|
|
7
|
+
/**
|
|
8
|
+
* `EventRaffleEntryForm` — W1-18 — fills the gap noted in the plan ("Raffle
|
|
9
|
+
* entry form (71 LOC stub) — no entry form"). Renders the prize hero,
|
|
10
|
+
* eligibility status, an optional message field, and a submit button. Server
|
|
11
|
+
* action wiring stays with the caller via the `onSubmit` prop.
|
|
12
|
+
*/
|
|
13
|
+
export function EventRaffleEntryForm({ eventId: _eventId, prizeLabel, raffleType = "open_raffle", topN, userEntryCount = 0, maxEntriesPerUser = 1, submitted = false, onSubmit, }) {
|
|
14
|
+
const [message, setMessage] = useState("");
|
|
15
|
+
const [busy, setBusy] = useState(false);
|
|
16
|
+
const overLimit = userEntryCount >= maxEntriesPerUser;
|
|
17
|
+
const handleSubmit = async (e) => {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
if (overLimit || submitted || busy)
|
|
20
|
+
return;
|
|
21
|
+
setBusy(true);
|
|
22
|
+
try {
|
|
23
|
+
await onSubmit(message.trim());
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
setBusy(false);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const eligibilityCopy = raffleType === "open_raffle"
|
|
30
|
+
? "Open to all eligible participants — one entry per user."
|
|
31
|
+
: raffleType === "top_n_scorers"
|
|
32
|
+
? `Top ${topN ?? "N"} highest-scoring entries win.`
|
|
33
|
+
: raffleType === "top_n_participants"
|
|
34
|
+
? `Earliest ${topN ?? "N"} entries qualify.`
|
|
35
|
+
: "Spin the wheel to claim your prize.";
|
|
36
|
+
return (_jsxs(Div, { className: "rounded-2xl border border-zinc-200 dark:border-zinc-700 p-6 space-y-4", children: [prizeLabel ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Badge, { variant: "warning", children: "Prize" }), _jsx(Heading, { level: 2, className: "text-2xl font-bold", children: prizeLabel })] })) : null, _jsx(Text, { className: "text-sm text-zinc-600 dark:text-zinc-400", children: eligibilityCopy }), submitted ? (_jsx(Div, { className: "rounded-lg bg-success-surface px-4 py-3 text-sm text-success", children: "You're in. Check the leaderboard for results." })) : overLimit ? (_jsxs(Div, { className: "rounded-lg bg-warning-surface px-4 py-3 text-sm text-warning", children: ["You've used all ", maxEntriesPerUser, " entry slot", maxEntriesPerUser === 1 ? "" : "s", " for this raffle."] })) : (_jsxs("form", { onSubmit: handleSubmit, className: "space-y-3", children: [_jsxs("label", { htmlFor: "raffle-message", className: "block text-sm font-medium", children: ["Message ", _jsx("span", { className: "text-zinc-400", children: "(optional)" })] }), _jsx("textarea", { id: "raffle-message", value: message, onChange: (e) => setMessage(e.target.value), rows: 3, maxLength: 500, className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 px-3 py-2 text-sm bg-white dark:bg-zinc-900 focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]", placeholder: "Share why you'd like to win", disabled: busy }), _jsx(Button, { type: "submit", variant: "primary", disabled: busy, children: busy ? "Submitting…" : "Enter raffle" })] }))] }));
|
|
37
|
+
}
|
|
@@ -4,9 +4,6 @@ export interface EventRafflesSectionProps {
|
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
6
|
* Renders a live-raffle/spin-wheel strip on the homepage.
|
|
7
|
-
*
|
|
8
|
-
* Reads events with `hasRaffle=true` and status in {"active","upcoming"}. The
|
|
9
|
-
* `hasRaffle` flag is added later with the raffle feature; for now the
|
|
10
|
-
* component renders an empty state and the section ships disabled in seed.
|
|
7
|
+
* W1-38 (2026-05-23): fetches events with hasRaffle=true and renders the EventCard grid.
|
|
11
8
|
*/
|
|
12
9
|
export declare function EventRafflesSection({ config, }: EventRafflesSectionProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -2,16 +2,27 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import { Container, Heading, Section, Stack, Text, } from "../../../ui";
|
|
4
4
|
import { ROUTES } from "../../../next";
|
|
5
|
+
import { eventRepository } from "../repository/events.repository";
|
|
6
|
+
import { EventCard } from "./EventCard";
|
|
5
7
|
/**
|
|
6
8
|
* Renders a live-raffle/spin-wheel strip on the homepage.
|
|
7
|
-
*
|
|
8
|
-
* Reads events with `hasRaffle=true` and status in {"active","upcoming"}. The
|
|
9
|
-
* `hasRaffle` flag is added later with the raffle feature; for now the
|
|
10
|
-
* component renders an empty state and the section ships disabled in seed.
|
|
9
|
+
* W1-38 (2026-05-23): fetches events with hasRaffle=true and renders the EventCard grid.
|
|
11
10
|
*/
|
|
12
11
|
export async function EventRafflesSection({ config, }) {
|
|
13
12
|
const title = config.title ?? "Live Raffles & Spin Wheels";
|
|
14
13
|
const subtitle = config.subtitle ?? "Participate in community events and win prizes";
|
|
15
|
-
const
|
|
16
|
-
|
|
14
|
+
const limit = 6;
|
|
15
|
+
let events = [];
|
|
16
|
+
try {
|
|
17
|
+
const result = await eventRepository.list({
|
|
18
|
+
filters: "hasRaffle==true,status==active",
|
|
19
|
+
sorts: "-startsAt",
|
|
20
|
+
pageSize: limit,
|
|
21
|
+
});
|
|
22
|
+
events = (result.items ?? []);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
events = [];
|
|
26
|
+
}
|
|
27
|
+
return (_jsx(Section, { className: "py-10", children: _jsx(Container, { size: "xl", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-2xl font-semibold text-zinc-900 dark:text-zinc-50", children: title }), subtitle ? (_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: subtitle })) : null] }), events.length === 0 ? (_jsxs(Stack, { align: "center", gap: "sm", className: "rounded-2xl border border-dashed border-zinc-300 px-6 py-12 text-center dark:border-slate-700", children: [_jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "No upcoming raffles \u2014 keep an eye on the events page." }), _jsx(Link, { href: String(ROUTES.PUBLIC.EVENTS), className: "text-sm font-medium text-primary hover:underline", children: "Browse all events \u2192" })] })) : (_jsx("div", { className: "fluid-grid-card gap-3", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) }))] }) }) }));
|
|
17
28
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface EventSaleBannerProps {
|
|
2
|
+
/** Discount percent (e.g. 20 = 20% off). */
|
|
3
|
+
discountPercent?: number;
|
|
4
|
+
/** Coupon code (when the sale is gated by a code). */
|
|
5
|
+
couponCode?: string;
|
|
6
|
+
/** Sale headline override. */
|
|
7
|
+
title?: string;
|
|
8
|
+
/** Sale subheading override. */
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
/** Filter the catalog page to a specific category / tag. */
|
|
11
|
+
filterParam?: {
|
|
12
|
+
key: string;
|
|
13
|
+
value: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* `EventSaleBanner` — W1-18 — sale event UI noted as missing in the plan.
|
|
18
|
+
* Renders a hero banner with the discount, optional coupon, and a CTA to the
|
|
19
|
+
* filtered products catalog.
|
|
20
|
+
*/
|
|
21
|
+
export declare function EventSaleBanner({ discountPercent, couponCode, title, subtitle, filterParam, }: EventSaleBannerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { Div, Heading, Stack, Text } from "../../../ui";
|
|
5
|
+
import { Button } from "../../../ui/components/Button";
|
|
6
|
+
import { ROUTES } from "../../../next/routing/route-map";
|
|
7
|
+
/**
|
|
8
|
+
* `EventSaleBanner` — W1-18 — sale event UI noted as missing in the plan.
|
|
9
|
+
* Renders a hero banner with the discount, optional coupon, and a CTA to the
|
|
10
|
+
* filtered products catalog.
|
|
11
|
+
*/
|
|
12
|
+
export function EventSaleBanner({ discountPercent, couponCode, title, subtitle, filterParam, }) {
|
|
13
|
+
const headline = title ?? (discountPercent ? `${discountPercent}% off, today only` : "Special sale");
|
|
14
|
+
const href = filterParam
|
|
15
|
+
? `${ROUTES.PUBLIC.PRODUCTS}?${encodeURIComponent(filterParam.key)}=${encodeURIComponent(filterParam.value)}`
|
|
16
|
+
: `${ROUTES.PUBLIC.PRODUCTS}?onSale=true`;
|
|
17
|
+
return (_jsx(Div, { className: "rounded-2xl bg-gradient-to-br from-[var(--appkit-color-primary)] to-[var(--appkit-color-secondary)] p-6 text-white shadow-lg", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, className: "text-3xl font-bold", children: headline }), subtitle ? _jsx(Text, { className: "text-base text-white/90", children: subtitle }) : null] }), couponCode ? (_jsxs(Div, { className: "inline-flex items-center gap-3 rounded-lg bg-white/10 px-4 py-2 backdrop-blur", children: [_jsx("span", { className: "text-xs uppercase tracking-wide opacity-80", children: "Code" }), _jsx("span", { className: "font-mono text-lg font-bold", children: couponCode })] })) : null, _jsx(Div, { children: _jsx(Link, { href: href, children: _jsx(Button, { variant: "secondary", children: "Shop the sale" }) }) })] }) }));
|
|
18
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback, useMemo } from "react";
|
|
4
|
-
import { X } from "lucide-react";
|
|
5
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
5
|
import { useEvents } from "../hooks/useEvents";
|
|
7
|
-
import { ListingToolbar, Pagination, Text } from "../../../ui";
|
|
6
|
+
import { ListingFilterDrawer, ListingToolbar, Pagination, Text } from "../../../ui";
|
|
8
7
|
import { EventCard } from "./EventCard";
|
|
9
8
|
import { EventFilters, EVENT_PUBLIC_SORT_OPTIONS } from "./EventFilters";
|
|
10
9
|
import { EVENT_FIELDS } from "../../../constants/field-names";
|
|
@@ -116,5 +115,5 @@ export function EventsIndexListing({ initialData }) {
|
|
|
116
115
|
const commitSearch = useCallback(() => {
|
|
117
116
|
table.set(TABLE_KEYS.QUERY, searchInput.trim());
|
|
118
117
|
}, [searchInput, table]);
|
|
119
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search events...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || sortBy(EVENT_FIELDS.STARTS_AT, "ASC"), sortOptions: EVENT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-4 space-y-2", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded mt-2" })] })] }, i))) })) : events.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No events found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) }),
|
|
118
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search events...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || sortBy(EVENT_FIELDS.STARTS_AT, "ASC"), sortOptions: EVENT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-video bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-4 space-y-2", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx("div", { className: "h-8 bg-zinc-200 dark:bg-slate-700 rounded mt-2" })] })] }, i))) })) : events.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No events found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: events.map((event) => (_jsx(EventCard, { event: event }, event.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(EventFilters, { table: pendingTable, variant: "public" }) })] }));
|
|
120
119
|
}
|
|
@@ -29,3 +29,9 @@ export { EventRaffleWinnerView } from "./EventRaffleWinnerView";
|
|
|
29
29
|
export type { EventRaffleWinnerViewProps } from "./EventRaffleWinnerView";
|
|
30
30
|
export { SpinWheelView } from "./SpinWheelView";
|
|
31
31
|
export type { SpinWheelViewProps } from "./SpinWheelView";
|
|
32
|
+
export { EventRaffleEntryForm } from "./EventRaffleEntryForm";
|
|
33
|
+
export type { EventRaffleEntryFormProps } from "./EventRaffleEntryForm";
|
|
34
|
+
export { EventSaleBanner } from "./EventSaleBanner";
|
|
35
|
+
export type { EventSaleBannerProps } from "./EventSaleBanner";
|
|
36
|
+
export { EventOfferCard } from "./EventOfferCard";
|
|
37
|
+
export type { EventOfferCardProps } from "./EventOfferCard";
|
|
@@ -15,3 +15,7 @@ export { EventPollWidget } from "./EventPollWidget";
|
|
|
15
15
|
export { EventRafflesSection } from "./EventRafflesSection";
|
|
16
16
|
export { EventRaffleWinnerView } from "./EventRaffleWinnerView";
|
|
17
17
|
export { SpinWheelView } from "./SpinWheelView";
|
|
18
|
+
// W1-18: Event participation flows (raffle entry / sale banner / offer coupon)
|
|
19
|
+
export { EventRaffleEntryForm } from "./EventRaffleEntryForm";
|
|
20
|
+
export { EventSaleBanner } from "./EventSaleBanner";
|
|
21
|
+
export { EventOfferCard } from "./EventOfferCard";
|
|
@@ -7,6 +7,11 @@ declare class EventEntryRepository extends BaseRepository<EventEntryDocument> {
|
|
|
7
7
|
protected mapDoc<D = EventEntryDocument>(snap: import("../../../providers/db-firebase").DocumentSnapshot): D;
|
|
8
8
|
listForEvent(eventId: string, model: SieveModel): Promise<FirebaseSieveResult<EventEntryDocument>>;
|
|
9
9
|
listForUser(userId: string, model: SieveModel): Promise<FirebaseSieveResult<EventEntryDocument>>;
|
|
10
|
+
/**
|
|
11
|
+
* W1-42 — admin-facing list (all events, all users). Filterable on eventId,
|
|
12
|
+
* userId, reviewStatus, submittedAt; sortable on submittedAt + points.
|
|
13
|
+
*/
|
|
14
|
+
list(model: SieveModel): Promise<FirebaseSieveResult<EventEntryDocument>>;
|
|
10
15
|
hasUserEntered(eventId: string, userId: string): Promise<boolean>;
|
|
11
16
|
countUserEntries(eventId: string, userId: string): Promise<number>;
|
|
12
17
|
getLeaderboard(eventId: string, limit?: number): Promise<import("../types").LeaderboardEntry[]>;
|
|
@@ -23,6 +23,13 @@ class EventEntryRepository extends BaseRepository {
|
|
|
23
23
|
baseQuery: this.getCollection().where(EVENT_ENTRY_FIELDS.USER_ID, "==", userId),
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* W1-42 — admin-facing list (all events, all users). Filterable on eventId,
|
|
28
|
+
* userId, reviewStatus, submittedAt; sortable on submittedAt + points.
|
|
29
|
+
*/
|
|
30
|
+
async list(model) {
|
|
31
|
+
return this.sieveQuery(model, EventEntryRepository.SIEVE_FIELDS);
|
|
32
|
+
}
|
|
26
33
|
async hasUserEntered(eventId, userId) {
|
|
27
34
|
try {
|
|
28
35
|
const snapshot = await this.getCollection()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FacetOption } from "./FilterFacetSection";
|
|
2
|
-
import type { AsyncPage } from "../../ui/components/
|
|
2
|
+
import type { AsyncPage } from "../../ui/components/PaginatedSelect";
|
|
3
3
|
export interface AsyncFacetSectionProps {
|
|
4
4
|
title: string;
|
|
5
5
|
selected: string[];
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export declare function hashBannerMessage(msg: string): string;
|
|
1
2
|
export interface AnnouncementBarProps {
|
|
2
3
|
message: string;
|
|
3
4
|
className?: string;
|
|
5
|
+
/** Called when the user dismisses — consumer wires this to a server action to persist. */
|
|
6
|
+
onDismiss?: (hash: string) => void;
|
|
4
7
|
}
|
|
5
|
-
export declare function AnnouncementBar({ message, className }: AnnouncementBarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export declare function AnnouncementBar({ message, className, onDismiss }: AnnouncementBarProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,10 +1,57 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
import { useAuth } from "../../../react/contexts/SessionContext";
|
|
6
|
+
const STORAGE_KEY = "letitrip:announcement-dismissed";
|
|
7
|
+
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
8
|
+
export function hashBannerMessage(msg) {
|
|
9
|
+
let h = 0;
|
|
10
|
+
for (let i = 0; i < msg.length; i++) {
|
|
11
|
+
h = (Math.imul(31, h) + msg.charCodeAt(i)) | 0;
|
|
12
|
+
}
|
|
13
|
+
return h.toString(36);
|
|
14
|
+
}
|
|
15
|
+
function isLocallyDismissed(message) {
|
|
16
|
+
try {
|
|
17
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
18
|
+
if (!raw)
|
|
19
|
+
return false;
|
|
20
|
+
const { hash, at } = JSON.parse(raw);
|
|
21
|
+
if (hash !== hashBannerMessage(message))
|
|
22
|
+
return false;
|
|
23
|
+
return Date.now() - at < ONE_WEEK_MS;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function saveLocalDismissal(message) {
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ hash: hashBannerMessage(message), at: Date.now() }));
|
|
32
|
+
}
|
|
33
|
+
catch { /* quota exceeded — ignore */ }
|
|
34
|
+
}
|
|
35
|
+
export function AnnouncementBar({ message, className = "", onDismiss }) {
|
|
36
|
+
const { user } = useAuth();
|
|
37
|
+
const bannerHash = hashBannerMessage(message);
|
|
38
|
+
const userAlreadyDismissed = !!user?.dismissedBannerHash && user.dismissedBannerHash === bannerHash;
|
|
39
|
+
const [dismissed, setDismissed] = useState(userAlreadyDismissed);
|
|
40
|
+
const [mounted, setMounted] = useState(userAlreadyDismissed);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (userAlreadyDismissed) {
|
|
43
|
+
setDismissed(true);
|
|
44
|
+
}
|
|
45
|
+
else if (isLocallyDismissed(message)) {
|
|
46
|
+
setDismissed(true);
|
|
47
|
+
}
|
|
48
|
+
setMounted(true);
|
|
49
|
+
}, [message, userAlreadyDismissed]);
|
|
7
50
|
if (dismissed)
|
|
8
51
|
return null;
|
|
9
|
-
return (_jsx("div", { className: `relative left-1/2 right-1/2 w-screen -translate-x-1/2 bg-primary-700 ${className}`, role: "banner", "data-section": "announcementbar-div-310", children: _jsx("div", { className: "container mx-auto max-w-[1920px] px-4 sm:px-6 lg:px-8", "data-section": "announcementbar-div-311", children: _jsxs("div", { className: "relative flex items-center justify-center py-2 text-center text-sm font-medium text-white", "data-section": "announcementbar-div-312", children: [_jsx("span", { children: message }), _jsx("button", { type: "button", onClick: () =>
|
|
52
|
+
return (_jsx("div", { className: `relative left-1/2 right-1/2 w-screen -translate-x-1/2 bg-primary-700 transition-opacity duration-200 ${mounted ? "opacity-100" : "opacity-0"} ${className}`, role: "banner", "data-section": "announcementbar-div-310", children: _jsx("div", { className: "container mx-auto max-w-[1920px] px-4 sm:px-6 lg:px-8", "data-section": "announcementbar-div-311", children: _jsxs("div", { className: "relative flex items-center justify-center py-2 text-center text-sm font-medium text-white", "data-section": "announcementbar-div-312", children: [_jsx("span", { children: message }), _jsx("button", { type: "button", onClick: () => {
|
|
53
|
+
saveLocalDismissal(message);
|
|
54
|
+
onDismiss?.(bannerHash);
|
|
55
|
+
setDismissed(true);
|
|
56
|
+
}, className: "absolute right-0 top-1/2 -translate-y-1/2 rounded p-0.5 hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white", "aria-label": "Dismiss announcement", children: _jsx(X, { className: "h-4 w-4" }) })] }) }) }));
|
|
10
57
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
export interface FAQTab {
|
|
3
2
|
value: string;
|
|
4
3
|
label: string;
|
|
@@ -26,10 +25,6 @@ export interface FAQSectionProps {
|
|
|
26
25
|
viewMoreLabel?: string;
|
|
27
26
|
hasMore?: boolean;
|
|
28
27
|
moreCount?: number;
|
|
29
|
-
/** @deprecated Tabs are now derived internally or from the tabs prop */
|
|
30
|
-
activeTab?: string;
|
|
31
|
-
/** @deprecated Use showCategoryTabs + tabs props instead */
|
|
32
|
-
renderTabs?: () => React.ReactNode;
|
|
33
28
|
className?: string;
|
|
34
29
|
}
|
|
35
30
|
export declare function FAQSection({ title, subtitle, items, tabs: tabsProp, showCategoryTabs, allowMultipleOpen, defaultOpenCount, viewMoreHref, viewMoreLabel, hasMore, moreCount, className, }: FAQSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,5 +3,7 @@ export type { MarketplaceHomepageViewAdSlots } from "../lib/section-renderer";
|
|
|
3
3
|
export interface MarketplaceHomepageViewProps {
|
|
4
4
|
adSlots?: import("../lib/section-renderer").MarketplaceHomepageViewAdSlots;
|
|
5
5
|
newsletterFormSlot?: React.ReactNode;
|
|
6
|
+
/** Callback when user dismisses announcement banner — wire to a server action to persist. */
|
|
7
|
+
onBannerDismiss?: (hash: string) => void;
|
|
6
8
|
}
|
|
7
|
-
export declare function MarketplaceHomepageView({ adSlots, newsletterFormSlot, }?: MarketplaceHomepageViewProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
9
|
+
export declare function MarketplaceHomepageView({ adSlots, newsletterFormSlot, onBannerDismiss, }?: MarketplaceHomepageViewProps): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
@@ -23,7 +23,7 @@ function toCarouselSlides(docs) {
|
|
|
23
23
|
updatedAt: updatedAt instanceof Date ? updatedAt.toISOString() : undefined,
|
|
24
24
|
}));
|
|
25
25
|
}
|
|
26
|
-
export async function MarketplaceHomepageView({ adSlots, newsletterFormSlot, } = {}) {
|
|
26
|
+
export async function MarketplaceHomepageView({ adSlots, newsletterFormSlot, onBannerDismiss, } = {}) {
|
|
27
27
|
const slides = await carouselRepository.getActiveSlides().catch(() => []);
|
|
28
28
|
const siteSettings = await siteSettingsRepository.getSingleton().catch(() => null);
|
|
29
29
|
const announcementMessage = siteSettings?.announcementBar?.message?.trim() ||
|
|
@@ -113,5 +113,5 @@ export async function MarketplaceHomepageView({ adSlots, newsletterFormSlot, } =
|
|
|
113
113
|
: undefined,
|
|
114
114
|
};
|
|
115
115
|
const carouselSlides = toCarouselSlides(slides);
|
|
116
|
-
return (_jsxs(Main, { children: [showAnnouncement ? _jsx(AnnouncementBar, { message: announcementMessage }) : null, orderedSections.map((section) => renderSection(section, adSlots, newsletterFormSlot ?? null, faqItems, carouselSlides, liveStats, sectionData))] }));
|
|
116
|
+
return (_jsxs(Main, { children: [showAnnouncement ? _jsx(AnnouncementBar, { message: announcementMessage, onDismiss: onBannerDismiss }) : null, orderedSections.map((section) => renderSection(section, adSlots, newsletterFormSlot ?? null, faqItems, carouselSlides, liveStats, sectionData))] }));
|
|
117
117
|
}
|
|
@@ -53,7 +53,7 @@ export { FeaturedResultsSection } from "./FeaturedResultsSection";
|
|
|
53
53
|
export type { HowItWorksInfoStep, HowItWorksInfoDetail, HowItWorksInfoViewProps, } from "./HowItWorksInfoView";
|
|
54
54
|
export { HowItWorksInfoView } from "./HowItWorksInfoView";
|
|
55
55
|
export type { AnnouncementBarProps } from "./AnnouncementBar";
|
|
56
|
-
export { AnnouncementBar } from "./AnnouncementBar";
|
|
56
|
+
export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar";
|
|
57
57
|
export type { ShopByCategorySectionProps } from "./ShopByCategorySection";
|
|
58
58
|
export { ShopByCategorySection } from "./ShopByCategorySection";
|
|
59
59
|
export type { FeaturedProductsSectionProps } from "./FeaturedProductsSection";
|
|
@@ -26,7 +26,7 @@ export { WhatsAppCommunitySection } from "./WhatsAppCommunitySection";
|
|
|
26
26
|
export { HomepageSkeleton } from "./HomepageSkeleton";
|
|
27
27
|
export { FeaturedResultsSection } from "./FeaturedResultsSection";
|
|
28
28
|
export { HowItWorksInfoView } from "./HowItWorksInfoView";
|
|
29
|
-
export { AnnouncementBar } from "./AnnouncementBar";
|
|
29
|
+
export { AnnouncementBar, hashBannerMessage } from "./AnnouncementBar";
|
|
30
30
|
export { ShopByCategorySection } from "./ShopByCategorySection";
|
|
31
31
|
export { FeaturedProductsSection } from "./FeaturedProductsSection";
|
|
32
32
|
export { FeaturedAuctionsSection } from "./FeaturedAuctionsSection";
|