@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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Form, FormActions, Label, Select, SideDrawer, StackedViewShell, Toggle, useToast, } from "../../../ui";
|
|
5
|
+
import { Button, Div, Form, FormActions, Label, Select, SideDrawer, Span, StackedViewShell, Toggle, useToast, } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
const CAPABILITY_GROUPS = [
|
|
@@ -98,12 +98,12 @@ export function AdminStoreEditorView({ open, onClose, storeId, storeName, curren
|
|
|
98
98
|
},
|
|
99
99
|
});
|
|
100
100
|
const renderStatusSection = () => (_jsx(Select, { label: "Store status", options: STATUS_OPTIONS, value: storeStatus, onValueChange: setStoreStatus }));
|
|
101
|
-
const renderNotesSection = () => (_jsxs(
|
|
101
|
+
const renderNotesSection = () => (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { children: "Admin notes (optional)" }), _jsx("textarea", { value: adminNotes, onChange: (e) => setAdminNotes(e.target.value), rows: 3, placeholder: "e.g. Reason for suspension, approval notes\u2026", className: TEXTAREA_CHROME })] }));
|
|
102
102
|
const renderTogglesSection = () => (_jsxs(_Fragment, { children: [_jsx(Toggle, { label: "Verified store", checked: isVerified, onChange: setIsVerified }), _jsx(Toggle, { label: "Featured store", checked: isFeatured, onChange: setIsFeatured })] }));
|
|
103
|
-
const renderSuspensionSection = () => storeStatus === "suspended" ? (_jsxs(
|
|
104
|
-
const renderCapabilitiesSection = () => (_jsxs(
|
|
103
|
+
const renderSuspensionSection = () => storeStatus === "suspended" ? (_jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { children: "Suspension reason (optional)" }), _jsx("textarea", { value: suspensionReason, onChange: (e) => setSuspensionReason(e.target.value), rows: 2, placeholder: "e.g. Policy violation, fraudulent activity\u2026", className: TEXTAREA_CHROME })] })) : null;
|
|
104
|
+
const renderCapabilitiesSection = () => (_jsxs(Div, { className: "flex flex-col gap-2", children: [_jsxs(Span, { size: "sm", weight: "medium", className: "text-zinc-700 dark:text-zinc-300", children: ["Capabilities", _jsxs(Span, { size: "xs", weight: "normal", className: "ml-2 text-zinc-500 dark:text-zinc-400", children: ["(", capabilities.size, " active)"] })] }), _jsx(Div, { className: "rounded-xl border border-zinc-200 dark:border-slate-700 divide-y divide-zinc-100 dark:divide-slate-700", children: CAPABILITY_GROUPS.map((group) => {
|
|
105
105
|
const checked = group.caps.filter((c) => capabilities.has(c.key)).length;
|
|
106
|
-
return (_jsxs("details", { className: "group", children: [_jsxs("summary", { className: "flex cursor-pointer items-center justify-between px-3 py-2
|
|
106
|
+
return (_jsxs("details", { className: "group", children: [_jsxs("summary", { className: "flex cursor-pointer items-center justify-between px-3 py-2 font-semibold uppercase tracking-wide text-zinc-600 dark:text-zinc-400 select-none hover:bg-zinc-50 dark:hover:bg-slate-800 transition-colors", children: [_jsx(Span, { size: "xs", children: group.label }), _jsxs(Span, { size: "xs", weight: "normal", className: "normal-case text-zinc-400 dark:text-zinc-400", children: [checked, "/", group.caps.length] })] }), _jsx(Div, { className: "grid grid-cols-2 gap-x-2 gap-y-1.5 px-3 py-2.5 bg-zinc-50/60 dark:bg-slate-800/40", children: group.caps.map((cap) => (_jsxs("label", { className: "flex items-center gap-2 cursor-pointer text-xs text-zinc-700 dark:text-zinc-300", children: [_jsx("input", { type: "checkbox", checked: capabilities.has(cap.key), onChange: () => toggleCapability(cap.key), className: "h-3.5 w-3.5 rounded border-zinc-300 dark:border-slate-600 accent-primary" }), cap.label] }, cap.key))) })] }, group.label));
|
|
107
107
|
}) })] }));
|
|
108
108
|
const renderActionsSection = () => (_jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "secondary", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: !storeId || saveMutation.isPending, children: "Save changes" })] }));
|
|
109
109
|
return (_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: storeName ? `Manage: ${storeName}` : "Manage Store", children: _jsx(Form, { onSubmit: (e) => {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
5
|
import React, { useState } from "react";
|
|
4
6
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
7
|
import { FilterChipGroup, ListingLayout, RowActionMenu, useToast } from "../../../ui";
|
|
@@ -43,12 +45,12 @@ export function AdminStoresView({ children, ...props }) {
|
|
|
43
45
|
searchPlaceholder: "Search stores, slugs, or owner names",
|
|
44
46
|
emptyLabel: "No stores found",
|
|
45
47
|
filterKeys: ["status"],
|
|
46
|
-
defaultSort: "
|
|
48
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
47
49
|
queryKey: ["admin", "stores", "listing"],
|
|
48
50
|
endpoint: ADMIN_ENDPOINTS.STORES,
|
|
49
51
|
sortOptions: [
|
|
50
|
-
{ value: "
|
|
51
|
-
{ value: "createdAt", label: "Oldest" },
|
|
52
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
53
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
52
54
|
{ value: "storeName", label: "Name A–Z" },
|
|
53
55
|
],
|
|
54
56
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
@@ -63,7 +65,7 @@ export function AdminStoresView({ children, ...props }) {
|
|
|
63
65
|
_raw: item,
|
|
64
66
|
})),
|
|
65
67
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
66
|
-
buildFilters: (state) => state.status && state.status !== "All" ?
|
|
68
|
+
buildFilters: (state) => state.status && state.status !== "All" ? sieveFilter("status", SIEVE_OP.EQ, state.status) : undefined,
|
|
67
69
|
onRowClick: (row) => setEditorRow(row),
|
|
68
70
|
buildBulkActions: (selection) => [
|
|
69
71
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
4
5
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
5
6
|
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
@@ -12,14 +13,14 @@ export function AdminSublistingCategoriesView({ onBulkDelete, }) {
|
|
|
12
13
|
searchPlaceholder: "Search sub-listing categories…",
|
|
13
14
|
emptyLabel: "No sub-listing categories found",
|
|
14
15
|
filterKeys: [],
|
|
15
|
-
defaultSort: "name",
|
|
16
|
+
defaultSort: sortBy("name", "ASC"),
|
|
16
17
|
queryKey: ["admin", "sublisting-categories", "listing"],
|
|
17
18
|
endpoint: ADMIN_ENDPOINTS.SUBLISTING_CATEGORIES,
|
|
18
19
|
sortOptions: [
|
|
19
|
-
{ value: "name", label: "Name A–Z" },
|
|
20
|
-
{ value: "
|
|
21
|
-
{ value: "
|
|
22
|
-
{ value: "
|
|
20
|
+
{ value: sortBy("name", "ASC"), label: "Name A–Z" },
|
|
21
|
+
{ value: sortBy("name", "DESC"), label: "Name Z–A" },
|
|
22
|
+
{ value: sortBy("productCount", "DESC"), label: "Most listings" },
|
|
23
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
23
24
|
],
|
|
24
25
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
25
26
|
id: toStringValue(item.id, `sc-${index}`),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
5
|
-
import { Button, ConfirmDeleteModal, Form, Input, StackedViewShell, useToast, } from "../../../ui";
|
|
5
|
+
import { Button, ConfirmDeleteModal, Div, Form, Input, StackedViewShell, useToast, } from "../../../ui";
|
|
6
6
|
import { FieldInput, FormShellContext, useFormShellState } from "../../../ui/forms";
|
|
7
7
|
import { ImageUpload } from "../../media/upload/ImageUpload";
|
|
8
8
|
import { useMediaUpload } from "../../media";
|
|
@@ -79,9 +79,9 @@ export function AdminSublistingCategoryEditorView({ categoryId, onSaved, onDelet
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
saveMutation.mutate();
|
|
82
|
-
}, className: "space-y-4", children: [_jsxs(
|
|
82
|
+
}, className: "space-y-4", children: [_jsxs(Div, { className: "grid sm:grid-cols-2 gap-4", children: [_jsx(FieldInput, { name: "name", label: "Category name", value: name, onChange: (v) => setName(v), required: true, placeholder: "e.g. Base Set Charizard 108/120" }), _jsx(Input, { label: "Item code", value: itemCode, onChange: (e) => setItemCode(e.target.value), placeholder: "e.g. PSA 10, 108/120, STH", helperText: "Grade, card number, or series code. Optional." })] }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Brief description shown on the public category page" }), _jsx(ImageUpload, { label: "Cover image", currentImage: coverImage, onUpload: (file) => upload(file, "sublisting-categories", true, {
|
|
83
83
|
type: "category-image",
|
|
84
84
|
name: name || "sublisting",
|
|
85
|
-
}), onChange: setCoverImage }), _jsxs(
|
|
85
|
+
}), onChange: setCoverImage }), _jsxs(Div, { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !name || isSubmitting, children: isEdit ? "Save changes" : "Create category" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteConfirmOpen(true), children: "Delete" }))] })] }, "sc-editor-form") }, "sc-ctx"),
|
|
86
86
|
] }), deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Sublisting Category", message: "Delete this category? All linked listings will be unlinked. This cannot be undone.", onConfirm: () => { deleteMutation.mutate(); setDeleteConfirmOpen(false); }, onClose: () => setDeleteConfirmOpen(false), isDeleting: deleteMutation.isPending }))] }));
|
|
87
87
|
}
|
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Div, FormActions, Input, Row, Select, SideDrawer, Text, Toggle, useToast, } from "../../../ui";
|
|
5
|
+
import { Button, Div, FormActions, Input, Label, Row, Select, SideDrawer, Span, Text, Toggle, useToast, } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
|
+
const __P = {
|
|
9
|
+
p3: "p-3",
|
|
10
|
+
p4: "p-4",
|
|
11
|
+
};
|
|
12
|
+
const __O = {
|
|
13
|
+
yAuto: "overflow-y-auto",
|
|
14
|
+
};
|
|
8
15
|
const STATUS_OPTIONS = [
|
|
9
16
|
{ label: "Open", value: "open" },
|
|
10
17
|
{ label: "In Progress", value: "in_progress" },
|
|
@@ -233,9 +240,9 @@ export function AdminSupportTicketDetailView({ open, onClose, ticketId, subject,
|
|
|
233
240
|
showToast(err?.message ?? "Failed to update order items.", "error");
|
|
234
241
|
},
|
|
235
242
|
});
|
|
236
|
-
return (_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: subject ?? "Support Ticket", children: _jsxs(Div, { className:
|
|
243
|
+
return (_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: subject ?? "Support Ticket", children: _jsxs(Div, { className: `flex flex-col gap-4 ${__P.p4}`, children: [_jsxs(Div, { className: "flex flex-wrap items-center gap-2", children: [_jsx(Span, { size: "xs", weight: "medium", className: `inline-flex rounded-full px-2.5 py-1 ${STATUS_COLOR[currentStatus ?? "open"] ?? STATUS_COLOR.open}`, children: (currentStatus ?? "open").replace(/_/g, " ") }), _jsx(Span, { size: "xs", className: "rounded-full bg-zinc-100 px-2.5 py-1 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300", children: category }), orderId && (_jsxs(Span, { size: "xs", className: "rounded-full bg-zinc-100 px-2.5 py-1 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-300", children: ["Order: ", orderId] }))] }), _jsxs(Div, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: ["From: ", _jsx(Span, { weight: "medium", className: "text-zinc-700 dark:text-zinc-200", children: userDisplayName })] }), description && (_jsxs(Div, { className: `rounded-lg border border-zinc-200 bg-zinc-50 ${__P.p3} dark:border-zinc-700 dark:bg-zinc-900/40`, children: [_jsx(Text, { className: "mb-1 text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Description" }), _jsx(Text, { className: "whitespace-pre-wrap text-sm text-zinc-700 dark:text-zinc-200", children: description })] })), messages.length > 0 && (_jsxs(Div, { className: "space-y-2", children: [_jsxs(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: ["Messages (", messages.length, ")"] }), _jsx(Div, { className: `space-y-2 max-h-64 ${__O.yAuto}`, children: messages.map((msg, i) => (_jsxs(Div, { className: `rounded-lg p-3 text-sm ${msg.authorRole === "user"
|
|
237
244
|
? "bg-zinc-50 border border-zinc-200 dark:bg-zinc-900/40 dark:border-zinc-700"
|
|
238
|
-
: "bg-info-surface border border-blue-200 dark:border-blue-800"}`, children: [_jsxs(
|
|
245
|
+
: "bg-info-surface border border-blue-200 dark:border-blue-800"}`, children: [_jsxs(Div, { className: "mb-1 flex items-center gap-2 text-xs text-zinc-400 dark:text-zinc-400", children: [_jsx(Span, { weight: "medium", className: "text-zinc-600 dark:text-zinc-300", children: ROLE_LABEL[msg.authorRole ?? "user"] ?? msg.authorRole }), msg.createdAt && (_jsx(Span, { children: new Date(msg.createdAt).toLocaleString() }))] }), _jsx(Text, { className: "whitespace-pre-wrap text-zinc-700 dark:text-zinc-200", children: msg.body })] }, msg.id ?? i))) })] })), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Reply to user" }), _jsx("textarea", { value: replyBody, onChange: (e) => setReplyBody(e.target.value), rows: 3, placeholder: "Type a reply\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" }), _jsx(Button, { type: "button", variant: "primary", size: "sm", isLoading: replyMutation.isPending, disabled: !replyBody.trim() || !ticketId || replyMutation.isPending, onClick: () => replyMutation.mutate(), children: "Send reply" })] }), _jsx("hr", { className: "border-zinc-200 dark:border-zinc-700" }), _jsx(Select, { label: "Status", options: STATUS_OPTIONS, value: status, onValueChange: setStatus }), _jsx(Select, { label: "Priority", options: PRIORITY_OPTIONS, value: priority, onValueChange: setPriority }), _jsxs(Div, { className: "flex flex-col gap-1", children: [_jsx(Label, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Internal notes (staff only)" }), _jsx("textarea", { value: notes, onChange: (e) => setNotes(e.target.value), rows: 3, placeholder: "Notes visible only to admins and employees\u2026", className: "w-full rounded-lg border border-zinc-300 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 focus:outline-none focus:ring-2 focus:ring-primary-500" })] }), _jsxs(Div, { padding: "sm", className: "flex flex-col gap-2 rounded-lg border border-zinc-200 dark:border-zinc-700", children: [_jsx(Text, { className: "text-xs font-semibold text-zinc-500 dark:text-zinc-400 uppercase tracking-wide", children: "Linked parties" }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Tag the buyer / store / order / product / bid this ticket concerns." }), [
|
|
239
246
|
["userId", "User slug"],
|
|
240
247
|
["storeId", "Store slug"],
|
|
241
248
|
["orderId", "Order ID"],
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
5
|
import React, { useState } from "react";
|
|
4
|
-
import { FilterChipGroup, ListingLayout, RowActionMenu, Text } from "../../../ui";
|
|
6
|
+
import { Div, FilterChipGroup, ListingLayout, RowActionMenu, Span, Text } from "../../../ui";
|
|
5
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
6
8
|
import { ROW_ACTION_META, ROW_ACTION_ID } from "../../../features/products/constants/action-defs";
|
|
7
9
|
import { ADMIN_SUPPORT_TICKET_STATUS_TABS, ADMIN_SUPPORT_TICKET_PRIORITY_TABS, } from "../constants/filter-tabs";
|
|
@@ -27,7 +29,7 @@ const TICKET_COLUMNS = [
|
|
|
27
29
|
header: "Subject",
|
|
28
30
|
render: (row) => {
|
|
29
31
|
const priority = toStringValue(row._raw?.priority, "normal");
|
|
30
|
-
return (_jsxs(
|
|
32
|
+
return (_jsxs(Div, { className: "space-y-1", children: [_jsx(Text, { className: "font-medium text-zinc-900 dark:text-zinc-100", children: row.primary }), row.secondary ? (_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: row.secondary })) : null, _jsx("span", { className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${PRIORITY_BADGE[priority] ?? PRIORITY_BADGE.normal}`, children: priority })] }));
|
|
31
33
|
},
|
|
32
34
|
},
|
|
33
35
|
{
|
|
@@ -40,7 +42,7 @@ const TICKET_COLUMNS = [
|
|
|
40
42
|
key: "updatedAt",
|
|
41
43
|
header: "Updated",
|
|
42
44
|
className: "w-32",
|
|
43
|
-
render: (row) => (_jsx(
|
|
45
|
+
render: (row) => (_jsx(Span, { size: "sm", className: "text-zinc-500 dark:text-zinc-400", children: row.updatedAt })),
|
|
44
46
|
},
|
|
45
47
|
];
|
|
46
48
|
export function AdminSupportTicketsView({ children, ...props }) {
|
|
@@ -55,13 +57,13 @@ export function AdminSupportTicketsView({ children, ...props }) {
|
|
|
55
57
|
searchPlaceholder: "Search by subject",
|
|
56
58
|
emptyLabel: "No support tickets found",
|
|
57
59
|
filterKeys: ["status", "priority"],
|
|
58
|
-
defaultSort: "
|
|
60
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
59
61
|
queryKey: ["admin", "support-tickets", "listing"],
|
|
60
62
|
endpoint: ADMIN_ENDPOINTS.SUPPORT_TICKETS,
|
|
61
63
|
sortOptions: [
|
|
62
|
-
{ value: "
|
|
63
|
-
{ value: "createdAt", label: "Oldest" },
|
|
64
|
-
{ value: "
|
|
64
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
65
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
66
|
+
{ value: sortBy("updatedAt", "DESC"), label: "Recently updated" },
|
|
65
67
|
],
|
|
66
68
|
columns: TICKET_COLUMNS,
|
|
67
69
|
mapRows: (response) => toRecordArray(response.tickets).map((item, index) => ({
|
|
@@ -90,9 +92,9 @@ export function AdminSupportTicketsView({ children, ...props }) {
|
|
|
90
92
|
buildFilters: (f) => {
|
|
91
93
|
const parts = [];
|
|
92
94
|
if (f.status && f.status !== "All")
|
|
93
|
-
parts.push(
|
|
95
|
+
parts.push(sieveFilter("status", SIEVE_OP.EQ, f.status));
|
|
94
96
|
if (f.priority && f.priority !== "All")
|
|
95
|
-
parts.push(
|
|
97
|
+
parts.push(sieveFilter("priority", SIEVE_OP.EQ, f.priority));
|
|
96
98
|
return parts.join(",") || undefined;
|
|
97
99
|
},
|
|
98
100
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
5
|
import React, { useState, useCallback } from "react";
|
|
4
6
|
import { UserPlus } from "lucide-react";
|
|
5
7
|
import { Button, FilterChipGroup, ListingLayout, RowActionMenu } from "../../../ui";
|
|
@@ -58,12 +60,12 @@ export function AdminTeamView({ children, onBulkRemove, ...props }) {
|
|
|
58
60
|
searchPlaceholder: "Search by name or email",
|
|
59
61
|
emptyLabel: "No employees found",
|
|
60
62
|
filterKeys: ["group"],
|
|
61
|
-
defaultSort: "
|
|
63
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
62
64
|
queryKey: ["admin", "team", "listing"],
|
|
63
65
|
endpoint: ADMIN_ENDPOINTS.TEAM,
|
|
64
66
|
sortOptions: [
|
|
65
|
-
{ value: "
|
|
66
|
-
{ value: "createdAt", label: "Oldest" },
|
|
67
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
68
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
67
69
|
{ value: "displayName", label: "Name A–Z" },
|
|
68
70
|
],
|
|
69
71
|
mapRows: (response) => toRecordArray(response.users).map((item, index) => ({
|
|
@@ -90,7 +92,7 @@ export function AdminTeamView({ children, onBulkRemove, ...props }) {
|
|
|
90
92
|
return response.total;
|
|
91
93
|
return mappedRows.length;
|
|
92
94
|
},
|
|
93
|
-
buildFilters: (state) => state.group && state.group !== "All" ?
|
|
95
|
+
buildFilters: (state) => state.group && state.group !== "All" ? sieveFilter("permissionGroup", SIEVE_OP.EQ, state.group) : undefined,
|
|
94
96
|
toolbarExtra: (_jsxs(Button, { type: "button", variant: "primary", onClick: openInvite, className: "flex items-center gap-1.5 whitespace-nowrap", children: [_jsx(UserPlus, { className: "h-4 w-4" }), "Invite Employee"] })),
|
|
95
97
|
buildBulkActions: onBulkRemove
|
|
96
98
|
? (selection) => [
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Shield, Ban, AlertTriangle, Headphones, Flag, ClipboardList } from "lucide-react";
|
|
3
|
-
import { Div, Heading, Span, Text, Section, Alert } from "../../../ui";
|
|
3
|
+
import { Div, Heading, Span, Text, Section, Alert, Table, Thead, Tbody, Tr, Th, Td } from "../../../ui";
|
|
4
4
|
import { GC } from "../../_guide-cls";
|
|
5
5
|
const STILL_ALLOWED = "✓ Still allowed";
|
|
6
6
|
export function AdminTrustGuideView() {
|
|
7
7
|
return (_jsxs(Div, { className: "space-y-8 pb-10 max-w-3xl mx-auto", children: [_jsxs(Section, { children: [_jsxs(Div, { className: "flex items-center gap-3 mb-2", children: [_jsx(Div, { className: "flex-shrink-0 w-10 h-10 rounded-xl flex items-center justify-center", style: { background: "linear-gradient(135deg,var(--appkit-color-primary-700,#4f46e5) 0%,var(--appkit-color-cobalt,#2563eb) 100%)" }, children: _jsx(Shield, { className: "w-5 h-5 text-white" }) }), _jsx(Text, { className: "text-sm font-semibold text-[var(--appkit-color-text-muted)] uppercase tracking-widest", children: "Admin Guide" })] }), _jsx(Heading, { level: 1, className: "text-2xl md:text-3xl font-bold text-[var(--appkit-color-text)] mb-2", children: "Trust & Safety" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "Bans, scam registry, support tickets, moderation, and reports on LetItRip." })] }), [
|
|
8
8
|
{
|
|
9
9
|
Icon: Ban, title: "Soft Ban vs Hard Ban",
|
|
10
|
-
content: (_jsxs(_Fragment, { children: [_jsx(Div, { className: "overflow-x-auto", children: _jsxs(
|
|
10
|
+
content: (_jsxs(_Fragment, { children: [_jsx(Div, { className: "overflow-x-auto", children: _jsxs(Table, { className: "w-full text-sm border-collapse", children: [_jsx(Thead, { children: _jsx(Tr, { className: "border-b border-[var(--appkit-color-border)]", children: ["", "Soft Ban", "Hard Ban"].map((h) => (_jsx(Th, { className: "text-left py-2 pr-4 font-semibold text-[var(--appkit-color-text)]", children: h }, h))) }) }), _jsx(Tbody, { className: "text-[var(--appkit-color-text-muted)] text-sm", children: [
|
|
11
11
|
["Login", STILL_ALLOWED, "✗ Blocked"],
|
|
12
12
|
["Browse", STILL_ALLOWED, STILL_ALLOWED],
|
|
13
13
|
["Buy", "Depends on scope", "✗ Blocked"],
|
|
14
14
|
["Sell", "Depends on scope", "✗ Blocked — store suspended"],
|
|
15
15
|
["Bid", "Can restrict with place_bids scope", "✗ Blocked"],
|
|
16
16
|
["Duration", "Set expiry date", "Permanent until admin lifts"],
|
|
17
|
-
].map(([action, soft, hard]) => (_jsxs(
|
|
17
|
+
].map(([action, soft, hard]) => (_jsxs(Tr, { className: "border-b border-[var(--appkit-color-border)]/50", children: [_jsx(Td, { className: "py-2 pr-4 font-medium text-[var(--appkit-color-text)]", children: action }), _jsx(Td, { className: "py-2 pr-4", children: soft }), _jsx(Td, { className: "py-2", children: hard })] }, action))) })] }) }), _jsxs(Text, { className: "text-sm text-[var(--appkit-color-text-muted)] mt-3", children: [_jsx(Span, { weight: "bold", className: "text-[var(--appkit-color-text)]", children: "Soft ban scopes" }), ": ", _jsx("code", { className: "text-xs bg-[var(--appkit-color-border)] px-1 rounded", children: "place_bids" }), ", ", _jsx("code", { className: "text-xs bg-[var(--appkit-color-border)] px-1 rounded", children: "write_reviews" }), ", ", _jsx("code", { className: "text-xs bg-[var(--appkit-color-border)] px-1 rounded", children: "create_listings" }), ", ", _jsx("code", { className: "text-xs bg-[var(--appkit-color-border)] px-1 rounded", children: "open_tickets" }), ", ", _jsx("code", { className: "text-xs bg-[var(--appkit-color-border)] px-1 rounded", children: "join_events" }), ". Multiple scopes can be combined."] })] })),
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
Icon: AlertTriangle, title: "Scam Registry",
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Users, Search, Edit, Monitor, UserCog, AlertTriangle } from "lucide-react";
|
|
3
|
-
import { Div, Heading, Span, Text, Section, Alert } from "../../../ui";
|
|
3
|
+
import { Div, Heading, Span, Text, Section, Alert, Table, Thead, Tbody, Tr, Th, Td } from "../../../ui";
|
|
4
4
|
import { GC } from "../../_guide-cls";
|
|
5
5
|
export function AdminUsersGuideView() {
|
|
6
6
|
return (_jsxs(Div, { className: "space-y-8 pb-10 max-w-3xl mx-auto", children: [_jsxs(Section, { children: [_jsxs(Div, { className: "flex items-center gap-3 mb-2", children: [_jsx(Div, { className: "flex-shrink-0 w-10 h-10 rounded-xl flex items-center justify-center", style: { background: "linear-gradient(135deg,var(--appkit-color-primary-700,#4f46e5) 0%,var(--appkit-color-cobalt,#2563eb) 100%)" }, children: _jsx(Users, { className: "w-5 h-5 text-white" }) }), _jsx(Text, { className: "text-sm font-semibold text-[var(--appkit-color-text-muted)] uppercase tracking-widest", children: "Admin Guide" })] }), _jsx(Heading, { level: 1, className: "text-2xl md:text-3xl font-bold text-[var(--appkit-color-text)] mb-2", children: "Users & Accounts" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: "Managing users, roles, sessions, and employee accounts on LetItRip." })] }), [
|
|
7
7
|
{
|
|
8
8
|
Icon: Users, title: "User Roles Overview",
|
|
9
|
-
content: (_jsx(Div, { className: "overflow-x-auto", children: _jsxs(
|
|
9
|
+
content: (_jsx(Div, { className: "overflow-x-auto", children: _jsxs(Table, { className: "w-full text-sm border-collapse", children: [_jsx(Thead, { children: _jsx(Tr, { className: "border-b border-[var(--appkit-color-border)]", children: ["Role", "What they can do", "How assigned"].map((h) => (_jsx(Th, { className: "text-left py-2 pr-4 font-semibold text-[var(--appkit-color-text)]", children: h }, h))) }) }), _jsx(Tbody, { className: "text-[var(--appkit-color-text-muted)]", children: [
|
|
10
10
|
["user", "Browse, buy, bid, wishlist, reviews, support tickets", "Auto on registration"],
|
|
11
11
|
["seller", "Everything above + store management + listings", "Auto when store is created"],
|
|
12
12
|
["moderator", "Review content, manage scam reports, FAQ moderation", "Admin team invite"],
|
|
13
13
|
["employee", "Assigned permission-group access to admin sections", "Admin team invite"],
|
|
14
14
|
["admin", "Full access to all admin sections, bypasses RBAC checks", "Manual via Firebase console"],
|
|
15
|
-
].map(([role, can, how]) => (_jsxs(
|
|
15
|
+
].map(([role, can, how]) => (_jsxs(Tr, { className: "border-b border-[var(--appkit-color-border)]/50", children: [_jsx(Td, { className: "py-2 pr-4 font-mono text-xs text-[var(--appkit-color-primary)]", children: role }), _jsx(Td, { className: "py-2 pr-4", children: can }), _jsx(Td, { className: "py-2", children: how })] }, role))) })] }) })),
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
Icon: Search, title: "User List & Search",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
5
|
import React, { useState } from "react";
|
|
4
6
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
7
|
import { Button, FilterChipGroup, Form, FormActions, Input, ListingLayout, Modal, RowActionMenu, Text as AppText, useToast, } from "../../../ui";
|
|
@@ -54,12 +56,12 @@ export function AdminUsersView({ children, ...props }) {
|
|
|
54
56
|
searchPlaceholder: "Search users, email, or seller handles",
|
|
55
57
|
emptyLabel: "No users found",
|
|
56
58
|
filterKeys: ["status", "role"],
|
|
57
|
-
defaultSort: "
|
|
59
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
58
60
|
queryKey: ["admin", "users", "listing"],
|
|
59
61
|
endpoint: ADMIN_ENDPOINTS.USERS,
|
|
60
62
|
sortOptions: [
|
|
61
|
-
{ value: "
|
|
62
|
-
{ value: "createdAt", label: "Oldest" },
|
|
63
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
64
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
63
65
|
{ value: "displayName", label: "Name A–Z" },
|
|
64
66
|
],
|
|
65
67
|
mapRows: (response) => toRecordArray(response.users).map((item, index) => {
|
|
@@ -98,7 +100,7 @@ export function AdminUsersView({ children, ...props }) {
|
|
|
98
100
|
parts.push(f.status === "Active" ? "disabled==false" : "disabled==true");
|
|
99
101
|
}
|
|
100
102
|
if (f.role && f.role !== "All")
|
|
101
|
-
parts.push(
|
|
103
|
+
parts.push(sieveFilter("role", SIEVE_OP.EQ, f.role));
|
|
102
104
|
return parts.join(",") || undefined;
|
|
103
105
|
},
|
|
104
106
|
onRowClick: (row) => {
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Div, Grid, Row, Span, Stack, Text } from "../../../ui";
|
|
4
|
+
const __P = {
|
|
5
|
+
p3: "p-3",
|
|
6
|
+
};
|
|
7
|
+
const __O = {
|
|
8
|
+
hidden: "overflow-hidden",
|
|
9
|
+
};
|
|
4
10
|
const FLAG_BADGES = [
|
|
5
11
|
{ key: "featured", label: "Featured", color: "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300" },
|
|
6
12
|
{ key: "isPromoted", label: "Promoted", color: "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300" },
|
|
@@ -8,13 +14,13 @@ const FLAG_BADGES = [
|
|
|
8
14
|
{ key: "isSold", label: "Sold", color: "bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400" },
|
|
9
15
|
];
|
|
10
16
|
function StatusBadge({ status }) {
|
|
11
|
-
return (_jsx(Span, { className: "inline-flex rounded-full bg-primary-50 px-2 py-0.5 text-
|
|
17
|
+
return (_jsx(Span, { size: "xs", weight: "medium", className: "inline-flex rounded-full bg-primary-50 px-2 py-0.5 text-primary-800 dark:bg-secondary-900/30 dark:text-secondary-300 truncate max-w-[120px]", children: status }));
|
|
12
18
|
}
|
|
13
19
|
function SkeletonCard({ view }) {
|
|
14
20
|
if (view === "list") {
|
|
15
21
|
return (_jsxs(Row, { gap: "sm", className: "px-4 py-3 animate-pulse", children: [_jsx(Div, { className: "h-4 w-4 rounded bg-zinc-200 dark:bg-slate-700 shrink-0" }), _jsxs(Stack, { gap: "xs", className: "flex-1", children: [_jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" }), _jsx(Div, { className: "h-2.5 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] }), _jsx(Div, { className: "h-5 w-16 bg-zinc-200 dark:bg-slate-700 rounded-full shrink-0" }), _jsx(Div, { className: "h-3 w-20 bg-zinc-200 dark:bg-slate-700 rounded shrink-0" })] }));
|
|
16
22
|
}
|
|
17
|
-
return (_jsx(Div, { rounded: "xl", border: "subtle", className:
|
|
23
|
+
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} animate-pulse`, children: _jsxs(Stack, { gap: "xs", padding: "md", children: [_jsx(Div, { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/2" }), _jsx(Div, { className: "h-5 bg-zinc-200 dark:bg-slate-700 rounded-full w-20 mt-1" }), _jsx(Div, { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] }) }));
|
|
18
24
|
}
|
|
19
25
|
function AdminCardItem({ row, view, selected, onToggleSelect, onRowClick, }) {
|
|
20
26
|
const flags = FLAG_BADGES.filter(({ key }) => Boolean(row[key]));
|
|
@@ -27,20 +33,20 @@ function AdminCardItem({ row, view, selected, onToggleSelect, onRowClick, }) {
|
|
|
27
33
|
return (_jsxs(Row, { gap: "sm", className: [
|
|
28
34
|
"px-4 py-3 cursor-pointer transition-colors hover:bg-zinc-50 dark:hover:bg-slate-800/50",
|
|
29
35
|
selected ? "bg-primary-50/40 dark:bg-primary-900/10" : "",
|
|
30
|
-
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsx(Div, { "data-checkbox": true, className: "shrink-0", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: _jsx("input", { type: "checkbox", checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }) })), _jsxs(Stack, { gap: "none", className: "flex-1 min-w-0", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "truncate text-zinc-900 dark:text-zinc-100", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary })] }), flags.length > 0 && (_jsx(Row, { gap: "xs", className: "hidden sm:flex shrink-0", children: flags.map(({ key, label, color }) => (_jsx(Span, { className: `inline-flex rounded-full px-1.5 py-0.5 text-[10px]
|
|
36
|
+
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsx(Div, { "data-checkbox": true, className: "shrink-0", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: _jsx("input", { type: "checkbox", checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }) })), _jsxs(Stack, { gap: "none", className: "flex-1 min-w-0", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "truncate text-zinc-900 dark:text-zinc-100", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary })] }), flags.length > 0 && (_jsx(Row, { gap: "xs", className: "hidden sm:flex shrink-0", children: flags.map(({ key, label, color }) => (_jsx(Span, { weight: "medium", className: `inline-flex rounded-full px-1.5 py-0.5 text-[10px] ${color}`, children: label }, key))) })), _jsx(StatusBadge, { status: row.status }), _jsx(Span, { size: "xs", color: "muted", className: "hidden sm:block shrink-0 w-24 text-right", children: row.updatedAt })] }));
|
|
31
37
|
}
|
|
32
38
|
return (_jsxs(Div, { rounded: "xl", className: [
|
|
33
39
|
"border overflow-hidden cursor-pointer transition-all hover:shadow-md hover:-translate-y-0.5",
|
|
34
40
|
selected
|
|
35
41
|
? "border-primary ring-1 ring-primary/20 bg-primary-50/30 dark:bg-primary-900/10"
|
|
36
42
|
: "border-zinc-100 dark:border-slate-700 bg-white dark:bg-slate-900",
|
|
37
|
-
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsxs(Row, { gap: "xs", "data-checkbox": true, className: "px-3 pt-3", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: [_jsx("input", { type: "checkbox", checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }), flags.length > 0 && (_jsx(Row, { gap: "xs", wrap: true, children: flags.map(({ key, label, color }) => (_jsx(Span, { className: `inline-flex rounded-full px-1.5 py-0.5 text-[10px]
|
|
43
|
+
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsxs(Row, { gap: "xs", "data-checkbox": true, className: "px-3 pt-3", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: [_jsx("input", { type: "checkbox", checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }), flags.length > 0 && (_jsx(Row, { gap: "xs", wrap: true, children: flags.map(({ key, label, color }) => (_jsx(Span, { weight: "medium", className: `inline-flex rounded-full px-1.5 py-0.5 text-[10px] ${color}`, children: label }, key))) }))] })), _jsxs(Stack, { gap: "xs", className: `${__P.p3}.5`, children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "line-clamp-2 leading-snug text-zinc-900 dark:text-zinc-100", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary })] }), _jsxs(Row, { justify: "between", gap: "xs", children: [_jsx(StatusBadge, { status: row.status }), _jsx(Span, { color: "muted", className: "text-[11px] shrink-0", children: row.updatedAt })] })] })] }));
|
|
38
44
|
}
|
|
39
45
|
export function AdminViewCards({ rows, view, isLoading, emptyLabel = "No items found", onRowClick, selectedIdSet, onToggleSelect, }) {
|
|
40
46
|
if (isLoading) {
|
|
41
47
|
const count = view === "grid" ? 12 : 8;
|
|
42
48
|
if (view === "list") {
|
|
43
|
-
return (_jsx(Div, { rounded: "xl", border: "subtle", className:
|
|
49
|
+
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} divide-y divide-zinc-100 dark:divide-slate-700`, children: Array.from({ length: count }).map((_, i) => _jsx(SkeletonCard, { view: "list" }, i)) }));
|
|
44
50
|
}
|
|
45
51
|
return (_jsx(Grid, { gap: "md", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: Array.from({ length: count }).map((_, i) => _jsx(SkeletonCard, { view: "grid" }, i)) }));
|
|
46
52
|
}
|
|
@@ -48,7 +54,7 @@ export function AdminViewCards({ rows, view, isLoading, emptyLabel = "No items f
|
|
|
48
54
|
return (_jsx(Text, { size: "sm", color: "muted", className: "py-12 text-center", children: emptyLabel }));
|
|
49
55
|
}
|
|
50
56
|
if (view === "list") {
|
|
51
|
-
return (_jsx(Div, { rounded: "xl", border: "subtle", className:
|
|
57
|
+
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} divide-y divide-zinc-100 dark:divide-slate-700`, children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "list", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick }, row.id))) }));
|
|
52
58
|
}
|
|
53
59
|
return (_jsx(Grid, { gap: "md", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "grid", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick }, row.id))) }));
|
|
54
60
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { ListingLayout } from "../../../ui";
|
|
5
6
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -11,12 +12,12 @@ const ADMIN_WISHLISTS_CONFIG = {
|
|
|
11
12
|
searchPlaceholder: "Search by user ID",
|
|
12
13
|
emptyLabel: "No user wishlists found",
|
|
13
14
|
filterKeys: [],
|
|
14
|
-
defaultSort: "
|
|
15
|
+
defaultSort: sortBy("updatedAt", "DESC"),
|
|
15
16
|
queryKey: ["admin", "wishlists", "listing"],
|
|
16
17
|
endpoint: ADMIN_ENDPOINTS.ADMIN_WISHLISTS,
|
|
17
18
|
sortOptions: [
|
|
18
|
-
{ value: "
|
|
19
|
-
{ value: "
|
|
19
|
+
{ value: sortBy("updatedAt", "DESC"), label: "Recently updated" },
|
|
20
|
+
{ value: sortBy("itemCount", "DESC"), label: "Largest first" },
|
|
20
21
|
],
|
|
21
22
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
22
23
|
const itemCount = typeof item.itemCount === "number" ? item.itemCount : 0;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Form, Input, Toggle, useToast } from "../../../ui";
|
|
5
|
+
import { Button, Div, Form, Input, Toggle, useToast } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
function toBrandSlug(str) {
|
|
@@ -32,5 +32,5 @@ export function BrandQuickCreateForm({ onSaved, onCancel }) {
|
|
|
32
32
|
return (_jsxs(Form, { onSubmit: (e) => {
|
|
33
33
|
e.preventDefault();
|
|
34
34
|
mutation.mutate();
|
|
35
|
-
}, className: "space-y-4", children: [_jsx(Input, { label: "Brand name", value: name, onChange: (e) => setName(e.target.value), required: true, placeholder: "e.g. Hot Wheels", autoFocus: true }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Optional brief description" }), _jsx(Toggle, { label: "Active", checked: isActive, onChange: setIsActive }), _jsxs(
|
|
35
|
+
}, className: "space-y-4", children: [_jsx(Input, { label: "Brand name", value: name, onChange: (e) => setName(e.target.value), required: true, placeholder: "e.g. Hot Wheels", autoFocus: true }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Optional brief description" }), _jsx(Toggle, { label: "Active", checked: isActive, onChange: setIsActive }), _jsxs(Div, { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: mutation.isPending, disabled: !name || mutation.isPending, children: "Create brand" }), _jsx(Button, { type: "button", variant: "ghost", onClick: onCancel, children: "Cancel" })] })] }));
|
|
36
36
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useMutation } from "@tanstack/react-query";
|
|
5
|
-
import { Button, Form, Input, Toggle, useToast } from "../../../ui";
|
|
5
|
+
import { Button, Div, Form, Input, Toggle, useToast } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
function toCategorySlug(str) {
|
|
@@ -31,5 +31,5 @@ export function CategoryQuickCreateForm({ onSaved, onCancel }) {
|
|
|
31
31
|
return (_jsxs(Form, { onSubmit: (e) => {
|
|
32
32
|
e.preventDefault();
|
|
33
33
|
mutation.mutate();
|
|
34
|
-
}, className: "space-y-4", children: [_jsx(Input, { label: "Category name", value: name, onChange: (e) => setName(e.target.value), required: true, placeholder: "e.g. Trading Cards", autoFocus: true }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Optional brief description" }), _jsx(Toggle, { label: "Active", checked: isActive, onChange: setIsActive }), _jsxs(
|
|
34
|
+
}, className: "space-y-4", children: [_jsx(Input, { label: "Category name", value: name, onChange: (e) => setName(e.target.value), required: true, placeholder: "e.g. Trading Cards", autoFocus: true }), _jsx(Input, { label: "Description", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Optional brief description" }), _jsx(Toggle, { label: "Active", checked: isActive, onChange: setIsActive }), _jsxs(Div, { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: mutation.isPending, disabled: !name || mutation.isPending, children: "Create category" }), _jsx(Button, { type: "button", variant: "ghost", onClick: onCancel, children: "Cancel" })] })] }));
|
|
35
35
|
}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { TrendingUp, ShoppingBag, Users, Package, Clock, Star } from "lucide-react";
|
|
4
|
-
import { Grid, Text } from "../../../ui";
|
|
4
|
+
import { Div, Grid, Text } from "../../../ui";
|
|
5
5
|
import { formatCurrency } from "../../../utils/number.formatter";
|
|
6
6
|
import { getDefaultCurrency } from "../../../core/baseline-resolver";
|
|
7
|
+
const __P = {
|
|
8
|
+
p5: "p-5",
|
|
9
|
+
};
|
|
10
|
+
const __O = {
|
|
11
|
+
hidden: "overflow-hidden",
|
|
12
|
+
};
|
|
7
13
|
// Brand gradient stop colors (mirrors SiteLogo wordmark gradient)
|
|
8
14
|
const BRAND_FROM = "var(--appkit-color-primary-700, #1343de)";
|
|
9
15
|
const BRAND_MID = "var(--appkit-color-cobalt, #3570fc)";
|
|
10
16
|
const BRAND_TO = "var(--appkit-color-secondary-400, #84e122)";
|
|
11
17
|
function StatCard({ label, value, sub, icon: Icon, gradient, iconColor }) {
|
|
12
|
-
return (_jsxs(
|
|
18
|
+
return (_jsxs(Div, { className: `relative rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden} shadow-sm hover:shadow-md transition-shadow`, children: [_jsx(Div, { className: "absolute top-0 left-0 right-0 h-[3px]", style: { background: gradient }, "aria-hidden": "true" }), _jsxs(Div, { className: "px-5 pb-5 pt-6 flex items-start justify-between gap-3", children: [_jsxs(Div, { className: `min-w-0 flex-1 ${__O.hidden}`, children: [_jsx(Text, { className: "text-[11px] font-semibold uppercase tracking-widest text-[var(--appkit-color-text-muted)] truncate", children: label }), _jsx(Text, { className: "mt-2 text-xl font-bold text-[var(--appkit-color-text)] tabular-nums leading-tight break-words", children: value }), sub && (_jsx(Text, { className: "mt-1.5 text-xs text-[var(--appkit-color-text-muted)]", children: sub }))] }), _jsx(Div, { className: "flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center", style: { background: gradient, opacity: 0.92 }, children: _jsx(Icon, { className: "w-5 h-5 text-white drop-shadow-sm" }) })] })] }));
|
|
13
19
|
}
|
|
14
20
|
function SkeletonCard() {
|
|
15
|
-
return (_jsxs(
|
|
21
|
+
return (_jsxs(Div, { className: `relative rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] ${__O.hidden} ${__P.p5} animate-pulse`, children: [_jsx(Div, { className: "absolute top-0 left-0 right-0 h-[3px] bg-[var(--appkit-color-border)]" }), _jsxs(Div, { className: "flex items-start justify-between gap-3 pt-1", children: [_jsxs(Div, { className: "flex-1 space-y-2", children: [_jsx(Div, { className: "h-2.5 w-20 rounded bg-[var(--appkit-color-border)]" }), _jsx(Div, { className: "h-7 w-24 rounded bg-[var(--appkit-color-border)]" })] }), _jsx(Div, { className: "w-10 h-10 rounded-lg bg-[var(--appkit-color-border)]" })] })] }));
|
|
16
22
|
}
|
|
17
23
|
export function DashboardStatsGrid({ stats, isLoading, labels = {}, }) {
|
|
18
24
|
if (isLoading) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Plus } from "lucide-react";
|
|
4
|
-
import { BulkActionBar, Button, ListingFilterDrawer, ListingToolbar, Pagination, SideDrawer, } from "../../../ui";
|
|
4
|
+
import { BulkActionBar, Button, Div, ListingFilterDrawer, ListingToolbar, Pagination, SideDrawer, } from "../../../ui";
|
|
5
5
|
import { useBottomActions } from "../../layout";
|
|
6
6
|
import { useAdminListing } from "../hooks/useAdminListing";
|
|
7
7
|
import { AdminViewCards } from "./AdminViewCards";
|
|
@@ -42,9 +42,9 @@ export function DataListingView({ config, }) {
|
|
|
42
42
|
? `Add ${config.title.replace(/s$/, "")}`
|
|
43
43
|
: `Edit ${config.title.replace(/s$/, "")}`;
|
|
44
44
|
const isEditorOpen = panel.isCreateOpen || panel.isEditOpen;
|
|
45
|
-
return (_jsxs(
|
|
45
|
+
return (_jsxs(Div, { className: config.className ?? "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: config.searchPlaceholder, onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || config.defaultSort, sortOptions: config.sortOptions, onSortChange: (v) => table.set("sort", v), showTableView: !config.hideTableView, toggles: config.toggles, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: config.primaryAction || config.toolbarExtra ? (_jsxs(Div, { className: "flex items-center gap-2", children: [config.toolbarExtra, config.primaryAction && (_jsxs(Button, { size: "sm", onClick: () => config.primaryAction.onClick({
|
|
46
46
|
openCreatePanel: panel.openCreatePanel,
|
|
47
|
-
}), className: "flex items-center gap-1.5", children: [config.primaryAction.icon ?? _jsx(Plus, { className: "h-4 w-4" }), config.primaryAction.label] }))] })) : undefined }), config.renderAboveContent?.(), bulkActionItems && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActionItems })), totalPages > 1 && (_jsx(
|
|
47
|
+
}), className: "flex items-center gap-1.5", children: [config.primaryAction.icon ?? _jsx(Plus, { className: "h-4 w-4" }), config.primaryAction.label] }))] })) : undefined }), config.renderAboveContent?.(), bulkActionItems && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActionItems })), totalPages > 1 && (_jsx(Div, { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsxs(Div, { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-error/20 bg-error-surface px-4 py-3 text-sm text-error", children: errorMessage })), view === "table" ? (_jsx(DataTable, { columns: config.columns, rows: rows, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: (next) => next
|
|
48
48
|
? selection.setSelectedIds(rows.map((r) => r.id))
|
|
49
49
|
: selection.clearSelection(), getRowHref: config.getRowHref, onRowClick: config.onRowClick
|
|
50
50
|
? (row) => config.onRowClick(row, {
|