@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,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, 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, { useCallback } from "react";
|
|
4
6
|
import { useQueryClient } from "@tanstack/react-query";
|
|
5
7
|
import { Div, FilterChipGroup, ListingLayout, Text, useToast } from "../../../ui";
|
|
@@ -47,12 +49,12 @@ export function AdminCouponsView({ children, onBulkArchive, onBulkDelete, ...pro
|
|
|
47
49
|
searchPlaceholder: "Search codes, campaigns, or seller scopes",
|
|
48
50
|
emptyLabel: "No coupons found",
|
|
49
51
|
filterKeys: ["type"],
|
|
50
|
-
defaultSort: "
|
|
52
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
51
53
|
queryKey: ["admin", "coupons", "listing"],
|
|
52
54
|
endpoint: ADMIN_ENDPOINTS.COUPONS,
|
|
53
55
|
sortOptions: [
|
|
54
|
-
{ value: "
|
|
55
|
-
{ value: "createdAt", label: "Oldest" },
|
|
56
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
57
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
56
58
|
{ value: "code", label: "Code A–Z" },
|
|
57
59
|
],
|
|
58
60
|
hideTableView: true,
|
|
@@ -61,7 +63,7 @@ export function AdminCouponsView({ children, onBulkArchive, onBulkDelete, ...pro
|
|
|
61
63
|
raw: item,
|
|
62
64
|
})),
|
|
63
65
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
64
|
-
buildFilters: (state) => state.type && state.type !== "All" ?
|
|
66
|
+
buildFilters: (state) => state.type && state.type !== "All" ? sieveFilter("type", SIEVE_OP.EQ, state.type) : undefined,
|
|
65
67
|
primaryAction: {
|
|
66
68
|
label: "Add Coupon",
|
|
67
69
|
onClick: ({ openCreatePanel }) => openCreatePanel(),
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* AdminDigitalCodesView — admin browse of digital-code listings (W1-29).
|
|
5
5
|
*/
|
|
6
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
6
7
|
import React from "react";
|
|
7
8
|
import { ListingLayout } from "../../../ui";
|
|
8
9
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -14,12 +15,12 @@ const ADMIN_DIGITAL_CODES_CONFIG = {
|
|
|
14
15
|
searchPlaceholder: "Search digital code listings",
|
|
15
16
|
emptyLabel: "No digital code listings",
|
|
16
17
|
filterKeys: [],
|
|
17
|
-
defaultSort: "
|
|
18
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
18
19
|
queryKey: ["admin", "digital-codes", "listing"],
|
|
19
20
|
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
20
21
|
sortOptions: [
|
|
21
|
-
{ value: "
|
|
22
|
-
{ value: "createdAt", label: "Oldest" },
|
|
22
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
23
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
23
24
|
{ value: "title", label: "Title A–Z" },
|
|
24
25
|
],
|
|
25
26
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx, 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, ConfirmDeleteModal, Form, FormActions, Select, SideDrawer, Text, useToast } from "../../../ui";
|
|
5
|
+
import { Button, ConfirmDeleteModal, Div, Form, FormActions, Label, Select, SideDrawer, Span, Text, useToast } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
import { PERMISSION_GROUPS, } from "../../auth/permissions/constants";
|
|
9
|
+
const __O = {
|
|
10
|
+
yAuto: "overflow-y-auto",
|
|
11
|
+
};
|
|
9
12
|
// --- Helpers -----------------------------------------------------------------
|
|
10
13
|
const GROUP_OPTIONS = [
|
|
11
14
|
{ label: "Content Moderator", value: "content_moderator" },
|
|
@@ -70,12 +73,12 @@ function formatPermLabel(perm) {
|
|
|
70
73
|
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
71
74
|
}
|
|
72
75
|
function PermissionDomainsPanel({ permissions, togglePerm }) {
|
|
73
|
-
return (_jsxs(
|
|
76
|
+
return (_jsxs(Div, { className: "flex flex-col gap-2", children: [_jsxs(Span, { size: "sm", weight: "medium", className: "text-zinc-700 dark:text-zinc-300", children: ["Permissions", _jsxs(Span, { size: "xs", weight: "normal", className: "ml-2 text-zinc-500 dark:text-zinc-400", children: ["(", permissions.size, " selected)"] })] }), _jsx(Div, { className: `rounded-xl border border-zinc-200 dark:border-slate-700 divide-y divide-zinc-100 dark:divide-slate-700 max-h-[42vh] ${__O.yAuto}`, children: PERMISSION_DOMAINS.map((domain) => {
|
|
74
77
|
const domainPerms = getPermissionsForDomain(domain.prefix);
|
|
75
78
|
if (domainPerms.length === 0)
|
|
76
79
|
return null;
|
|
77
80
|
const checked = domainPerms.filter((p) => permissions.has(p)).length;
|
|
78
|
-
return (_jsxs("details", { className: "group", children: [_jsxs("summary", { className: "flex cursor-pointer items-center justify-between px-3 py-2
|
|
81
|
+
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: domain.label }), _jsxs(Span, { size: "xs", weight: "normal", className: "normal-case text-zinc-400 dark:text-zinc-400", children: [checked, "/", domainPerms.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: domainPerms.map((perm) => (_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: permissions.has(perm), onChange: () => togglePerm(perm), className: "h-3.5 w-3.5 rounded border-zinc-300 dark:border-slate-600 accent-primary" }), formatPermLabel(perm)] }, perm))) })] }, domain.prefix));
|
|
79
82
|
}) })] }));
|
|
80
83
|
}
|
|
81
84
|
// --- Component ---------------------------------------------------------------
|
|
@@ -167,5 +170,5 @@ export function AdminEmployeeEditorView({ open, onClose, mode, userId, displayNa
|
|
|
167
170
|
else
|
|
168
171
|
updateMutation.mutate();
|
|
169
172
|
};
|
|
170
|
-
return (_jsxs(_Fragment, { children: [_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: mode === "invite" ? "Invite Employee" : `Edit — ${displayName ?? "Employee"}`, children: _jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-5 p-4", children: [mode === "invite" && (_jsxs(
|
|
173
|
+
return (_jsxs(_Fragment, { children: [_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: mode === "invite" ? "Invite Employee" : `Edit — ${displayName ?? "Employee"}`, children: _jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-5 p-4", children: [mode === "invite" && (_jsxs(Div, { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Email address" }), _jsx("input", { type: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value), placeholder: "employee@example.com", className: "rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-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/60 transition" })] })), _jsxs(Div, { className: "flex flex-col gap-1.5", children: [_jsx(Label, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Permission group" }), _jsx(Select, { value: group, onChange: (e) => applyGroupPreset(e.target.value), options: GROUP_OPTIONS }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Selecting a group auto-fills the permissions below. You can still customise individual permissions." })] }), _jsx(PermissionDomainsPanel, { permissions: permissions, togglePerm: togglePerm }), _jsxs(FormActions, { children: [_jsx(Button, { type: "submit", variant: "primary", disabled: isBusy, isLoading: isBusy, children: mode === "invite" ? "Send Invite" : "Save" }), mode === "edit" && userId && (_jsx(Button, { type: "button", variant: "danger", disabled: isBusy, onClick: () => setRevokeOpen(true), children: "Revoke Access" }))] })] }) }), mode === "edit" && (_jsx(ConfirmDeleteModal, { isOpen: revokeOpen, onClose: () => setRevokeOpen(false), onConfirm: () => revokeMutation.mutate(), isDeleting: revokeMutation.isPending, title: "Revoke employee access?", message: `${displayName ?? "This employee"} will lose admin panel access immediately. Their user account remains active — only their role is reset to user.`, confirmText: "Revoke Access", variant: "danger" }))] }));
|
|
171
174
|
}
|
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } 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, RichTextEditor, Select, StackedViewShell, TagInput, Text, Toggle, useToast } from "../../../ui";
|
|
5
|
+
import { Button, ConfirmDeleteModal, Div, Form, Input, RichTextEditor, Select, StackedViewShell, TagInput, Text, Toggle, useToast } from "../../../ui";
|
|
6
6
|
import { FieldInput, FormShellContext, useFormShellState } from "../../../ui/forms";
|
|
7
7
|
import { apiClient } from "../../../http";
|
|
8
8
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
const __P = {
|
|
10
|
+
p4: "p-4",
|
|
11
|
+
};
|
|
12
|
+
const __O = {
|
|
13
|
+
yAuto: "overflow-y-auto",
|
|
14
|
+
};
|
|
9
15
|
// --- Constants ---------------------------------------------------------------
|
|
10
16
|
const CATEGORY_OPTIONS = [
|
|
11
17
|
{ label: "Shipping", value: "shipping" },
|
|
@@ -126,9 +132,9 @@ export function AdminFaqEditorView({ faqId, onSaved, onDeleted, embedded, ...res
|
|
|
126
132
|
}, className: "space-y-5", children: [_jsx(FieldInput, { name: "question", label: "Question", value: question, onChange: (v) => handleQuestionChange(v), required: true, placeholder: "e.g. How does bidding work on LetItRip?" }), _jsx(Input, { label: "Slug", value: slug, onChange: (e) => {
|
|
127
133
|
setSlug(e.target.value);
|
|
128
134
|
setSlugManual(true);
|
|
129
|
-
}, placeholder: "faq-how-does-bidding-work", helperText: "Auto-generated from question. Must start with 'faq-'." }), _jsxs(
|
|
135
|
+
}, placeholder: "faq-how-does-bidding-work", helperText: "Auto-generated from question. Must start with 'faq-'." }), _jsxs(Div, { className: "space-y-1", children: [_jsx(Text, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Answer" }), _jsx(RichTextEditor, { value: answer, onChange: setAnswer, placeholder: "Write a clear, helpful answer...", minHeightClassName: "min-h-[200px]" })] }), _jsxs(Div, { className: "grid grid-cols-2 gap-4", children: [_jsx(Select, { label: "Category", options: CATEGORY_OPTIONS, value: category, onValueChange: setCategory }), _jsx(Input, { label: "Display order", value: String(order), onChange: (e) => setOrder(parseInt(e.target.value, 10) || 0), type: "number", min: 0, helperText: "Lower = shown first within category." })] }), _jsx(Input, { label: "Priority", value: String(priority), onChange: (e) => setPriority(parseInt(e.target.value, 10) || 0), type: "number", min: 0, helperText: "Higher priority FAQs appear first in search results." }), _jsx(TagInput, { label: "Tags", value: tags, onChange: setTags, placeholder: "e.g. shipping, pokemon, returns" }), _jsxs(Div, { className: `space-y-3 rounded-lg border border-zinc-200 dark:border-zinc-700 ${__P.p4}`, children: [_jsx(Text, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300", children: "Visibility" }), _jsx(Toggle, { label: "Active (visible to users)", checked: isActive, onChange: setIsActive }), _jsx(Toggle, { label: "Pinned (always shown at top)", checked: isPinned, onChange: setIsPinned }), _jsx(Toggle, { label: "Show on homepage FAQ section", checked: showOnHomepage, onChange: setShowOnHomepage }), _jsx(Toggle, { label: "Show in footer FAQ links", checked: showInFooter, onChange: setShowInFooter })] }), _jsxs(Div, { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: !canSave || isSubmitting, children: isEdit ? "Save changes" : "Create FAQ" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteConfirmOpen(true), children: "Delete FAQ" }))] })] }, "faq-form"), deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete FAQ", message: "Delete this FAQ? This cannot be undone.", onConfirm: () => { deleteMutation.mutate(); setDeleteConfirmOpen(false); }, onClose: () => setDeleteConfirmOpen(false), isDeleting: deleteMutation.isPending }))] }));
|
|
130
136
|
if (embedded) {
|
|
131
|
-
return _jsx(
|
|
137
|
+
return _jsx(Div, { className: `${__O.yAuto} ${__P.p4}`, children: formSection });
|
|
132
138
|
}
|
|
133
139
|
return (_jsx(StackedViewShell, { portal: "admin", ...rest, title: isEdit ? "Edit FAQ" : "New FAQ", sections: [formSection] }));
|
|
134
140
|
}
|
|
@@ -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, { useMemo } from "react";
|
|
4
|
-
import { Heading, ListingLayout, Span, Text } from "../../../ui";
|
|
6
|
+
import { Div, Heading, ListingLayout, Span, Text } from "../../../ui";
|
|
5
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
6
8
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
7
9
|
import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
|
|
@@ -13,13 +15,13 @@ const COLUMNS = [
|
|
|
13
15
|
key: "primary",
|
|
14
16
|
header: "Question",
|
|
15
17
|
sortable: true,
|
|
16
|
-
render: (row) => (_jsxs(
|
|
18
|
+
render: (row) => (_jsxs(Div, { className: "space-y-1", children: [_jsx(Text, { className: "font-semibold text-zinc-900 dark:text-zinc-100", children: row.primary }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: row.secondary })] })),
|
|
17
19
|
},
|
|
18
20
|
{
|
|
19
21
|
key: "status",
|
|
20
22
|
header: "Status",
|
|
21
23
|
className: "w-32",
|
|
22
|
-
render: (row) => (_jsx(Span, { className: "inline-flex rounded-full bg-primary-50 px-2.5 py-1 text-
|
|
24
|
+
render: (row) => (_jsx(Span, { size: "xs", weight: "medium", className: "inline-flex rounded-full bg-primary-50 px-2.5 py-1 text-primary-800 dark:bg-secondary-900/30 dark:text-secondary-300", children: row.status })),
|
|
23
25
|
},
|
|
24
26
|
{
|
|
25
27
|
key: "updatedAt",
|
|
@@ -35,12 +37,12 @@ export function AdminFaqsView({ children, onBulkArchive, onBulkDelete, ...props
|
|
|
35
37
|
searchPlaceholder: "Search questions, categories, or tokens",
|
|
36
38
|
emptyLabel: "No FAQs found",
|
|
37
39
|
filterKeys: ["isActive"],
|
|
38
|
-
defaultSort: "priority",
|
|
40
|
+
defaultSort: sortBy("priority", "ASC"),
|
|
39
41
|
queryKey: ["admin", "faqs", "listing"],
|
|
40
42
|
endpoint: ADMIN_ENDPOINTS.FAQS,
|
|
41
43
|
sortOptions: [
|
|
42
44
|
{ value: "priority", label: "Priority" },
|
|
43
|
-
{ value: "
|
|
45
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
44
46
|
{ value: "question", label: "Question A–Z" },
|
|
45
47
|
],
|
|
46
48
|
columns: COLUMNS,
|
|
@@ -56,7 +58,7 @@ export function AdminFaqsView({ children, onBulkArchive, onBulkDelete, ...props
|
|
|
56
58
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
57
59
|
})),
|
|
58
60
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
59
|
-
buildFilters: (state) => state.isActive ?
|
|
61
|
+
buildFilters: (state) => state.isActive ? sieveFilter("isActive", SIEVE_OP.EQ, state.isActive) : undefined,
|
|
60
62
|
primaryAction: {
|
|
61
63
|
label: "Add FAQ",
|
|
62
64
|
onClick: ({ openCreatePanel }) => openCreatePanel(),
|
|
@@ -79,7 +81,7 @@ export function AdminFaqsView({ children, onBulkArchive, onBulkDelete, ...props
|
|
|
79
81
|
]
|
|
80
82
|
: []),
|
|
81
83
|
],
|
|
82
|
-
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(
|
|
84
|
+
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(Div, { className: "space-y-2", children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest text-zinc-500 dark:text-zinc-400", children: "Status" }), _jsx(Div, { className: "flex flex-wrap gap-2", children: [
|
|
83
85
|
{ label: "All", value: "" },
|
|
84
86
|
{ label: "Published", value: "true" },
|
|
85
87
|
{ label: "Draft", value: "false" },
|
|
@@ -7,6 +7,12 @@ import { apiClient } from "../../../http";
|
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
import { ERROR_MESSAGES } from "../../../errors/messages";
|
|
9
9
|
import { PRODUCT_FEATURE_CATEGORY_OPTIONS, PRODUCT_FEATURE_DEFAULT_DISPLAY_ORDER, PRODUCT_FEATURE_ICON_COLOR_OPTIONS, PRODUCT_FEATURE_PRODUCT_TYPE_OPTIONS, PRODUCT_FEATURE_SCOPE_OPTIONS, } from "../../products/constants/product-features.constants";
|
|
10
|
+
const __P = {
|
|
11
|
+
p4: "p-4",
|
|
12
|
+
};
|
|
13
|
+
const __O = {
|
|
14
|
+
yAuto: "overflow-y-auto",
|
|
15
|
+
};
|
|
10
16
|
const PILL_BASE_CLASS = "inline-flex items-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-medium cursor-pointer transition-colors";
|
|
11
17
|
const PILL_CHECKED_CLASS = "bg-primary text-white border-primary";
|
|
12
18
|
const PILL_UNCHECKED_CLASS = "border-zinc-300 dark:border-slate-600 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-slate-800";
|
|
@@ -142,7 +148,7 @@ export function AdminFeatureEditorView({ featureId, fixedScope, fixedStoreId, em
|
|
|
142
148
|
}) })] }), !fixedScope && (_jsx(Select, { label: "Scope", value: scope, onChange: (e) => setScope(e.target.value), options: PRODUCT_FEATURE_SCOPE_OPTIONS })), scope === "store" && !fixedStoreId && (_jsx(Select, { label: "Store", value: storeId, onChange: (e) => setStoreId(e.target.value), options: storeOptions, required: true, helperText: "Store-scope features are visible only on this store's listings." })), _jsx(Toggle, { label: "Active", checked: isActive, onChange: setIsActive }), _jsxs(Div, { className: "flex gap-3 pt-2", children: [_jsx(Button, { type: "submit", isLoading: isSubmitting, disabled: isDisabled, children: isEdit ? "Save changes" : "Create feature" }), isEdit && (_jsx(Button, { type: "button", variant: "danger", isLoading: deleteMutation.isPending, onClick: () => setDeleteConfirmOpen(true), children: "Delete" }))] })] }) }, "feature-form"));
|
|
143
149
|
const deleteModal = deleteConfirmOpen && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Feature", message: DELETE_CONFIRM_TEXT, onConfirm: () => { deleteMutation.mutate(); setDeleteConfirmOpen(false); }, onClose: () => setDeleteConfirmOpen(false), isDeleting: deleteMutation.isPending }));
|
|
144
150
|
if (embedded) {
|
|
145
|
-
return _jsxs(Div, { className:
|
|
151
|
+
return _jsxs(Div, { className: `${__O.yAuto} ${__P.p4}`, children: [formSection, deleteModal] });
|
|
146
152
|
}
|
|
147
153
|
return (_jsxs(_Fragment, { children: [_jsx(StackedViewShell, { portal: "admin", ...rest, title: isEdit ? "Edit Feature" : "New Feature", sections: [formSection] }), deleteModal] }));
|
|
148
154
|
}
|
|
@@ -5,6 +5,9 @@ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
5
5
|
import { Alert, Button, Div, Form, FormActions, Input, StackedViewShell, Text, Toggle, useToast, } from "../../../ui";
|
|
6
6
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
7
7
|
import { apiClient } from "../../../http";
|
|
8
|
+
const __O = {
|
|
9
|
+
hidden: "overflow-hidden",
|
|
10
|
+
};
|
|
8
11
|
// Platform feature keys (flat booleans with rollout % support)
|
|
9
12
|
const PLATFORM_FLAGS = [
|
|
10
13
|
{ key: "blog", label: "Blog Posts", desc: "Publish articles for admins / sellers" },
|
|
@@ -38,7 +41,7 @@ const CATEGORY_TYPE_FLAGS = [
|
|
|
38
41
|
];
|
|
39
42
|
function AccordionSection({ title, defaultOpen = true, children }) {
|
|
40
43
|
const [open, setOpen] = React.useState(defaultOpen);
|
|
41
|
-
return (_jsxs(Div, { className:
|
|
44
|
+
return (_jsxs(Div, { className: `rounded-lg border border-zinc-200 dark:border-zinc-700 ${__O.hidden}`, children: [_jsxs("button", { type: "button", onClick: () => setOpen((v) => !v), className: "w-full flex items-center justify-between px-4 py-3 bg-zinc-50 dark:bg-zinc-800/60 text-left", "aria-expanded": open, children: [_jsx(Text, { className: "text-xs font-semibold uppercase tracking-widest text-zinc-500 dark:text-zinc-400", children: title }), _jsx("svg", { className: `h-4 w-4 text-zinc-400 transition-transform ${open ? "rotate-180" : ""}`, fill: "none", stroke: "currentColor", strokeWidth: 2, viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), open && (_jsx(Div, { className: "divide-y divide-zinc-100 dark:divide-zinc-800", children: children }))] }));
|
|
42
45
|
}
|
|
43
46
|
function FlagRow({ label, desc, checked, onChange, rollout, onRolloutChange, showRollout }) {
|
|
44
47
|
return (_jsxs(Div, { surface: "default", padding: "inline", className: "flex items-center justify-between gap-4", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [_jsx(Toggle, { checked: checked, onChange: onChange, label: label }), _jsx(Text, { className: "mt-0.5 ml-10 text-xs text-zinc-400 dark:text-zinc-400 truncate", children: desc })] }), showRollout && (_jsxs(Div, { className: "flex flex-col gap-1 w-28 shrink-0", children: [_jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400", children: "Rollout %" }), _jsx(Input, { type: "number", min: 0, max: 100, value: rollout ?? 100, onChange: (e) => onRolloutChange?.(Math.min(100, Math.max(0, Number(e.target.value)))), disabled: !checked, className: "w-full" })] }))] }));
|
|
@@ -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 { useRouter, useSearchParams, usePathname } from "next/navigation";
|
|
5
6
|
import { ListingLayout, Row } from "../../../ui";
|
|
@@ -44,15 +45,15 @@ export function AdminFeaturesView({ children, ...props }) {
|
|
|
44
45
|
searchPlaceholder: "Search features by label",
|
|
45
46
|
emptyLabel: "No features found",
|
|
46
47
|
filterKeys: [],
|
|
47
|
-
defaultSort: "displayOrder",
|
|
48
|
+
defaultSort: sortBy("displayOrder", "ASC"),
|
|
48
49
|
pageSize: PAGE_SIZE,
|
|
49
50
|
queryKey: ["admin", "features", "listing", scopeFilter],
|
|
50
51
|
endpoint: `${ADMIN_ENDPOINTS.PRODUCT_FEATURES}?scope=${scopeFilter}`,
|
|
51
52
|
sortOptions: [
|
|
52
|
-
{ value: "displayOrder", label: "Display order" },
|
|
53
|
+
{ value: sortBy("displayOrder", "ASC"), label: "Display order" },
|
|
53
54
|
{ value: "label", label: "Label A–Z" },
|
|
54
|
-
{ value: "
|
|
55
|
-
{ value: "
|
|
55
|
+
{ value: sortBy("label", "DESC"), label: "Label Z–A" },
|
|
56
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
56
57
|
],
|
|
57
58
|
mapRows: (response) => toRecordArray(response.items).map(mapFeatureRow),
|
|
58
59
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Button } from "@mohasinac/appkit/ui";
|
|
2
|
+
import { Button, Div } from "@mohasinac/appkit/ui";
|
|
3
3
|
export function AdminFilterBar({ children, columns = 3, className = "", withCard = true, deferred = false, onApply, onReset, pendingCount = 0, labels = { apply: "Apply", reset: "Reset" }, themeConfig = { cardPadding: "p-4", flexEnd: "flex justify-end" }, }) {
|
|
4
4
|
const gridCols = {
|
|
5
5
|
1: "grid-cols-1",
|
|
@@ -7,7 +7,7 @@ export function AdminFilterBar({ children, columns = 3, className = "", withCard
|
|
|
7
7
|
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 2xl:grid-cols-4",
|
|
8
8
|
4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-4 2xl:grid-cols-4",
|
|
9
9
|
};
|
|
10
|
-
const innerContent = (_jsxs(_Fragment, { children: [_jsx(
|
|
10
|
+
const innerContent = (_jsxs(_Fragment, { children: [_jsx(Div, { className: `grid ${gridCols[columns]} gap-4`, children: children }), deferred && (_jsxs(Div, { className: `${themeConfig.flexEnd} gap-2 mt-3`, children: [pendingCount > 0 && (_jsx(Button, { variant: "ghost", size: "sm", onClick: onReset, children: labels.reset })), _jsx(Button, { variant: "primary", size: "sm", onClick: onApply, children: pendingCount > 0
|
|
11
11
|
? `${labels.applyCount || labels.apply} (${pendingCount})`
|
|
12
12
|
: labels.apply })] }))] }));
|
|
13
13
|
// If Card component is provided in config, use it; otherwise wrap in plain div
|
|
@@ -15,7 +15,7 @@ export function AdminFilterBar({ children, columns = 3, className = "", withCard
|
|
|
15
15
|
return (_jsx(themeConfig.Card, { className: `${themeConfig.cardPadding} ${className}`, children: innerContent }));
|
|
16
16
|
}
|
|
17
17
|
if (!withCard)
|
|
18
|
-
return _jsx(
|
|
18
|
+
return _jsx(Div, { className: className, children: innerContent });
|
|
19
19
|
// Fallback: render as plain div if no Card provided but withCard=true
|
|
20
|
-
return (_jsx(
|
|
20
|
+
return (_jsx(Div, { className: `${themeConfig.cardPadding} ${className}`, children: innerContent }));
|
|
21
21
|
}
|
|
@@ -1,43 +1,79 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
4
|
* AdminGroupedListingsView — admin moderation view for grouped product listings.
|
|
5
5
|
* W1-29 — pairs with the new GET /api/admin/grouped-listings endpoint.
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
7
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
8
|
+
import React, { useState } from "react";
|
|
8
9
|
import { ListingLayout } from "../../../ui";
|
|
10
|
+
import { Button, Row, SideDrawer, Stack, Text, useToast, } from "../../../ui";
|
|
9
11
|
import { toRecordArray, toRelativeDate, toStringValue, } from "../hooks/useAdminListingData";
|
|
10
12
|
import { DataListingView } from "./DataListingView";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
36
|
-
buildFilters: () => "",
|
|
37
|
-
};
|
|
13
|
+
import { ProductInlineSelect } from "../../seller/components/ProductInlineSelect";
|
|
14
|
+
import { apiClient } from "../../../http";
|
|
15
|
+
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
16
|
+
function ReassignProductsDrawer({ state, onClose, onSaved, }) {
|
|
17
|
+
const [productIds, setProductIds] = useState(state.currentProductIds);
|
|
18
|
+
const [saving, setSaving] = useState(false);
|
|
19
|
+
const { showToast } = useToast();
|
|
20
|
+
const handleSave = async () => {
|
|
21
|
+
setSaving(true);
|
|
22
|
+
try {
|
|
23
|
+
await apiClient.patch(ADMIN_ENDPOINTS.GROUPED_LISTING_BY_ID(state.groupId), { productIds });
|
|
24
|
+
showToast("Products reassigned.", "success");
|
|
25
|
+
onSaved();
|
|
26
|
+
onClose();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
showToast("Failed to save changes.", "error");
|
|
30
|
+
}
|
|
31
|
+
finally {
|
|
32
|
+
setSaving(false);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsxs(Text, { size: "sm", color: "muted", children: ["Select products to include in \u201C", state.groupTitle, "\u201D. Changes replace the current list."] }), _jsx(ProductInlineSelect, { scope: "admin", multiple: true, value: productIds, onChange: setProductIds, placeholder: "Search products to add\u2026" }), _jsxs(Row, { justify: "end", gap: "sm", children: [_jsx(Button, { variant: "outline", onClick: onClose, disabled: saving, children: "Cancel" }), _jsxs(Button, { variant: "primary", onClick: handleSave, disabled: saving, isLoading: saving, children: ["Save (", productIds.length, " product", productIds.length !== 1 ? "s" : "", ")"] })] })] }));
|
|
36
|
+
}
|
|
38
37
|
export function AdminGroupedListingsView({ children, ...props }) {
|
|
38
|
+
const [reassign, setReassign] = useState(null);
|
|
39
|
+
const [refreshKey, setRefreshKey] = useState(0);
|
|
40
|
+
const config = React.useMemo(() => ({
|
|
41
|
+
portal: "admin",
|
|
42
|
+
title: "Grouped Listings",
|
|
43
|
+
searchPlaceholder: "Search grouped listings by title or seller",
|
|
44
|
+
emptyLabel: "No grouped listings",
|
|
45
|
+
filterKeys: [],
|
|
46
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
47
|
+
queryKey: ["admin", "grouped-listings", refreshKey],
|
|
48
|
+
endpoint: ADMIN_ENDPOINTS.GROUPED_LISTINGS,
|
|
49
|
+
sortOptions: [
|
|
50
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
51
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
52
|
+
{ value: "title", label: "Title A–Z" },
|
|
53
|
+
],
|
|
54
|
+
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
55
|
+
id: toStringValue(item.id, `grouped-listing-${index}`),
|
|
56
|
+
primary: toStringValue(item.title ?? item.name, "Untitled group"),
|
|
57
|
+
secondary: [
|
|
58
|
+
toStringValue(item.storeName ?? item.storeId, "Unknown store"),
|
|
59
|
+
`${Array.isArray(item.productIds) ? item.productIds.length : 0} items`,
|
|
60
|
+
].join(" · "),
|
|
61
|
+
status: toStringValue(item.isActive === false ? "inactive" : "active", "active"),
|
|
62
|
+
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
63
|
+
_raw: item,
|
|
64
|
+
})),
|
|
65
|
+
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
66
|
+
buildFilters: () => "",
|
|
67
|
+
renderRowActions: (row) => (_jsx(Button, { size: "sm", variant: "outline", onClick: () => setReassign({
|
|
68
|
+
groupId: row.id,
|
|
69
|
+
groupTitle: row.primary,
|
|
70
|
+
currentProductIds: Array.isArray(row._raw?.productIds)
|
|
71
|
+
? (row._raw?.productIds ?? []).map(String)
|
|
72
|
+
: [],
|
|
73
|
+
}), children: "Reassign products" })),
|
|
74
|
+
}), [refreshKey]);
|
|
39
75
|
if (React.Children.count(children) > 0) {
|
|
40
76
|
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
41
77
|
}
|
|
42
|
-
return _jsx(DataListingView, { config:
|
|
78
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(SideDrawer, { isOpen: reassign !== null, onClose: () => setReassign(null), title: reassign ? `Reassign products — ${reassign.groupTitle}` : "Reassign products", children: reassign && (_jsx(ReassignProductsDrawer, { state: reassign, onClose: () => setReassign(null), onSaved: () => setRefreshKey((k) => k + 1) })) })] }));
|
|
43
79
|
}
|
|
@@ -2,6 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Users, Package, Store, ShoppingBag, FileText, Settings, Shield, BarChart2, AlertTriangle, BookOpen, } from "lucide-react";
|
|
3
3
|
import { Div, Heading, Text, Section, Alert } from "../../../ui";
|
|
4
4
|
import { ROUTES } from "../../../next/routing/route-map";
|
|
5
|
+
const CLS_WARN_PANEL = "rounded-2xl border border-amber-200 bg-warning-surface dark:border-amber-800 p-6";
|
|
6
|
+
const CLS_WARN_HEAD = "font-semibold text-amber-800 dark:text-amber-300 mb-1";
|
|
7
|
+
const CLS_WARN_BODY = "text-sm text-amber-700 dark:text-amber-400";
|
|
5
8
|
const GUIDE_CARDS = [
|
|
6
9
|
{
|
|
7
10
|
Icon: Users,
|
|
@@ -75,5 +78,5 @@ export function AdminGuideHubView({ permissions = [], isFullAdmin = false }) {
|
|
|
75
78
|
background: "linear-gradient(135deg,var(--appkit-color-primary-700,#4f46e5) 0%,var(--appkit-color-cobalt,#2563eb) 60%,var(--appkit-color-secondary-400,#7c3aed) 100%)",
|
|
76
79
|
}, children: [_jsxs(Div, { className: "flex items-center gap-3 mb-3", children: [_jsx(Div, { className: "flex-shrink-0 w-10 h-10 rounded-xl bg-white/20 flex items-center justify-center", children: _jsx(BookOpen, { className: "w-5 h-5 text-white" }) }), _jsx(Text, { className: "text-sm font-semibold text-white/80 uppercase tracking-widest", children: "Admin & Employee Guide" })] }), _jsx(Heading, { level: 1, className: "text-2xl md:text-3xl font-bold text-white mb-2", children: "LetItRip Internal Guide" }), _jsx(Text, { className: "text-white/80 text-base", children: "Everything you need to operate and manage LetItRip \u2014 India's largest collectibles marketplace." })] }) }), _jsx(Alert, { variant: "info", compact: true, children: "These guides describe expected platform behaviour. Real access to each section is enforced independently by the permission system \u2014 this page is reference only." }), !hasAny && (_jsx(Alert, { variant: "info", title: "Limited access", children: "Your permission set doesn't include read access to any admin sections yet. Contact your admin to request the permissions you need." })), hasAny && (_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "text-lg font-semibold text-[var(--appkit-color-text)] mb-4", children: "Guides" }), _jsx(Div, { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3", children: visibleCards.map(({ Icon, title, description, href }) => (_jsxs("a", { href: href, className: "group flex flex-col gap-3 rounded-xl border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] p-5 hover:border-[var(--appkit-color-primary)] hover:shadow-md transition-all", children: [_jsxs(Div, { className: "flex items-center gap-3", children: [_jsx(Div, { className: "flex-shrink-0 w-9 h-9 rounded-lg flex items-center justify-center", style: {
|
|
77
80
|
background: "linear-gradient(135deg,var(--appkit-color-primary-700,#4f46e5) 0%,var(--appkit-color-cobalt,#2563eb) 100%)",
|
|
78
|
-
}, children: _jsx(Icon, { className: "w-4 h-4 text-white" }) }), _jsx(Text, { className: "font-semibold text-[var(--appkit-color-text)] group-hover:text-[var(--appkit-color-primary)] transition-colors", children: title })] }), _jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)] leading-relaxed", children: description }), _jsx(Text, { className: "text-xs font-medium text-[var(--appkit-color-primary)] mt-auto", children: "Read guide \u2192" })] }, title))) })] })), _jsx(Section, { className:
|
|
81
|
+
}, children: _jsx(Icon, { className: "w-4 h-4 text-white" }) }), _jsx(Text, { className: "font-semibold text-[var(--appkit-color-text)] group-hover:text-[var(--appkit-color-primary)] transition-colors", children: title })] }), _jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)] leading-relaxed", children: description }), _jsx(Text, { className: "text-xs font-medium text-[var(--appkit-color-primary)] mt-auto", children: "Read guide \u2192" })] }, title))) })] })), _jsx(Section, { className: CLS_WARN_PANEL, children: _jsxs(Div, { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-warning flex-shrink-0 mt-0.5" }), _jsxs(Div, { children: [_jsx(Text, { className: CLS_WARN_HEAD, children: "Remember: with great access comes responsibility" }), _jsx(Text, { className: CLS_WARN_BODY, children: "Admin actions are logged. Never access user PII (email, phone) without a legitimate support reason. Never grant capabilities or permissions without documented approval. When in doubt, escalate to a senior admin." })] })] }) })] }));
|
|
79
82
|
}
|
|
@@ -4,6 +4,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
4
4
|
* AdminHistoryView — read-only admin insights for the top-level `history` collection.
|
|
5
5
|
* One row per user with item count + last visit. Mirrors AdminWishlistsView.
|
|
6
6
|
*/
|
|
7
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
7
8
|
import React from "react";
|
|
8
9
|
import { ListingLayout } from "../../../ui";
|
|
9
10
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -15,12 +16,12 @@ const ADMIN_HISTORY_CONFIG = {
|
|
|
15
16
|
searchPlaceholder: "Search by user ID",
|
|
16
17
|
emptyLabel: "No user history records found",
|
|
17
18
|
filterKeys: [],
|
|
18
|
-
defaultSort: "
|
|
19
|
+
defaultSort: sortBy("updatedAt", "DESC"),
|
|
19
20
|
queryKey: ["admin", "history", "listing"],
|
|
20
21
|
endpoint: ADMIN_ENDPOINTS.ADMIN_HISTORY,
|
|
21
22
|
sortOptions: [
|
|
22
|
-
{ value: "
|
|
23
|
-
{ value: "
|
|
23
|
+
{ value: sortBy("updatedAt", "DESC"), label: "Recently active" },
|
|
24
|
+
{ value: sortBy("itemCount", "DESC"), label: "Largest first" },
|
|
24
25
|
],
|
|
25
26
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
26
27
|
const itemCount = typeof item.itemCount === "number" ? item.itemCount : 0;
|
|
@@ -3,6 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* AdminLiveView — admin browse of live-item listings (W1-29).
|
|
5
5
|
*/
|
|
6
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
6
7
|
import React from "react";
|
|
7
8
|
import { ListingLayout } from "../../../ui";
|
|
8
9
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -14,12 +15,12 @@ const ADMIN_LIVE_CONFIG = {
|
|
|
14
15
|
searchPlaceholder: "Search live items",
|
|
15
16
|
emptyLabel: "No live item listings",
|
|
16
17
|
filterKeys: [],
|
|
17
|
-
defaultSort: "
|
|
18
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
18
19
|
queryKey: ["admin", "live-items", "listing"],
|
|
19
20
|
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
20
21
|
sortOptions: [
|
|
21
|
-
{ value: "
|
|
22
|
-
{ value: "createdAt", label: "Oldest" },
|
|
22
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
23
|
+
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
23
24
|
{ value: "title", label: "Title A–Z" },
|
|
24
25
|
],
|
|
25
26
|
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
@@ -4,6 +4,9 @@ import React from "react";
|
|
|
4
4
|
import { Alert, Button, Div, Input, Select, StackedViewShell, Text, useToast, } from "../../../ui";
|
|
5
5
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
6
6
|
import { MediaUploadField, MediaUploadList, useMediaCleanup, useMediaUpload, } from "../../media";
|
|
7
|
+
const __P = {
|
|
8
|
+
p4: "p-4",
|
|
9
|
+
};
|
|
7
10
|
const PREFIX_OPTIONS = [
|
|
8
11
|
{ value: "", label: "All" },
|
|
9
12
|
{ value: "products/", label: "Products" },
|
|
@@ -58,7 +61,7 @@ function MediaBrowser({ onCopy }) {
|
|
|
58
61
|
return files;
|
|
59
62
|
return files.filter((f) => f.name.toLowerCase().includes(q));
|
|
60
63
|
}, [files, search]);
|
|
61
|
-
return (_jsxs(Div, { className:
|
|
64
|
+
return (_jsxs(Div, { className: `space-y-3 rounded-xl border border-zinc-200 bg-white ${__P.p4} dark:border-slate-700 dark:bg-slate-900`, children: [_jsx(Text, { className: "text-sm font-semibold text-zinc-900 dark:text-zinc-100", children: "Browse existing media" }), _jsxs(Div, { className: "flex flex-wrap items-center gap-2", children: [_jsx(Select, { value: prefix, onChange: (e) => setPrefix(e.target.value), options: PREFIX_OPTIONS, "aria-label": "Prefix filter", className: "min-w-[140px]" }), _jsx(Input, { type: "text", placeholder: "Search filename\u2026", value: search, onChange: (e) => setSearch(e.target.value), className: "flex-1 min-w-[160px]" })] }), error && (_jsx(Alert, { variant: "error", title: "Load failed", children: error })), _jsxs(Div, { className: "grid grid-cols-2 gap-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6", children: [filtered.map((f) => {
|
|
62
65
|
const isImage = (f.contentType ?? "").startsWith("image/");
|
|
63
66
|
return (_jsxs(Div, { className: "group rounded-lg border border-zinc-200 dark:border-slate-700 overflow-hidden bg-zinc-50 dark:bg-slate-800", children: [_jsx(Div, { className: "aspect-square flex items-center justify-center bg-zinc-100 dark:bg-slate-700 text-xs text-zinc-500 dark:text-zinc-400", children: isImage ? (
|
|
64
67
|
// eslint-disable-next-line @next/next/no-img-element
|
|
@@ -2,13 +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, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { Alert, Button, ConfirmDeleteModal, RowActionMenu, StackedViewShell, Text, Toggle, useToast } from "../../../ui";
|
|
5
|
+
import { Alert, Button, ConfirmDeleteModal, Div, RowActionMenu, Span, StackedViewShell, Text, Toggle, useToast } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
8
|
import { AdminNavEditorView } from "./AdminNavEditorView";
|
|
9
9
|
import { ROW_ACTION_META, ROW_ACTION_ID } from "../../../features/products/constants/action-defs";
|
|
10
|
+
const __O = {
|
|
11
|
+
hidden: "overflow-hidden",
|
|
12
|
+
};
|
|
10
13
|
function NavItemRow({ item, idx, total, reorderPending, onMoveUp, onMoveDown, onVisibilityChange, onEdit, onDelete, }) {
|
|
11
|
-
return (_jsxs("
|
|
14
|
+
return (_jsxs(Div, { surface: "default", className: "flex items-center gap-3 px-4 py-3", children: [_jsxs(Div, { className: "flex flex-col gap-0.5 shrink-0", children: [_jsx(Button, { variant: "ghost", type: "button", onClick: () => onMoveUp(idx), disabled: idx === 0 || reorderPending, className: "text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200 disabled:opacity-30 leading-none text-xs p-0 min-h-0 h-auto rounded-none", "aria-label": "Move up", children: "\u25B2" }), _jsx(Button, { variant: "ghost", type: "button", onClick: () => onMoveDown(idx), disabled: idx >= total - 1 || reorderPending, className: "text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200 disabled:opacity-30 leading-none text-xs p-0 min-h-0 h-auto rounded-none", "aria-label": "Move down", children: "\u25BC" })] }), _jsxs(Div, { className: "flex-1 min-w-0", children: [_jsxs(Text, { className: "text-sm font-medium text-zinc-800 dark:text-zinc-100 truncate", children: [item.parentId ? _jsx(Span, { className: "text-zinc-400 mr-1", children: "\u21B3" }) : null, item.label] }), _jsx(Text, { className: "text-xs text-zinc-500 dark:text-zinc-400 truncate", children: item.href })] }), _jsx(Toggle, { checked: item.isVisible ?? true, onChange: (val) => onVisibilityChange(item.id, val), label: "" }), _jsx(RowActionMenu, { actions: [
|
|
12
15
|
{ label: ROW_ACTION_META[ROW_ACTION_ID.EDIT].label, onClick: () => onEdit(item) },
|
|
13
16
|
{ label: ROW_ACTION_META[ROW_ACTION_ID.DELETE].label, destructive: true, onClick: () => onDelete(item) },
|
|
14
17
|
] })] }));
|
|
@@ -78,11 +81,11 @@ export function AdminNavigationView({ labels = {}, ...rest }) {
|
|
|
78
81
|
return (_jsxs(_Fragment, { children: [_jsx(StackedViewShell, { portal: "admin", ...rest, title: labels.title ?? "Navigation", sections: [
|
|
79
82
|
isLoading ? (_jsx(Alert, { variant: "info", title: "Loading", children: "Fetching nav items\u2026" }, "loading")) : null,
|
|
80
83
|
error ? (_jsx(Alert, { variant: "error", title: "Load failed", children: error instanceof Error ? error.message : "Unknown error" }, "error")) : null,
|
|
81
|
-
_jsxs(
|
|
84
|
+
_jsxs(Div, { className: "flex items-center justify-between mb-4", children: [_jsxs(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: [sorted.length, " nav item", sorted.length !== 1 ? "s" : ""] }), _jsx(Button, { onClick: () => {
|
|
82
85
|
setEditing(null);
|
|
83
86
|
setDrawerOpen(true);
|
|
84
87
|
}, children: "+ New item" })] }, "header"),
|
|
85
88
|
sorted.length === 0 && !isLoading ? (_jsx(Text, { className: "text-sm text-zinc-400 dark:text-zinc-400 py-8 text-center", children: "No nav items yet. Click \"New item\" to add one." }, "empty")) : null,
|
|
86
|
-
_jsx(
|
|
89
|
+
_jsx(Div, { className: `divide-y divide-zinc-200 dark:divide-zinc-700 rounded-lg border border-zinc-200 dark:border-zinc-700 ${__O.hidden}`, children: sorted.map((item, idx) => (_jsx(NavItemRow, { item: item, idx: idx, total: sorted.length, reorderPending: reorderMutation.isPending, onMoveUp: handleMoveUp, onMoveDown: handleMoveDown, onVisibilityChange: (id, isVisible) => visibilityMutation.mutate({ id, isVisible }), onEdit: (i) => { setEditing(i); setDrawerOpen(true); }, onDelete: setDeleteTarget }, item.id))) }, "list"),
|
|
87
90
|
] }), _jsx(AdminNavEditorView, { open: drawerOpen, onClose: () => setDrawerOpen(false), onSaved: () => queryClient.invalidateQueries({ queryKey: ["admin", "navigation"] }), item: editing, parentOptions: parentOptions }), _jsx(ConfirmDeleteModal, { isOpen: Boolean(deleteTarget), onClose: () => setDeleteTarget(null), onConfirm: () => deleteMutation.mutate(deleteTarget.id), isDeleting: deleteMutation.isPending, title: "Delete nav item", message: `Remove "${deleteTarget?.label}" from navigation? This cannot be undone.` })] }));
|
|
88
91
|
}
|