@mohasinac/appkit 3.4.8 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +1 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +1 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +1 -1
- package/dist/_internal/client/features/filters/filter-load-options.js +10 -9
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +11 -4
- package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
- package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +10 -3
- package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +2 -2
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +3 -1
- package/dist/_internal/server/features/checkout/actions.d.ts +16 -0
- package/dist/_internal/server/features/checkout/actions.js +149 -35
- package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +31 -0
- package/dist/_internal/server/features/checkout/bundle-expansion.js +41 -0
- package/dist/_internal/server/features/lottery/actions.js +14 -4
- package/dist/_internal/server/features/maintenance/analyze.js +4 -2
- package/dist/_internal/server/features/orders/actions.js +9 -0
- package/dist/_internal/server/features/orders/adapters.js +19 -0
- package/dist/_internal/server/features/seo/robots.js +1 -1
- package/dist/_internal/server/functions/firestore.d.ts +47 -1
- package/dist/_internal/server/functions/firestore.js +56 -1
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +9 -1
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.d.ts +10 -0
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.js +49 -0
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +32 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +26 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +181 -0
- package/dist/_internal/server/jobs/core/index.d.ts +4 -1
- package/dist/_internal/server/jobs/core/index.js +4 -1
- package/dist/_internal/server/jobs/core/jobRunners.d.ts +28 -0
- package/dist/_internal/server/jobs/core/jobRunners.js +37 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +15 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +38 -0
- package/dist/_internal/server/jobs/core/onJobCreated.d.ts +22 -0
- package/dist/_internal/server/jobs/core/onJobCreated.js +59 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.d.ts +6 -1
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -2
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +6 -0
- package/dist/_internal/server/jobs/handlers/index.js +8 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.d.ts +12 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.js +20 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.js +9 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +25 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +71 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.d.ts +14 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.js +23 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +17 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +26 -0
- package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +3 -1
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +136 -0
- package/dist/_internal/shared/features/blog/schema.d.ts +8 -8
- package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +8 -8
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/_internal/shared/features/products/schema.d.ts +8 -8
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +4 -4
- package/dist/client/api/useFeatureFlags.d.ts +22 -0
- package/dist/client/api/useFeatureFlags.js +27 -0
- package/dist/client/observability/reportClientError.js +3 -2
- package/dist/client.d.ts +4 -2
- package/dist/client.js +2 -1
- package/dist/configs/next.js +1 -0
- package/dist/constants/api-endpoints.d.ts +279 -3
- package/dist/constants/api-endpoints.js +130 -2
- package/dist/core/hooks/useSyncManager.js +5 -4
- package/dist/errors/conflict-error.d.ts +4 -0
- package/dist/errors/conflict-error.js +6 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/features/about/components/FeesView.js +2 -2
- package/dist/features/about/components/HelpPageView.js +2 -2
- package/dist/features/about/components/HowAuctionsWorkView.js +2 -2
- package/dist/features/about/components/HowCheckoutWorksView.js +2 -2
- package/dist/features/about/components/HowEmiWorksView.js +2 -2
- package/dist/features/about/components/HowOffersWorkView.js +3 -3
- package/dist/features/about/components/HowOrdersWorkView.js +3 -3
- package/dist/features/about/components/HowPayoutsWorkView.js +2 -2
- package/dist/features/about/components/HowPreOrdersWorkView.js +2 -2
- package/dist/features/about/components/HowReviewsWorkView.js +2 -2
- package/dist/features/about/components/PublicProfileView.d.ts +8 -1
- package/dist/features/about/components/PublicProfileView.js +11 -9
- package/dist/features/about/components/SecurityPrivacyView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +2 -2
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/NotificationBell.js +5 -5
- package/dist/features/account/components/NotificationPreferencesPanel.js +5 -2
- package/dist/features/account/components/UserOffersPanel.js +5 -4
- package/dist/features/account/components/UserSidebar.js +2 -2
- package/dist/features/account/components/UserSupportView.js +3 -3
- package/dist/features/account/schemas/index.d.ts +12 -12
- package/dist/features/addresses/schemas/index.d.ts +6 -6
- package/dist/features/admin/components/AdminAdEditorView.js +3 -3
- package/dist/features/admin/components/AdminAddressEditorView.js +3 -3
- package/dist/features/admin/components/AdminAdsView.js +3 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBlogView.js +12 -15
- package/dist/features/admin/components/AdminBrandEditorView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +12 -13
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -4
- package/dist/features/admin/components/AdminBundlesView.js +32 -23
- package/dist/features/admin/components/AdminCarouselEditorView.js +5 -5
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCatalogGuideView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +12 -13
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminContactEditorView.js +2 -2
- package/dist/features/admin/components/AdminCouponEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +7 -2
- package/dist/features/admin/components/AdminCouponsView.js +32 -27
- package/dist/features/admin/components/AdminEmployeeEditorView.js +3 -3
- package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +20 -20
- package/dist/features/admin/components/AdminFeatureEditorView.js +5 -5
- package/dist/features/admin/components/AdminFeaturesView.js +9 -10
- package/dist/features/admin/components/AdminFilterBar.js +1 -1
- package/dist/features/admin/components/AdminFulfillmentView.js +4 -4
- package/dist/features/admin/components/AdminGuideHubView.js +2 -2
- package/dist/features/admin/components/AdminMediaView.js +3 -2
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +3 -3
- package/dist/features/admin/components/AdminOrdersView.js +21 -30
- package/dist/features/admin/components/AdminPageHeader.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +8 -8
- package/dist/features/admin/components/AdminPrizeDrawsView.js +8 -9
- package/dist/features/admin/components/AdminProductEditorView.d.ts +9 -1
- package/dist/features/admin/components/AdminProductEditorView.js +7 -4
- package/dist/features/admin/components/AdminProductsView.js +30 -41
- package/dist/features/admin/components/AdminReviewsView.js +14 -17
- package/dist/features/admin/components/AdminScammerEditorView.js +5 -5
- package/dist/features/admin/components/AdminSectionsView.js +3 -3
- package/dist/features/admin/components/AdminSessionsView.js +8 -10
- package/dist/features/admin/components/AdminSidebar.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +10 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +4 -5
- package/dist/features/admin/components/AdminStoresView.js +18 -13
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamView.js +9 -5
- package/dist/features/admin/components/AdminUsersView.js +19 -15
- package/dist/features/admin/components/AdminViewCards.js +5 -5
- package/dist/features/admin/components/DashboardStats.js +1 -1
- package/dist/features/admin/components/DataListingView.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/DrawerFormFooter.js +1 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +2 -2
- package/dist/features/admin/components/analytics/AdminStatCard.js +1 -1
- package/dist/features/admin/hooks/useAdminListing.d.ts +3 -2
- package/dist/features/admin/hooks/useAdminListing.js +8 -2
- package/dist/features/admin/permission-map.js +2 -0
- package/dist/features/admin/schemas/firestore.d.ts +7 -0
- package/dist/features/admin/schemas/firestore.js +4 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +4 -4
- package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
- package/dist/features/auctions/schemas/index.d.ts +16 -16
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +2 -0
- package/dist/features/auth/schemas/index.d.ts +6 -6
- package/dist/features/before-after/schemas/index.d.ts +3 -3
- package/dist/features/blog/actions/blog-actions.d.ts +32 -32
- package/dist/features/blog/components/BlogFeaturedCard.js +2 -2
- package/dist/features/blog/components/BlogIndexListing.js +2 -2
- package/dist/features/blog/components/BlogListView.js +4 -4
- package/dist/features/blog/components/BlogPostView.js +4 -4
- package/dist/features/blog/schemas/index.d.ts +77 -77
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/catalogue/actions/approve-catalogue-listing.d.ts +12 -0
- package/dist/features/catalogue/actions/approve-catalogue-listing.js +50 -0
- package/dist/features/catalogue/actions/list-from-catalogue.d.ts +17 -0
- package/dist/features/catalogue/actions/list-from-catalogue.js +50 -0
- package/dist/features/catalogue/actions/submit-for-approval.d.ts +8 -0
- package/dist/features/catalogue/actions/submit-for-approval.js +30 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.d.ts +2 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +53 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +7 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +79 -0
- package/dist/features/catalogue/components/PublicCatalogueView.d.ts +5 -0
- package/dist/features/catalogue/components/PublicCatalogueView.js +22 -0
- package/dist/features/catalogue/components/UserCatalogueView.d.ts +12 -0
- package/dist/features/catalogue/components/UserCatalogueView.js +51 -0
- package/dist/features/catalogue/index.d.ts +12 -0
- package/dist/features/catalogue/index.js +9 -0
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +39 -0
- package/dist/features/catalogue/repository/catalogue.repository.js +68 -0
- package/dist/features/catalogue/schemas/firestore.d.ts +47 -0
- package/dist/features/catalogue/schemas/firestore.js +22 -0
- package/dist/features/catalogue/schemas/index.d.ts +2 -0
- package/dist/features/catalogue/schemas/index.js +2 -0
- package/dist/features/catalogue/schemas/validation.d.ts +71 -0
- package/dist/features/catalogue/schemas/validation.js +25 -0
- package/dist/features/catalogue/utils/freshness.d.ts +10 -0
- package/dist/features/catalogue/utils/freshness.js +15 -0
- package/dist/features/catalogue/utils/product-from-item.d.ts +15 -0
- package/dist/features/catalogue/utils/product-from-item.js +34 -0
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/BrandDetailTabs.js +2 -2
- package/dist/features/categories/components/BundleCollage.js +2 -2
- package/dist/features/categories/components/BundleItemsPicker.js +3 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +8 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +10 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
- package/dist/features/categories/components/CategoryGrid.js +3 -3
- package/dist/features/categories/components/CategoryProductsListing.js +1 -1
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +1 -1
- package/dist/features/categories/components/CategoryTableColumns.js +1 -1
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/hooks/useCategories.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +32 -32
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/consultation/components/ConsultationForm.js +1 -1
- package/dist/features/consultation/schemas/index.d.ts +10 -10
- package/dist/features/contact/components/ContactForm.js +4 -4
- package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +2 -1
- package/dist/features/copilot/components/AdminCopilotView.js +5 -4
- package/dist/features/corporate/schemas/index.d.ts +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +3 -3
- package/dist/features/events/components/AdminEventEditorView.js +4 -4
- package/dist/features/events/components/AdminEventEntriesView.js +2 -2
- package/dist/features/events/components/AdminEventsView.js +8 -8
- package/dist/features/events/components/EventBanner.js +1 -1
- package/dist/features/events/components/EventCard.js +3 -3
- package/dist/features/events/components/EventLeaderboard.js +1 -1
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +5 -5
- package/dist/features/events/components/EventRafflesSection.js +1 -1
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/events/components/EventsIndexListing.js +4 -2
- package/dist/features/events/components/EventsListView.js +2 -2
- package/dist/features/events/components/SpinWheelView.js +11 -5
- package/dist/features/events/schemas/index.d.ts +100 -100
- package/dist/features/faq/actions/faq-actions.d.ts +6 -6
- package/dist/features/faq/components/ContactCTA.js +3 -3
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +3 -3
- package/dist/features/faq/schemas/index.d.ts +12 -12
- package/dist/features/filters/AsyncFacetSection.js +4 -4
- package/dist/features/filters/FilterFacetSection.js +8 -8
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +2 -8
- package/dist/features/forms/Input.js +2 -1
- package/dist/features/forms/Radio.js +3 -3
- package/dist/features/forms/Select.d.ts +1 -1
- package/dist/features/forms/Select.js +3 -2
- package/dist/features/forms/Slider.js +5 -11
- package/dist/features/forms/Textarea.js +2 -1
- package/dist/features/grouped/schemas/index.d.ts +6 -6
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +4 -4
- package/dist/features/homepage/components/AnnouncementBar.js +3 -3
- package/dist/features/homepage/components/BeforeAfterCard.js +1 -1
- package/dist/features/homepage/components/BrandsSection.js +9 -9
- package/dist/features/homepage/components/CTABannerSection.js +1 -1
- package/dist/features/homepage/components/CharacterHotspot.js +4 -4
- package/dist/features/homepage/components/CharacterHotspotForm.js +15 -13
- package/dist/features/homepage/components/CollectionCardsSection.js +1 -1
- package/dist/features/homepage/components/CustomCardsSection.js +6 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +2 -2
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -3
- package/dist/features/homepage/components/FeaturedResultsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +6 -6
- package/dist/features/homepage/components/HeroBanner.js +1 -1
- package/dist/features/homepage/components/HeroCarousel.js +5 -4
- package/dist/features/homepage/components/HeroSection.js +1 -7
- package/dist/features/homepage/components/HomepageSkeleton.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/NewsletterBanner.js +2 -2
- package/dist/features/homepage/components/NewsletterSection.js +1 -1
- package/dist/features/homepage/components/PromoGrid.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +6 -6
- package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -10
- package/dist/features/homepage/components/SiteFeaturesSection.js +2 -2
- package/dist/features/homepage/components/SocialFeedSection.js +5 -5
- package/dist/features/homepage/components/SocialPostCard.js +1 -1
- package/dist/features/homepage/components/StatsCounterSection.js +1 -1
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/TrustBadges.js +1 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +2 -2
- package/dist/features/homepage/components/TrustIndicatorsSection.js +2 -2
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/hooks/useActiveAd.js +2 -1
- package/dist/features/homepage/schemas/firestore.d.ts +10 -0
- package/dist/features/homepage/schemas/index.d.ts +116 -116
- package/dist/features/jobs/actions/enqueue-job.d.ts +24 -0
- package/dist/features/jobs/actions/enqueue-job.js +44 -0
- package/dist/features/jobs/repository/jobs.repository.d.ts +21 -0
- package/dist/features/jobs/repository/jobs.repository.js +48 -0
- package/dist/features/jobs/schemas/firestore.d.ts +54 -0
- package/dist/features/jobs/schemas/firestore.js +24 -0
- package/dist/features/layout/AppLayoutShell.js +17 -11
- package/dist/features/layout/AutoBreadcrumbs.js +1 -1
- package/dist/features/layout/BackToTop.js +2 -2
- package/dist/features/layout/BottomActions.js +7 -7
- package/dist/features/layout/BottomNavItem.js +2 -2
- package/dist/features/layout/BottomNavLayout.js +13 -4
- package/dist/features/layout/BottomNavbar.d.ts +9 -1
- package/dist/features/layout/BottomNavbar.js +12 -5
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/Breadcrumbs.js +1 -1
- package/dist/features/layout/FooterLayout.js +2 -2
- package/dist/features/layout/NavItem.js +3 -3
- package/dist/features/layout/NavbarLayout.js +6 -6
- package/dist/features/layout/SidebarLayout.d.ts +3 -0
- package/dist/features/layout/SidebarLayout.js +3 -3
- package/dist/features/layout/TitleBarLayout.js +4 -4
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +3 -3
- package/dist/features/lottery/types/index.d.ts +3 -1
- package/dist/features/lottery/types/index.js +16 -3
- package/dist/features/loyalty/components/CoinsDisplay.js +2 -2
- package/dist/features/media/MediaImage.d.ts +6 -1
- package/dist/features/media/MediaImage.js +10 -4
- package/dist/features/media/MediaLightbox.js +1 -1
- package/dist/features/media/MediaPickerModal.js +4 -3
- package/dist/features/media/MediaVideo.js +1 -1
- package/dist/features/media/modals/ImageCropModal.js +1 -1
- package/dist/features/media/modals/ImageEditor.js +1 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +9 -0
- package/dist/features/media/types/index.d.ts +4 -4
- package/dist/features/media/upload/MediaUploadField.js +3 -3
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +4 -3
- package/dist/features/messages/hooks/useConversations.js +2 -1
- package/dist/features/messages/schemas/index.d.ts +6 -6
- package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
- package/dist/features/orders/components/OrderPaymentSummary.d.ts +16 -0
- package/dist/features/orders/components/OrderPaymentSummary.js +32 -0
- package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
- package/dist/features/orders/components/OrdersList.d.ts +7 -2
- package/dist/features/orders/components/OrdersList.js +5 -5
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/repository/orders.repository.d.ts +8 -0
- package/dist/features/orders/repository/orders.repository.js +24 -0
- package/dist/features/orders/schemas/firestore.d.ts +59 -0
- package/dist/features/orders/schemas/firestore.js +5 -0
- package/dist/features/orders/schemas/index.d.ts +91 -40
- package/dist/features/orders/schemas/index.js +10 -0
- package/dist/features/orders/types/index.d.ts +15 -0
- package/dist/features/payments/schemas/index.d.ts +12 -12
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -5
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +7 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +3 -3
- package/dist/features/pre-orders/schemas/index.d.ts +12 -12
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +3 -3
- package/dist/features/products/components/CompareOverlay.js +15 -10
- package/dist/features/products/components/CustomFieldsEditor.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -3
- package/dist/features/products/components/FeatureBadge.js +2 -2
- package/dist/features/products/components/GroupSettingsPanel.js +5 -4
- package/dist/features/products/components/MakeOfferButton.js +4 -4
- package/dist/features/products/components/MarketplaceBundleCard.js +3 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -6
- package/dist/features/products/components/PrizeDrawDetailPageView.js +5 -5
- package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -4
- package/dist/features/products/components/PrizeDrawsIndexListing.js +11 -4
- package/dist/features/products/components/PrizeDrawsSection.js +1 -1
- package/dist/features/products/components/PrizeRevealModal.js +9 -4
- package/dist/features/products/components/ProductDetailActions.js +2 -1
- package/dist/features/products/components/ProductDetailPageView.js +16 -16
- package/dist/features/products/components/ProductFeaturesSelector.js +5 -5
- package/dist/features/products/components/ProductForm.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +5 -3
- package/dist/features/products/components/ProductGrid.js +11 -11
- package/dist/features/products/components/ProductTabs.js +2 -2
- package/dist/features/products/components/ProductTabsShell.js +2 -1
- package/dist/features/products/components/ProductsIndexListing.js +6 -1
- package/dist/features/products/components/ShareButton.js +2 -1
- package/dist/features/products/components/ShowGroupSection.js +9 -5
- package/dist/features/products/components/SublistingCarouselSection.js +8 -4
- package/dist/features/products/constants/action-defs.d.ts +10 -2
- package/dist/features/products/constants/action-defs.js +20 -2
- package/dist/features/products/schemas/firestore.d.ts +5 -0
- package/dist/features/products/schemas/index.d.ts +40 -40
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/promotions/components/CouponCard.js +13 -7
- package/dist/features/promotions/components/CouponsIndexListing.js +4 -6
- package/dist/features/promotions/components/PromotionsView.js +2 -2
- package/dist/features/promotions/schemas/index.d.ts +26 -26
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +11 -11
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewsList.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +22 -22
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/schemas/index.d.ts +20 -20
- package/dist/features/search/components/Search.js +9 -9
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +3 -3
- package/dist/features/search/components/SearchView.js +1 -1
- package/dist/features/search/hooks/useNavSuggestions.js +2 -1
- package/dist/features/search/hooks/useSearch.js +2 -2
- package/dist/features/search/schemas/index.d.ts +3 -3
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/QuickProductForm.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +4 -4
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +3 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerArtView.js +11 -11
- package/dist/features/seller/components/SellerAuctionsView.js +11 -11
- package/dist/features/seller/components/SellerBidsView.js +3 -3
- package/dist/features/seller/components/SellerBundlesView.js +12 -12
- package/dist/features/seller/components/SellerClassifiedView.js +11 -11
- package/dist/features/seller/components/SellerCouponEditorView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +11 -11
- package/dist/features/seller/components/SellerFeaturesView.js +4 -4
- package/dist/features/seller/components/SellerLiveView.js +11 -11
- package/dist/features/seller/components/SellerOffersPanel.js +3 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
- package/dist/features/seller/components/SellerPayoutRequestView.js +6 -5
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +20 -6
- package/dist/features/seller/components/SellerProductsCards.js +3 -3
- package/dist/features/seller/components/SellerProductsView.js +4 -4
- package/dist/features/seller/components/SellerReviewsView.js +7 -6
- package/dist/features/seller/components/SellerShippingView.js +2 -1
- package/dist/features/seller/components/SellerSidebar.js +5 -5
- package/dist/features/seller/components/SellerStickersView.js +11 -11
- package/dist/features/seller/components/SellerTemplatesView.js +1 -1
- package/dist/features/seller/schemas/index.d.ts +20 -20
- package/dist/features/server-errors/schemas/index.d.ts +6 -6
- package/dist/features/shell/CommandPalette.d.ts +27 -0
- package/dist/features/shell/CommandPalette.js +92 -0
- package/dist/features/shell/FormShell.js +4 -3
- package/dist/features/shell/QuickFormDrawer.js +3 -2
- package/dist/features/shell/StepForm.js +2 -2
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.d.ts +7 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.js +123 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.d.ts +6 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +96 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.d.ts +9 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +44 -0
- package/dist/features/shipments/components/AdminShipmentsView.d.ts +8 -0
- package/dist/features/shipments/components/AdminShipmentsView.js +82 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.d.ts +15 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.js +37 -0
- package/dist/features/shipments/hooks/useShipments.d.ts +69 -0
- package/dist/features/shipments/hooks/useShipments.js +96 -0
- package/dist/features/shipments/index.d.ts +10 -0
- package/dist/features/shipments/index.js +7 -0
- package/dist/features/shipments/manifest.d.ts +2 -0
- package/dist/features/shipments/manifest.js +26 -0
- package/dist/features/shipments/repository/shipment-items.repository.d.ts +56 -0
- package/dist/features/shipments/repository/shipment-items.repository.js +78 -0
- package/dist/features/shipments/repository/shipment-lots.repository.d.ts +48 -0
- package/dist/features/shipments/repository/shipment-lots.repository.js +55 -0
- package/dist/features/shipments/repository/shipments.repository.d.ts +50 -0
- package/dist/features/shipments/repository/shipments.repository.js +77 -0
- package/dist/features/shipments/schemas/firestore.d.ts +150 -0
- package/dist/features/shipments/schemas/firestore.js +76 -0
- package/dist/features/shipments/schemas/index.d.ts +2 -0
- package/dist/features/shipments/schemas/index.js +2 -0
- package/dist/features/shipments/schemas/validation.d.ts +350 -0
- package/dist/features/shipments/schemas/validation.js +96 -0
- package/dist/features/shipments/utils/cost-allocation.d.ts +25 -0
- package/dist/features/shipments/utils/cost-allocation.js +83 -0
- package/dist/features/site-settings/components/ActionPermissionsManager.js +2 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +2 -2
- package/dist/features/stores/components/StoreAboutView.js +1 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +3 -3
- package/dist/features/stores/components/StoreAuctionsView.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
- package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
- package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
- package/dist/features/stores/components/StoreFinanceGuideView.js +2 -2
- package/dist/features/stores/components/StoreGuideHubView.js +2 -2
- package/dist/features/stores/components/StoreHeader.js +4 -4
- package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
- package/dist/features/stores/components/StoreNavTabs.js +2 -2
- package/dist/features/stores/components/StoreOrdersGuideView.js +1 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +3 -3
- package/dist/features/stores/components/StoreProductsListing.js +1 -1
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoreReviewsView.js +1 -1
- package/dist/features/stores/components/StoreSettingsGuideView.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +9 -3
- package/dist/features/stores/schemas/index.d.ts +10 -10
- package/dist/features/support/schemas/index.d.ts +22 -22
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +3 -3
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +1 -1
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -2
- package/dist/index.d.ts +44 -1
- package/dist/index.js +37 -1
- package/dist/next/routing/route-map.d.ts +18 -0
- package/dist/next/routing/route-map.js +9 -0
- package/dist/react/hooks/useVisualViewportInset.d.ts +1 -0
- package/dist/react/hooks/useVisualViewportInset.js +59 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/repositories/index.d.ts +5 -0
- package/dist/repositories/index.js +5 -0
- package/dist/schemas/registry.d.ts +398 -364
- package/dist/schemas/sieve.d.ts +2 -2
- package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
- package/dist/schemas/webhooks/razorpay.d.ts +100 -100
- package/dist/seed/_helpers/media.js +1 -0
- package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
- package/dist/seed/catalogue-seed-data.d.ts +2 -0
- package/dist/seed/catalogue-seed-data.js +112 -0
- package/dist/seed/grouped-listings-seed-data.d.ts +5 -0
- package/dist/seed/homepage-sections-seed-data.js +0 -1
- package/dist/seed/index.d.ts +2 -0
- package/dist/seed/index.js +2 -0
- package/dist/seed/manifest.js +6 -0
- package/dist/seed/products-preorders-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.js +185 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +5 -0
- package/dist/styles.css +75 -19
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +0 -2
- package/dist/tokens/index.js +0 -2
- package/dist/tokens/tokens.css +12 -2
- package/dist/ui/DataTable.js +4 -3
- package/dist/ui/components/Button.d.ts +4 -1
- package/dist/ui/components/Button.js +11 -5
- package/dist/ui/components/Checkbox.d.ts +9 -1
- package/dist/ui/components/Checkbox.js +5 -2
- package/dist/ui/components/ClaimCouponButton.js +2 -1
- package/dist/ui/components/ConfirmDeleteModal.style.css +1 -1
- package/dist/ui/components/Drawer.style.css +13 -1
- package/dist/ui/components/Dropdown.style.css +2 -2
- package/dist/ui/components/FilterDrawer.d.ts +4 -1
- package/dist/ui/components/FilterDrawer.js +8 -2
- package/dist/ui/components/Form.d.ts +1 -1
- package/dist/ui/components/Form.js +2 -2
- package/dist/ui/components/FormActionBar.style.css +6 -1
- package/dist/ui/components/IconButton.d.ts +6 -1
- package/dist/ui/components/IconButton.js +5 -2
- package/dist/ui/components/IconButton.style.css +11 -0
- package/dist/ui/components/ImageGallery.style.css +2 -0
- package/dist/ui/components/ImageLightbox.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.d.ts +4 -1
- package/dist/ui/components/ListingFilterDrawer.js +4 -3
- package/dist/ui/components/ListingLayout.style.css +2 -2
- package/dist/ui/components/Modal.style.css +1 -1
- package/dist/ui/components/Pagination.d.ts +5 -1
- package/dist/ui/components/Pagination.js +4 -2
- package/dist/ui/components/RowActionMenu.js +1 -1
- package/dist/ui/components/RowActionMenu.style.css +1 -1
- package/dist/ui/components/Select.d.ts +6 -1
- package/dist/ui/components/Select.js +18 -13
- package/dist/ui/components/Select.style.css +1 -1
- package/dist/ui/components/Semantic.d.ts +13 -0
- package/dist/ui/components/Semantic.js +16 -3
- package/dist/ui/components/SideDrawer.style.css +16 -4
- package/dist/ui/components/SideModal.style.css +1 -1
- package/dist/ui/components/StickyToolbar.d.ts +3 -2
- package/dist/ui/components/StickyToolbar.js +1 -1
- package/dist/ui/components/Textarea.d.ts +5 -0
- package/dist/ui/components/Textarea.js +8 -4
- package/dist/ui/components/Toast.style.css +3 -0
- package/dist/ui/components/UnsavedChangesModal.style.css +1 -1
- package/dist/ui/components/surface-tokens.d.ts +121 -113
- package/dist/ui/components/surface-tokens.js +110 -104
- package/dist/ui/forms/FormShell.d.ts +8 -27
- package/dist/ui/forms/FormShell.js +1 -194
- package/dist/ui/forms/index.d.ts +2 -2
- package/dist/ui/forms/index.js +1 -1
- package/dist/ui/index.d.ts +8 -4
- package/dist/ui/index.js +4 -2
- package/dist/utils/id-generators.d.ts +27 -0
- package/dist/utils/id-generators.js +45 -0
- package/dist/utils/number.formatter.d.ts +7 -0
- package/dist/utils/number.formatter.js +9 -0
- package/dist/validation/schemas.d.ts +5 -5
- package/package.json +1 -1
|
@@ -3,10 +3,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { normalizeError } from "../../../errors/normalize";
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import { Pencil, Trash2, ToggleLeft, ToggleRight } from "lucide-react";
|
|
6
|
-
import { Badge, BaseListingCard, ConfirmDeleteModal, Div, Row, Span, Stack, Text } from "../../../ui";
|
|
6
|
+
import { Badge, BaseListingCard, Button, ConfirmDeleteModal, Div, IconButton, Row, Span, Stack, Text } from "../../../ui";
|
|
7
7
|
import { useLongPress } from "../../../react/hooks/useLongPress";
|
|
8
|
+
import { useFeatureFlags } from "../../../client/api/useFeatureFlags";
|
|
9
|
+
import { ACCOUNT_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
10
|
const CLS_TOGGLE_ON = "h-4 w-4 text-success dark:text-success";
|
|
9
|
-
const CLS_DELETE_BTN = "
|
|
11
|
+
const CLS_DELETE_BTN = "p-[var(--appkit-space-1-5)] text-[var(--appkit-color-text-muted)] hover:bg-error-surface dark:hover:bg-error-surface hover:text-error dark:hover:text-error transition-colors disabled:opacity-50";
|
|
10
12
|
const TYPE_COLORS = {
|
|
11
13
|
percentage: { card: "bg-purple-50 border-purple-200 dark:bg-purple-950/30 dark:border-purple-800", code: "bg-purple-100 dark:bg-purple-900/40 text-purple-800 dark:text-purple-200 border-purple-300 dark:border-purple-700" },
|
|
12
14
|
fixed: { card: "bg-success-surface border-success dark:bg-success-surface dark:border-success", code: "bg-success-surface dark:bg-success-surface text-success dark:text-success border-success dark:border-success" },
|
|
@@ -100,8 +102,12 @@ export function CouponCard({ coupon, labels: labelsProp, onCopy, className = "",
|
|
|
100
102
|
const discountLabel = formatDiscount(n, labels);
|
|
101
103
|
const hasAdminActions = Boolean(onEdit || onToggleActive || onDelete);
|
|
102
104
|
// Show Claim by default on public surfaces; hide automatically when this
|
|
103
|
-
// card is being rendered with admin/CRUD actions wired.
|
|
104
|
-
|
|
105
|
+
// card is being rendered with admin/CRUD actions wired. Also hidden
|
|
106
|
+
// whenever the COUPONS feature is disabled — the claim endpoint 404s in
|
|
107
|
+
// that state, and previously that 404 was silently swallowed (see
|
|
108
|
+
// handleClaim below) instead of the CTA simply not being offered.
|
|
109
|
+
const { flags: featureFlags } = useFeatureFlags();
|
|
110
|
+
const showClaim = (hideClaim === undefined ? !hasAdminActions : !hideClaim) && featureFlags.COUPONS === true;
|
|
105
111
|
const handleCopy = () => {
|
|
106
112
|
if (!n.code)
|
|
107
113
|
return;
|
|
@@ -119,7 +125,7 @@ export function CouponCard({ coupon, labels: labelsProp, onCopy, className = "",
|
|
|
119
125
|
// ignore so the deep-link still works), then jump to cart with the
|
|
120
126
|
// code pre-filled.
|
|
121
127
|
try {
|
|
122
|
-
await fetch(
|
|
128
|
+
await fetch(ACCOUNT_ENDPOINTS.COUPONS_CLAIM, {
|
|
123
129
|
method: "POST",
|
|
124
130
|
headers: { "Content-Type": "application/json" },
|
|
125
131
|
credentials: "include",
|
|
@@ -161,7 +167,7 @@ export function CouponCard({ coupon, labels: labelsProp, onCopy, className = "",
|
|
|
161
167
|
setBusy(null);
|
|
162
168
|
}
|
|
163
169
|
};
|
|
164
|
-
return (_jsxs(Stack, { className: `group relative h-full border-2 ${colors.card} ${isSelected ? "ring-2 ring-primary" : ""} ${!n.isActive ? "opacity-70" : ""} ${className}`, rounded: "xl", padding: "md", onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(n.id, !isSelected); }, label: isSelected ? "Deselect coupon" : "Select coupon", position: "top-2 right-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), (hasAdminActions || n.scope) && (_jsxs(Row, { gap: "xs", wrap: true, className: "mb-2", children: [_jsx(Badge, { variant: n.isActive ? "active" : "inactive", size: "xs", className: "text-[10px] uppercase tracking-wide", children: n.isActive ? labels.active : labels.inactive }), n.scope && (_jsx(Span, { layout: "inline-flex", weight: "semibold", className: "bg-neutral-200/70 text-[10px] tracking-wide bg-[var(--appkit-color-border)]/60", rounded: "full", padding: "pill-xs", color: "primary", transform: "uppercase", children: n.scope }))] })), _jsxs(Div, { className: "mb-3", children: [_jsx(Text, { className: "font-extrabold tracking-tight leading-none", size: "2xl", children: discountLabel }), n.name && (_jsx(Text, { className: "mt-0.5 opacity-80", size: "sm", weight: "medium", children: n.name }))] }), n.description && (_jsx(Text, { className: "opacity-60 mb-3", size: "xs", children: n.description })), _jsxs(Row, { className: `border border-dashed ${colors.code}`, align: "center", gap: "sm", rounded: "lg", padding: "inlineSm", children: [_jsx(Span, { size: "sm", weight: "bold", className: "flex-1 font-mono tracking-widest select-all", transform: "uppercase", children: n.code || "—" }), n.code && (_jsx("
|
|
170
|
+
return (_jsxs(Stack, { className: `group relative h-full border-2 ${colors.card} ${isSelected ? "ring-2 ring-primary" : ""} ${!n.isActive ? "opacity-70" : ""} ${className}`, rounded: "xl", padding: "md", onMouseDown: onSelect && !isSelected ? longPress.onMouseDown : undefined, onMouseUp: onSelect && !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: onSelect && !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: onSelect && !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: onSelect && !isSelected ? longPress.onTouchEnd : undefined, children: [onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (e) => { e.preventDefault(); onSelect(n.id, !isSelected); }, label: isSelected ? "Deselect coupon" : "Select coupon", position: "top-2 right-2", className: selectable || isSelected ? "opacity-100" : "opacity-0 group-hover:opacity-100 transition-opacity" })), (hasAdminActions || n.scope) && (_jsxs(Row, { gap: "xs", wrap: true, className: "mb-2", children: [_jsx(Badge, { variant: n.isActive ? "active" : "inactive", size: "xs", className: "text-[10px] uppercase tracking-wide", children: n.isActive ? labels.active : labels.inactive }), n.scope && (_jsx(Span, { layout: "inline-flex", weight: "semibold", className: "bg-neutral-200/70 text-[10px] tracking-wide bg-[var(--appkit-color-border)]/60", rounded: "full", padding: "pill-xs", color: "primary", transform: "uppercase", children: n.scope }))] })), _jsxs(Div, { className: "mb-3", children: [_jsx(Text, { className: "font-extrabold tracking-tight leading-none", size: "2xl", children: discountLabel }), n.name && (_jsx(Text, { className: "mt-0.5 opacity-80", size: "sm", weight: "medium", children: n.name }))] }), n.description && (_jsx(Text, { className: "opacity-60 mb-3", size: "xs", children: n.description })), _jsxs(Row, { className: `border border-dashed ${colors.code}`, align: "center", gap: "sm", rounded: "lg", padding: "inlineSm", children: [_jsx(Span, { size: "sm", weight: "bold", className: "flex-1 font-mono tracking-widest select-all", transform: "uppercase", children: n.code || "—" }), n.code && (_jsx(Button, { variant: "outline", type: "button", onClick: handleCopy, rounded: "md", paddingX: "sm", paddingY: "none", textSize: "xs", weight: "semibold", className: "shrink-0 hover:opacity-80 active:scale-95 border-current/20", "aria-label": "Copy coupon code", children: copied ? labels.copied : labels.copy }))] }), showClaim && n.code && n.isActive && (_jsx(Div, { className: "mt-2", children: _jsx(Button, { variant: "primary", type: "button", onClick: handleClaim, disabled: claiming, rounded: "md", paddingX: "md", paddingY: "xs", textSize: "xs", weight: "semibold", className: "w-full active:scale-95 bg-[var(--appkit-color-primary-700)] hover:bg-[var(--appkit-color-primary-800)]", "aria-label": `Claim coupon ${n.code} and apply at checkout`, children: claiming ? labels.claiming : labels.claim }) })), _jsxs(Row, { textSize: "xs", wrap: true, gap: "sm", className: "opacity-60 mt-2", children: [n.minOrderAmount ? (_jsxs(Span, { children: [labels.minOrder, ": \u20B9", (n.minOrderAmount / 100).toFixed(0)] })) : null, expiry && (_jsxs(Span, { children: [labels.expires, ": ", expiry] })), n.usageLimit ? (_jsxs(Span, { children: [n.usageCount, "/", n.usageLimit, " ", labels.used] })) : n.usageCount > 0 ? (_jsxs(Span, { children: [n.usageCount, " ", labels.used] })) : null] }), hasAdminActions && (_jsxs(Row, { gap: "xs", justify: "end", className: "mt-auto", padding: "t-sm", children: [onEdit && (_jsx(IconButton, { type: "button", onClick: () => onEdit(n.id), title: labels.edit, "aria-label": labels.edit, variant: "ghost", rounded: "lg", className: "text-[var(--appkit-color-text-muted)]", children: _jsx(Pencil, { className: "h-4 w-4" }) })), onToggleActive && (_jsx(IconButton, { type: "button", onClick: handleToggle, disabled: busy === "toggle", title: n.isActive ? labels.deactivate : labels.activate, "aria-label": n.isActive ? labels.deactivate : labels.activate, variant: "ghost", rounded: "lg", className: "text-[var(--appkit-color-text-muted)]", children: n.isActive
|
|
165
171
|
? _jsx(ToggleRight, { className: CLS_TOGGLE_ON })
|
|
166
|
-
: _jsx(ToggleLeft, { className: "h-4 w-4" }) })), onDelete && (_jsx(
|
|
172
|
+
: _jsx(ToggleLeft, { className: "h-4 w-4" }) })), onDelete && (_jsx(IconButton, { type: "button", onClick: () => setDeleteConfirmOpen(true), disabled: busy === "delete", title: labels.delete, "aria-label": labels.delete, variant: "ghost", rounded: "lg", className: CLS_DELETE_BTN, children: _jsx(Trash2, { className: "h-4 w-4" }) }))] })), deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Coupon", message: labels.deleteConfirm, onConfirm: handleDeleteConfirmed, onClose: () => setDeleteConfirmOpen(false), isDeleting: busy === "delete" }))] }));
|
|
167
173
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { useState, useCallback, useMemo } from "react";
|
|
4
4
|
import { Search, SlidersHorizontal, X } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
|
-
import { Button,
|
|
6
|
+
import { Button, DateInput, IconButton, Input, ListingFilterDrawer, Pagination, RadioGroup, SortDropdown, Div, Grid, Row, Span, Stack, Text, Heading } from "../../../ui";
|
|
7
7
|
import { usePromotions } from "../hooks/usePromotions";
|
|
8
8
|
import { CouponCard } from "./CouponCard";
|
|
9
9
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
@@ -13,7 +13,7 @@ const __O = {
|
|
|
13
13
|
hidden: "overflow-hidden",
|
|
14
14
|
};
|
|
15
15
|
const DEFAULT_SORT = sortBy(COUPON_FIELDS.CREATED_AT);
|
|
16
|
-
const CLS_CHIP_BTN = "p-0 min-h-0 h-auto inline-flex";
|
|
16
|
+
const CLS_CHIP_BTN = "p-[var(--appkit-space-0)] min-h-0 h-auto inline-flex";
|
|
17
17
|
const COUPON_SORT_OPTIONS = [
|
|
18
18
|
{ value: sortBy(COUPON_FIELDS.NAME, "ASC"), label: "Name A–Z" },
|
|
19
19
|
{ value: sortBy(COUPON_FIELDS.NAME), label: "Name Z–A" },
|
|
@@ -93,14 +93,12 @@ export function CouponsIndexListing({ initialCoupons, storeSlug: _storeSlug, sto
|
|
|
93
93
|
const clearFilters = () => {
|
|
94
94
|
table.setMany({ type: "", [TABLE_KEYS.DATE_FROM]: "", [TABLE_KEYS.DATE_TO]: "" });
|
|
95
95
|
};
|
|
96
|
-
return (_jsxs(Div, { className: "min-h-[40vh]", children: [_jsxs(Div, { border: "default", paddingY: "y-xs-tall", className: "sticky top-[var(--header-height,0px)] z-20 border-b backdrop-blur-sm", surface: "default", padding: "x-md", children: [_jsxs(Row, { gap: "xs", className: "max-w-full", children: [_jsxs(
|
|
97
|
-
? "border-primary bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-300"
|
|
98
|
-
: "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]"}`, children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsxs(Span, { className: "hidden sm:inline", children: ["Filters", hasActiveFilters ? " •" : ""] })] }), _jsxs(Row, { surface: "default", className: `flex-1 ${__O.hidden}`, border: "strong", rounded: "lg", children: [_jsx("input", { type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search by name or description\u2026", className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-zinc-400 outline-none" }), searchInput && (_jsx("button", { type: "button", onClick: () => { setSearchInput(""); table.set(TABLE_KEYS.QUERY, ""); }, className: "p-2 text-zinc-400 hover:text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)]", "aria-label": "Clear search", children: _jsx(X, { className: "h-3.5 w-3.5" }) })), _jsx("button", { type: "button", onClick: commitSearch, className: "flex shrink-0 items-center justify-center px-3 py-2 text-zinc-400 hover:text-primary dark:hover:text-primary-400 transition-colors", "aria-label": "Search", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs(Row, { color: "muted", textSize: "sm", gap: "xs", className: "shrink-0", children: [_jsx(Span, { className: "hidden md:inline whitespace-nowrap", children: "Sort by" }), _jsx(SortDropdown, { value: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, onChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, options: COUPON_SORT_OPTIONS })] })] }), hasActiveFilters && (_jsxs(Row, { gap: "xs", wrap: true, className: "mt-2", children: [activeType && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: [COUPON_TYPES.find((t) => t.value === activeType)?.label ?? activeType, _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.TYPE, ""); }, "aria-label": "Remove type filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_FROM) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["From: ", table.get(TABLE_KEYS.DATE_FROM), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_FROM, ""); }, "aria-label": "Remove from-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_TO) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["To: ", table.get(TABLE_KEYS.DATE_TO), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_TO, ""); }, "aria-label": "Remove to-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), _jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text-muted)] underline", children: "Clear all" })] }))] }), _jsxs(Div, { paddingY: "y-lg", paddingX: "x-md", children: [isLoading ? (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Stack, { border: "skeleton", gap: "sm", rounded: "xl", padding: "md", className: "animate-pulse", children: [_jsx(Div, { className: "h-6 w-2/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" })] }, i))) })) : displayCoupons.length === 0 ? (_jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { color: "faint", children: "No coupons match your search." }) })) : (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: displayCoupons.map((coupon) => (_jsx(CouponCard, { coupon: coupon, labels: {
|
|
96
|
+
return (_jsxs(Div, { className: "min-h-[40vh]", children: [_jsxs(Div, { border: "default", paddingY: "y-xs-tall", className: "sticky top-[var(--header-height,0px)] z-20 border-b backdrop-blur-sm", surface: "default", padding: "x-md", children: [_jsxs(Row, { gap: "xs", className: "max-w-full", children: [_jsxs(Button, { type: "button", variant: hasActiveFilters ? "outline" : "ghost", onClick: openFilters, gap: "sm", rounded: "lg", paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", className: hasActiveFilters ? "border-primary bg-primary-50 text-primary-700 dark:bg-primary-900/30 dark:text-primary-300 shrink-0" : "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] shrink-0", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsxs(Span, { className: "hidden sm:inline", children: ["Filters", hasActiveFilters ? " •" : ""] })] }), _jsxs(Row, { surface: "default", className: `flex-1 ${__O.hidden}`, border: "strong", rounded: "lg", children: [_jsx(Input, { bare: true, type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: handleKeyDown, placeholder: "Search by name or description\u2026", className: "min-w-0 flex-1 bg-transparent px-[var(--appkit-space-3)] py-[var(--appkit-space-2)] text-[length:var(--appkit-text-sm)] text-[var(--appkit-color-text)] placeholder-zinc-400 outline-none" }), searchInput && (_jsx(IconButton, { type: "button", onClick: () => { setSearchInput(""); table.set(TABLE_KEYS.QUERY, ""); }, "aria-label": "Clear search", variant: "ghost", size: "sm", children: _jsx(X, { className: "h-3.5 w-3.5" }) })), _jsx(IconButton, { type: "button", onClick: commitSearch, "aria-label": "Search", variant: "ghost", size: "sm", children: _jsx(Search, { className: "h-4 w-4" }) })] }), _jsxs(Row, { color: "muted", textSize: "sm", gap: "xs", className: "shrink-0", children: [_jsx(Span, { className: "hidden md:inline whitespace-nowrap", children: "Sort by" }), _jsx(SortDropdown, { value: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, onChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, options: COUPON_SORT_OPTIONS })] })] }), hasActiveFilters && (_jsxs(Row, { gap: "xs", wrap: true, className: "mt-2", children: [activeType && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: [COUPON_TYPES.find((t) => t.value === activeType)?.label ?? activeType, _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.TYPE, ""); }, "aria-label": "Remove type filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_FROM) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["From: ", table.get(TABLE_KEYS.DATE_FROM), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_FROM, ""); }, "aria-label": "Remove from-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), table.get(TABLE_KEYS.DATE_TO) && (_jsxs(Span, { layout: "flex", gap: "xs", size: "xs", weight: "medium", className: "bg-primary-50 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300", rounded: "full", padding: "pill-sm-tall", children: ["To: ", table.get(TABLE_KEYS.DATE_TO), _jsx(Button, { variant: "ghost", type: "button", onClick: () => { table.set(TABLE_KEYS.DATE_TO, ""); }, "aria-label": "Remove to-date filter", className: CLS_CHIP_BTN, children: _jsx(X, { className: "h-3 w-3" }) })] })), _jsx(Button, { variant: "ghost", type: "button", onClick: clearFilters, textSize: "xs", textColor: "muted", className: "underline", children: "Clear all" })] }))] }), _jsxs(Div, { paddingY: "y-lg", paddingX: "x-md", children: [isLoading ? (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsxs(Stack, { border: "skeleton", gap: "sm", rounded: "xl", padding: "md", className: "animate-pulse", children: [_jsx(Div, { className: "h-6 w-2/3", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-4 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" })] }, i))) })) : displayCoupons.length === 0 ? (_jsx(Div, { className: "text-left", padding: "y-4xl", children: _jsx(Text, { color: "faint", children: "No coupons match your search." }) })) : (_jsx(Grid, { gap: "sm", className: "md:grid-cols-2 lg:grid-cols-3", children: displayCoupons.map((coupon) => (_jsx(CouponCard, { coupon: coupon, labels: {
|
|
99
97
|
copy: "Copy",
|
|
100
98
|
copied: "Copied!",
|
|
101
99
|
expires: "Expires",
|
|
102
100
|
minOrder: "Min. order",
|
|
103
101
|
off: "OFF",
|
|
104
102
|
freeShipping: "Free Shipping",
|
|
105
|
-
} }, coupon.id))) })), totalPages > 1 && (_jsx(Row, { justify: "center", className: "mt-8", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-
|
|
103
|
+
} }, coupon.id))) })), totalPages > 1 && (_jsx(Row, { justify: "center", className: "mt-8", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-left", children: _jsxs(Text, { size: "xs", color: "faint", children: [total, " coupon", total !== 1 ? "s" : "", " available"] }) }))] }), _jsxs(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearPending, activeCount: activeFilterCount, children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "tracking-wider mb-3", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Discount Type" }), _jsxs(Stack, { gap: "xs", children: [_jsx(RadioGroup, { name: "coupon-type", variant: "classic", options: COUPON_TYPES, value: pendingTable.get(TABLE_KEYS.TYPE), onChange: (v) => { pendingTable.set(TABLE_KEYS.TYPE, v); } }), pendingTable.get(TABLE_KEYS.TYPE) && (_jsx(Button, { variant: "ghost", type: "button", onClick: () => { pendingTable.set(TABLE_KEYS.TYPE, ""); }, textSize: "xs", textColor: "faint", className: "underline w-fit", children: "Clear type" }))] })] }), _jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "tracking-wider mb-3", color: "muted", size: "xs", weight: "semibold", transform: "uppercase", children: "Valid Date Range" }), _jsxs(Stack, { gap: "sm", children: [_jsx(DateInput, { label: "From date", value: pendingTable.get(TABLE_KEYS.DATE_FROM) || "", onChange: (v) => { pendingTable.set(TABLE_KEYS.DATE_FROM, v); } }), _jsx(DateInput, { label: "To date", value: pendingTable.get(TABLE_KEYS.DATE_TO) || "", onChange: (v) => { pendingTable.set(TABLE_KEYS.DATE_TO, v); } })] })] })] })] }));
|
|
106
104
|
}
|
|
@@ -7,9 +7,9 @@ export function PromotionsViewProductSection({ title, subtitle, renderProducts,
|
|
|
7
7
|
}
|
|
8
8
|
/** Slim hero banner for the promotions page — tabs + content live in the page. */
|
|
9
9
|
export function PromotionsHero({ labels, heroBannerClass = "", }) {
|
|
10
|
-
return (_jsx(Section, { color: "inverse", tone: "accent-banner", className: `${heroBannerClass}`, padding: "y-2-5xl", children: _jsxs(Div, { paddingX: "x-page", className: "max-w-5xl mx-auto text-
|
|
10
|
+
return (_jsx(Section, { color: "inverse", tone: "accent-banner", className: `${heroBannerClass}`, padding: "y-2-5xl", children: _jsxs(Div, { paddingX: "x-page", className: "max-w-5xl mx-auto text-left", children: [_jsxs(Text, { color: "inverse", className: "mb-2 tracking-widest", size: "sm", weight: "medium", transform: "uppercase", children: ["\uD83C\uDF89 ", labels.exclusiveOffersBadge] }), _jsx(Heading, { color: "inverse", level: 1, variant: "none", className: "mb-4", children: labels.title }), _jsx(Text, { color: "inverse", variant: "none", className: "/90 max-w-2xl mx-auto", size: "lg", children: labels.subtitle })] }) }));
|
|
11
11
|
}
|
|
12
12
|
/** @deprecated Use PromotionsHero + per-tab content in your page instead. */
|
|
13
13
|
export function PromotionsView({ labels, hasContent, heroBannerClass = "", renderCoupons, couponsCount = 0, renderDealsSection, renderFeaturedSection, }) {
|
|
14
|
-
return (_jsxs(Div, { surface: "default", className: "min-h-screen", children: [_jsx(PromotionsHero, { labels: labels, heroBannerClass: heroBannerClass }), _jsxs(Stack, { gap: "section", paddingX: "x-page", className: "max-w-5xl mx-auto", padding: "y-3xl", children: [!hasContent && (_jsxs(Div, { className: "text-
|
|
14
|
+
return (_jsxs(Div, { surface: "default", className: "min-h-screen", children: [_jsx(PromotionsHero, { labels: labels, heroBannerClass: heroBannerClass }), _jsxs(Stack, { gap: "section", paddingX: "x-page", className: "max-w-5xl mx-auto", padding: "y-3xl", children: [!hasContent && (_jsxs(Div, { className: "text-left", padding: "y-4xl", children: [_jsx(Heading, { level: 2, className: "mb-2", children: labels.emptyDeals }), _jsx(Text, { variant: "secondary", children: labels.checkBack })] })), hasContent && (_jsxs(Stack, { gap: "section", children: [renderCoupons && (_jsxs(Section, { children: [_jsxs(Div, { className: "mb-6", children: [_jsx(Heading, { level: 2, children: labels.couponsTitle }), couponsCount > 0 && (_jsx(Text, { variant: "secondary", className: "mt-1", children: labels.couponsSubtitle }))] }), couponsCount > 0 ? (renderCoupons()) : (_jsx(Text, { variant: "secondary", size: "sm", children: labels.emptyCoupons }))] })), renderDealsSection?.(), renderFeaturedSection?.()] }))] })] }));
|
|
15
15
|
}
|
|
@@ -274,16 +274,16 @@ export declare const couponFirestoreSchema: z.ZodObject<{
|
|
|
274
274
|
}, "strip", z.ZodTypeAny, {
|
|
275
275
|
code: string;
|
|
276
276
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
277
|
+
id: string;
|
|
278
|
+
scope: "seller" | "admin";
|
|
279
|
+
name: string;
|
|
277
280
|
createdAt: string | Date | z.objectOutputType<{
|
|
278
281
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
279
282
|
}, z.ZodTypeAny, "passthrough">;
|
|
280
|
-
description: string;
|
|
281
|
-
id: string;
|
|
282
283
|
updatedAt: string | Date | z.objectOutputType<{
|
|
283
284
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
284
285
|
}, z.ZodTypeAny, "passthrough">;
|
|
285
|
-
|
|
286
|
-
scope: "seller" | "admin";
|
|
286
|
+
description: string;
|
|
287
287
|
stats: {
|
|
288
288
|
totalUses: number;
|
|
289
289
|
totalRevenue: number;
|
|
@@ -333,16 +333,16 @@ export declare const couponFirestoreSchema: z.ZodObject<{
|
|
|
333
333
|
}, {
|
|
334
334
|
code: string;
|
|
335
335
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
336
|
+
id: string;
|
|
337
|
+
scope: "seller" | "admin";
|
|
338
|
+
name: string;
|
|
336
339
|
createdAt: string | Date | z.objectInputType<{
|
|
337
340
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
338
341
|
}, z.ZodTypeAny, "passthrough">;
|
|
339
|
-
description: string;
|
|
340
|
-
id: string;
|
|
341
342
|
updatedAt: string | Date | z.objectInputType<{
|
|
342
343
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
343
344
|
}, z.ZodTypeAny, "passthrough">;
|
|
344
|
-
|
|
345
|
-
scope: "seller" | "admin";
|
|
345
|
+
description: string;
|
|
346
346
|
stats: {
|
|
347
347
|
totalUses: number;
|
|
348
348
|
totalRevenue: number;
|
|
@@ -470,8 +470,8 @@ export declare const claimedCouponSnapshotSchema: z.ZodObject<{
|
|
|
470
470
|
}>;
|
|
471
471
|
}, "strip", z.ZodTypeAny, {
|
|
472
472
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
473
|
-
name: string;
|
|
474
473
|
scope: "seller" | "admin";
|
|
474
|
+
name: string;
|
|
475
475
|
discount: {
|
|
476
476
|
value: number;
|
|
477
477
|
maxDiscount?: number | undefined;
|
|
@@ -490,8 +490,8 @@ export declare const claimedCouponSnapshotSchema: z.ZodObject<{
|
|
|
490
490
|
description?: string | undefined;
|
|
491
491
|
}, {
|
|
492
492
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
493
|
-
name: string;
|
|
494
493
|
scope: "seller" | "admin";
|
|
494
|
+
name: string;
|
|
495
495
|
discount: {
|
|
496
496
|
value: number;
|
|
497
497
|
maxDiscount?: number | undefined;
|
|
@@ -561,8 +561,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
561
561
|
}>;
|
|
562
562
|
}, "strip", z.ZodTypeAny, {
|
|
563
563
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
564
|
-
name: string;
|
|
565
564
|
scope: "seller" | "admin";
|
|
565
|
+
name: string;
|
|
566
566
|
discount: {
|
|
567
567
|
value: number;
|
|
568
568
|
maxDiscount?: number | undefined;
|
|
@@ -581,8 +581,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
581
581
|
description?: string | undefined;
|
|
582
582
|
}, {
|
|
583
583
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
584
|
-
name: string;
|
|
585
584
|
scope: "seller" | "admin";
|
|
585
|
+
name: string;
|
|
586
586
|
discount: {
|
|
587
587
|
value: number;
|
|
588
588
|
maxDiscount?: number | undefined;
|
|
@@ -632,8 +632,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
632
632
|
}, z.ZodTypeAny, "passthrough">>]>;
|
|
633
633
|
}, "strip", z.ZodTypeAny, {
|
|
634
634
|
status: "used" | "active" | "expired";
|
|
635
|
-
source: "prize-draw" | "manual" | "promo" | "spin" | "raffle";
|
|
636
635
|
id: string;
|
|
636
|
+
source: "manual" | "prize-draw" | "promo" | "spin" | "raffle";
|
|
637
637
|
updatedAt: string | Date | z.objectOutputType<{
|
|
638
638
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
639
639
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -642,8 +642,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
642
642
|
couponId: string;
|
|
643
643
|
couponSnapshot: {
|
|
644
644
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
645
|
-
name: string;
|
|
646
645
|
scope: "seller" | "admin";
|
|
646
|
+
name: string;
|
|
647
647
|
discount: {
|
|
648
648
|
value: number;
|
|
649
649
|
maxDiscount?: number | undefined;
|
|
@@ -673,8 +673,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
673
673
|
usedOrderId?: string | undefined;
|
|
674
674
|
}, {
|
|
675
675
|
status: "used" | "active" | "expired";
|
|
676
|
-
source: "prize-draw" | "manual" | "promo" | "spin" | "raffle";
|
|
677
676
|
id: string;
|
|
677
|
+
source: "manual" | "prize-draw" | "promo" | "spin" | "raffle";
|
|
678
678
|
updatedAt: string | Date | z.objectInputType<{
|
|
679
679
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
680
680
|
}, z.ZodTypeAny, "passthrough">;
|
|
@@ -683,8 +683,8 @@ export declare const claimedCouponFirestoreSchema: z.ZodObject<{
|
|
|
683
683
|
couponId: string;
|
|
684
684
|
couponSnapshot: {
|
|
685
685
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
686
|
-
name: string;
|
|
687
686
|
scope: "seller" | "admin";
|
|
687
|
+
name: string;
|
|
688
688
|
discount: {
|
|
689
689
|
value: number;
|
|
690
690
|
maxDiscount?: number | undefined;
|
|
@@ -757,12 +757,12 @@ export declare const couponItemSchema: z.ZodObject<{
|
|
|
757
757
|
}, "strip", z.ZodTypeAny, {
|
|
758
758
|
code: string;
|
|
759
759
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
760
|
-
createdAt: string;
|
|
761
|
-
description: string;
|
|
762
760
|
id: string;
|
|
763
|
-
updatedAt: string;
|
|
764
|
-
name: string;
|
|
765
761
|
scope: "seller" | "admin";
|
|
762
|
+
name: string;
|
|
763
|
+
createdAt: string;
|
|
764
|
+
updatedAt: string;
|
|
765
|
+
description: string;
|
|
766
766
|
isActive: boolean;
|
|
767
767
|
isPublic: boolean;
|
|
768
768
|
usageCount: number;
|
|
@@ -781,12 +781,12 @@ export declare const couponItemSchema: z.ZodObject<{
|
|
|
781
781
|
}, {
|
|
782
782
|
code: string;
|
|
783
783
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
784
|
-
createdAt: string;
|
|
785
|
-
description: string;
|
|
786
784
|
id: string;
|
|
787
|
-
updatedAt: string;
|
|
788
|
-
name: string;
|
|
789
785
|
scope: "seller" | "admin";
|
|
786
|
+
name: string;
|
|
787
|
+
createdAt: string;
|
|
788
|
+
updatedAt: string;
|
|
789
|
+
description: string;
|
|
790
790
|
isActive: boolean;
|
|
791
791
|
isPublic: boolean;
|
|
792
792
|
usageCount: number;
|
|
@@ -813,18 +813,18 @@ export declare const promotionsListParamsSchema: z.ZodObject<{
|
|
|
813
813
|
sort: z.ZodOptional<z.ZodString>;
|
|
814
814
|
}, "strip", z.ZodTypeAny, {
|
|
815
815
|
sort?: string | undefined;
|
|
816
|
-
storeId?: string | undefined;
|
|
817
816
|
page?: number | undefined;
|
|
818
817
|
scope?: "seller" | "admin" | undefined;
|
|
819
818
|
pageSize?: number | undefined;
|
|
819
|
+
storeId?: string | undefined;
|
|
820
820
|
isActive?: boolean | undefined;
|
|
821
821
|
filters?: string | undefined;
|
|
822
822
|
}, {
|
|
823
823
|
sort?: string | undefined;
|
|
824
|
-
storeId?: string | undefined;
|
|
825
824
|
page?: number | undefined;
|
|
826
825
|
scope?: "seller" | "admin" | undefined;
|
|
827
826
|
pageSize?: number | undefined;
|
|
827
|
+
storeId?: string | undefined;
|
|
828
828
|
isActive?: boolean | undefined;
|
|
829
829
|
filters?: string | undefined;
|
|
830
830
|
}>;
|
|
@@ -10,7 +10,7 @@ export async function ReviewDetailPageView({ id }) {
|
|
|
10
10
|
// storeId === storeSlug for stores in this project (pure slug IDs)
|
|
11
11
|
const storeSlug = doc?.storeId ?? null;
|
|
12
12
|
if (!review || review.status !== "approved") {
|
|
13
|
-
return (_jsx(Main, { children: _jsx(Section, { padding: "y-6xl", children: _jsx(Container, { size: "sm", children: _jsxs(Div, { className: "text-
|
|
13
|
+
return (_jsx(Main, { children: _jsx(Section, { padding: "y-6xl", children: _jsx(Container, { size: "sm", children: _jsxs(Div, { className: "text-left", children: [_jsx(Text, { className: "mb-4", size: "5xl", "aria-hidden": "true", children: "\uD83D\uDD0D" }), _jsx(Heading, { color: "inverse", level: 1, className: "text-[var(--appkit-color-text)] dark: mb-2", size: "2xl", weight: "bold", children: "Review not found" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)] mb-6", size: "sm", children: "This review may have been removed or is no longer available." }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "inline-flex items-center gap-[var(--appkit-space-2)] rounded-lg bg-primary px-[var(--appkit-space-5)] py-[var(--appkit-space-2-5)] text-[length:var(--appkit-text-sm)] font-medium text-white hover:bg-primary-600 transition-colors", children: "\u2190 Back to Reviews" })] }) }) }) }));
|
|
14
14
|
}
|
|
15
15
|
return (_jsxs(Main, { children: [_jsx(Div, { paddingY: "y-xs-tall", className: "border-b border-neutral-100 bg-neutral-50", padding: "x-md", children: _jsxs(Nav, { layout: "flex", gap: "2xs", textSize: "xs", color: "faint", className: "mx-auto max-w-3xl", "aria-label": "Breadcrumb", children: [_jsx(Link, { href: String(ROUTES.HOME), className: "hover:text-primary transition-colors", children: "Home" }), _jsx(Span, { children: "/" }), _jsx(Link, { href: String(ROUTES.PUBLIC.REVIEWS), className: "hover:text-primary transition-colors", children: "Reviews" }), _jsx(Span, { children: "/" }), _jsx(Span, { className: "text-neutral-700 truncate max-w-[200px]", children: review.title ?? review.id })] }) }), _jsx(ReviewDetailShell, { review: review, storeHref: storeSlug ? String(ROUTES.PUBLIC.STORE_DETAIL(storeSlug)) : null })] }));
|
|
16
16
|
}
|
|
@@ -3,22 +3,22 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import { normalizeError } from "../../../errors/normalize";
|
|
4
4
|
import { useState, useEffect, useCallback } from "react";
|
|
5
5
|
const __P = {
|
|
6
|
-
p4: "p-4",
|
|
6
|
+
p4: "p-[var(--appkit-space-4)]",
|
|
7
7
|
};
|
|
8
8
|
const __O = {
|
|
9
9
|
hidden: "overflow-hidden",
|
|
10
10
|
};
|
|
11
|
-
const CLS_RELATED_LINK = "group flex items-center gap-3 rounded-xl border border-neutral-200 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] p-4 hover:border-primary hover:shadow-sm transition-all";
|
|
12
|
-
const CLS_RELATED_LABEL = "text-xs text-[var(--appkit-color-text-faint)] mb-0.5";
|
|
13
|
-
const CLS_RELATED_TITLE = "text-sm font-medium text-[var(--appkit-color-text)] dark:text-white truncate group-hover:text-primary transition-colors";
|
|
14
|
-
const CLS_RATING_PILL = "inline-flex items-center gap-1 rounded-full bg-warning-surface px-3 py-1 text-warning dark:bg-warning-surface dark:text-warning";
|
|
11
|
+
const CLS_RELATED_LINK = "group flex items-center gap-[var(--appkit-space-3)] rounded-xl border border-neutral-200 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] p-[var(--appkit-space-4)] hover:border-primary hover:shadow-sm transition-all";
|
|
12
|
+
const CLS_RELATED_LABEL = "text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-faint)] mb-0.5";
|
|
13
|
+
const CLS_RELATED_TITLE = "text-[length:var(--appkit-text-sm)] font-medium text-[var(--appkit-color-text)] dark:text-white truncate group-hover:text-primary transition-colors";
|
|
14
|
+
const CLS_RATING_PILL = "inline-flex items-center gap-[var(--appkit-space-1)] rounded-full bg-warning-surface px-[var(--appkit-space-3)] py-[var(--appkit-space-1)] text-warning dark:bg-warning-surface dark:text-warning";
|
|
15
15
|
const CLS_HELPFUL_ACTIVE = "border-success bg-success-surface text-success dark:border-success cursor-default";
|
|
16
|
-
const CLS_ICON_ORANGE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-warning-surface dark:bg-warning-surface text-xl";
|
|
17
|
-
const CLS_ICON_BLUE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-info-surface dark:bg-info-surface text-xl";
|
|
18
|
-
const CLS_ICON_PURPLE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-purple-100 dark:bg-purple-900/30 text-xl";
|
|
16
|
+
const CLS_ICON_ORANGE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-warning-surface dark:bg-warning-surface text-[length:var(--appkit-text-xl)]";
|
|
17
|
+
const CLS_ICON_BLUE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-info-surface dark:bg-info-surface text-[length:var(--appkit-text-xl)]";
|
|
18
|
+
const CLS_ICON_PURPLE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-purple-100 dark:bg-purple-900/30 text-[length:var(--appkit-text-xl)]";
|
|
19
19
|
const CLS_ICON_PURPLE_BARE = "flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-purple-100 dark:bg-purple-900/30";
|
|
20
20
|
import Link from "next/link";
|
|
21
|
-
import { Div, Grid, Heading, RichText, Row, Section, Span, StarRating, Stack, Text } from "../../../ui";
|
|
21
|
+
import { Button, Div, Grid, Heading, IconButton, RichText, Row, Section, Span, StarRating, Stack, Text } from "../../../ui";
|
|
22
22
|
import { MediaImage } from "../../media/MediaImage";
|
|
23
23
|
import { maskName } from "../../../security";
|
|
24
24
|
import { getDefaultLocale } from "../../../core/baseline-resolver";
|
|
@@ -92,9 +92,9 @@ export function ReviewDetailShell({ review, storeHref }) {
|
|
|
92
92
|
? String(ROUTES.PUBLIC.PROFILE(reviewerProfileId))
|
|
93
93
|
: null;
|
|
94
94
|
const currentImage = lightboxIdx !== null ? images[lightboxIdx] : null;
|
|
95
|
-
return (_jsxs(_Fragment, { children: [_jsx(Div, { surface: "default", className: "border-b border-neutral-200 pt-[2.5rem]", padding: "b-xl", children: _jsxs(Div, { className: "mx-auto max-w-3xl", padding: "x-md", children: [_jsxs(Row, { gap: "sm", className: "mb-4", children: [_jsx(StarRating, { value: review.rating, size: "lg", readOnly: true }), _jsxs(Span, { color: "inverse", weight: "bold", className: "text-[var(--appkit-color-text)] dark:", size: "2xl", children: [review.rating, ".0"] }), review.verified && (_jsx(Span, { layout: "inline-flex", gap: "xs", color: "success", surface: "success-surface", size: "xs", weight: "semibold", rounded: "full", padding: "pill-md", children: "\u2713 Verified Purchase" })), review.featured && (_jsx(Span, { size: "xs", weight: "semibold", className: CLS_RATING_PILL, children: "\u2605 Featured" }))] }), review.title && (_jsx(Heading, { color: "inverse", level: 1, className: "text-[var(--appkit-color-text)] dark: mb-4 leading-snug", size: "2xl", weight: "bold", children: review.title })), _jsxs(Row, { gap: "sm", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-11 w-11 flex-shrink-0 ring-2 ring-white ring-[var(--appkit-color-border-subtle)]", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "bold", textSize: "base", centered: true, className: "h-11 w-11 flex-shrink-0 bg-primary/10 text-primary ring-2 ring-white ring-[var(--appkit-color-border-subtle)]", rounded: "full", children: initials })), _jsxs(Div, { className: "min-w-0", children: [reviewerHref ? (_jsx(Link, { href: reviewerHref, className: "text-sm font-semibold text-[var(--appkit-color-text)] dark:text-white hover:text-primary transition-colors", children: displayName })) : (_jsx(Span, { color: "inverse", size: "sm", weight: "semibold", className: "text-[var(--appkit-color-text)] dark:", children: review.isAnonymous ? "Anonymous" : displayName })), date && (_jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: date }))] })] })] }) }), _jsxs(Stack, { gap: "xl", className: "mx-auto max-w-3xl", paddingY: "y-xl", paddingX: "x-md", children: [review.comment && (_jsx(Section, { children: _jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-neutral dark:prose-invert max-w-none prose-p:leading-relaxed prose-headings:font-semibold prose-img:rounded-lg prose-a:text-primary", className: "text-neutral-700 text-[var(--appkit-color-text-muted)]" }) })), images.length > 0 && (_jsxs(Section, { children: [_jsxs(Heading, { level: 2, className: "tracking-wide mb-3", color: "faint", size: "sm", weight: "semibold", transform: "uppercase", children: ["Photos (", images.length, ")"] }), _jsx(Grid, { gap: "xs", className: "grid-cols-3 sm:grid-cols-4", children: images.map((img, i) => (_jsxs("
|
|
95
|
+
return (_jsxs(_Fragment, { children: [_jsx(Div, { surface: "default", className: "border-b border-neutral-200 pt-[2.5rem]", padding: "b-xl", children: _jsxs(Div, { className: "mx-auto max-w-3xl", padding: "x-md", children: [_jsxs(Row, { gap: "sm", className: "mb-4", children: [_jsx(StarRating, { value: review.rating, size: "lg", readOnly: true }), _jsxs(Span, { color: "inverse", weight: "bold", className: "text-[var(--appkit-color-text)] dark:", size: "2xl", children: [review.rating, ".0"] }), review.verified && (_jsx(Span, { layout: "inline-flex", gap: "xs", color: "success", surface: "success-surface", size: "xs", weight: "semibold", rounded: "full", padding: "pill-md", children: "\u2713 Verified Purchase" })), review.featured && (_jsx(Span, { size: "xs", weight: "semibold", className: CLS_RATING_PILL, children: "\u2605 Featured" }))] }), review.title && (_jsx(Heading, { color: "inverse", level: 1, className: "text-[var(--appkit-color-text)] dark: mb-4 leading-snug", size: "2xl", weight: "bold", children: review.title })), _jsxs(Row, { gap: "sm", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-11 w-11 flex-shrink-0 ring-2 ring-white ring-[var(--appkit-color-border-subtle)]", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "bold", textSize: "base", centered: true, className: "h-11 w-11 flex-shrink-0 bg-primary/10 text-primary ring-2 ring-white ring-[var(--appkit-color-border-subtle)]", rounded: "full", children: initials })), _jsxs(Div, { className: "min-w-0", children: [reviewerHref ? (_jsx(Link, { href: reviewerHref, className: "text-[length:var(--appkit-text-sm)] font-semibold text-[var(--appkit-color-text)] dark:text-white hover:text-primary transition-colors", children: displayName })) : (_jsx(Span, { color: "inverse", size: "sm", weight: "semibold", className: "text-[var(--appkit-color-text)] dark:", children: review.isAnonymous ? "Anonymous" : displayName })), date && (_jsx(Text, { size: "xs", color: "muted", className: "mt-0.5", children: date }))] })] })] }) }), _jsxs(Stack, { gap: "xl", className: "mx-auto max-w-3xl", paddingY: "y-xl", paddingX: "x-md", children: [review.comment && (_jsx(Section, { children: _jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-neutral dark:prose-invert max-w-none prose-p:leading-relaxed prose-headings:font-semibold prose-img:rounded-lg prose-a:text-primary", className: "text-neutral-700 text-[var(--appkit-color-text-muted)]" }) })), images.length > 0 && (_jsxs(Section, { children: [_jsxs(Heading, { level: 2, className: "tracking-wide mb-3", color: "faint", size: "sm", weight: "semibold", transform: "uppercase", children: ["Photos (", images.length, ")"] }), _jsx(Grid, { gap: "xs", className: "grid-cols-3 sm:grid-cols-4", children: images.map((img, i) => (_jsxs(Button, { variant: "ghost", type: "button", onClick: () => setLightboxIdx(i), "aria-label": `View photo ${i + 1}`, rounded: "xl", paddingX: "none", paddingY: "none", className: "group relative aspect-square overflow-hidden border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface-elevated)] focus-visible:ring-2 focus-visible:ring-primary", children: [_jsx(MediaImage, { src: img.thumbnailUrl ?? img.url, alt: `Review image ${i + 1}`, size: "card", className: "transition-transform duration-300 group-hover:scale-105" }), _jsx(Row, { centered: true, className: "absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity bg-[rgba(0,0,0,0.3)]", children: _jsx(Span, { color: "inverse", size: "xl", children: "\uD83D\uDD0D" }) })] }, i))) })] })), review.video && (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "tracking-wide mb-3", color: "faint", size: "sm", weight: "semibold", transform: "uppercase", children: "Video" }), _jsx(Div, { className: `${__O.hidden} border border-[var(--appkit-color-border)] bg-[rgb(0,0,0)] aspect-video`, rounded: "xl", children: _jsx("video", { src: review.video.url, poster: review.video.thumbnailUrl, controls: true, className: "h-full w-full", preload: "metadata" }) })] })), _jsxs(Section, { className: "flex items-[center] gap-[1rem] border-t border-neutral-100", padding: "y-md", children: [_jsx(Div, { textSize: "sm", className: "text-[var(--appkit-color-text-muted)]", children: helpfulCount > 0 && (_jsxs(Span, { children: [_jsx(Span, { color: "inverse", weight: "bold", className: "text-[var(--appkit-color-text)] dark:", children: helpfulCount }), " ", helpfulCount === 1 ? "person" : "people", " found this helpful"] })) }), _jsxs(Button, { variant: "outline", type: "button", onClick: handleVote, disabled: voted || voting, gap: "sm", rounded: "lg", paddingX: "md", paddingY: "sm", textSize: "sm", weight: "medium", className: `ml-auto transition-colors ${voted
|
|
96
96
|
? CLS_HELPFUL_ACTIVE
|
|
97
|
-
: "border-
|
|
97
|
+
: "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:border-primary hover:text-primary dark:hover:border-primary dark:hover:text-primary disabled:opacity-50"}`, children: [_jsx(Span, { "aria-hidden": "true", children: voted ? "✓" : "👍" }), voted ? "Marked helpful" : voting ? "Saving…" : "Helpful?"] })] }), _jsxs(Section, { className: "grid gap-[0.75rem] sm:grid-cols-3", children: [productHref && (_jsxs(Link, { href: productHref, className: CLS_RELATED_LINK, children: [_jsx(Span, { className: CLS_ICON_ORANGE, children: "\uD83D\uDCE6" }), _jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: CLS_RELATED_LABEL, children: "Product" }), _jsx(Text, { className: CLS_RELATED_TITLE, children: review.productTitle ?? "View Product" })] })] })), sellerHref && (_jsxs(Link, { href: sellerHref, className: CLS_RELATED_LINK, children: [_jsx(Span, { className: CLS_ICON_BLUE, children: "\uD83C\uDFEA" }), _jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: CLS_RELATED_LABEL, children: "Seller" }), _jsx(Text, { className: CLS_RELATED_TITLE, children: "View Seller" })] })] })), reviewerHref ? (_jsxs(Link, { href: reviewerHref, className: CLS_RELATED_LINK, children: [_jsx(Span, { className: CLS_ICON_PURPLE, children: "\uD83D\uDC64" }), _jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { className: CLS_RELATED_LABEL, children: "Reviewer" }), _jsx(Text, { className: CLS_RELATED_TITLE, children: displayName })] })] })) : (_jsxs(Row, { surface: "default", gap: "sm", className: `border border-neutral-200 dark:border-[var(--appkit-color-border)] ${__P.p4}`, rounded: "xl", children: [_jsx(Span, { size: "xl", className: CLS_ICON_PURPLE_BARE, children: "\uD83D\uDC64" }), _jsxs(Div, { className: "min-w-0", children: [_jsx(Span, { size: "xs", className: "block mb-0.5", color: "faint", children: "Reviewer" }), _jsx(Span, { color: "inverse", size: "sm", weight: "medium", className: "block text-[var(--appkit-color-text)] dark: truncate", children: "Anonymous" })] })] }))] })] }), lightboxIdx !== null && currentImage && (_jsxs(Row, { centered: true, className: "fixed inset-0 z-50 bg-[rgba(0,0,0,0.95)]", onClick: closeLightbox, role: "dialog", "aria-modal": "true", "aria-label": "Image lightbox", children: [_jsx(IconButton, { type: "button", onClick: closeLightbox, "aria-label": "Close lightbox", variant: "scrim", rounded: "full", className: "absolute top-4 right-4 z-10 h-10 w-10", children: _jsx(Span, { size: "xl", children: "\u00D7" }) }), _jsxs(Div, { textSize: "sm", className: "absolute top-4 left-1/2 -translate-x-1/2 text-white/70", children: [lightboxIdx + 1, " / ", images.length] }), images.length > 1 && (_jsx(IconButton, { type: "button", onClick: (e) => { e.stopPropagation(); prevImage(); }, "aria-label": "Previous image", variant: "scrim", rounded: "full", className: "absolute left-4 top-1/2 -translate-y-1/2 z-10 h-12 w-12", children: _jsx(Span, { size: "2xl", children: "\u2039" }) })), _jsx(Row, { centered: true, className: "relative h-[85vh] w-[85vw]", onClick: (e) => e.stopPropagation(), children: _jsx(MediaImage, { src: currentImage.url, alt: `Review photo ${lightboxIdx + 1}`, size: "hero", objectFit: "contain", rounded: "lg", shadow: "2xl" }) }), images.length > 1 && (_jsx(IconButton, { type: "button", onClick: (e) => { e.stopPropagation(); nextImage(); }, "aria-label": "Next image", variant: "scrim", rounded: "full", className: "absolute right-4 top-1/2 -translate-y-1/2 z-10 h-12 w-12", children: _jsx(Span, { size: "2xl", children: "\u203A" }) })), images.length > 1 && (_jsx(Row, { justify: "center", gap: "xs", className: "absolute bottom-4 left-0 right-0", padding: "x-md", children: images.map((img, i) => (_jsx(Button, { variant: "ghost", type: "button", onClick: (e) => { e.stopPropagation(); setLightboxIdx(i); }, "aria-label": `Go to image ${i + 1}`, rounded: "md", paddingX: "none", paddingY: "none", className: `h-12 w-12 flex-shrink-0 overflow-hidden border-2 transition-all ${i === lightboxIdx
|
|
98
98
|
? "border-white scale-110"
|
|
99
99
|
: "border-transparent opacity-60 hover:opacity-100"}`, children: _jsx(MediaImage, { src: img.thumbnailUrl ?? img.url, alt: `Thumbnail ${i + 1}`, size: "thumbnail" }) }, i))) }))] }))] }));
|
|
100
100
|
}
|
|
@@ -24,5 +24,5 @@ export function ViewReviewModal({ review, isOpen, onClose, }) {
|
|
|
24
24
|
day: "numeric",
|
|
25
25
|
})
|
|
26
26
|
: "";
|
|
27
|
-
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Review Details", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "3", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-10 w-10 flex-shrink-0", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-10 w-10 flex-shrink-0 bg-neutral-200 text-[var(--appkit-color-text-muted)]", align: "center", justify: "center", rounded: "full", children: displayName.charAt(0).toUpperCase() })), _jsxs(Div, { children: [_jsxs(Row, { gap: "sm", children: [_jsx(Text, { color: "inverse", className: "text-[var(--appkit-color-text)] dark:", weight: "medium", children: displayName }), review.verified && (_jsx(Text, { className: THEMED_TEXT_SUCCESS, size: "xs", children: "\u2713 Verified purchase" }))] }), _jsxs(Row, { className: "mt-0.5", gap: "sm", children: [_jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }), date && (_jsx(Text, { size: "xs", color: "faint", children: date }))] })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "text-[var(--appkit-color-text)] dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-sm leading-relaxed text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", children: review.images.map((img, i) => (_jsx("
|
|
27
|
+
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: "Review Details", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Row, { gap: "3", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-10 w-10 flex-shrink-0", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-10 w-10 flex-shrink-0 bg-neutral-200 text-[var(--appkit-color-text-muted)]", align: "center", justify: "center", rounded: "full", children: displayName.charAt(0).toUpperCase() })), _jsxs(Div, { children: [_jsxs(Row, { gap: "sm", children: [_jsx(Text, { color: "inverse", className: "text-[var(--appkit-color-text)] dark:", weight: "medium", children: displayName }), review.verified && (_jsx(Text, { className: THEMED_TEXT_SUCCESS, size: "xs", children: "\u2713 Verified purchase" }))] }), _jsxs(Row, { className: "mt-0.5", gap: "sm", children: [_jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }), date && (_jsx(Text, { size: "xs", color: "faint", children: date }))] })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "text-[var(--appkit-color-text)] dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "text-[length:var(--appkit-text-sm)] leading-relaxed text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", children: review.images.map((img, i) => (_jsx(Button, { variant: "ghost", type: "button", "aria-label": `View image ${i + 1}`, onClick: () => setLightboxIdx(i), rounded: "lg", paddingX: "none", paddingY: "none", className: `h-20 w-20 overflow-hidden transition hover:opacity-80 flex-shrink-0 ${lightboxIdx === i ? "ring-2 ring-primary-500" : "border-neutral-100 border-[var(--appkit-color-border)]"}`, children: _jsx(MediaImage, { src: img.thumbnailUrl ?? img.url, alt: `Review thumbnail ${i + 1}`, size: "thumbnail" }) }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { size: "xs", color: "faint", children: [review.helpfulCount, " people found this helpful"] })), _jsx(Row, { justify: "end", padding: "t-xs", children: _jsx(Button, { variant: "ghost", onClick: onClose, children: "Close" }) })] }) }));
|
|
28
28
|
}
|
|
@@ -10,7 +10,7 @@ import { TABLE_KEYS, VIEW_MODE } from "../../../constants/table-keys";
|
|
|
10
10
|
import { sortBy } from "../../../constants/sort";
|
|
11
11
|
import { REVIEW_FIELDS } from "../../../constants/field-names";
|
|
12
12
|
const __P = {
|
|
13
|
-
p4: "p-4",
|
|
13
|
+
p4: "p-[var(--appkit-space-4)]",
|
|
14
14
|
};
|
|
15
15
|
const __O = {
|
|
16
16
|
hidden: "overflow-hidden",
|
|
@@ -108,5 +108,5 @@ export function ReviewsIndexListing({ initialData, variant = "public", }) {
|
|
|
108
108
|
value: opt.value,
|
|
109
109
|
label: SORT_OPTION_LABELS[opt.key] ?? opt.key,
|
|
110
110
|
}));
|
|
111
|
-
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews by product name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: _jsxs(Stack, { className: `${__P.p4}`, gap: "3", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "
|
|
111
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews by product name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx(Row, { border: "bottom", className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 backdrop-blur-sm", surface: "default", padding: "toolbar", justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { padding: "y-lg", children: isLoading ? (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => (_jsx(Div, { className: `${__O.hidden} animate-pulse`, border: "subtle", rounded: "xl", children: _jsxs(Stack, { className: `${__P.p4}`, gap: "3", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-full", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-2/3", surface: "subtle", rounded: "default" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { paddingY: "3xl", color: "muted", size: "sm", align: "start", children: "No reviews found." })) : view === "list" ? (_jsx(Stack, { className: "divide-y divide-zinc-100 divide-[var(--appkit-color-border-subtle)]", border: "subtle", rounded: "xl", children: reviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) })) : (_jsx(Div, { layout: "grid", gap: "6", className: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3", children: reviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(ReviewFilters, { table: pendingTable, variant: variant }) })] }));
|
|
112
112
|
}
|
|
@@ -28,14 +28,14 @@ export function ReviewCard({ review, context = "general", className = "" }) {
|
|
|
28
28
|
const showProductLink = context !== "listing" && !!productHref;
|
|
29
29
|
const showProfileLink = !!profileHref;
|
|
30
30
|
const hasFooter = showStoreLink || showProductLink || showProfileLink;
|
|
31
|
-
return (_jsxs(Stack, { padding: "5", shadow: "hover-md", className: `group h-full border border-neutral-200 transition ${className}`, rounded: "xl", surface: "default", children: [_jsxs(Link, { href: reviewHref, className: "flex flex-col flex-1 min-h-0", children: [_jsxs(Row, { align: "start", gap: "3", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-9 w-9 flex-shrink-0", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-9 w-9 flex-shrink-0 bg-neutral-200 text-[var(--appkit-color-text-muted)]", align: "center", justify: "center", rounded: "full", children: initials })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { wrap: true, gap: "sm", children: [_jsx(Span, { color: "inverse", weight: "medium", className: "text-[var(--appkit-color-text)] dark:", children: displayName }), review.verified && (_jsx(Span, { color: "success", surface: "success-surface", size: "xs", weight: "medium", rounded: "full", padding: "pill-xs", children: "Verified" })), date && (_jsx(Span, { size: "xs", color: "muted", children: date }))] }), _jsx(Div, { className: "mt-1", children: _jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }) })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "mt-3 text-[var(--appkit-color-text)] dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "mt-2 text-sm leading-relaxed text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mt-3", children: review.images.map((img, i) => (_jsx(Div, { className: "relative h-16 w-16 flex-shrink-0 border border-neutral-100", rounded: "lg", overflow: "hidden", children: _jsx(MediaImage, { src: img.thumbnailUrl ?? img.url, alt: `Review image ${i + 1}`, size: "thumbnail" }) }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { className: "mt-3", color: "faint", size: "xs", children: [review.helpfulCount, " found this helpful"] }))] }), hasFooter && (_jsxs(Stack, { gap: "xs", className: "mt-3 border-t border-neutral-100", padding: "t-sm", children: [showStoreLink && (_jsxs(Link, { href: String(ROUTES.PUBLIC.STORE_DETAIL(review.storeSlug)), className: "flex items-center gap-1
|
|
31
|
+
return (_jsxs(Stack, { padding: "5", shadow: "hover-md", className: `group h-full border border-neutral-200 transition ${className}`, rounded: "xl", surface: "default", children: [_jsxs(Link, { href: reviewHref, className: "flex flex-col flex-1 min-h-0", children: [_jsxs(Row, { align: "start", gap: "3", children: [review.userAvatar ? (_jsx(Div, { className: "relative h-9 w-9 flex-shrink-0", rounded: "full", overflow: "hidden", children: _jsx(MediaImage, { src: review.userAvatar, alt: displayName, size: "avatar" }) })) : (_jsx(Row, { textWeight: "medium", textSize: "sm", className: "h-9 w-9 flex-shrink-0 bg-neutral-200 text-[var(--appkit-color-text-muted)]", align: "center", justify: "center", rounded: "full", children: initials })), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Row, { wrap: true, gap: "sm", children: [_jsx(Span, { color: "inverse", weight: "medium", className: "text-[var(--appkit-color-text)] dark:", children: displayName }), review.verified && (_jsx(Span, { color: "success", surface: "success-surface", size: "xs", weight: "medium", rounded: "full", padding: "pill-xs", children: "Verified" })), date && (_jsx(Span, { size: "xs", color: "muted", children: date }))] }), _jsx(Div, { className: "mt-1", children: _jsx(StarRating, { value: review.rating, size: "sm", readOnly: true }) })] })] }), review.title && (_jsx(Heading, { color: "inverse", level: 4, className: "mt-3 text-[var(--appkit-color-text)] dark:", weight: "semibold", children: review.title })), review.comment && (_jsx(RichText, { html: normalizeRichTextHtml(review.comment), proseClass: "prose prose-sm max-w-none dark:prose-invert prose-p:my-0", className: "mt-2 text-[length:var(--appkit-text-sm)] leading-relaxed text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)]" })), review.images && review.images.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mt-3", children: review.images.map((img, i) => (_jsx(Div, { className: "relative h-16 w-16 flex-shrink-0 border border-neutral-100", rounded: "lg", overflow: "hidden", children: _jsx(MediaImage, { src: img.thumbnailUrl ?? img.url, alt: `Review image ${i + 1}`, size: "thumbnail" }) }, i))) })), (review.helpfulCount ?? 0) > 0 && (_jsxs(Text, { className: "mt-3", color: "faint", size: "xs", children: [review.helpfulCount, " found this helpful"] }))] }), hasFooter && (_jsxs(Stack, { gap: "xs", className: "mt-3 border-t border-neutral-100", padding: "t-sm", children: [showStoreLink && (_jsxs(Link, { href: String(ROUTES.PUBLIC.STORE_DETAIL(review.storeSlug)), className: "flex items-center gap-[var(--appkit-space-1-5)] text-[length:var(--appkit-text-xs)] font-medium text-primary hover:underline", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83C\uDFEA" }), _jsx(Span, { truncate: true, children: review.storeName })] })), showProductLink && (_jsxs(Link, { href: productHref, className: "flex items-center gap-[var(--appkit-space-1-5)] text-[length:var(--appkit-text-xs)] font-medium text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:text-neutral-700 hover:text-[var(--appkit-color-text-muted)]", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDCE6" }), _jsx(Span, { truncate: true, children: review.productTitle ?? "View Product" }), _jsx(Span, { "aria-hidden": "true", className: "ml-auto text-primary group-hover:translate-x-0.5 transition-transform", children: "\u2192" })] })), showProfileLink && (_jsxs(Link, { href: profileHref, className: "flex items-center gap-[var(--appkit-space-1-5)] text-[length:var(--appkit-text-xs)] font-medium text-[var(--appkit-color-text-muted)] text-[var(--appkit-color-text-muted)] hover:text-neutral-700 hover:text-[var(--appkit-color-text-muted)]", children: [_jsx(Span, { "aria-hidden": "true", children: "\uD83D\uDC64" }), _jsx(Span, { truncate: true, children: displayName })] }))] }))] }));
|
|
32
32
|
}
|
|
33
33
|
export function ReviewsList({ reviews, context = "general", isLoading, totalPages = 1, currentPage = 1, onPageChange, emptyLabel = "No reviews yet", }) {
|
|
34
34
|
if (isLoading) {
|
|
35
35
|
return (_jsx(Stack, { gap: "md", children: Array.from({ length: 4 }).map((_, i) => (_jsxs(Div, { padding: "5", className: "border border-neutral-200", rounded: "xl", children: [_jsxs(Row, { gap: "3", children: [_jsx(Skeleton, { className: "h-9 w-9 rounded-full" }), _jsxs(Stack, { gap: "sm", className: "flex-1", children: [_jsx(Skeleton, { className: "h-4 w-24 rounded" }), _jsx(Skeleton, { className: "h-3 w-16 rounded" })] })] }), _jsxs(Stack, { gap: "xs", className: "mt-3", children: [_jsx(Skeleton, { className: "h-3 w-full rounded" }), _jsx(Skeleton, { className: "h-3 w-3/4 rounded" })] })] }, i))) }));
|
|
36
36
|
}
|
|
37
37
|
if (reviews.length === 0) {
|
|
38
|
-
return (_jsx(Text, { paddingY: "3xl", className: "text-[var(--appkit-color-text-muted)]", size: "sm", align: "
|
|
38
|
+
return (_jsx(Text, { paddingY: "3xl", className: "text-[var(--appkit-color-text-muted)]", size: "sm", align: "start", children: emptyLabel }));
|
|
39
39
|
}
|
|
40
40
|
return (_jsxs(Stack, { gap: "lg", children: [_jsx(Stack, { gap: "md", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: context }, review.id))) }), totalPages > 1 && onPageChange && (_jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: onPageChange }) }))] }));
|
|
41
41
|
}
|