@mohasinac/appkit 2.8.2 → 2.8.4
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 +7 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +4 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +7 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +3 -2
- package/dist/_internal/client/features/live/LiveItemDetailView.js +11 -2
- package/dist/_internal/client/scaffolds/AppShell.js +2 -1
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +2 -1
- package/dist/_internal/server/features/checkout/actions.js +40 -39
- package/dist/_internal/shared/actions/action-registry.js +6 -0
- package/dist/_internal/shared/config/index.d.ts +1 -1
- package/dist/_internal/shared/config/schema.d.ts +0 -8
- package/dist/client-entry.d.ts +1 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +3 -1
- package/dist/configs/next.js +12 -22
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/features/about/components/AboutView.js +5 -2
- package/dist/features/about/components/FAQPageView.js +3 -3
- package/dist/features/about/components/FeesView.js +13 -5
- package/dist/features/about/components/HelpPageView.js +9 -5
- package/dist/features/about/components/HowAuctionsWorkView.js +9 -5
- package/dist/features/about/components/HowCheckoutWorksView.js +9 -5
- package/dist/features/about/components/HowOffersWorkView.js +10 -5
- package/dist/features/about/components/HowOrdersWorkView.js +10 -5
- package/dist/features/about/components/HowPayoutsWorkView.js +9 -5
- package/dist/features/about/components/HowPreOrdersWorkView.js +9 -5
- package/dist/features/about/components/HowReviewsWorkView.js +9 -5
- package/dist/features/about/components/PolicyPageView.js +3 -3
- package/dist/features/about/components/PublicProfileView.js +11 -4
- package/dist/features/about/components/SecurityPrivacyView.js +8 -4
- package/dist/features/about/components/ShippingPolicyView.js +3 -2
- package/dist/features/about/components/TrackOrderView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +3 -3
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +2 -2
- package/dist/features/account/components/AddressInlineSelect.d.ts +24 -0
- package/dist/features/account/components/AddressInlineSelect.js +78 -0
- package/dist/features/account/components/AddressSelectorCreate.d.ts +2 -1
- package/dist/features/account/components/AddressSelectorCreate.js +5 -32
- package/dist/features/account/components/AddressesIndexListing.js +3 -3
- package/dist/features/account/components/ChatWindow.js +2 -1
- package/dist/features/account/components/NotificationBell.js +13 -7
- package/dist/features/account/components/NotificationPreferencesPanel.js +4 -1
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/account/components/UserSidebar.js +11 -7
- package/dist/features/account/components/UserSupportView.js +13 -4
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/addresses/repository/addresses.repository.d.ts +1 -0
- package/dist/features/addresses/repository/addresses.repository.js +13 -0
- package/dist/features/admin/components/AdminAdEditorView.js +8 -5
- package/dist/features/admin/components/AdminAddressEditorView.js +5 -5
- package/dist/features/admin/components/AdminAdsView.js +10 -7
- package/dist/features/admin/components/AdminAllEventEntriesView.js +5 -3
- package/dist/features/admin/components/AdminBidsView.js +6 -4
- package/dist/features/admin/components/AdminBlogEditorView.js +15 -9
- package/dist/features/admin/components/AdminBlogView.js +6 -4
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -4
- package/dist/features/admin/components/AdminBrandsView.js +12 -10
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +13 -11
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +6 -6
- package/dist/features/admin/components/AdminCartsView.js +6 -4
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -1
- package/dist/features/admin/components/AdminCategoriesView.js +12 -10
- package/dist/features/admin/components/AdminCategoryEditorView.js +11 -5
- package/dist/features/admin/components/AdminClassifiedView.js +4 -3
- package/dist/features/admin/components/AdminContactEditorView.js +8 -1
- package/dist/features/admin/components/AdminContactView.js +6 -4
- package/dist/features/admin/components/AdminCouponEditorView.js +23 -5
- package/dist/features/admin/components/AdminCouponsView.js +6 -4
- package/dist/features/admin/components/AdminDigitalCodesView.js +4 -3
- package/dist/features/admin/components/AdminEmployeeEditorView.js +7 -4
- package/dist/features/admin/components/AdminFaqEditorView.js +9 -3
- package/dist/features/admin/components/AdminFaqsView.js +9 -7
- package/dist/features/admin/components/AdminFeatureEditorView.js +7 -1
- package/dist/features/admin/components/AdminFeatureFlagsView.js +4 -1
- package/dist/features/admin/components/AdminFeaturesView.js +5 -4
- package/dist/features/admin/components/AdminFilterBar.js +4 -4
- package/dist/features/admin/components/AdminGroupedListingsView.js +66 -30
- package/dist/features/admin/components/AdminGuideHubView.js +4 -1
- package/dist/features/admin/components/AdminHistoryView.js +4 -3
- package/dist/features/admin/components/AdminLiveView.js +4 -3
- package/dist/features/admin/components/AdminMediaView.js +4 -1
- package/dist/features/admin/components/AdminNavigationView.js +7 -4
- package/dist/features/admin/components/AdminNewsletterView.js +5 -3
- package/dist/features/admin/components/AdminNotificationsView.js +8 -6
- package/dist/features/admin/components/AdminOrderEditorView.js +2 -2
- package/dist/features/admin/components/AdminOrdersView.js +6 -4
- package/dist/features/admin/components/AdminPageHeader.js +5 -2
- package/dist/features/admin/components/AdminPayoutsView.js +7 -5
- package/dist/features/admin/components/AdminPrizeDrawsView.js +11 -9
- package/dist/features/admin/components/AdminProductEditorView.js +12 -5
- package/dist/features/admin/components/AdminProductsView.js +11 -9
- package/dist/features/admin/components/AdminReturnRequestsView.js +4 -3
- package/dist/features/admin/components/AdminReviewsView.js +10 -8
- package/dist/features/admin/components/AdminScammerEditorView.js +6 -2
- package/dist/features/admin/components/AdminScammersView.js +11 -9
- package/dist/features/admin/components/AdminSectionsView.js +20 -22
- package/dist/features/admin/components/AdminSessionsManager.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +8 -6
- package/dist/features/admin/components/AdminSidebar.js +11 -7
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +2 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +5 -1
- package/dist/features/admin/components/AdminStoreAddressesView.js +4 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +5 -5
- package/dist/features/admin/components/AdminStoresView.js +6 -4
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +6 -5
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +3 -3
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +10 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +11 -9
- package/dist/features/admin/components/AdminTeamView.js +6 -4
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersView.js +6 -4
- package/dist/features/admin/components/AdminViewCards.js +12 -6
- package/dist/features/admin/components/AdminWishlistsView.js +4 -3
- package/dist/features/admin/components/BrandQuickCreateForm.js +2 -2
- package/dist/features/admin/components/CategoryQuickCreateForm.js +2 -2
- package/dist/features/admin/components/DashboardStats.js +9 -3
- package/dist/features/admin/components/DataListingView.js +3 -3
- package/dist/features/admin/components/DataTable.js +11 -7
- package/dist/features/admin/components/DrawerFormFooter.js +2 -2
- package/dist/features/admin/components/QuickEditMenu.js +2 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +5 -1
- package/dist/features/admin/constants/filter-tabs.d.ts +1 -1
- package/dist/features/admin/constants/filter-tabs.js +0 -11
- package/dist/features/admin/types/index.d.ts +1 -1
- package/dist/features/auctions/actions/bid-actions.js +4 -2
- package/dist/features/auctions/components/AuctionBidsTable.js +4 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +14 -6
- package/dist/features/auctions/components/AuctionsListView.js +7 -6
- package/dist/features/auctions/components/CollapsibleBidHistory.js +5 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +8 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +4 -1
- package/dist/features/auth/components/RegisterForm.js +2 -2
- package/dist/features/auth/components/VerifyEmailView.js +5 -2
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/actions/blog-actions.js +3 -2
- package/dist/features/blog/components/BlogFeaturedCard.js +8 -1
- package/dist/features/blog/components/BlogIndexListing.js +11 -5
- package/dist/features/blog/components/BlogListView.js +11 -3
- package/dist/features/blog/components/BlogPostView.js +10 -3
- package/dist/features/cart/components/CartDrawer.js +11 -3
- package/dist/features/cart/components/CartSummary.js +2 -2
- package/dist/features/cart/components/CheckoutOtpModal.js +2 -1
- package/dist/features/categories/components/BrandDetailPageView.js +15 -10
- package/dist/features/categories/components/BrandDetailTabs.js +5 -1
- package/dist/features/categories/components/BundleDetailView.js +6 -3
- package/dist/features/categories/components/BundleDynamicRuleEditor.js +3 -1
- package/dist/features/categories/components/BundleItemsPicker.js +10 -3
- package/dist/features/categories/components/CategoriesIndexListing.js +13 -7
- package/dist/features/categories/components/CategoriesIndexPageView.js +5 -4
- package/dist/features/categories/components/CategoryBundlesListing.js +10 -6
- package/dist/features/categories/components/CategoryDetailPageView.js +18 -12
- package/dist/features/categories/components/CategoryDetailTabs.js +5 -1
- package/dist/features/categories/components/CategoryFilters.d.ts +12 -12
- package/dist/features/categories/components/CategoryFilters.js +13 -12
- package/dist/features/categories/components/CategoryForm.js +6 -3
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/categories/components/CategoryProductsListing.js +10 -4
- package/dist/features/categories/components/CategorySelectorCreate.js +3 -3
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +3 -3
- package/dist/features/categories/components/CategoryTableColumns.js +10 -6
- package/dist/features/categories/components/CategoryTree.d.ts +1 -1
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +2 -2
- package/dist/features/checkout/actions/checkout-actions.d.ts +1 -1
- package/dist/features/checkout/actions/checkout-actions.js +1 -1
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/classified/components/ClassifiedListView.js +6 -5
- package/dist/features/collections/components/CollectionCard.js +2 -1
- package/dist/features/contact/components/ContactForm.js +4 -2
- package/dist/features/contact/components/ContactInfoSidebar.js +4 -1
- package/dist/features/copilot/components/AdminCopilotView.js +13 -5
- package/dist/features/cron/jobs/auction-expiry.job.d.ts +2 -2
- package/dist/features/cron/jobs/auction-expiry.job.js +2 -1
- package/dist/features/cron/jobs/preorder-reminder.job.d.ts +1 -1
- package/dist/features/cron/jobs/preorder-reminder.job.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +9 -3
- package/dist/features/digital-codes/components/DigitalCodesListView.js +4 -3
- package/dist/features/events/actions/event-actions.js +6 -4
- package/dist/features/events/components/AdminEventEditorView.js +63 -41
- package/dist/features/events/components/AdminEventEntriesView.js +9 -6
- package/dist/features/events/components/AdminEventsView.js +7 -5
- package/dist/features/events/components/EventCard.js +7 -1
- package/dist/features/events/components/EventFilters.d.ts +4 -4
- package/dist/features/events/components/EventFilters.js +2 -2
- package/dist/features/events/components/EventFormDrawer.js +2 -1
- package/dist/features/events/components/EventLeaderboard.js +4 -4
- package/dist/features/events/components/EventOfferCard.js +4 -1
- package/dist/features/events/components/EventParticipateView.js +3 -2
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +5 -2
- package/dist/features/events/components/EventRaffleWinnerView.js +7 -1
- package/dist/features/events/components/EventRafflesSection.js +6 -4
- package/dist/features/events/components/EventSaleBanner.js +5 -2
- package/dist/features/events/components/EventsIndexListing.js +8 -2
- package/dist/features/events/components/EventsListView.js +4 -1
- package/dist/features/events/components/SpinWheelView.js +7 -2
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/types/index.d.ts +1 -0
- package/dist/features/faq/actions/faq-actions.js +4 -2
- package/dist/features/faq/components/ContactCTA.js +4 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +8 -5
- package/dist/features/faq/components/FAQPageContent.js +7 -6
- package/dist/features/faq/components/FAQSortDropdown.js +2 -2
- package/dist/features/filters/AsyncFacetSection.js +4 -2
- package/dist/features/filters/FilterFacetSection.js +14 -6
- package/dist/features/filters/RangeFilter.js +4 -2
- package/dist/features/filters/SwitchFilter.js +2 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Radio.js +1 -1
- package/dist/features/forms/Slider.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +13 -4
- package/dist/features/homepage/components/AnnouncementBar.js +2 -1
- package/dist/features/homepage/components/BeforeAfterCard.js +8 -2
- package/dist/features/homepage/components/BrandsSection.js +6 -3
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +5 -2
- package/dist/features/homepage/components/CharacterHotspotForm.js +8 -4
- package/dist/features/homepage/components/CustomCardsSection.js +13 -7
- package/dist/features/homepage/components/CustomerReviewsSection.js +9 -3
- package/dist/features/homepage/components/FAQSection.js +7 -4
- package/dist/features/homepage/components/FeaturedBundlesSection.js +8 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +14 -8
- package/dist/features/homepage/components/HeroCarousel.js +1 -1
- package/dist/features/homepage/components/HomepageSkeleton.js +7 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +2 -2
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/MarketplaceHomepageView.js +4 -2
- package/dist/features/homepage/components/NewsletterBanner.js +3 -2
- package/dist/features/homepage/components/NewsletterSection.js +5 -2
- package/dist/features/homepage/components/PromoGrid.js +4 -1
- package/dist/features/homepage/components/SectionCarousel.js +7 -4
- package/dist/features/homepage/components/SecurityHighlightsSection.js +3 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -4
- package/dist/features/homepage/components/SiteFeaturesSection.js +5 -2
- package/dist/features/homepage/components/SocialFeedSection.js +4 -4
- package/dist/features/homepage/components/SocialPostCard.js +6 -3
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
- package/dist/features/homepage/components/TrustIndicatorsSection.js +5 -2
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +3 -3
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BackToTop.js +1 -1
- package/dist/features/layout/BottomActions.js +4 -30
- package/dist/features/layout/BottomActionsContext.d.ts +0 -36
- package/dist/features/layout/BottomActionsContext.js +0 -36
- package/dist/features/layout/BottomNavItem.js +1 -1
- package/dist/features/layout/BottomSheet.js +4 -1
- package/dist/features/layout/FooterLayout.js +1 -1
- package/dist/features/layout/NavbarLayout.js +4 -1
- package/dist/features/layout/SidebarLayout.js +5 -2
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +9 -3
- package/dist/features/live/components/LiveItemsListView.js +6 -5
- package/dist/features/loyalty/components/CoinsDisplay.js +4 -2
- package/dist/features/media/AvatarUpload.js +2 -2
- package/dist/features/media/MediaLightbox.js +3 -2
- package/dist/features/media/modals/VideoThumbnailSelector.js +4 -1
- package/dist/features/media/modals/VideoTrimModal.js +1 -1
- package/dist/features/media/upload/CameraCapture.js +1 -1
- package/dist/features/media/upload/ImageUpload.js +4 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -2
- package/dist/features/media/upload/MediaUploadList.js +5 -1
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -2
- package/dist/features/orders/components/OrdersList.js +2 -1
- package/dist/features/orders/components/RefundHistoryTable.js +4 -1
- package/dist/features/orders/components/RefundRequestView.js +2 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -1
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +3 -3
- package/dist/features/pre-orders/components/PreOrderBadge.js +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +16 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +32 -24
- package/dist/features/pre-orders/components/PreOrdersListView.js +5 -4
- package/dist/features/products/actions/product-actions.js +17 -15
- package/dist/features/products/columns/index.d.ts +1 -1
- package/dist/features/products/columns/index.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +9 -4
- package/dist/features/products/components/AuctionsIndexListing.js +9 -3
- package/dist/features/products/components/BidHistory.js +4 -4
- package/dist/features/products/components/CompareOverlay.js +10 -2
- package/dist/features/products/components/CustomFieldsEditor.js +2 -1
- package/dist/features/products/components/CustomSectionTabContent.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -2
- package/dist/features/products/components/GroupSettingsPanel.js +34 -26
- package/dist/features/products/components/MakeOfferButton.js +6 -2
- package/dist/features/products/components/MakeOfferForm.js +2 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +6 -3
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +3 -2
- package/dist/features/products/components/PlaceBidForm.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -16
- package/dist/features/products/components/PrizeDrawDetailPageView.js +6 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +6 -3
- package/dist/features/products/components/PrizeDrawsListingView.js +5 -4
- package/dist/features/products/components/PrizeDrawsSection.js +6 -4
- package/dist/features/products/components/PrizeRevealModal.js +5 -1
- package/dist/features/products/components/ProductDetailPageView.js +32 -16
- package/dist/features/products/components/ProductFeatureBadges.js +9 -9
- package/dist/features/products/components/ProductForm.d.ts +11 -1
- package/dist/features/products/components/ProductForm.js +10 -5
- package/dist/features/products/components/ProductGalleryClient.js +8 -4
- package/dist/features/products/components/ProductGradingTab.js +4 -1
- package/dist/features/products/components/ProductGrid.js +35 -14
- package/dist/features/products/components/ProductInfo.js +2 -1
- package/dist/features/products/components/ProductTabs.js +2 -1
- package/dist/features/products/components/ProductTabsShell.js +5 -1
- package/dist/features/products/components/ProductsIndexListing.js +32 -24
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/components/RelatedProducts.js +3 -3
- package/dist/features/products/components/ShowGroupSection.js +10 -6
- package/dist/features/products/components/SublistingCarouselSection.js +7 -3
- package/dist/features/products/components/SublistingCategorySelect.d.ts +3 -1
- package/dist/features/products/components/SublistingCategorySelect.js +4 -37
- package/dist/features/products/constants/action-defs.js +3 -3
- package/dist/features/products/constants/sieve.d.ts +2 -2
- package/dist/features/products/constants/sieve.js +2 -2
- package/dist/features/products/hooks/useRelatedProducts.js +5 -4
- package/dist/features/promotions/components/CouponCard.js +5 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +7 -3
- package/dist/features/promotions/repository/coupons.repository.d.ts +8 -0
- package/dist/features/promotions/repository/coupons.repository.js +2 -0
- package/dist/features/reviews/actions/review-actions.js +2 -1
- package/dist/features/reviews/components/ReviewDetailPageView.js +3 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +15 -3
- package/dist/features/reviews/components/ReviewSummary.js +4 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +8 -2
- package/dist/features/reviews/components/ReviewsIndexPageView.js +7 -6
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/actions/scam-actions.js +3 -2
- 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 +11 -8
- package/dist/features/search/actions/search-actions.js +7 -6
- package/dist/features/search/components/Search.js +9 -6
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +1 -1
- package/dist/features/seller/components/CouponInlineSelect.d.ts +22 -0
- package/dist/features/seller/components/CouponInlineSelect.js +104 -0
- package/dist/features/seller/components/GroupInlineSelect.d.ts +23 -0
- package/dist/features/seller/components/GroupInlineSelect.js +80 -0
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -1
- package/dist/features/seller/components/PrintCenterView.js +2 -1
- package/dist/features/seller/components/ProductInlineSelect.d.ts +24 -0
- package/dist/features/seller/components/ProductInlineSelect.js +42 -0
- package/dist/features/seller/components/QuickProductForm.js +4 -1
- package/dist/features/seller/components/SellerAddressesView.js +8 -3
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +6 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerAuctionsView.js +7 -5
- package/dist/features/seller/components/SellerBidsView.js +12 -10
- package/dist/features/seller/components/SellerBundlesView.js +9 -7
- package/dist/features/seller/components/SellerClassifiedView.js +6 -5
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +2 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +15 -3
- package/dist/features/seller/components/SellerCouponsView.js +7 -5
- package/dist/features/seller/components/SellerDashboardView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +7 -6
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -2
- package/dist/features/seller/components/SellerGroupedListingsView.js +10 -9
- package/dist/features/seller/components/SellerLiveView.js +6 -5
- package/dist/features/seller/components/SellerOffersView.js +6 -4
- package/dist/features/seller/components/SellerOrdersView.js +18 -13
- package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -6
- package/dist/features/seller/components/SellerPayoutRequestView.js +5 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -2
- package/dist/features/seller/components/SellerPayoutsView.js +6 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +12 -10
- package/dist/features/seller/components/SellerPrizeDrawsView.js +12 -10
- package/dist/features/seller/components/SellerProductShell.js +1 -1
- package/dist/features/seller/components/SellerProductsCards.js +4 -1
- package/dist/features/seller/components/SellerProductsView.js +14 -12
- package/dist/features/seller/components/SellerReviewsView.js +7 -3
- package/dist/features/seller/components/SellerShippingConfigsView.js +7 -6
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +15 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +5 -4
- package/dist/features/seller/components/SellerStorefrontView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +11 -7
- package/dist/features/seller/components/SublistingInlineSelect.d.ts +19 -0
- package/dist/features/seller/components/SublistingInlineSelect.js +84 -0
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/components/index.d.ts +8 -0
- package/dist/features/seller/components/index.js +4 -0
- package/dist/features/shell/FormShell.js +10 -2
- package/dist/features/shell/QuickFormDrawer.js +5 -5
- package/dist/features/shell/StepForm.js +6 -6
- package/dist/features/site-settings/components/ActionPermissionsManager.js +8 -4
- package/dist/features/site-settings/components/NavPermissionsManager.js +7 -4
- package/dist/features/stores/actions/store-query-actions.js +3 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +5 -1
- package/dist/features/stores/components/StoreAboutView.js +4 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.d.ts +2 -1
- package/dist/features/stores/components/StoreAddressSelectorCreate.js +5 -31
- package/dist/features/stores/components/StoreAuctionsListing.js +6 -3
- package/dist/features/stores/components/StoreAuctionsPageView.js +4 -2
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -1
- package/dist/features/stores/components/StoreDetailLayoutView.js +7 -6
- package/dist/features/stores/components/StoreGuideHubView.js +5 -2
- package/dist/features/stores/components/StoreHeader.js +8 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +6 -3
- package/dist/features/stores/components/StorePreOrdersPageView.js +4 -2
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +4 -2
- package/dist/features/stores/components/StoreProductsListing.js +6 -3
- package/dist/features/stores/components/StoreProductsPageView.js +2 -1
- package/dist/features/stores/components/StoreProductsView.js +5 -4
- package/dist/features/stores/components/StoreReviewsListing.js +8 -2
- package/dist/features/stores/components/StoresIndexListing.js +16 -9
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +7 -1
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +2 -1
- package/dist/features/wishlist/components/WishlistPage.js +2 -1
- package/dist/features/wishlist/components/WishlistView.js +4 -3
- package/dist/index.d.ts +10 -0
- package/dist/index.js +13 -1
- package/dist/next/components/GlobalError.js +2 -2
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +1 -0
- package/dist/react/ErrorBoundary.js +2 -2
- package/dist/styles.css +2 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +17 -16
- package/dist/ui/components/DateInput.js +2 -2
- package/dist/ui/components/DetailPageGallery.js +4 -1
- package/dist/ui/components/DetailPageTabs.js +6 -2
- package/dist/ui/components/ImageLightbox.js +5 -3
- package/dist/ui/components/Input.js +6 -3
- package/dist/ui/components/Layout.d.ts +4 -0
- package/dist/ui/components/Layout.js +1 -1
- package/dist/ui/components/Layout.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.js +4 -1
- package/dist/ui/components/ListingLayout.js +9 -8
- package/dist/ui/components/ListingToolbar.js +5 -1
- package/dist/ui/components/PaginatedSelect.d.ts +1 -2
- package/dist/ui/components/PaginatedSelect.js +1 -2
- package/dist/ui/components/Radio.js +1 -1
- package/dist/ui/components/Select.js +2 -1
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/VacationBanner.js +2 -1
- package/dist/ui/components/surface-tokens.d.ts +1 -0
- package/dist/ui/components/surface-tokens.js +1 -0
- package/package.json +11 -2
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { StatusBadge, Span, Button } from "../../../ui";
|
|
2
|
+
import { Div, StatusBadge, Span, Button } from "../../../ui";
|
|
3
3
|
import { MediaImage } from "../../media";
|
|
4
|
+
const __O = {
|
|
5
|
+
hidden: "overflow-hidden",
|
|
6
|
+
};
|
|
7
|
+
const CLS_DELETE_BTN = "text-red-600 hover:text-red-800 dark:text-red-400";
|
|
4
8
|
const DEFAULT_LABELS = {
|
|
5
9
|
colName: "Name",
|
|
6
10
|
colSlug: "Slug",
|
|
@@ -18,13 +22,13 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
|
|
|
18
22
|
{
|
|
19
23
|
key: "image",
|
|
20
24
|
header: "",
|
|
21
|
-
render: (cat) => (_jsx(
|
|
25
|
+
render: (cat) => (_jsx(Div, { className: `relative w-9 h-9 rounded ${__O.hidden} flex-shrink-0`, children: cat.display?.coverImage ? (_jsx(MediaImage, { src: cat.display.coverImage, alt: "", size: "thumbnail", className: "w-full h-full object-cover" })) : (_jsx(Div, { className: "w-full h-full flex items-center justify-center text-base", style: { backgroundColor: cat.display?.color ?? "#94a3b8", color: "#fff" }, children: cat.display?.icon ?? "🗂️" })) })),
|
|
22
26
|
},
|
|
23
27
|
{
|
|
24
28
|
key: "name",
|
|
25
29
|
header: L.colName,
|
|
26
30
|
sortable: true,
|
|
27
|
-
render: (cat) => (_jsxs(
|
|
31
|
+
render: (cat) => (_jsxs(Div, { style: { paddingLeft: `${cat.tier * 20}px` }, children: [cat.name, cat.tier > 0 && (_jsxs(Span, { size: "xs", className: "text-zinc-400 dark:text-zinc-400 ml-2", children: ["(Tier ", cat.tier, ")"] }))] })),
|
|
28
32
|
},
|
|
29
33
|
{
|
|
30
34
|
key: "slug",
|
|
@@ -34,7 +38,7 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
|
|
|
34
38
|
{
|
|
35
39
|
key: "metrics",
|
|
36
40
|
header: L.colProducts,
|
|
37
|
-
render: (cat) => (_jsxs(Span, {
|
|
41
|
+
render: (cat) => (_jsxs(Span, { size: "sm", children: [cat.metrics.productCount, " (", cat.metrics.totalProductCount, ")"] })),
|
|
38
42
|
},
|
|
39
43
|
{
|
|
40
44
|
key: "isActive",
|
|
@@ -43,12 +47,12 @@ export function getCategoryTableColumns(onEdit, onDelete, labels = {}) {
|
|
|
43
47
|
render: (cat) => (_jsx(StatusBadge, { status: cat.isActive ? "active" : "inactive", label: cat.isActive ? L.statusActive : L.statusInactive })),
|
|
44
48
|
},
|
|
45
49
|
],
|
|
46
|
-
actions: (cat) => (_jsxs(
|
|
50
|
+
actions: (cat) => (_jsxs(Div, { className: "flex gap-2", children: [_jsx(Button, { variant: "ghost", onClick: (e) => {
|
|
47
51
|
e.stopPropagation();
|
|
48
52
|
onEdit(cat);
|
|
49
53
|
}, className: "text-primary hover:text-primary/80", children: L.actionEdit }), _jsx(Button, { variant: "ghost", onClick: (e) => {
|
|
50
54
|
e.stopPropagation();
|
|
51
55
|
onDelete(cat);
|
|
52
|
-
}, className:
|
|
56
|
+
}, className: CLS_DELETE_BTN, children: L.actionDelete })] })),
|
|
53
57
|
};
|
|
54
58
|
}
|
|
@@ -10,6 +10,6 @@ export interface CategoryTreeProps {
|
|
|
10
10
|
* CategoryTree — hierarchical expandable navigation for categories.
|
|
11
11
|
*
|
|
12
12
|
* Builds a tree from a flat list by grouping on `rootId` and `parentIds`.
|
|
13
|
-
* Root-level nodes have
|
|
13
|
+
* Root-level nodes have sieveFilter("tier", SIEVE_OP.EQ, "= 0") or no `parentIds`.
|
|
14
14
|
*/
|
|
15
15
|
export declare function CategoryTree({ categories, activeId, onSelect, className, }: CategoryTreeProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -19,13 +19,13 @@ function CategoryTreeNode({ item, children = [], activeId, onSelect, depth = 0,
|
|
|
19
19
|
setExpanded((p) => !p);
|
|
20
20
|
onSelect?.(item);
|
|
21
21
|
}, className: `flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-sm transition select-none
|
|
22
|
-
${isActive ? "bg-primary-50 font-semibold text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, style: { paddingLeft: `${8 + indent}px` }, children: [hasChildren && (_jsx(Span, { "aria-hidden": "true", className: `text-
|
|
22
|
+
${isActive ? "bg-primary-50 font-semibold text-primary-700 dark:bg-primary-900/30 dark:text-primary-400" : "text-neutral-700 hover:bg-neutral-50 dark:text-zinc-300 dark:hover:bg-zinc-800"}`, style: { paddingLeft: `${8 + indent}px` }, children: [hasChildren && (_jsx(Span, { size: "xs", "aria-hidden": "true", className: `text-zinc-400 dark:text-zinc-400 transition-transform duration-150 ${expanded ? "rotate-90" : ""}`, children: "\u25B6" })), !hasChildren && _jsx(Span, { className: "w-3" }), item.display?.icon && (_jsx(Span, { size: "base", "aria-hidden": "true", className: "flex-shrink-0", children: item.display.icon })), _jsx(Text, { className: "flex-1 truncate", children: item.name }), item.metrics && (_jsx(Span, { size: "xs", className: "ml-auto flex-shrink-0 text-zinc-400 dark:text-zinc-400 tabular-nums", children: item.metrics.productCount }))] }), hasChildren && expanded && (_jsx(Div, { role: "group", children: children.map((child) => (_jsx(CategoryTreeNode, { item: child, activeId: activeId, onSelect: onSelect, depth: depth + 1 }, child.id))) }))] }));
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* CategoryTree — hierarchical expandable navigation for categories.
|
|
26
26
|
*
|
|
27
27
|
* Builds a tree from a flat list by grouping on `rootId` and `parentIds`.
|
|
28
|
-
* Root-level nodes have
|
|
28
|
+
* Root-level nodes have sieveFilter("tier", SIEVE_OP.EQ, "= 0") or no `parentIds`.
|
|
29
29
|
*/
|
|
30
30
|
export function CategoryTree({ categories, activeId, onSelect, className = "", }) {
|
|
31
31
|
// Group children by parent
|
|
@@ -36,7 +36,7 @@ export type BundleQueryRule = {
|
|
|
36
36
|
/**
|
|
37
37
|
* Per-member metadata stored alongside `bundleProductIds`.
|
|
38
38
|
* `drawCount` — only meaningful when the member product has
|
|
39
|
-
*
|
|
39
|
+
* sieveFilter("listingType", SIEVE_OP.EQ, "= "prize-draw""). Represents how many draw entries
|
|
40
40
|
* the buyer receives for that product when they purchase the bundle
|
|
41
41
|
* (e.g. drawCount=5 means 5 raffle entries, not 5 copies of the draw).
|
|
42
42
|
*/
|
|
@@ -195,7 +195,7 @@ export declare const categoryQueryHelpers: {
|
|
|
195
195
|
/** @deprecated Use byCategoryType("brand"). */
|
|
196
196
|
readonly brands: () => readonly ["isBrand", "==", true];
|
|
197
197
|
/** SB-UNI B + C + D — discriminator-based listing. */
|
|
198
|
-
readonly byCategoryType: (type: import("../types").CategoryType) => readonly ["categoryType", "==", import("
|
|
198
|
+
readonly byCategoryType: (type: import("../types").CategoryType) => readonly ["categoryType", "==", import("@mohasinac/appkit").CategoryType];
|
|
199
199
|
readonly sublistings: () => readonly ["categoryType", "==", "sublisting"];
|
|
200
200
|
readonly brandPages: () => readonly ["categoryType", "==", "brand"];
|
|
201
201
|
readonly active: () => readonly ["isActive", "==", true];
|
|
@@ -25,7 +25,7 @@ export declare function grantCheckoutConsentViaSms(userId: string, userPhone: st
|
|
|
25
25
|
* `verifiedVia: "admin_bypass"` marker prevents bypass-credit grants.
|
|
26
26
|
*
|
|
27
27
|
* Security: callers MUST verify the requesting user is an admin AND that
|
|
28
|
-
*
|
|
28
|
+
* sieveFilter("siteSettings.featureFlags.adminCheckoutBypass", SIEVE_OP.EQ, "= true") before calling this.
|
|
29
29
|
*/
|
|
30
30
|
export declare function grantAdminCheckoutBypass(userId: string, addressId: string, bypassingAdminUid: string): Promise<void>;
|
|
31
31
|
export { userRepository };
|
|
@@ -103,7 +103,7 @@ export async function grantCheckoutConsentViaSms(userId, userPhone, addressId) {
|
|
|
103
103
|
* `verifiedVia: "admin_bypass"` marker prevents bypass-credit grants.
|
|
104
104
|
*
|
|
105
105
|
* Security: callers MUST verify the requesting user is an admin AND that
|
|
106
|
-
*
|
|
106
|
+
* sieveFilter("siteSettings.featureFlags.adminCheckoutBypass", SIEVE_OP.EQ, "= true") before calling this.
|
|
107
107
|
*/
|
|
108
108
|
export async function grantAdminCheckoutBypass(userId, addressId, bypassingAdminUid) {
|
|
109
109
|
const address = await findUserAddress(userId, addressId);
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { FilterFacetSection } from "../../filters/FilterFacetSection";
|
|
4
4
|
import { AsyncFacetSection } from "../../filters/AsyncFacetSection";
|
|
5
5
|
import { RangeFilter } from "../../filters/RangeFilter";
|
|
6
|
-
import { Div } from "../../../ui";
|
|
6
|
+
import { Div, Label } from "../../../ui";
|
|
7
7
|
const NEGOTIABLE_OPTIONS = [
|
|
8
8
|
{ value: "true", label: "Negotiable only" },
|
|
9
9
|
];
|
|
@@ -16,5 +16,5 @@ export function ClassifiedFilters({ table, categoryOptions = [], loadCategoryOpt
|
|
|
16
16
|
: [];
|
|
17
17
|
const selectedNegotiable = table.get("negotiable") ? [table.get("negotiable")] : [];
|
|
18
18
|
const selectedShipping = table.get("acceptsShipping") ? [table.get("acceptsShipping")] : [];
|
|
19
|
-
return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs(
|
|
19
|
+
return (_jsxs(Div, { children: [loadCategoryOptions ? (_jsx(AsyncFacetSection, { title: "Category", loadOptions: loadCategoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), defaultCollapsed: false })) : categoryOptions.length > 0 ? (_jsx(FilterFacetSection, { title: "Category", options: categoryOptions, selected: selectedCategories, onChange: (vals) => table.set("category", vals.join("|")), searchable: true, defaultCollapsed: categoryOptions.length > 6 })) : null, _jsxs(Div, { className: "border-t border-[var(--appkit-color-border)] pt-4 mt-4", children: [_jsx(Label, { className: "block text-sm font-medium text-[var(--appkit-color-text)] mb-2", children: "City / Area" }), _jsx("input", { type: "text", value: table.get("city") || "", onChange: (e) => table.set("city", e.target.value), placeholder: "e.g. Mumbai", className: "w-full rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-[var(--appkit-color-text-faint)] focus:outline-none focus:ring-2 focus:ring-[var(--appkit-color-primary)]" })] }), _jsx(FilterFacetSection, { title: "Negotiable", options: NEGOTIABLE_OPTIONS, selected: selectedNegotiable, onChange: (vals) => table.set("negotiable", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(FilterFacetSection, { title: "Shipping", options: SHIPPING_OPTIONS, selected: selectedShipping, onChange: (vals) => table.set("acceptsShipping", vals[0] ?? ""), searchable: false, selectionMode: "single", defaultCollapsed: false }), _jsx(RangeFilter, { title: "Asking Price", minValue: table.get("minPrice"), maxValue: table.get("maxPrice"), onMinChange: (v) => table.set("minPrice", v), onMaxChange: (v) => table.set("maxPrice", v), prefix: currencyPrefix, showSlider: true, minBound: 0, maxBound: 500000, step: 100, minPlaceholder: "Min price", maxPlaceholder: "Max price", defaultCollapsed: false })] }));
|
|
20
20
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useProducts } from "../../products/hooks/useProducts";
|
|
6
|
-
import { BulkActionBar, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text } from "../../../ui";
|
|
6
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text } from "../../../ui";
|
|
7
7
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
8
8
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
@@ -19,6 +19,12 @@ import { ClassifiedFilters } from "./ClassifiedFilters";
|
|
|
19
19
|
import { ACTION_ID } from "../../products/constants/action-defs";
|
|
20
20
|
import { useToast } from "../../../ui";
|
|
21
21
|
import { useBottomActions } from "../../layout";
|
|
22
|
+
const __P = {
|
|
23
|
+
p3: "p-3",
|
|
24
|
+
};
|
|
25
|
+
const __O = {
|
|
26
|
+
hidden: "overflow-hidden",
|
|
27
|
+
};
|
|
22
28
|
const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
|
|
23
29
|
const SORT_OPTIONS = [
|
|
24
30
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
|
|
@@ -105,7 +111,7 @@ export function ClassifiedIndexListing({ initialData }) {
|
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
113
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
|
|
108
|
-
return (_jsxs(
|
|
114
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search classified listings\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
|
|
109
115
|
commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
|
|
110
|
-
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(
|
|
116
|
+
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No classified listings found." })) : (_jsx(Div, { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.CLASSIFIED_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ClassifiedFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
111
117
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
2
3
|
import { productRepository } from "../../../repositories";
|
|
3
4
|
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
@@ -16,18 +17,18 @@ function buildClassifiedFilters(params) {
|
|
|
16
17
|
const minPrice = sp(params, "minPrice");
|
|
17
18
|
const maxPrice = sp(params, "maxPrice");
|
|
18
19
|
if (minPrice)
|
|
19
|
-
parts.push(
|
|
20
|
+
parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
|
|
20
21
|
if (maxPrice)
|
|
21
|
-
parts.push(
|
|
22
|
+
parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
|
|
22
23
|
const city = sp(params, "city");
|
|
23
24
|
if (city)
|
|
24
|
-
parts.push(
|
|
25
|
+
parts.push(sieveFilter("classifiedCity", SIEVE_OP.EQ, city));
|
|
25
26
|
const negotiable = sp(params, "negotiable");
|
|
26
27
|
if (negotiable === "true")
|
|
27
|
-
parts.push(
|
|
28
|
+
parts.push(sieveFilter("classifiedNegotiable", SIEVE_OP.EQ, "true"));
|
|
28
29
|
const acceptsShipping = sp(params, "acceptsShipping");
|
|
29
30
|
if (acceptsShipping === "true")
|
|
30
|
-
parts.push(
|
|
31
|
+
parts.push(sieveFilter("classifiedAcceptsShipping", SIEVE_OP.EQ, "true"));
|
|
31
32
|
return parts.join(",");
|
|
32
33
|
}
|
|
33
34
|
export async function ClassifiedListView({ searchParams = {} }) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Div, Heading, Text, TextLink } from "../../../ui";
|
|
3
3
|
import { LAYOUT } from "../../../tokens";
|
|
4
|
+
const CLS_PLACEHOLDER = "w-full bg-gradient-to-br from-indigo-100 to-purple-100 dark:from-indigo-900/30 dark:to-purple-900/30";
|
|
4
5
|
export function CollectionCard({ collection, href }) {
|
|
5
|
-
return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`, style: { backgroundImage: `url(${collection.image})` } })) : (_jsx(Div, { className: `${LAYOUT.cardHeight.md}
|
|
6
|
+
return (_jsxs(TextLink, { href: href, className: "group relative block overflow-hidden rounded-xl bg-gray-100 dark:bg-slate-800 transition-shadow hover:shadow-lg", children: [collection.image ? (_jsx(Div, { role: "img", "aria-label": collection.title, className: `${LAYOUT.cardHeight.md} w-full bg-cover bg-center transition-transform duration-300 group-hover:scale-105`, style: { backgroundImage: `url(${collection.image})` } })) : (_jsx(Div, { className: `${LAYOUT.cardHeight.md} ${CLS_PLACEHOLDER}` })), _jsxs(Div, { surface: "default", padding: "sm", children: [_jsx(Heading, { level: 3, className: "font-semibold text-gray-900 dark:text-zinc-100", children: collection.title }), collection.subtitle && (_jsx(Text, { className: "mt-1 text-sm text-gray-500 dark:text-zinc-400", children: collection.subtitle })), collection.productCount !== undefined && (_jsxs(Text, { className: "mt-2 text-xs text-gray-400 dark:text-zinc-500", children: [collection.productCount, " ", collection.productCount === 1 ? "item" : "items"] }))] })] }));
|
|
6
7
|
}
|
|
7
8
|
export function CollectionGrid({ collections, getHref }) {
|
|
8
9
|
return (_jsx(Div, { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: collections.map((c) => (_jsx(CollectionCard, { collection: c, href: getHref(c.slug) }, c.slug))) }));
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { Button, Div, Heading, Span, Text, Textarea } from "../../../ui";
|
|
5
|
+
const CLS_FIELD_ERROR = "text-red-500";
|
|
6
|
+
const CLS_ERROR_BANNER = "rounded-lg bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-700 px-4 py-3 text-sm text-red-700 dark:text-red-300";
|
|
5
7
|
const INITIAL_FORM = {
|
|
6
8
|
name: "",
|
|
7
9
|
email: "",
|
|
@@ -51,8 +53,8 @@ export function ContactForm({ onSubmit, labels = {}, className = "", }) {
|
|
|
51
53
|
if (submitted) {
|
|
52
54
|
return (_jsxs(Div, { className: `text-center py-12 ${className}`, children: [_jsx(Div, { className: "text-5xl mb-4", children: "\u2705" }), _jsx(Heading, { level: 2, className: "mb-2", children: labels.successTitle ?? "Message Sent!" }), _jsx(Text, { variant: "secondary", className: "mb-6", children: labels.successDescription ?? "We'll get back to you shortly." }), _jsx(Button, { type: "button", variant: "outline", onClick: () => setSubmitted(false), children: labels.sendAnotherButton ?? "Send another message" })] }));
|
|
53
55
|
}
|
|
54
|
-
const field = (id, label, placeholder, multiline) => (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: label }), multiline ? (_jsx(Textarea, { id: id, value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, rows: 5, className: "w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm outline-none focus:ring-2 ring-primary/20 transition" })) : (_jsx("input", { id: id, type: id === "email" ? "email" : "text", value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, className: "h-10 w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition" })), errors[id] && _jsx(Span, {
|
|
55
|
-
return (_jsxs("form", { onSubmit: handleSubmit, noValidate: true, className: `space-y-4 ${className}`, children: [_jsx(Heading, { level: 2, className: "mb-6", children: labels.title ?? "Send us a message" }), submitError && (_jsx(Div, { className:
|
|
56
|
+
const field = (id, label, placeholder, multiline) => (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: label }), multiline ? (_jsx(Textarea, { id: id, value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, rows: 5, className: "w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 py-2 text-sm outline-none focus:ring-2 ring-primary/20 transition" })) : (_jsx("input", { id: id, type: id === "email" ? "email" : "text", value: form[id], onChange: (e) => setForm((f) => ({ ...f, [id]: e.target.value })), placeholder: placeholder, className: "h-10 w-full rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition" })), errors[id] && _jsx(Span, { size: "xs", className: CLS_FIELD_ERROR, children: errors[id] })] }));
|
|
57
|
+
return (_jsxs("form", { onSubmit: handleSubmit, noValidate: true, className: `space-y-4 ${className}`, children: [_jsx(Heading, { level: 2, className: "mb-6", children: labels.title ?? "Send us a message" }), submitError && (_jsx(Div, { className: CLS_ERROR_BANNER, children: submitError })), field("name", labels.nameLabel ?? "Your Name", labels.namePlaceholder ?? "Enter your name"), field("email", labels.emailLabel ?? "Email", labels.emailPlaceholder ?? "your@email.com"), field("subject", labels.subjectLabel ?? "Subject", labels.subjectPlaceholder ?? "How can we help?"), field("message", labels.messageLabel ?? "Message", labels.messagePlaceholder ?? "Tell us more…", true), _jsx(Button, { type: "submit", variant: "primary", disabled: isSubmitting, className: "w-full sm:w-auto", children: isSubmitting
|
|
56
58
|
? (labels.submittingButton ?? "Sending…")
|
|
57
59
|
: (labels.submitButton ?? "Send Message") })] }));
|
|
58
60
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Div, Heading, Span, Stack, Text } from "../../../ui";
|
|
3
|
+
const __P = {
|
|
4
|
+
p4: "p-4",
|
|
5
|
+
};
|
|
3
6
|
export function ContactInfoSidebar({ infoItems, labels = {}, renderActions, }) {
|
|
4
|
-
return (_jsxs(Stack, { as: "aside", gap: "lg", children: [_jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-4", children: labels.title ?? "Contact Information" }), _jsx(Stack, { gap: "md", children: infoItems.map((item) => (_jsxs(Div, { className: "flex items-start gap-3", children: [_jsx(Span, {
|
|
7
|
+
return (_jsxs(Stack, { as: "aside", gap: "lg", children: [_jsxs(Div, { children: [_jsx(Heading, { level: 3, className: "mb-4", children: labels.title ?? "Contact Information" }), _jsx(Stack, { gap: "md", children: infoItems.map((item) => (_jsxs(Div, { className: "flex items-start gap-3", children: [_jsx(Span, { size: "xl", className: "flex-shrink-0 mt-0.5", children: item.icon }), _jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-neutral-400 uppercase tracking-wide mb-0.5", children: item.label }), item.href ? (_jsx("a", { href: item.href, className: "text-sm text-primary-800 dark:text-primary-300 hover:underline", children: item.value })) : (_jsx(Text, { className: "text-sm", children: item.value }))] })] }, item.label))) })] }), (labels.businessHoursLabel || labels.responseTimeLabel) && (_jsxs(Stack, { gap: "sm", className: `rounded-xl border border-neutral-200 dark:border-slate-700 bg-neutral-50 dark:bg-slate-800/60 ${__P.p4}`, children: [labels.businessHoursLabel && labels.businessHoursValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.businessHoursLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.businessHoursValue })] })), labels.responseTimeLabel && labels.responseTimeValue && (_jsxs(Div, { children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: labels.responseTimeLabel }), _jsx(Text, { className: "text-sm mt-0.5", children: labels.responseTimeValue })] }))] })), renderActions?.()] }));
|
|
5
8
|
}
|
|
@@ -6,21 +6,29 @@ import { Alert, Button, Div, Heading, Input, Span, StackedViewShell, Text, } fro
|
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { useCopilotChat } from "../hooks/useCopilotChat";
|
|
8
8
|
import { THEME_CONSTANTS } from "../../../tokens";
|
|
9
|
+
const __P = {
|
|
10
|
+
p3: "p-3",
|
|
11
|
+
p4: "p-4",
|
|
12
|
+
};
|
|
13
|
+
const __O = {
|
|
14
|
+
yAuto: "overflow-y-auto",
|
|
15
|
+
};
|
|
9
16
|
const LBL_CONVERSATION_ID = "Conversation ID";
|
|
17
|
+
const CLS_ERROR_TEXT = "text-center text-sm text-red-500";
|
|
10
18
|
function MessageBubble({ msg }) {
|
|
11
19
|
const isUser = msg.role === "user";
|
|
12
20
|
return (_jsx(Div, { className: `flex ${isUser ? "justify-end" : "justify-start"}`, children: _jsxs(Div, { className: `max-w-[80%] rounded-2xl px-4 py-2.5 text-sm ${isUser
|
|
13
21
|
? "bg-primary text-white rounded-tr-sm"
|
|
14
|
-
: "bg-neutral-100 dark:bg-slate-700 text-neutral-900 dark:text-neutral-100 rounded-tl-sm"}`, children: [_jsx(Text, { className: "whitespace-pre-wrap text-sm leading-relaxed", children: msg.content }), msg.durationMs ? (_jsxs(Span, { className: "mt-1 block
|
|
22
|
+
: "bg-neutral-100 dark:bg-slate-700 text-neutral-900 dark:text-neutral-100 rounded-tl-sm"}`, children: [_jsx(Text, { className: "whitespace-pre-wrap text-sm leading-relaxed", children: msg.content }), msg.durationMs ? (_jsxs(Span, { size: "xs", className: "mt-1 block opacity-60", children: [(msg.durationMs / 1000).toFixed(1), "s"] })) : null] }) }));
|
|
15
23
|
}
|
|
16
24
|
function renderCopilotChatPanel(props) {
|
|
17
25
|
const { messages, conversationId, isLoading, error, input, setInput, labels, messagesEndRef, handleSubmit } = props;
|
|
18
|
-
return (_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className:
|
|
26
|
+
return (_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: `border-b border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels?.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: `flex-1 ${__O.yAuto} ${__P.p4} space-y-4`, children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels?.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels?.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => _jsx(MessageBubble, { msg: msg }, msg.id)), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? _jsx(Text, { className: CLS_ERROR_TEXT, children: labels?.errorLabel ?? "An error occurred. Please try again." }) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { className: `border-t border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (e) => setInput(e.target.value), placeholder: labels?.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels?.sendingButton ?? "Sending..." : labels?.sendButton ?? "Send" })] }) })] }));
|
|
19
27
|
}
|
|
20
28
|
function renderCopilotHistoryPanel(props) {
|
|
21
29
|
const { historyQuery, conversationInput, setConversationInput, loadConversation, labels } = props;
|
|
22
30
|
return (_jsxs(Div, { surface: "card", padding: "sm", className: "space-y-3", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold", children: labels?.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (e) => { e.preventDefault(); if (!conversationInput.trim())
|
|
23
|
-
return; loadConversation(conversationInput.trim()); }, children: [_jsx(Input, { label: labels?.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (e) => setConversationInput(e.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels?.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className:
|
|
31
|
+
return; loadConversation(conversationInput.trim()); }, children: [_jsx(Input, { label: labels?.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (e) => setConversationInput(e.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels?.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: `max-h-72 ${__O.yAuto} space-y-2`, children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] }));
|
|
24
32
|
}
|
|
25
33
|
export function AdminCopilotView({ endpoint, historyEndpoint = "/api/copilot/history", renderHeader, labels = {}, className = "", }) {
|
|
26
34
|
const [input, setInput] = useState("");
|
|
@@ -44,11 +52,11 @@ export function AdminCopilotView({ endpoint, historyEndpoint = "/api/copilot/his
|
|
|
44
52
|
};
|
|
45
53
|
return (_jsx(StackedViewShell, { portal: "admin", title: labels.title ?? "AI Copilot", className: className, sections: [
|
|
46
54
|
renderHeader ? (renderHeader(startNewConversation)) : (_jsxs(Div, { className: "flex items-center justify-between gap-3", children: [_jsx(Heading, { level: 2, children: labels.title ?? "AI Copilot" }), _jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: startNewConversation, children: labels.newConversation ?? "New Conversation" })] })),
|
|
47
|
-
_jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-[2fr,1fr] gap-4", children: [_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className:
|
|
55
|
+
_jsxs(Div, { className: "grid grid-cols-1 lg:grid-cols-[2fr,1fr] gap-4", children: [_jsxs(Div, { className: "flex flex-col rounded-xl border border-neutral-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 h-[calc(100vh-300px)]", children: [_jsx(Div, { className: `border-b border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: [labels.conversationId ?? LBL_CONVERSATION_ID, ": ", conversationId] }) }), _jsxs(Div, { className: `flex-1 ${__O.yAuto} ${__P.p4} space-y-4`, children: [messages.length === 0 ? (_jsxs(Div, { className: "flex flex-col items-center justify-center h-full text-center", children: [_jsx(Text, { className: "font-medium", children: labels.noMessages ?? "No messages yet" }), _jsx(Text, { variant: "secondary", className: "text-sm mt-1", children: labels.noMessagesDesc ?? "Ask anything to get started" })] })) : null, messages.map((msg) => (_jsx(MessageBubble, { msg: msg }, msg.id))), isLoading ? (_jsx(Div, { className: "flex justify-start", children: _jsx(Div, { className: "rounded-2xl rounded-tl-sm bg-neutral-100 dark:bg-slate-700 px-4 py-2.5", children: _jsx(Span, { size: "sm", className: "opacity-60 animate-pulse", children: "Thinking..." }) }) })) : null, error ? (_jsx(Text, { className: CLS_ERROR_TEXT, children: labels.errorLabel ?? "An error occurred. Please try again." })) : null, _jsx(Div, { ref: messagesEndRef })] }), _jsx(Div, { className: `border-t border-neutral-200 dark:border-slate-700 ${__P.p3}`, children: _jsxs("form", { onSubmit: handleSubmit, className: "flex gap-2", children: [_jsx("input", { type: "text", value: input, onChange: (event) => setInput(event.target.value), placeholder: labels.inputPlaceholder ?? "Ask anything...", disabled: isLoading, className: "flex-1 h-10 rounded-lg border border-neutral-200 dark:border-slate-600 bg-white dark:bg-slate-800 px-3 text-sm outline-none focus:ring-2 ring-primary/20 transition disabled:opacity-60" }), _jsx(Button, { type: "submit", variant: "primary", disabled: isLoading || !input.trim(), className: "shrink-0", children: isLoading ? labels.sendingButton ?? "Sending..." : labels.sendButton ?? "Send" })] }) })] }), _jsxs(Div, { surface: "card", padding: "sm", className: "space-y-3", children: [_jsx(Heading, { level: 3, className: "text-sm font-semibold", children: labels.historyTitle ?? "Conversation History" }), _jsxs("form", { className: "space-y-2", onSubmit: (event) => {
|
|
48
56
|
event.preventDefault();
|
|
49
57
|
if (!conversationInput.trim())
|
|
50
58
|
return;
|
|
51
59
|
loadConversation(conversationInput.trim());
|
|
52
|
-
}, children: [_jsx(Input, { label: labels.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (event) => setConversationInput(event.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className:
|
|
60
|
+
}, children: [_jsx(Input, { label: labels.conversationId ?? LBL_CONVERSATION_ID, value: conversationInput, onChange: (event) => setConversationInput(event.target.value), placeholder: "conv_..." }), _jsx(Button, { type: "submit", variant: "secondary", size: "sm", className: "w-full", children: labels.loadConversation ?? "Load conversation" })] }), historyQuery.error ? (_jsx(Alert, { variant: "warning", title: "History unavailable", children: historyQuery.error instanceof Error ? historyQuery.error.message : "Could not load history" })) : null, _jsxs(Div, { className: `max-h-72 ${__O.yAuto} space-y-2`, children: [(historyQuery.data?.messages ?? []).map((log, index) => (_jsxs(Div, { className: "rounded-lg border border-neutral-200 dark:border-slate-700 p-2", children: [_jsx(Text, { className: "text-xs font-medium text-neutral-500 dark:text-zinc-400", children: new Date(log.createdAt).toLocaleString() }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3}`, children: ["Q: ", log.prompt] }), _jsxs(Text, { className: `text-sm mt-1 ${THEME_CONSTANTS.utilities.textClamp3} text-neutral-600 dark:text-zinc-300`, children: ["A: ", log.response] })] }, `${log.createdAt}-${index}`))), !historyQuery.isLoading && (historyQuery.data?.messages?.length ?? 0) === 0 ? (_jsx(Text, { variant: "secondary", className: "text-sm", children: "No server history found for this conversation yet." })) : null] })] })] }),
|
|
53
61
|
] }));
|
|
54
62
|
}
|
|
@@ -3,7 +3,7 @@ import type { IRepository } from "../../../contracts";
|
|
|
3
3
|
* Built-in job: Close live auctions whose `endTime` has passed.
|
|
4
4
|
*
|
|
5
5
|
* Run interval: every 5 minutes (recommended).
|
|
6
|
-
* Requires an
|
|
6
|
+
* Requires an sieveFilter("IRepository", SIEVE_OP.LT, "AuctionDocument>") injected at registration time.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
@@ -23,5 +23,5 @@ interface AuctionDocument {
|
|
|
23
23
|
highestBidAmount?: number;
|
|
24
24
|
closedAt?: string;
|
|
25
25
|
}
|
|
26
|
-
export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("
|
|
26
|
+
export declare function createAuctionExpiryJob(auctionRepo: IRepository<AuctionDocument>): import("@mohasinac/appkit").CronJobDefinition;
|
|
27
27
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
1
2
|
import { createCronJob } from "../registry";
|
|
2
3
|
export function createAuctionExpiryJob(auctionRepo) {
|
|
3
4
|
return createCronJob({
|
|
@@ -9,7 +10,7 @@ export function createAuctionExpiryJob(auctionRepo) {
|
|
|
9
10
|
timeoutSeconds: 60,
|
|
10
11
|
}, async (ctx) => {
|
|
11
12
|
const result = await auctionRepo.findAll({
|
|
12
|
-
filters:
|
|
13
|
+
filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "live"), sieveFilter("endTime", SIEVE_OP.LTE, ctx.scheduleTime)),
|
|
13
14
|
perPage: 500,
|
|
14
15
|
});
|
|
15
16
|
let processed = 0;
|
|
@@ -10,5 +10,5 @@ interface PreOrderDocument {
|
|
|
10
10
|
status: string;
|
|
11
11
|
expectedShippingDate?: string;
|
|
12
12
|
}
|
|
13
|
-
export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("
|
|
13
|
+
export declare function createPreOrderReminderJob(preOrderRepo: IRepository<PreOrderDocument>): import("@mohasinac/appkit").CronJobDefinition;
|
|
14
14
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sieveFilter, sieveAnd, SIEVE_OP } from "@mohasinac/appkit";
|
|
1
2
|
import { createCronJob } from "../registry";
|
|
2
3
|
export function createPreOrderReminderJob(preOrderRepo) {
|
|
3
4
|
const sevenDaysFromNow = () => {
|
|
@@ -15,7 +16,7 @@ export function createPreOrderReminderJob(preOrderRepo) {
|
|
|
15
16
|
}, async () => {
|
|
16
17
|
const cutoff = sevenDaysFromNow();
|
|
17
18
|
const result = await preOrderRepo.findAll({
|
|
18
|
-
filters:
|
|
19
|
+
filters: sieveAnd(sieveFilter("status", SIEVE_OP.EQ, "confirmed"), sieveFilter("expectedShippingDate", SIEVE_OP.LTE, cutoff)),
|
|
19
20
|
perPage: 500,
|
|
20
21
|
});
|
|
21
22
|
let processed = 0;
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useCallback } from "react";
|
|
4
4
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useProducts } from "../../products/hooks/useProducts";
|
|
6
|
-
import { BulkActionBar, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
|
|
6
|
+
import { BulkActionBar, Div, FilterDrawer, ListingToolbar, LoginRequiredModal, Pagination, Text, useToast } from "../../../ui";
|
|
7
7
|
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
8
8
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
9
9
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
@@ -18,6 +18,12 @@ import { InteractiveProductCard } from "../../products/components/InteractivePro
|
|
|
18
18
|
import { DigitalCodeFilters } from "./DigitalCodeFilters";
|
|
19
19
|
import { ACTION_ID } from "../../products/constants/action-defs";
|
|
20
20
|
import { useBottomActions } from "../../layout";
|
|
21
|
+
const __P = {
|
|
22
|
+
p3: "p-3",
|
|
23
|
+
};
|
|
24
|
+
const __O = {
|
|
25
|
+
hidden: "overflow-hidden",
|
|
26
|
+
};
|
|
21
27
|
const DEFAULT_SORT = sortBy(PRODUCT_FIELDS.CREATED_AT);
|
|
22
28
|
const SORT_OPTIONS = [
|
|
23
29
|
{ value: sortBy(PRODUCT_FIELDS.CREATED_AT), label: "Newest First" },
|
|
@@ -102,7 +108,7 @@ export function DigitalCodesIndexListing({ initialData }) {
|
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
110
|
useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] } } : {});
|
|
105
|
-
return (_jsxs(
|
|
111
|
+
return (_jsxs(Div, { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search digital codes\u2026", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: (e) => { if (e.key === "Enter")
|
|
106
112
|
commitSearch(); }, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: (v) => { if (v !== "table")
|
|
107
|
-
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(
|
|
113
|
+
setView(v); }, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [] }), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx(Div, { className: "py-6", children: isLoading ? (_jsx(Div, { className: gridClass, children: Array.from({ length: 10 }).map((_, i) => (_jsxs(Div, { className: `rounded-xl border border-zinc-100 dark:border-slate-700 ${__O.hidden} animate-pulse`, children: [_jsx(Div, { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs(Div, { className: `${__P.p3} space-y-2`, children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : products.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No digital code listings found." })) : (_jsx(Div, { className: view === "list" ? "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800" : gridClass, children: products.map((product) => (_jsx(InteractiveProductCard, { product: product, href: String(ROUTES.PUBLIC.DIGITAL_CODE_DETAIL(product.id)), variant: view === "list" ? "list" : "grid", isWishlisted: wishlistActions.isWishlisted(product.id), onToggleWishlist: handleToggleWishlist, selectable: selection.isSelecting, isSelected: selection.isSelected(product.id), onSelect: (id) => selection.toggle(id) }, product.id))) })) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(DigitalCodeFilters, { table: pendingTable, categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
108
114
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
2
3
|
import { productRepository } from "../../../repositories";
|
|
3
4
|
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
@@ -16,12 +17,12 @@ function buildDigitalCodeFilters(params) {
|
|
|
16
17
|
const minPrice = sp(params, "minPrice");
|
|
17
18
|
const maxPrice = sp(params, "maxPrice");
|
|
18
19
|
if (minPrice)
|
|
19
|
-
parts.push(
|
|
20
|
+
parts.push(sieveFilter("price", SIEVE_OP.GTE, minPrice));
|
|
20
21
|
if (maxPrice)
|
|
21
|
-
parts.push(
|
|
22
|
+
parts.push(sieveFilter("price", SIEVE_OP.LTE, maxPrice));
|
|
22
23
|
const deliveryMethod = sp(params, "deliveryMethod");
|
|
23
24
|
if (deliveryMethod)
|
|
24
|
-
parts.push(
|
|
25
|
+
parts.push(sieveFilter("digitalCodeDelivery", SIEVE_OP.EQ, deliveryMethod));
|
|
25
26
|
return parts.join(",");
|
|
26
27
|
}
|
|
27
28
|
export async function DigitalCodesListView({ searchParams = {} }) {
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Business logic for event CRUD, status changes, entries, and public access.
|
|
5
5
|
* Auth, rate-limiting, and input validation are handled by the calling server action.
|
|
6
6
|
*/
|
|
7
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
8
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
7
9
|
import { serverLogger } from "../../../monitoring";
|
|
8
10
|
import { eventRepository } from "../repository/events.repository";
|
|
9
11
|
import { eventEntryRepository } from "../repository/event-entry.repository";
|
|
@@ -108,13 +110,13 @@ export async function listPublicEvents(params) {
|
|
|
108
110
|
if (!filters) {
|
|
109
111
|
const parts = [];
|
|
110
112
|
if (sp.has("status"))
|
|
111
|
-
parts.push(
|
|
113
|
+
parts.push(sieveFilter("status", SIEVE_OP.EQ, sp.get("status")));
|
|
112
114
|
if (sp.has("type"))
|
|
113
|
-
parts.push(
|
|
115
|
+
parts.push(sieveFilter("type", SIEVE_OP.EQ, sp.get("type")));
|
|
114
116
|
if (sp.has("types")) {
|
|
115
117
|
const types = sp.get("types").split(",");
|
|
116
118
|
if (types.length === 1)
|
|
117
|
-
parts.push(
|
|
119
|
+
parts.push(sieveFilter("type", SIEVE_OP.EQ, types[0]));
|
|
118
120
|
}
|
|
119
121
|
if (parts.length)
|
|
120
122
|
filters = parts.join(",");
|
|
@@ -157,7 +159,7 @@ export async function adminGetEventById(id) {
|
|
|
157
159
|
}
|
|
158
160
|
export async function adminGetEventEntries(eventId, params) {
|
|
159
161
|
const result = await eventEntryRepository.listForEvent(eventId, {
|
|
160
|
-
sorts: "
|
|
162
|
+
sorts: sortBy("createdAt", "DESC"),
|
|
161
163
|
page: params?.page ?? 1,
|
|
162
164
|
pageSize: params?.pageSize ?? 50,
|
|
163
165
|
});
|