@mohasinac/appkit 2.7.27 → 2.7.31
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 +29 -0
- package/dist/_internal/client/features/filters/filter-load-options.js +98 -0
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
- package/dist/_internal/server/features/checkout/actions.js +42 -35
- package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
- package/dist/_internal/server/features/classified/adapters.js +24 -0
- package/dist/_internal/server/features/classified/index.d.ts +3 -0
- package/dist/_internal/server/features/classified/index.js +3 -0
- package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
- package/dist/_internal/server/features/classified/metadata.js +43 -0
- package/dist/_internal/server/features/classified/og.d.ts +30 -0
- package/dist/_internal/server/features/classified/og.js +76 -0
- package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
- package/dist/_internal/server/features/digital-code/adapters.js +29 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
- package/dist/_internal/server/features/digital-code/index.js +3 -0
- package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
- package/dist/_internal/server/features/digital-code/metadata.js +36 -0
- package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
- package/dist/_internal/server/features/digital-code/og.js +77 -0
- package/dist/_internal/server/features/live/adapters.d.ts +21 -0
- package/dist/_internal/server/features/live/adapters.js +34 -0
- package/dist/_internal/server/features/live/index.d.ts +3 -0
- package/dist/_internal/server/features/live/index.js +3 -0
- package/dist/_internal/server/features/live/metadata.d.ts +8 -0
- package/dist/_internal/server/features/live/metadata.js +39 -0
- package/dist/_internal/server/features/live/og.d.ts +27 -0
- package/dist/_internal/server/features/live/og.js +72 -0
- package/dist/_internal/server/features/promotions/actions.js +4 -3
- package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
- package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
- package/dist/_internal/shared/actions/action-registry.js +504 -9
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
- package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
- package/dist/_internal/shared/features/events/schema.d.ts +8 -8
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +42 -42
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
- package/dist/_internal/shared/media/limits.js +4 -3
- package/dist/client.d.ts +4 -0
- package/dist/client.js +2 -0
- package/dist/configs/next.js +4 -0
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +1 -0
- package/dist/constants/field-names.js +1 -0
- package/dist/constants/table-keys.d.ts +6 -0
- package/dist/constants/table-keys.js +9 -0
- package/dist/core/hooks/useSyncManager.js +9 -8
- package/dist/features/about/components/FeesView.js +10 -7
- package/dist/features/about/components/HelpPageView.js +10 -1
- package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
- package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
- package/dist/features/about/components/HowOffersWorkView.js +10 -1
- package/dist/features/about/components/HowOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
- package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowReviewsWorkView.js +10 -1
- package/dist/features/about/components/PublicProfileView.js +46 -16
- package/dist/features/about/components/SecurityPrivacyView.js +7 -1
- package/dist/features/account/components/AddressesIndexListing.js +2 -2
- package/dist/features/account/components/NotificationBell.js +27 -16
- package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
- package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
- package/dist/features/account/components/UserSidebar.js +4 -4
- package/dist/features/account/components/UserSupportView.js +16 -6
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/account/schemas/index.d.ts +4 -4
- package/dist/features/account/types/index.d.ts +34 -0
- package/dist/features/admin/actions/admin-actions.js +4 -3
- package/dist/features/admin/actions/notification-actions.d.ts +24 -22
- package/dist/features/admin/actions/notification-actions.js +122 -22
- package/dist/features/admin/components/AdminAdEditorView.js +29 -15
- package/dist/features/admin/components/AdminAddressEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminAddressEditorView.js +117 -0
- package/dist/features/admin/components/AdminAdsView.js +22 -28
- package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
- package/dist/features/admin/components/AdminBidsView.js +10 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
- package/dist/features/admin/components/AdminBlogView.js +8 -3
- package/dist/features/admin/components/AdminBrandsView.js +7 -2
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +13 -7
- package/dist/features/admin/components/AdminCategoriesView.js +8 -3
- package/dist/features/admin/components/AdminCategoryEditorView.js +12 -9
- package/dist/features/admin/components/AdminContactView.js +6 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
- package/dist/features/admin/components/AdminCouponsView.js +6 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
- package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
- package/dist/features/admin/components/AdminFaqsView.js +7 -2
- package/dist/features/admin/components/AdminFeatureFlagsView.js +58 -13
- package/dist/features/admin/components/AdminFeaturesView.js +4 -3
- package/dist/features/admin/components/AdminMediaView.js +9 -8
- package/dist/features/admin/components/AdminNavigationView.js +10 -17
- package/dist/features/admin/components/AdminNewsletterView.js +6 -1
- package/dist/features/admin/components/AdminNotificationsView.js +11 -3
- package/dist/features/admin/components/AdminOrdersView.js +6 -1
- package/dist/features/admin/components/AdminPayoutsView.js +10 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
- package/dist/features/admin/components/AdminProductEditorView.d.ts +3 -1
- package/dist/features/admin/components/AdminProductEditorView.js +12 -9
- package/dist/features/admin/components/AdminProductsView.js +18 -12
- package/dist/features/admin/components/AdminReturnRequestsView.js +5 -4
- package/dist/features/admin/components/AdminReviewsView.js +36 -26
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
- package/dist/features/admin/components/AdminScammersView.js +28 -26
- package/dist/features/admin/components/AdminSectionsView.js +112 -99
- package/dist/features/admin/components/AdminSessionsView.js +10 -3
- package/dist/features/admin/components/AdminSidebar.js +4 -4
- package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
- package/dist/features/admin/components/AdminStoresView.js +6 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
- package/dist/features/admin/components/AdminTeamView.js +6 -1
- package/dist/features/admin/components/AdminUserEditorView.js +8 -15
- package/dist/features/admin/components/AdminUsersView.js +6 -1
- package/dist/features/admin/components/AdminViewCards.js +4 -3
- package/dist/features/admin/components/DashboardStats.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- 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 +4 -3
- package/dist/features/admin/repository/chat.repository.js +8 -8
- package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
- package/dist/features/admin/repository/site-settings.repository.js +11 -9
- package/dist/features/admin/schemas/firestore.d.ts +38 -0
- package/dist/features/admin/schemas/firestore.js +15 -0
- package/dist/features/auctions/components/AuctionBidsTable.d.ts +13 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +62 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +15 -21
- package/dist/features/auctions/components/AuctionFilters.d.ts +7 -1
- package/dist/features/auctions/components/AuctionFilters.js +3 -2
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
- package/dist/features/auctions/components/index.d.ts +2 -1
- package/dist/features/auctions/components/index.js +1 -1
- package/dist/features/auctions/schemas/index.d.ts +14 -14
- package/dist/features/auth/actions/realtime-token-actions.js +19 -4
- package/dist/features/auth/components/RegisterForm.js +8 -4
- package/dist/features/auth/consent-otp.d.ts +2 -0
- package/dist/features/auth/consent-otp.js +8 -0
- package/dist/features/auth/schemas/firestore.d.ts +2 -0
- package/dist/features/auth/schemas/firestore.js +18 -25
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/before-after/api/[id]/route.js +8 -6
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +3 -3
- package/dist/features/blog/components/BlogIndexListing.js +21 -2
- package/dist/features/blog/components/BlogPostForm.js +11 -5
- package/dist/features/blog/components/BlogPostView.js +10 -2
- package/dist/features/blog/schemas/index.d.ts +18 -18
- package/dist/features/cart/components/CartDrawer.js +3 -2
- package/dist/features/cart/components/CartView.js +2 -1
- package/dist/features/cart/components/CheckoutView.js +2 -1
- package/dist/features/cart/repository/cart.repository.js +4 -3
- package/dist/features/cart/utils/pending-ops.d.ts +1 -1
- package/dist/features/categories/api/[id]/route.js +4 -3
- package/dist/features/categories/api/route.js +4 -3
- package/dist/features/categories/components/BrandDetailPageView.js +2 -2
- package/dist/features/categories/components/BrandDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/BrandDetailTabs.js +30 -16
- package/dist/features/categories/components/BundleCollage.d.ts +8 -0
- package/dist/features/categories/components/BundleCollage.js +50 -0
- package/dist/features/categories/components/BundleDetailView.js +2 -10
- package/dist/features/categories/components/BundleItemsPicker.js +20 -13
- package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
- package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +31 -16
- package/dist/features/categories/components/CategoryProductsListing.js +52 -13
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/categories/schemas/index.d.ts +6 -6
- package/dist/features/checkout/actions/checkout-actions.js +4 -3
- package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
- package/dist/features/classified/components/ClassifiedFilters.d.ts +12 -0
- package/dist/features/classified/components/ClassifiedFilters.js +20 -0
- package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
- package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
- package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
- package/dist/features/classified/components/ClassifiedListView.js +43 -0
- package/dist/features/classified/components/index.d.ts +6 -0
- package/dist/features/classified/components/index.js +3 -0
- package/dist/features/collections/api/[slug]/route.js +16 -12
- package/dist/features/collections/schemas/index.d.ts +5 -5
- package/dist/features/consultation/api/[id]/route.js +12 -9
- package/dist/features/consultation/components/ConsultationForm.js +3 -2
- package/dist/features/consultation/schemas/index.d.ts +6 -6
- package/dist/features/contact/email.js +77 -116
- package/dist/features/copilot/components/AdminCopilotView.js +12 -2
- package/dist/features/corporate/api/[id]/route.js +12 -9
- package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +12 -0
- package/dist/features/digital-codes/components/DigitalCodeFilters.js +17 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
- package/dist/features/digital-codes/components/index.d.ts +6 -0
- package/dist/features/digital-codes/components/index.js +3 -0
- package/dist/features/events/actions/event-actions.js +4 -3
- package/dist/features/events/components/AdminEventEditorView.js +3 -2
- package/dist/features/events/components/AdminEventsView.js +4 -2
- package/dist/features/events/components/EventPollWidget.js +5 -5
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/repository/event-entry.repository.d.ts +1 -0
- package/dist/features/events/repository/event-entry.repository.js +5 -0
- package/dist/features/events/schemas/index.d.ts +20 -20
- package/dist/features/faq/actions/faq-actions.d.ts +8 -8
- package/dist/features/faq/components/ContactCTA.js +3 -1
- package/dist/features/faq/components/FAQAccordion.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
- package/dist/features/filters/AsyncFacetSection.js +65 -0
- package/dist/features/filters/index.d.ts +2 -0
- package/dist/features/filters/index.js +1 -0
- package/dist/features/forms/Checkbox.js +2 -2
- package/dist/features/forms/Input.js +2 -2
- package/dist/features/forms/Radio.js +5 -5
- package/dist/features/forms/Select.js +2 -2
- package/dist/features/forms/Slider.js +2 -2
- package/dist/features/forms/Textarea.js +2 -2
- package/dist/features/homepage/api/[id]/route.js +4 -3
- package/dist/features/homepage/api/sections/[id]/route.js +12 -9
- package/dist/features/homepage/components/AdSlot.js +2 -1
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
- package/dist/features/homepage/components/BrandsSection.js +2 -2
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +119 -157
- package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
- package/dist/features/homepage/components/CustomCardsSection.js +8 -6
- package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
- package/dist/features/homepage/components/HeroBanner.js +5 -4
- package/dist/features/homepage/components/HeroCarousel.js +13 -26
- package/dist/features/homepage/components/HowItWorksSection.js +4 -2
- package/dist/features/homepage/components/SocialFeedSection.js +2 -2
- package/dist/features/homepage/components/SocialPostCard.js +3 -2
- package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
- package/dist/features/layout/AppLayoutShell.d.ts +8 -2
- package/dist/features/layout/AppLayoutShell.js +54 -78
- package/dist/features/layout/BottomActions.js +43 -48
- package/dist/features/live/components/LiveItemFilters.d.ts +12 -0
- package/dist/features/live/components/LiveItemFilters.js +24 -0
- package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
- package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
- package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
- package/dist/features/live/components/LiveItemsListView.js +43 -0
- package/dist/features/live/components/index.d.ts +6 -0
- package/dist/features/live/components/index.js +3 -0
- package/dist/features/media/MediaLightbox.js +8 -14
- package/dist/features/media/types/index.d.ts +2 -2
- package/dist/features/media/upload/CameraCapture.js +2 -2
- package/dist/features/media/upload/ImageUpload.js +4 -2
- package/dist/features/media/upload/MediaUploadField.js +24 -8
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/orders/actions/order-actions.js +4 -3
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
- package/dist/features/orders/components/OrderFilters.js +12 -9
- package/dist/features/orders/schemas/index.d.ts +6 -6
- package/dist/features/pre-orders/api/[id]/route.js +12 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +29 -22
- package/dist/features/pre-orders/components/PreOrderFilters.d.ts +7 -1
- package/dist/features/pre-orders/components/PreOrderFilters.js +3 -2
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
- package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
- package/dist/features/pre-orders/components/PreorderCard.js +2 -13
- package/dist/features/pre-orders/components/index.d.ts +1 -1
- package/dist/features/pre-orders/components/index.js +1 -1
- package/dist/features/pre-orders/schemas/index.d.ts +10 -10
- package/dist/features/products/api/[id]/route.js +9 -7
- package/dist/features/products/api/route.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +3 -3
- package/dist/features/products/components/AuctionsIndexListing.js +15 -51
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.d.ts +2 -0
- package/dist/features/products/components/CompareOverlay.js +3 -2
- package/dist/features/products/components/MakeOfferButton.js +20 -14
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
- package/dist/features/products/components/PrizeDrawCollage.js +54 -14
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
- package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
- package/dist/features/products/components/PrizeRevealModal.js +24 -14
- package/dist/features/products/components/ProductDetailPageView.js +2 -1
- package/dist/features/products/components/ProductFilters.d.ts +7 -1
- package/dist/features/products/components/ProductFilters.js +11 -8
- package/dist/features/products/components/ProductForm.js +18 -16
- package/dist/features/products/components/ProductGalleryClient.js +2 -1
- package/dist/features/products/components/ProductGrid.js +12 -15
- package/dist/features/products/components/ProductsIndexListing.js +16 -52
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/repository/products.repository.d.ts +4 -0
- package/dist/features/products/repository/products.repository.js +22 -3
- package/dist/features/products/schemas/firestore.d.ts +7 -1
- package/dist/features/products/schemas/index.d.ts +56 -56
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/products/types/index.d.ts +4 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/reviews/actions/review-actions.js +6 -5
- package/dist/features/reviews/api/[id]/route.js +4 -3
- package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
- package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +6 -6
- package/dist/features/scams/components/ScamProfileView.js +19 -10
- package/dist/features/scams/components/ScamRegistryView.js +2 -1
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/search/components/Search.js +56 -49
- package/dist/features/search/schemas/index.d.ts +5 -5
- package/dist/features/seller/actions/offer-actions.js +11 -9
- package/dist/features/seller/components/SellerAddressesView.js +6 -4
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +6 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
- package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
- package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
- package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
- package/dist/features/seller/components/SellerProductShell.js +75 -9
- package/dist/features/seller/components/SellerProductsView.js +10 -11
- package/dist/features/seller/components/SellerShippingView.js +3 -3
- package/dist/features/seller/components/SellerSidebar.js +10 -7
- package/dist/features/seller/components/SellerStorefrontView.js +3 -3
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/shell/FormShell.js +2 -1
- package/dist/features/shell/QuickFormDrawer.js +4 -3
- package/dist/features/shell/StepForm.js +4 -3
- package/dist/features/stores/actions/store-query-actions.js +4 -3
- package/dist/features/stores/components/StoreAboutView.js +2 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
- package/dist/features/stores/components/StoreDetailLayoutView.js +18 -4
- package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
- package/dist/features/stores/components/StoreProductsListing.js +16 -49
- package/dist/features/stores/components/StoresIndexListing.js +2 -2
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
- package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
- package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
- package/dist/index.d.ts +27 -3
- package/dist/index.js +1743 -1725
- package/dist/monitoring/server-logger.js +5 -9
- package/dist/next/api/apiHandler.js +56 -37
- package/dist/next/components/GlobalError.js +2 -1
- package/dist/next/routing/route-map.d.ts +41 -0
- package/dist/next/routing/route-map.js +17 -0
- package/dist/react/ErrorBoundary.js +2 -1
- package/dist/react/contexts/SessionContext.js +38 -28
- package/dist/react/hooks/useCamera.d.ts +1 -1
- package/dist/react/hooks/useCamera.js +8 -7
- package/dist/seed/products-auctions-seed-data.js +40 -40
- package/dist/seed/products-preorders-seed-data.js +16 -16
- package/dist/seed/products-prize-draws-seed-data.js +4 -4
- package/dist/seed/products-standard-seed-data.js +202 -202
- package/dist/seed/site-settings-seed-data.js +6 -0
- package/dist/server-entry.d.ts +3 -0
- package/dist/server-entry.js +3 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +15 -0
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +28 -7
- package/dist/ui/components/Button.d.ts +8 -1
- package/dist/ui/components/Button.js +47 -8
- package/dist/ui/components/CollageLightbox.d.ts +18 -0
- package/dist/ui/components/CollageLightbox.js +41 -0
- package/dist/ui/components/Dropdown.js +7 -6
- package/dist/ui/components/ImageLightbox.d.ts +7 -1
- package/dist/ui/components/ImageLightbox.js +15 -5
- package/dist/ui/components/PageLoader.js +4 -3
- package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
- package/dist/ui/components/PaginatedMultiSelect.js +141 -0
- package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
- package/dist/ui/components/Semantic.js +1 -1
- package/dist/ui/components/SideDrawer.js +17 -15
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/number.formatter.js +5 -13
- package/dist/utils/string.formatter.js +21 -18
- package/dist/validation/schemas.d.ts +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { productRepository } from "../../../repositories";
|
|
3
|
+
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
|
+
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
5
|
+
import { parseListingSearchParams } from "../../../utils/listing-params";
|
|
6
|
+
import { DigitalCodesIndexListing } from "./DigitalCodesIndexListing";
|
|
7
|
+
const DEFAULT_PAGE = 1;
|
|
8
|
+
const DEFAULT_PAGE_SIZE = 24;
|
|
9
|
+
const DEFAULT_SORT = "-createdAt";
|
|
10
|
+
function sp(params, key) {
|
|
11
|
+
const v = params[key];
|
|
12
|
+
return Array.isArray(v) ? v[0] ?? "" : v ?? "";
|
|
13
|
+
}
|
|
14
|
+
function buildDigitalCodeFilters(params) {
|
|
15
|
+
const parts = ["status==published", "listingType==digital-code"];
|
|
16
|
+
const minPrice = sp(params, "minPrice");
|
|
17
|
+
const maxPrice = sp(params, "maxPrice");
|
|
18
|
+
if (minPrice)
|
|
19
|
+
parts.push(`price>=${minPrice}`);
|
|
20
|
+
if (maxPrice)
|
|
21
|
+
parts.push(`price<=${maxPrice}`);
|
|
22
|
+
const deliveryMethod = sp(params, "deliveryMethod");
|
|
23
|
+
if (deliveryMethod)
|
|
24
|
+
parts.push(`digitalCodeDelivery==${deliveryMethod}`);
|
|
25
|
+
return parts.join(",");
|
|
26
|
+
}
|
|
27
|
+
export async function DigitalCodesListView({ searchParams = {} }) {
|
|
28
|
+
const std = parseListingSearchParams(searchParams);
|
|
29
|
+
const sort = std.sorts ?? DEFAULT_SORT;
|
|
30
|
+
const page = std.page ?? DEFAULT_PAGE;
|
|
31
|
+
const pageSize = std.pageSize ?? DEFAULT_PAGE_SIZE;
|
|
32
|
+
const filters = buildDigitalCodeFilters(searchParams);
|
|
33
|
+
const result = await productRepository
|
|
34
|
+
.list({ filters, sorts: sort, page, pageSize })
|
|
35
|
+
.catch(() => null);
|
|
36
|
+
return (_jsx(Main, { children: _jsx(Section, { className: "py-10", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "mb-8 text-3xl font-semibold text-zinc-900", children: "Digital Codes" }), _jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-6" }), _jsx(DigitalCodesIndexListing, { initialData: result ?? undefined }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] }) }) }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { DigitalCodesListView } from "./DigitalCodesListView";
|
|
2
|
+
export type { DigitalCodesListViewProps } from "./DigitalCodesListView";
|
|
3
|
+
export { DigitalCodesIndexListing } from "./DigitalCodesIndexListing";
|
|
4
|
+
export type { DigitalCodesIndexListingProps } from "./DigitalCodesIndexListing";
|
|
5
|
+
export { DigitalCodeFilters } from "./DigitalCodeFilters";
|
|
6
|
+
export type { DigitalCodeFiltersProps } from "./DigitalCodeFilters";
|
|
@@ -10,6 +10,7 @@ import { eventEntryRepository } from "../repository/event-entry.repository";
|
|
|
10
10
|
import { maskPublicEventEntry } from "../../../security";
|
|
11
11
|
import { ERROR_MESSAGES, AuthorizationError, ValidationError, NotFoundError, } from "../../../errors";
|
|
12
12
|
import { resolveDate } from "../../../utils";
|
|
13
|
+
const ERR_EVENT_NOT_FOUND = "Event not found";
|
|
13
14
|
import { coerceMediaField, getMediaUrl } from "../../../utils";
|
|
14
15
|
import { finalizeStagedMediaField, finalizeStagedMediaObject, finalizeStagedMediaObjectArray, } from "../../media/finalize";
|
|
15
16
|
// --- Admin: Create Event --------------------------------------------------
|
|
@@ -36,7 +37,7 @@ export async function createEvent(adminId, input) {
|
|
|
36
37
|
export async function updateEvent(adminId, id, input) {
|
|
37
38
|
const existing = await eventRepository.findById(id);
|
|
38
39
|
if (!existing)
|
|
39
|
-
throw new NotFoundError(
|
|
40
|
+
throw new NotFoundError(ERR_EVENT_NOT_FOUND);
|
|
40
41
|
const finalizedCoverUrl = await finalizeStagedMediaField(getMediaUrl(input.coverImage) ??
|
|
41
42
|
input.coverImageUrl);
|
|
42
43
|
const finalizedCoverImage = input.coverImageUrl === null
|
|
@@ -68,7 +69,7 @@ export async function updateEvent(adminId, id, input) {
|
|
|
68
69
|
export async function deleteEvent(adminId, id) {
|
|
69
70
|
const existing = await eventRepository.findById(id);
|
|
70
71
|
if (!existing)
|
|
71
|
-
throw new NotFoundError(
|
|
72
|
+
throw new NotFoundError(ERR_EVENT_NOT_FOUND);
|
|
72
73
|
await eventRepository.delete(id);
|
|
73
74
|
serverLogger.info("deleteEvent", { adminId, eventId: id });
|
|
74
75
|
}
|
|
@@ -76,7 +77,7 @@ export async function deleteEvent(adminId, id) {
|
|
|
76
77
|
export async function changeEventStatus(adminId, id, status) {
|
|
77
78
|
const existing = await eventRepository.findById(id);
|
|
78
79
|
if (!existing)
|
|
79
|
-
throw new NotFoundError(
|
|
80
|
+
throw new NotFoundError(ERR_EVENT_NOT_FOUND);
|
|
80
81
|
const updated = await eventRepository.changeStatus(id, status);
|
|
81
82
|
serverLogger.info("changeEventStatus", { adminId, eventId: id, status });
|
|
82
83
|
return updated;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
5
5
|
import { Alert, Button, Form, FormActions, Input, RichTextEditor, Select, StackedViewShell, Text, Toggle, } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
|
+
const CLS_PANEL_SM = "rounded-lg border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 p-3 space-y-2";
|
|
8
9
|
function toLocalDatetime(iso) {
|
|
9
10
|
if (!iso)
|
|
10
11
|
return "";
|
|
@@ -292,7 +293,7 @@ export function AdminEventEditorView({ eventId, onSaved, embedded, ...rest }) {
|
|
|
292
293
|
const formSection = (_jsxs(Form, { onSubmit: (e) => {
|
|
293
294
|
e.preventDefault();
|
|
294
295
|
saveMutation.mutate();
|
|
295
|
-
}, className: "space-y-6", children: [!eventId && (_jsx(Select, { label: "Event type", value: type, options: EVENT_TYPE_OPTIONS, onChange: (e) => setType(e.target.value) })), _jsx(Input, { label: "Title", value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Charizard Flash Sale 2026", required: true }), _jsxs(
|
|
296
|
+
}, className: "space-y-6", children: [!eventId && (_jsx(Select, { label: "Event type", value: type, options: EVENT_TYPE_OPTIONS, onChange: (e) => setType(e.target.value) })), _jsx(Input, { label: "Title", value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Charizard Flash Sale 2026", required: true }), _jsxs(_Fragment, { children: [_jsx("label", { className: "block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1", children: "Description" }), _jsx(RichTextEditor, { value: description, onChange: setDescription, minHeightClassName: "min-h-[120px]", placeholder: "Describe this event\u2026" })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [_jsx(Input, { label: "Starts at", type: "datetime-local", value: startsAt, onChange: (e) => setStartsAt(e.target.value), required: true }), _jsx(Input, { label: "Ends at", type: "datetime-local", value: endsAt, onChange: (e) => setEndsAt(e.target.value), required: true })] }), _jsx(Input, { label: "Cover image URL (optional)", value: coverImageUrl, onChange: (e) => setCoverImageUrl(e.target.value), placeholder: "https://\u2026" }), eventId && (_jsx(Select, { label: "Status", value: status, options: EVENT_STATUS_OPTIONS, onChange: (e) => setStatus(e.target.value) })), type === "sale" && (_jsxs("div", { className: CLS_PANEL_SM, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Sale configuration" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [_jsx(Input, { label: "Discount %", type: "number", value: discountPercent, onChange: (e) => setDiscountPercent(e.target.value), placeholder: "10" }), _jsx(Input, { label: "Banner text (optional)", value: saleBannerText, onChange: (e) => setSaleBannerText(e.target.value), placeholder: "Limited time \u2014 ends Sunday!" })] })] })), type === "offer" && (_jsxs("div", { className: CLS_PANEL_SM, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Offer configuration" }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [_jsx(Input, { label: "Coupon ID", value: couponId, onChange: (e) => setCouponId(e.target.value), placeholder: "Firestore coupon document ID", required: true }), _jsx(Input, { label: "Display code", value: displayCode, onChange: (e) => setDisplayCode(e.target.value), placeholder: "CHARIZARD25", required: true })] }), _jsx(Input, { label: "Banner text (optional)", value: offerBannerText, onChange: (e) => setOfferBannerText(e.target.value), placeholder: "Use CHARIZARD25 at checkout" })] })), type === "poll" && (_jsxs("div", { className: "rounded-xl border border-zinc-200 dark:border-slate-700 p-4 space-y-4", children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Poll configuration" }), _jsxs("div", { className: "space-y-2", children: [_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Options (minimum 2)" }), pollOptions.map((opt, idx) => (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex-1", children: _jsx(Input, { value: opt.label, onChange: (e) => updatePollOption(opt.id, e.target.value), placeholder: `Option ${idx + 1}` }) }), pollOptions.length > 2 && (_jsx("button", { type: "button", onClick: () => removePollOption(opt.id), className: "text-zinc-400 hover:text-red-500 transition-colors px-2 py-1 text-lg leading-none", "aria-label": "Remove option", children: "\u00D7" }))] }, opt.id))), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: addPollOption, children: "+ Add option" })] }), _jsx(Select, { label: "Results visibility", value: resultsVisibility, options: POLL_VISIBILITY_OPTIONS, onChange: (e) => setResultsVisibility(e.target.value) }), _jsxs("div", { className: "space-y-3", children: [_jsx(Toggle, { checked: allowMultiSelect, onChange: setAllowMultiSelect, label: "Allow multi-select" }), _jsx(Toggle, { checked: allowComment, onChange: setAllowComment, label: "Allow comment with vote" })] })] })), type === "survey" && (_jsxs("div", { className: CLS_PANEL_SM, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Survey configuration" }), _jsx(Input, { label: "Max entries per user", type: "number", value: maxEntriesPerUser, onChange: (e) => setMaxEntriesPerUser(e.target.value), placeholder: "1" }), _jsx(Toggle, { checked: requireLogin, onChange: setRequireLogin, label: "Require login to participate" }), _jsx(Toggle, { checked: hasLeaderboard, onChange: setHasLeaderboard, label: "Show leaderboard" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Form fields can be configured from the event detail page after saving." })] })), type === "feedback" && (_jsxs("div", { className: CLS_PANEL_SM, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Feedback configuration" }), _jsx(Toggle, { checked: anonymous, onChange: setAnonymous, label: "Allow anonymous submissions" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Form fields can be configured from the event detail page after saving." })] })), _jsxs("div", { className: "rounded-xl border border-zinc-200 dark:border-slate-700 p-4 space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-700 dark:text-zinc-300", children: "Raffle & spin wheel" }), type !== "raffle" && type !== "spin_wheel" && (_jsx(Toggle, { checked: hasRaffle, onChange: setHasRaffle, label: "Attach raffle" }))] }), (hasRaffle || type === "raffle" || type === "spin_wheel") && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [_jsx(Select, { label: "Raffle type", value: type === "spin_wheel" ? "spin_wheel" : raffleType, options: RAFFLE_TYPE_OPTIONS, onChange: (e) => setRaffleType(e.target.value), disabled: type === "spin_wheel" }), _jsx(Input, { label: "Top N (for top-N raffle types)", type: "number", value: raffleTopN, onChange: (e) => setRaffleTopN(e.target.value), placeholder: "10" })] }), _jsx(Input, { label: "Prize description", value: rafflePrize, onChange: (e) => setRafflePrize(e.target.value), placeholder: "\u20B92,000 store credit + exclusive Pikachu sticker" }), _jsx(Input, { label: "Coupon ID for winner (optional)", value: rafflePrizeCouponId, onChange: (e) => setRafflePrizeCouponId(e.target.value), placeholder: "coupon-vip-winner-2026" }), (raffleType === "spin_wheel" || type === "spin_wheel") && (_jsxs("div", { className: "rounded-lg border border-zinc-200 dark:border-slate-700 p-3 space-y-3", children: [_jsx(Text, { className: "text-xs font-medium text-zinc-600 dark:text-zinc-300", children: "Spin prizes (weighted random)" }), spinPrizes.length === 0 && (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "No spin prizes yet. Add at least one to enable spinning." })), spinPrizes.map((p) => (_jsxs("div", { className: "grid grid-cols-12 gap-2 items-end", children: [_jsx("div", { className: "col-span-5", children: _jsx(Input, { label: "Label", value: p.label, onChange: (e) => updateSpinPrize(p.id, { label: e.target.value }), placeholder: "\u20B9100 off" }) }), _jsx("div", { className: "col-span-3", children: _jsx(Input, { label: "Coupon ID", value: p.couponId ?? "", onChange: (e) => updateSpinPrize(p.id, {
|
|
296
297
|
couponId: e.target.value || undefined,
|
|
297
298
|
}) }) }), _jsx("div", { className: "col-span-2", children: _jsx(Input, { label: "Weight", type: "number", value: String(p.weight), onChange: (e) => updateSpinPrize(p.id, {
|
|
298
299
|
weight: Number(e.target.value) || 0,
|
|
@@ -6,7 +6,7 @@ import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
7
|
import { AdminViewCards } from "../../admin/components/AdminViewCards";
|
|
8
8
|
import { usePanelUrlSync } from "../../../react/hooks/use-panel-url-sync";
|
|
9
|
-
import { Button, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, SideDrawer } from "../../../ui";
|
|
9
|
+
import { BulkActionBar, Button, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, SideDrawer } from "../../../ui";
|
|
10
10
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
11
11
|
import { ADMIN_EVENT_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
12
12
|
import { toRecordArray, toRelativeDate, toStringValue, useAdminListingData, } from "../../admin/hooks/useAdminListingData";
|
|
@@ -102,5 +102,7 @@ export function AdminEventsView({ children, getRowHref, ...props }) {
|
|
|
102
102
|
if (hasChildren) {
|
|
103
103
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
104
104
|
}
|
|
105
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search events by title or type", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: openCreatePanel, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), "Add Event"] }) }),
|
|
105
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search events by title or type", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: openCreatePanel, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), "Add Event"] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
106
|
+
{ id: "delete", label: "Delete Selected", variant: "secondary", onClick: () => { selection.clearSelection(); } },
|
|
107
|
+
] }), 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) }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), view === "table" ? (_jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No events found", onRowClick: (row) => openEditPanel(row.id) })) : (_jsx(AdminViewCards, { rows: rows, view: view, isLoading: isLoading, emptyLabel: "No events found", onRowClick: undefined, selectedIdSet: selection.selectedIdSet, onToggleSelect: selection.toggle }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: [_jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, 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 })) })] }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] })), _jsx(SideDrawer, { isOpen: isCreateOpen || isEditOpen, onClose: closePanel, title: isCreateOpen ? "Add Event" : "Edit Event", mode: isCreateOpen ? "create" : "edit", children: (isCreateOpen || isEditOpen) && (_jsx(AdminEventEditorView, { eventId: editId ?? undefined, onSaved: closePanel, embedded: true })) })] }));
|
|
106
108
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { useAuth } from "../../../react/contexts/SessionContext";
|
|
5
5
|
import { ROUTES } from "../../../next";
|
|
6
|
-
import { LoginRequiredModal } from "../../../ui";
|
|
6
|
+
import { LoginRequiredModal, Text } from "../../../ui";
|
|
7
7
|
export function EventPollWidget({ eventId, pollConfig, eventStatus, totalEntries, entriesEndpoint, className = "", }) {
|
|
8
8
|
const { user } = useAuth();
|
|
9
9
|
const endpoint = entriesEndpoint ?? `/api/events/${eventId}/entries`;
|
|
@@ -56,13 +56,13 @@ export function EventPollWidget({ eventId, pollConfig, eventStatus, totalEntries
|
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
if (isEnded) {
|
|
59
|
-
return (_jsxs("div", { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 px-5 py-4 space-y-3 ${className}`, "data-section": "eventpollwidget-div-1", children: [_jsx(
|
|
59
|
+
return (_jsxs("div", { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 px-5 py-4 space-y-3 ${className}`, "data-section": "eventpollwidget-div-1", children: [_jsx(Text, { className: "text-sm font-medium text-zinc-500 dark:text-zinc-400", children: "This poll has closed." }), totalEntries !== undefined && (_jsxs(Text, { className: "text-sm text-zinc-400 dark:text-zinc-500", children: [totalEntries.toLocaleString(), " vote", totalEntries !== 1 ? "s" : "", " cast"] })), _jsx("div", { className: "space-y-2", "data-section": "eventpollwidget-div-2", children: pollConfig.options.map((opt) => (_jsx("div", { className: "rounded-lg border border-zinc-100 dark:border-zinc-800 px-4 py-2.5 text-sm text-zinc-600 dark:text-zinc-400", "data-section": "eventpollwidget-div-3", children: opt.label }, opt.id))) })] }));
|
|
60
60
|
}
|
|
61
61
|
if (pollConfig.requireLogin && !user) {
|
|
62
|
-
return (_jsxs("div", { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 px-6 py-8 text-center space-y-3 ${className}`, "data-section": "eventpollwidget-div-4", children: [_jsx(
|
|
62
|
+
return (_jsxs("div", { className: `rounded-xl border border-zinc-200 dark:border-zinc-700 px-6 py-8 text-center space-y-3 ${className}`, "data-section": "eventpollwidget-div-4", children: [_jsx(Text, { className: "font-semibold text-zinc-900 dark:text-zinc-100", children: "Login to vote" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "You need an account to participate in this poll." }), _jsx("a", { href: String(ROUTES.AUTH.LOGIN), className: "inline-block rounded-xl bg-primary px-6 py-2.5 text-sm font-semibold text-white hover:bg-primary-600", children: "Log In" })] }));
|
|
63
63
|
}
|
|
64
64
|
if (isSubmitted) {
|
|
65
|
-
return (_jsxs("div", { className: `rounded-xl border border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-900/20 px-6 py-8 text-center space-y-2 ${className}`, "data-section": "eventpollwidget-div-5", children: [_jsx(
|
|
65
|
+
return (_jsxs("div", { className: `rounded-xl border border-green-200 dark:border-green-800 bg-green-50 dark:bg-green-900/20 px-6 py-8 text-center space-y-2 ${className}`, "data-section": "eventpollwidget-div-5", children: [_jsx(Text, { className: "font-semibold text-green-700 dark:text-green-300", children: "Vote recorded!" }), _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Thanks for participating." })] }));
|
|
66
66
|
}
|
|
67
|
-
return (_jsxs("div", { className: `space-y-4 ${className}`, "data-section": "eventpollwidget-div-6", children: [_jsx(LoginRequiredModal, { isOpen: showLoginModal, onClose: () => setShowLoginModal(false), message: "You need to be signed in to vote in this poll. Please log in or create an account to continue." }), _jsx(
|
|
67
|
+
return (_jsxs("div", { className: `space-y-4 ${className}`, "data-section": "eventpollwidget-div-6", children: [_jsx(LoginRequiredModal, { isOpen: showLoginModal, onClose: () => setShowLoginModal(false), message: "You need to be signed in to vote in this poll. Please log in or create an account to continue." }), _jsx(Text, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-200", children: isMulti ? "Select all that apply:" : "Choose one:" }), _jsx("div", { className: "space-y-2", "data-section": "eventpollwidget-div-7", children: pollConfig.options.map((opt) => (_jsxs("label", { className: "flex items-center gap-3 cursor-pointer rounded-lg border border-zinc-200 dark:border-zinc-700 px-4 py-3 hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors", children: [_jsx("input", { type: isMulti ? "checkbox" : "radio", name: `poll-${eventId}`, value: opt.id, checked: selectedVotes.includes(opt.id), onChange: () => toggleVote(opt.id), className: "accent-primary" }), _jsx("span", { className: "text-sm text-zinc-700 dark:text-zinc-300", children: opt.label })] }, opt.id))) }), pollConfig.allowComment && (_jsx("textarea", { value: comment, onChange: (e) => setComment(e.target.value), placeholder: "Add a comment (optional)", rows: 3, className: "w-full rounded-lg border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-800 dark:text-zinc-200 placeholder:text-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary" })), error && _jsx(Text, { className: "text-sm text-red-500", children: error }), _jsx("button", { type: "button", onClick: handleSubmit, disabled: isLoading || selectedVotes.length === 0, className: "w-full rounded-xl bg-primary px-6 py-3 text-sm font-semibold text-white hover:bg-primary-600 disabled:opacity-60", children: isLoading ? "Submitting…" : "Submit Vote" })] }));
|
|
68
68
|
}
|
|
@@ -4,7 +4,7 @@ import { useState, useCallback, useMemo } from "react";
|
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { useEvents } from "../hooks/useEvents";
|
|
7
|
-
import { Pagination,
|
|
7
|
+
import { ListingToolbar, Pagination, Text } from "../../../ui";
|
|
8
8
|
import { EventCard } from "./EventCard";
|
|
9
9
|
import { EventFilters, EVENT_PUBLIC_SORT_OPTIONS } from "./EventFilters";
|
|
10
10
|
import { EVENT_FIELDS } from "../../../constants/field-names";
|
|
@@ -113,5 +113,5 @@ export function EventsIndexListing({ initialData }) {
|
|
|
113
113
|
const commitSearch = useCallback(() => {
|
|
114
114
|
table.set(TABLE_KEYS.QUERY, searchInput.trim());
|
|
115
115
|
}, [searchInput, table]);
|
|
116
|
-
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(
|
|
116
|
+
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))) })) }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(EventFilters, { table: pendingTable, variant: "public" }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] }))] }));
|
|
117
117
|
}
|
|
@@ -6,6 +6,7 @@ declare class EventEntryRepository extends BaseRepository<EventEntryDocument> {
|
|
|
6
6
|
constructor();
|
|
7
7
|
protected mapDoc<D = EventEntryDocument>(snap: import("../../../providers/db-firebase").DocumentSnapshot): D;
|
|
8
8
|
listForEvent(eventId: string, model: SieveModel): Promise<FirebaseSieveResult<EventEntryDocument>>;
|
|
9
|
+
listForUser(userId: string, model: SieveModel): Promise<FirebaseSieveResult<EventEntryDocument>>;
|
|
9
10
|
hasUserEntered(eventId: string, userId: string): Promise<boolean>;
|
|
10
11
|
countUserEntries(eventId: string, userId: string): Promise<number>;
|
|
11
12
|
getLeaderboard(eventId: string, limit?: number): Promise<EventEntryDocument[]>;
|
|
@@ -18,6 +18,11 @@ class EventEntryRepository extends BaseRepository {
|
|
|
18
18
|
baseQuery: this.getCollection().where(EVENT_ENTRY_FIELDS.EVENT_ID, "==", eventId),
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
async listForUser(userId, model) {
|
|
22
|
+
return this.sieveQuery(model, EventEntryRepository.SIEVE_FIELDS, {
|
|
23
|
+
baseQuery: this.getCollection().where(EVENT_ENTRY_FIELDS.USER_ID, "==", userId),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
21
26
|
async hasUserEntered(eventId, userId) {
|
|
22
27
|
try {
|
|
23
28
|
const snapshot = await this.getCollection()
|
|
@@ -90,14 +90,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
90
90
|
}, "strip", z.ZodTypeAny, {
|
|
91
91
|
type: "video" | "image" | "file";
|
|
92
92
|
url: string;
|
|
93
|
-
source?: "
|
|
93
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
94
94
|
alt?: string | undefined;
|
|
95
95
|
thumbnailUrl?: string | undefined;
|
|
96
96
|
youtubeId?: string | undefined;
|
|
97
97
|
}, {
|
|
98
98
|
type: "video" | "image" | "file";
|
|
99
99
|
url: string;
|
|
100
|
-
source?: "
|
|
100
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
101
101
|
alt?: string | undefined;
|
|
102
102
|
thumbnailUrl?: string | undefined;
|
|
103
103
|
youtubeId?: string | undefined;
|
|
@@ -107,7 +107,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
107
107
|
}, string>]>>>, {
|
|
108
108
|
type: "video" | "image" | "file";
|
|
109
109
|
url: string;
|
|
110
|
-
source?: "
|
|
110
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
111
111
|
alt?: string | undefined;
|
|
112
112
|
thumbnailUrl?: string | undefined;
|
|
113
113
|
youtubeId?: string | undefined;
|
|
@@ -117,7 +117,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
117
117
|
} | null, string | {
|
|
118
118
|
type: "video" | "image" | "file";
|
|
119
119
|
url: string;
|
|
120
|
-
source?: "
|
|
120
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
121
121
|
alt?: string | undefined;
|
|
122
122
|
thumbnailUrl?: string | undefined;
|
|
123
123
|
youtubeId?: string | undefined;
|
|
@@ -133,14 +133,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
133
133
|
}, "strip", z.ZodTypeAny, {
|
|
134
134
|
type: "video" | "image" | "file";
|
|
135
135
|
url: string;
|
|
136
|
-
source?: "
|
|
136
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
137
137
|
alt?: string | undefined;
|
|
138
138
|
thumbnailUrl?: string | undefined;
|
|
139
139
|
youtubeId?: string | undefined;
|
|
140
140
|
}, {
|
|
141
141
|
type: "video" | "image" | "file";
|
|
142
142
|
url: string;
|
|
143
|
-
source?: "
|
|
143
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
144
144
|
alt?: string | undefined;
|
|
145
145
|
thumbnailUrl?: string | undefined;
|
|
146
146
|
youtubeId?: string | undefined;
|
|
@@ -155,14 +155,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
155
155
|
}, "strip", z.ZodTypeAny, {
|
|
156
156
|
type: "video" | "image" | "file";
|
|
157
157
|
url: string;
|
|
158
|
-
source?: "
|
|
158
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
159
159
|
alt?: string | undefined;
|
|
160
160
|
thumbnailUrl?: string | undefined;
|
|
161
161
|
youtubeId?: string | undefined;
|
|
162
162
|
}, {
|
|
163
163
|
type: "video" | "image" | "file";
|
|
164
164
|
url: string;
|
|
165
|
-
source?: "
|
|
165
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
166
166
|
alt?: string | undefined;
|
|
167
167
|
thumbnailUrl?: string | undefined;
|
|
168
168
|
youtubeId?: string | undefined;
|
|
@@ -177,14 +177,14 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
177
177
|
}, "strip", z.ZodTypeAny, {
|
|
178
178
|
type: "video" | "image" | "file";
|
|
179
179
|
url: string;
|
|
180
|
-
source?: "
|
|
180
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
181
181
|
alt?: string | undefined;
|
|
182
182
|
thumbnailUrl?: string | undefined;
|
|
183
183
|
youtubeId?: string | undefined;
|
|
184
184
|
}, {
|
|
185
185
|
type: "video" | "image" | "file";
|
|
186
186
|
url: string;
|
|
187
|
-
source?: "
|
|
187
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
188
188
|
alt?: string | undefined;
|
|
189
189
|
thumbnailUrl?: string | undefined;
|
|
190
190
|
youtubeId?: string | undefined;
|
|
@@ -269,17 +269,17 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
269
269
|
status: "draft" | "ended" | "active" | "paused";
|
|
270
270
|
type: "offer" | "feedback" | "sale" | "poll" | "survey";
|
|
271
271
|
title: string;
|
|
272
|
+
description: string;
|
|
272
273
|
stats: {
|
|
273
274
|
totalEntries: number;
|
|
274
275
|
approvedEntries: number;
|
|
275
276
|
flaggedEntries: number;
|
|
276
277
|
};
|
|
277
|
-
description: string;
|
|
278
278
|
createdBy: string;
|
|
279
279
|
coverImage: {
|
|
280
280
|
type: "video" | "image" | "file";
|
|
281
281
|
url: string;
|
|
282
|
-
source?: "
|
|
282
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
283
283
|
alt?: string | undefined;
|
|
284
284
|
thumbnailUrl?: string | undefined;
|
|
285
285
|
youtubeId?: string | undefined;
|
|
@@ -292,7 +292,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
292
292
|
additionalImages: {
|
|
293
293
|
type: "video" | "image" | "file";
|
|
294
294
|
url: string;
|
|
295
|
-
source?: "
|
|
295
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
296
296
|
alt?: string | undefined;
|
|
297
297
|
thumbnailUrl?: string | undefined;
|
|
298
298
|
youtubeId?: string | undefined;
|
|
@@ -300,7 +300,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
300
300
|
eventImages: {
|
|
301
301
|
type: "video" | "image" | "file";
|
|
302
302
|
url: string;
|
|
303
|
-
source?: "
|
|
303
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
304
304
|
alt?: string | undefined;
|
|
305
305
|
thumbnailUrl?: string | undefined;
|
|
306
306
|
youtubeId?: string | undefined;
|
|
@@ -308,7 +308,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
308
308
|
winnerImages: {
|
|
309
309
|
type: "video" | "image" | "file";
|
|
310
310
|
url: string;
|
|
311
|
-
source?: "
|
|
311
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
312
312
|
alt?: string | undefined;
|
|
313
313
|
thumbnailUrl?: string | undefined;
|
|
314
314
|
youtubeId?: string | undefined;
|
|
@@ -340,19 +340,19 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
340
340
|
status: "draft" | "ended" | "active" | "paused";
|
|
341
341
|
type: "offer" | "feedback" | "sale" | "poll" | "survey";
|
|
342
342
|
title: string;
|
|
343
|
+
description: string;
|
|
343
344
|
stats: {
|
|
344
345
|
totalEntries: number;
|
|
345
346
|
approvedEntries: number;
|
|
346
347
|
flaggedEntries: number;
|
|
347
348
|
};
|
|
348
|
-
description: string;
|
|
349
349
|
createdBy: string;
|
|
350
350
|
startsAt: string;
|
|
351
351
|
endsAt: string;
|
|
352
352
|
coverImage?: string | {
|
|
353
353
|
type: "video" | "image" | "file";
|
|
354
354
|
url: string;
|
|
355
|
-
source?: "
|
|
355
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
356
356
|
alt?: string | undefined;
|
|
357
357
|
thumbnailUrl?: string | undefined;
|
|
358
358
|
youtubeId?: string | undefined;
|
|
@@ -360,7 +360,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
360
360
|
additionalImages?: {
|
|
361
361
|
type: "video" | "image" | "file";
|
|
362
362
|
url: string;
|
|
363
|
-
source?: "
|
|
363
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
364
364
|
alt?: string | undefined;
|
|
365
365
|
thumbnailUrl?: string | undefined;
|
|
366
366
|
youtubeId?: string | undefined;
|
|
@@ -369,7 +369,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
369
369
|
eventImages?: {
|
|
370
370
|
type: "video" | "image" | "file";
|
|
371
371
|
url: string;
|
|
372
|
-
source?: "
|
|
372
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
373
373
|
alt?: string | undefined;
|
|
374
374
|
thumbnailUrl?: string | undefined;
|
|
375
375
|
youtubeId?: string | undefined;
|
|
@@ -377,7 +377,7 @@ export declare const eventItemSchema: z.ZodObject<{
|
|
|
377
377
|
winnerImages?: {
|
|
378
378
|
type: "video" | "image" | "file";
|
|
379
379
|
url: string;
|
|
380
|
-
source?: "
|
|
380
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
381
381
|
alt?: string | undefined;
|
|
382
382
|
thumbnailUrl?: string | undefined;
|
|
383
383
|
youtubeId?: string | undefined;
|
|
@@ -26,10 +26,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
26
26
|
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
27
27
|
template: z.ZodOptional<z.ZodString>;
|
|
28
28
|
}, "strip", z.ZodTypeAny, {
|
|
29
|
+
category: string;
|
|
29
30
|
order: number;
|
|
30
31
|
priority: number;
|
|
31
32
|
isActive: boolean;
|
|
32
|
-
category: string;
|
|
33
33
|
question: string;
|
|
34
34
|
showInFooter: boolean;
|
|
35
35
|
showOnHomepage: boolean;
|
|
@@ -51,10 +51,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
51
51
|
format?: "html" | "plain" | "markdown" | undefined;
|
|
52
52
|
};
|
|
53
53
|
template?: string | undefined;
|
|
54
|
+
tags?: string[] | undefined;
|
|
54
55
|
order?: number | undefined;
|
|
55
56
|
priority?: number | undefined;
|
|
56
57
|
isActive?: boolean | undefined;
|
|
57
|
-
tags?: string[] | undefined;
|
|
58
58
|
variables?: Record<string, string> | undefined;
|
|
59
59
|
showInFooter?: boolean | undefined;
|
|
60
60
|
showOnHomepage?: boolean | undefined;
|
|
@@ -62,10 +62,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
62
62
|
relatedFAQs?: string[] | undefined;
|
|
63
63
|
useSiteSettings?: boolean | undefined;
|
|
64
64
|
}>, {
|
|
65
|
+
category: string;
|
|
65
66
|
order: number;
|
|
66
67
|
priority: number;
|
|
67
68
|
isActive: boolean;
|
|
68
|
-
category: string;
|
|
69
69
|
question: string;
|
|
70
70
|
showInFooter: boolean;
|
|
71
71
|
showOnHomepage: boolean;
|
|
@@ -87,10 +87,10 @@ export declare const faqCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
|
87
87
|
format?: "html" | "plain" | "markdown" | undefined;
|
|
88
88
|
};
|
|
89
89
|
template?: string | undefined;
|
|
90
|
+
tags?: string[] | undefined;
|
|
90
91
|
order?: number | undefined;
|
|
91
92
|
priority?: number | undefined;
|
|
92
93
|
isActive?: boolean | undefined;
|
|
93
|
-
tags?: string[] | undefined;
|
|
94
94
|
variables?: Record<string, string> | undefined;
|
|
95
95
|
showInFooter?: boolean | undefined;
|
|
96
96
|
showOnHomepage?: boolean | undefined;
|
|
@@ -124,11 +124,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
|
|
|
124
124
|
template: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
125
125
|
}, "strip", z.ZodTypeAny, {
|
|
126
126
|
template?: string | undefined;
|
|
127
|
+
category?: string | undefined;
|
|
128
|
+
tags?: string[] | undefined;
|
|
127
129
|
order?: number | undefined;
|
|
128
130
|
priority?: number | undefined;
|
|
129
131
|
isActive?: boolean | undefined;
|
|
130
|
-
category?: string | undefined;
|
|
131
|
-
tags?: string[] | undefined;
|
|
132
132
|
variables?: Record<string, string> | undefined;
|
|
133
133
|
question?: string | undefined;
|
|
134
134
|
showInFooter?: boolean | undefined;
|
|
@@ -142,11 +142,11 @@ export declare const faqUpdateSchema: z.ZodObject<{
|
|
|
142
142
|
useSiteSettings?: boolean | undefined;
|
|
143
143
|
}, {
|
|
144
144
|
template?: string | undefined;
|
|
145
|
+
category?: string | undefined;
|
|
146
|
+
tags?: string[] | undefined;
|
|
145
147
|
order?: number | undefined;
|
|
146
148
|
priority?: number | undefined;
|
|
147
149
|
isActive?: boolean | undefined;
|
|
148
|
-
category?: string | undefined;
|
|
149
|
-
tags?: string[] | undefined;
|
|
150
150
|
variables?: Record<string, string> | undefined;
|
|
151
151
|
question?: string | undefined;
|
|
152
152
|
showInFooter?: boolean | undefined;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Card, Div, Heading, Span, Text, TextLink } from "../../../ui";
|
|
3
|
+
const CLS_CONTACT_CARD = "flex items-center gap-3 rounded-lg border border-zinc-100 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800 px-4 py-3 hover:border-primary/40 transition-colors";
|
|
4
|
+
const CLS_CONTACT_LABEL = "text-xs text-zinc-500 dark:text-zinc-400";
|
|
3
5
|
export function ContactCTA({ email, phone, contactHref, labels, }) {
|
|
4
|
-
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className:
|
|
6
|
+
return (_jsxs(Card, { variant: "outlined", padding: "lg", className: "text-center dark:bg-slate-800/60", children: [_jsx(Div, { className: "mb-6 flex justify-center", children: _jsx(Div, { className: "rounded-full bg-primary/10 p-8", children: _jsx("svg", { className: "h-12 w-12 text-primary", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" }) }) }) }), _jsx(Heading, { level: 2, className: "mb-3 text-2xl font-semibold", children: labels?.title ?? "Need More Help?" }), _jsx(Text, { className: "mx-auto mb-6 max-w-2xl text-zinc-600 dark:text-zinc-300", children: labels?.description ?? "Our support team is here to help you." }), _jsxs(Div, { className: "mb-8 grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(TextLink, { href: `mailto:${email}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.emailUs ?? "Email Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: email })] }), _jsxs(TextLink, { href: `tel:${phone}`, variant: "none", className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.callUs ?? "Call Us" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: phone })] }), _jsxs(TextLink, { href: contactHref, className: CLS_CONTACT_CARD, children: [_jsx(Text, { className: CLS_CONTACT_LABEL, children: labels?.contactForm ?? "Contact Form" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: labels?.submitRequest ?? "Submit a request" })] })] }), _jsxs(TextLink, { href: contactHref, className: "inline-flex items-center gap-2 rounded-xl bg-primary p-6 font-medium text-white transition-colors hover:bg-primary/90", children: [_jsx(Span, { children: labels?.contactTeam ?? "Contact Team" }), _jsx("svg", { className: "h-5 w-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })] })] }));
|
|
5
7
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, Div, RichText, Row, Span, Text } from "../../../ui";
|
|
5
5
|
function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, }) {
|
|
6
|
-
return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
6
|
+
return (_jsxs(Div, { className: "border-b border-neutral-200 dark:border-slate-700 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, className: "flex w-full items-center justify-between gap-4 py-4 text-left text-sm font-medium text-neutral-900 dark:text-zinc-100 transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { className: "pb-4 text-sm text-neutral-600 dark:text-zinc-300", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "rounded-md bg-neutral-100 dark:bg-slate-700 px-2 py-1 text-xs text-neutral-600 dark:text-zinc-300", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: faq.answer.text, className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: faq.answer.text })), renderExpandedFooter?.(faq)] }))] }));
|
|
7
7
|
}
|
|
8
8
|
export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, }) {
|
|
9
9
|
const [openId, setOpenId] = useState(null);
|