@mohasinac/appkit 2.3.1 → 2.3.2
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/client.d.ts +12 -8
- package/dist/client.js +7 -4
- package/dist/constants/api-endpoints.d.ts +4 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/core/contact-submissions.repository.d.ts +32 -0
- package/dist/core/contact-submissions.repository.js +49 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +1 -0
- package/dist/features/about/components/HowPayoutsWorkView.js +1 -1
- package/dist/features/account/components/AddressFilters.d.ts +5 -0
- package/dist/features/account/components/AddressFilters.js +20 -0
- package/dist/features/account/components/AddressesIndexListing.d.ts +6 -0
- package/dist/features/account/components/AddressesIndexListing.js +51 -0
- package/dist/features/account/components/UserSidebar.d.ts +7 -3
- package/dist/features/account/components/UserSidebar.js +55 -7
- package/dist/features/account/hooks/useAddresses.d.ts +7 -0
- package/dist/features/account/hooks/useAddresses.js +12 -1
- package/dist/features/admin/actions/admin-read-actions.d.ts +12 -0
- package/dist/features/admin/actions/admin-read-actions.js +18 -0
- package/dist/features/admin/components/AdminBlogView.js +26 -2
- package/dist/features/admin/components/AdminCarouselView.js +18 -2
- package/dist/features/admin/components/AdminCategoriesView.js +27 -2
- package/dist/features/admin/components/AdminContactView.d.ts +4 -0
- package/dist/features/admin/components/AdminContactView.js +50 -0
- package/dist/features/admin/components/AdminFaqsView.js +19 -2
- package/dist/features/admin/components/AdminListingScaffold.d.ts +11 -2
- package/dist/features/admin/components/AdminListingScaffold.js +14 -3
- package/dist/features/admin/components/AdminNewsletterView.d.ts +4 -0
- package/dist/features/admin/components/AdminNewsletterView.js +50 -0
- package/dist/features/admin/components/AdminProductsView.js +30 -2
- package/dist/features/admin/components/AdminReviewsView.js +26 -2
- package/dist/features/admin/components/AdminStoresView.js +17 -2
- package/dist/features/admin/components/AdminUsersView.js +27 -2
- package/dist/features/admin/components/DataTable.d.ts +2 -1
- package/dist/features/admin/components/DataTable.js +18 -4
- package/dist/features/admin/components/index.d.ts +6 -0
- package/dist/features/admin/components/index.js +3 -0
- package/dist/features/admin/hooks/useAdminListingData.d.ts +3 -1
- package/dist/features/admin/hooks/useAdminListingData.js +12 -7
- package/dist/features/admin/server.d.ts +3 -0
- package/dist/features/admin/server.js +2 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +93 -47
- package/dist/features/auctions/components/AuctionFilters.d.ts +8 -0
- package/dist/features/auctions/components/AuctionFilters.js +12 -0
- package/dist/features/auctions/components/AuctionsListView.d.ts +6 -1
- package/dist/features/auctions/components/AuctionsListView.js +37 -5
- package/dist/features/auctions/schemas/index.d.ts +4 -4
- package/dist/features/blog/components/BlogFeaturedCard.d.ts +1 -7
- package/dist/features/blog/components/BlogFeaturedCard.js +4 -5
- package/dist/features/blog/components/BlogFilters.js +2 -1
- package/dist/features/blog/components/BlogIndexListing.js +14 -9
- package/dist/features/blog/components/BlogIndexPageView.d.ts +6 -1
- package/dist/features/blog/components/BlogIndexPageView.js +10 -2
- package/dist/features/blog/components/BlogListView.d.ts +2 -1
- package/dist/features/blog/components/BlogListView.js +10 -3
- package/dist/features/categories/components/CategoriesIndexListing.d.ts +1 -1
- package/dist/features/categories/components/CategoriesIndexListing.js +41 -38
- package/dist/features/categories/components/CategoriesIndexPageView.d.ts +6 -1
- package/dist/features/categories/components/CategoriesIndexPageView.js +41 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +13 -6
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +5 -0
- package/dist/features/categories/components/CategoryDetailTabs.js +17 -0
- package/dist/features/categories/components/CategoryFilters.js +2 -1
- package/dist/features/categories/components/CategoryGrid.d.ts +2 -1
- package/dist/features/categories/components/CategoryGrid.js +8 -6
- package/dist/features/categories/components/CategoryProductsListing.js +22 -11
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/categories/hooks/useCategories.d.ts +20 -0
- package/dist/features/categories/hooks/useCategories.js +50 -1
- package/dist/features/categories/hooks/useCategoryTree.d.ts +17 -0
- package/dist/features/categories/hooks/useCategoryTree.js +65 -0
- package/dist/features/events/components/AdminEventEditorView.d.ts +6 -0
- package/dist/features/events/components/AdminEventEditorView.js +203 -0
- package/dist/features/events/components/AdminEventsView.js +28 -2
- package/dist/features/events/components/EventCard.js +4 -2
- package/dist/features/events/components/EventFilters.js +2 -1
- package/dist/features/events/components/EventsIndexListing.js +40 -10
- package/dist/features/events/components/EventsListPageView.d.ts +6 -1
- package/dist/features/events/components/EventsListPageView.js +40 -7
- package/dist/features/events/components/index.d.ts +2 -0
- package/dist/features/events/components/index.js +1 -0
- package/dist/features/events/hooks/useEvents.js +2 -0
- package/dist/features/events/types/index.d.ts +1 -0
- package/dist/features/homepage/components/BlogArticlesSection.js +1 -1
- package/dist/features/homepage/components/EventsSection.js +1 -1
- package/dist/features/homepage/components/FeaturedAuctionsSection.js +1 -1
- package/dist/features/homepage/components/FeaturedPreOrdersSection.js +1 -1
- package/dist/features/homepage/components/FeaturedProductsSection.js +1 -1
- package/dist/features/homepage/components/FeaturedStoresSection.js +1 -1
- package/dist/features/homepage/components/HeroCarousel.js +1 -1
- package/dist/features/homepage/components/MarketplaceHomepageView.js +27 -17
- package/dist/features/homepage/components/SectionCarousel.js +4 -4
- package/dist/features/homepage/components/ShopByCategorySection.js +2 -2
- package/dist/features/homepage/schemas/firestore.d.ts +1 -1
- package/dist/features/homepage/schemas/firestore.js +2 -1
- package/dist/features/layout/AppLayoutShell.d.ts +6 -2
- package/dist/features/layout/AppLayoutShell.js +7 -3
- package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +3 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +6 -2
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +80 -12
- package/dist/features/pre-orders/components/PreOrderFilters.d.ts +8 -0
- package/dist/features/pre-orders/components/PreOrderFilters.js +21 -0
- package/dist/features/pre-orders/components/PreOrdersIndexListing.d.ts +2 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +69 -10
- package/dist/features/pre-orders/components/PreOrdersListView.d.ts +6 -1
- package/dist/features/pre-orders/components/PreOrdersListView.js +26 -7
- package/dist/features/pre-orders/components/index.d.ts +2 -0
- package/dist/features/pre-orders/components/index.js +1 -0
- package/dist/features/products/components/AuctionsIndexListing.d.ts +2 -1
- package/dist/features/products/components/AuctionsIndexListing.js +61 -9
- package/dist/features/products/components/InteractiveProductCard.d.ts +2 -4
- package/dist/features/products/components/InteractiveProductCard.js +2 -2
- package/dist/features/products/components/ProductDetailPageView.d.ts +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +116 -25
- package/dist/features/products/components/ProductFilters.d.ts +6 -11
- package/dist/features/products/components/ProductFilters.js +5 -3
- package/dist/features/products/components/ProductGrid.d.ts +8 -2
- package/dist/features/products/components/ProductGrid.js +20 -5
- package/dist/features/products/components/ProductTabsShell.d.ts +3 -11
- package/dist/features/products/components/ProductTabsShell.js +14 -14
- package/dist/features/products/components/ProductsIndexListing.js +73 -9
- package/dist/features/products/components/ProductsIndexPageView.d.ts +6 -1
- package/dist/features/products/components/ProductsIndexPageView.js +39 -6
- package/dist/features/products/components/RelatedProductsCarousel.d.ts +7 -0
- package/dist/features/products/components/RelatedProductsCarousel.js +11 -0
- package/dist/features/products/components/index.d.ts +1 -0
- package/dist/features/products/components/index.js +1 -0
- package/dist/features/products/hooks/useProducts.js +16 -0
- package/dist/features/products/repository/products.repository.d.ts +8 -0
- package/dist/features/products/repository/products.repository.js +2 -0
- package/dist/features/products/schemas/index.d.ts +8 -8
- package/dist/features/products/types/index.d.ts +12 -0
- package/dist/features/promotions/components/CouponsIndexListing.d.ts +9 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +86 -0
- package/dist/features/promotions/components/PromotionsView.d.ts +11 -5
- package/dist/features/promotions/components/PromotionsView.js +6 -1
- package/dist/features/promotions/components/index.d.ts +4 -2
- package/dist/features/promotions/components/index.js +2 -1
- package/dist/features/reviews/components/ReviewDetailPageView.d.ts +4 -0
- package/dist/features/reviews/components/ReviewDetailPageView.js +20 -0
- package/dist/features/reviews/components/ReviewDetailShell.d.ts +7 -0
- package/dist/features/reviews/components/ReviewDetailShell.js +80 -0
- package/dist/features/reviews/components/ReviewFilters.d.ts +3 -3
- package/dist/features/reviews/components/ReviewFilters.js +5 -4
- package/dist/features/reviews/components/ReviewsIndexListing.d.ts +4 -3
- package/dist/features/reviews/components/ReviewsIndexListing.js +35 -51
- package/dist/features/reviews/components/ReviewsIndexPageView.d.ts +6 -1
- package/dist/features/reviews/components/ReviewsIndexPageView.js +49 -3
- package/dist/features/reviews/components/ReviewsList.js +9 -1
- package/dist/features/reviews/components/index.d.ts +1 -0
- package/dist/features/reviews/hooks/useReviews.js +15 -1
- package/dist/features/reviews/types/index.d.ts +6 -1
- package/dist/features/seller/components/SellerSidebar.d.ts +8 -4
- package/dist/features/seller/components/SellerSidebar.js +6 -4
- package/dist/features/seller/components/index.d.ts +30 -0
- package/dist/features/seller/components/index.js +17 -0
- package/dist/features/seller/hooks/useSellerStore.d.ts +2 -0
- package/dist/features/seller/hooks/useSellerStore.js +2 -0
- package/dist/features/seller/permission-map.d.ts +4 -2
- package/dist/features/seller/permission-map.js +16 -14
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/stores/api/[storeSlug]/reviews/route.d.ts +1 -1
- package/dist/features/stores/api/[storeSlug]/reviews/route.js +24 -19
- package/dist/features/stores/components/InteractiveStoreCard.d.ts +0 -5
- package/dist/features/stores/components/InteractiveStoreCard.js +9 -9
- package/dist/features/stores/components/StoreAuctionsListing.js +27 -9
- package/dist/features/stores/components/StoreDetailLayoutView.js +2 -0
- package/dist/features/stores/components/StoreFilters.d.ts +5 -0
- package/dist/features/stores/components/StoreFilters.js +20 -0
- package/dist/features/stores/components/StoreHeader.js +2 -2
- package/dist/features/stores/components/StorePreOrdersListing.d.ts +5 -0
- package/dist/features/stores/components/StorePreOrdersListing.js +40 -0
- package/dist/features/stores/components/StorePreOrdersPageView.d.ts +4 -0
- package/dist/features/stores/components/StorePreOrdersPageView.js +21 -0
- package/dist/features/stores/components/StoreProductsListing.js +21 -11
- package/dist/features/stores/components/StoreReviewsListing.js +2 -7
- package/dist/features/stores/components/StoresIndexListing.js +42 -8
- package/dist/features/stores/components/StoresIndexPageView.d.ts +6 -1
- package/dist/features/stores/components/StoresIndexPageView.js +9 -2
- package/dist/features/stores/components/index.d.ts +3 -0
- package/dist/features/stores/components/index.js +1 -0
- package/dist/features/stores/hooks/useStores.d.ts +7 -1
- package/dist/features/stores/hooks/useStores.js +16 -3
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/stores/types/index.d.ts +3 -0
- package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +20 -0
- package/dist/features/wishlist/hooks/useGuestWishlist.js +49 -0
- package/dist/features/wishlist/hooks/useWishlistCount.d.ts +7 -0
- package/dist/features/wishlist/hooks/useWishlistCount.js +31 -0
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +56 -0
- package/dist/features/wishlist/hooks/useWishlistWithGuest.js +57 -0
- package/dist/features/wishlist/index.d.ts +3 -0
- package/dist/features/wishlist/index.js +3 -0
- package/dist/features/wishlist/utils/guest-wishlist.d.ts +22 -0
- package/dist/features/wishlist/utils/guest-wishlist.js +70 -0
- package/dist/index.d.ts +50 -1
- package/dist/index.js +63 -1
- package/dist/next/routing/route-map.d.ts +70 -36
- package/dist/next/routing/route-map.js +30 -22
- package/dist/seed/addresses-seed-data.js +62 -261
- package/dist/seed/beyblade-seed-data.d.ts +7 -0
- package/dist/seed/beyblade-seed-data.js +947 -0
- package/dist/seed/bids-seed-data.d.ts +10 -2
- package/dist/seed/bids-seed-data.js +220 -1071
- package/dist/seed/blog-posts-seed-data.d.ts +2 -2
- package/dist/seed/blog-posts-seed-data.js +455 -117
- package/dist/seed/cart-seed-data.d.ts +9 -9
- package/dist/seed/cart-seed-data.js +73 -74
- package/dist/seed/coupons-seed-data.d.ts +3 -4
- package/dist/seed/coupons-seed-data.js +3 -509
- package/dist/seed/events-seed-data.d.ts +2 -2
- package/dist/seed/events-seed-data.js +315 -476
- package/dist/seed/faq-seed-data.d.ts +18 -41
- package/dist/seed/faq-seed-data.js +1059 -1172
- package/dist/seed/hot-wheels-seed-data.d.ts +7 -0
- package/dist/seed/hot-wheels-seed-data.js +1365 -0
- package/dist/seed/index.d.ts +6 -1
- package/dist/seed/index.js +6 -1
- package/dist/seed/pokemon-carousel-slides-seed-data.d.ts +4 -2
- package/dist/seed/pokemon-carousel-slides-seed-data.js +152 -268
- package/dist/seed/pokemon-categories-seed-data.d.ts +18 -21
- package/dist/seed/pokemon-categories-seed-data.js +424 -1004
- package/dist/seed/pokemon-coupons-seed-data.d.ts +6 -0
- package/dist/seed/pokemon-coupons-seed-data.js +465 -0
- package/dist/seed/pokemon-homepage-sections-seed-data.d.ts +3 -2
- package/dist/seed/pokemon-homepage-sections-seed-data.js +67 -289
- package/dist/seed/pokemon-products-seed-data.js +662 -0
- package/dist/seed/pokemon-seed-bundle.d.ts +32 -11
- package/dist/seed/pokemon-seed-bundle.js +41 -11
- package/dist/seed/pokemon-stores-seed-data.d.ts +2 -3
- package/dist/seed/pokemon-stores-seed-data.js +56 -31
- package/dist/seed/pokemon-users-seed-data.d.ts +2 -2
- package/dist/seed/pokemon-users-seed-data.js +245 -261
- package/dist/seed/reviews-seed-data.d.ts +17 -2
- package/dist/seed/reviews-seed-data.js +519 -483
- package/dist/seed/site-settings-seed-data.js +14 -14
- package/dist/seed/store-addresses-seed-data.js +68 -50
- package/dist/seed/transformers-seed-data.d.ts +7 -0
- package/dist/seed/transformers-seed-data.js +510 -0
- package/dist/seed/wishlists-seed-data.d.ts +5 -1
- package/dist/seed/wishlists-seed-data.js +82 -4
- package/dist/server.d.ts +1 -0
- package/dist/server.js +2 -0
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/index.js +2 -0
- package/dist/ui/components/BaseListingCard.js +24 -26
- package/dist/ui/components/BaseListingCard.style.css +5 -5
- package/dist/ui/components/HorizontalScroller.d.ts +1 -1
- package/dist/ui/components/HorizontalScroller.js +19 -5
- package/dist/ui/components/SideDrawer.style.css +3 -11
- package/dist/ui/rich-text/RichText.js +19 -1
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -59,10 +59,13 @@ export type { NavigationLoaderProps } from "./ui/index";
|
|
|
59
59
|
export { ZodSetup } from "./validation/ZodSetup";
|
|
60
60
|
export type { ZodSetupProps } from "./validation/ZodSetup";
|
|
61
61
|
export { AdminSidebar } from "./features/admin/components/AdminSidebar";
|
|
62
|
-
export { AdminDashboardView, AdminAnalyticsView } from "./features/admin/index";
|
|
62
|
+
export { AdminDashboardView, AdminAnalyticsView, AdminListingScaffold, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
|
|
63
63
|
export type { AdminDashboardViewProps, AdminAnalyticsViewProps, AdminAnalyticsViewLabels } from "./features/admin/index";
|
|
64
|
+
export { ADMIN_ENDPOINTS } from "./constants/index";
|
|
64
65
|
export { UserSidebar } from "./features/account/components/UserSidebar";
|
|
65
|
-
export type { UserSidebarProps, UserNavItem } from "./features/account/components/UserSidebar";
|
|
66
|
+
export type { UserSidebarProps, UserNavItem, UserNavGroup } from "./features/account/components/UserSidebar";
|
|
67
|
+
export { CouponsIndexListing } from "./features/promotions/components/CouponsIndexListing";
|
|
68
|
+
export type { CouponsIndexListingProps } from "./features/promotions/components/CouponsIndexListing";
|
|
66
69
|
export { NotificationBell } from "./features/account/components/NotificationBell";
|
|
67
70
|
export { ProtectedRoute, AuthStatusPanel, ForgotPasswordView, LoginForm, RegisterForm, ResetPasswordView, VerifyEmailView } from "./features/auth/index";
|
|
68
71
|
export type { AuthGuardUser, ForgotPasswordViewProps, LoginFormProps, LoginFormValues, RegisterFormProps, RegisterFormValues, ResetPasswordViewProps, VerifyEmailViewProps, } from "./features/auth/index";
|
|
@@ -76,19 +79,20 @@ export { CategoryProductsView, CategoriesListView } from "./features/categories/
|
|
|
76
79
|
export type { CategoryItem } from "./features/categories/index";
|
|
77
80
|
export { MediaImage } from "./features/media/index";
|
|
78
81
|
export { ReviewsListView } from "./features/reviews/index";
|
|
79
|
-
export { SellerSidebar } from "./features/seller/components/SellerSidebar";
|
|
80
|
-
export type { SellerNavItem } from "./features/seller/components/SellerSidebar";
|
|
82
|
+
export { StoreSidebar, SellerSidebar } from "./features/seller/components/SellerSidebar";
|
|
83
|
+
export type { StoreNavItem, SellerNavItem } from "./features/seller/components/SellerSidebar";
|
|
81
84
|
export { StoreProductsView } from "./features/stores/index";
|
|
82
85
|
export type { StoreProductItem } from "./features/stores/index";
|
|
83
86
|
export { AdSlot } from "./features/homepage/components/AdSlot";
|
|
84
87
|
export { registerAdSlot, registerAdSlots, unregisterAdSlot, clearAdRegistry, setAdConsentGranted, isAdConsentGranted, isAdSlotRenderable, } from "./features/homepage/ad-registry";
|
|
85
88
|
export type { AdSlotId, AdProvider, AdSlotConfig } from "./features/homepage/ad-registry";
|
|
86
|
-
export { WishlistView } from "./features/wishlist/index";
|
|
87
|
-
export type { WishlistViewProps } from "./features/wishlist/index";
|
|
89
|
+
export { WishlistView, useGuestWishlist, useWishlistWithGuest } from "./features/wishlist/index";
|
|
90
|
+
export type { WishlistViewProps, GuestWishlistItem } from "./features/wishlist/index";
|
|
91
|
+
export { getGuestWishlistItems, addToGuestWishlist, removeFromGuestWishlist, isInGuestWishlist, clearGuestWishlist, getGuestWishlistCount, getGuestWishlistByType, } from "./features/wishlist/utils/guest-wishlist";
|
|
88
92
|
export { InteractiveProductCard } from "./features/products/index";
|
|
89
93
|
export type { InteractiveProductCardProps } from "./features/products/index";
|
|
90
|
-
export { SellerDashboardView, useSellerDashboard } from "./features/seller/index";
|
|
91
|
-
export type { SellerDashboardViewProps } from "./features/seller/index";
|
|
94
|
+
export { SellerDashboardView as StoreDashboardView, SellerDashboardView, useSellerDashboard as useStoreDashboard, useSellerDashboard } from "./features/seller/index";
|
|
95
|
+
export type { SellerDashboardViewProps as StoreDashboardViewProps, SellerDashboardViewProps } from "./features/seller/index";
|
|
92
96
|
export { UserAccountHubView, UserOrdersView } from "./features/account/index";
|
|
93
97
|
export type { UserAccountHubViewProps, UserAccountHubViewLabels, UserOrdersViewProps, UserOrdersViewLabels } from "./features/account/index";
|
|
94
98
|
export { useOrders, OrdersList } from "./features/orders/index";
|
package/dist/client.js
CHANGED
|
@@ -121,8 +121,10 @@ export { Search } from "./features/search/components";
|
|
|
121
121
|
export { ToastProvider, SkipToMain, NavigationLoader } from "./ui/index";
|
|
122
122
|
export { ZodSetup } from "./validation/ZodSetup";
|
|
123
123
|
export { AdminSidebar } from "./features/admin/components/AdminSidebar";
|
|
124
|
-
export { AdminDashboardView, AdminAnalyticsView } from "./features/admin/index";
|
|
124
|
+
export { AdminDashboardView, AdminAnalyticsView, AdminListingScaffold, useAdminListingData, toRecordArray, toStringValue, toRelativeDate, toRupees } from "./features/admin/index";
|
|
125
|
+
export { ADMIN_ENDPOINTS } from "./constants/index";
|
|
125
126
|
export { UserSidebar } from "./features/account/components/UserSidebar";
|
|
127
|
+
export { CouponsIndexListing } from "./features/promotions/components/CouponsIndexListing";
|
|
126
128
|
export { NotificationBell } from "./features/account/components/NotificationBell";
|
|
127
129
|
export { ProtectedRoute, AuthStatusPanel, ForgotPasswordView, LoginForm, RegisterForm, ResetPasswordView, VerifyEmailView } from "./features/auth/index";
|
|
128
130
|
export { useLogout, useLogin, useGoogleLogin, useRegister, useForgotPassword, useResetPassword, useVerifyEmail } from "./features/auth/index";
|
|
@@ -131,13 +133,14 @@ export { useAddresses } from "./features/account/index";
|
|
|
131
133
|
export { CategoryProductsView, CategoriesListView } from "./features/categories/index";
|
|
132
134
|
export { MediaImage } from "./features/media/index";
|
|
133
135
|
export { ReviewsListView } from "./features/reviews/index";
|
|
134
|
-
export { SellerSidebar } from "./features/seller/components/SellerSidebar";
|
|
136
|
+
export { StoreSidebar, SellerSidebar } from "./features/seller/components/SellerSidebar";
|
|
135
137
|
export { StoreProductsView } from "./features/stores/index";
|
|
136
138
|
export { AdSlot } from "./features/homepage/components/AdSlot";
|
|
137
139
|
export { registerAdSlot, registerAdSlots, unregisterAdSlot, clearAdRegistry, setAdConsentGranted, isAdConsentGranted, isAdSlotRenderable, } from "./features/homepage/ad-registry";
|
|
138
|
-
export { WishlistView } from "./features/wishlist/index";
|
|
140
|
+
export { WishlistView, useGuestWishlist, useWishlistWithGuest } from "./features/wishlist/index";
|
|
141
|
+
export { getGuestWishlistItems, addToGuestWishlist, removeFromGuestWishlist, isInGuestWishlist, clearGuestWishlist, getGuestWishlistCount, getGuestWishlistByType, } from "./features/wishlist/utils/guest-wishlist";
|
|
139
142
|
export { InteractiveProductCard } from "./features/products/index";
|
|
140
|
-
export { SellerDashboardView, useSellerDashboard } from "./features/seller/index";
|
|
143
|
+
export { SellerDashboardView as StoreDashboardView, SellerDashboardView, useSellerDashboard as useStoreDashboard, useSellerDashboard } from "./features/seller/index";
|
|
141
144
|
export { UserAccountHubView, UserOrdersView } from "./features/account/index";
|
|
142
145
|
export { useOrders, OrdersList } from "./features/orders/index";
|
|
143
146
|
export { useCouponValidate } from "./features/promotions/hooks/useCouponValidate";
|
|
@@ -71,6 +71,8 @@ export declare const ADMIN_ENDPOINTS: {
|
|
|
71
71
|
readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
|
|
72
72
|
readonly COUPONS: "/api/admin/coupons";
|
|
73
73
|
readonly SECTIONS: "/api/admin/sections";
|
|
74
|
+
readonly NEWSLETTER: "/api/admin/newsletter";
|
|
75
|
+
readonly CONTACT_SUBMISSIONS: "/api/admin/contact-submissions";
|
|
74
76
|
};
|
|
75
77
|
export declare const CHAT_ENDPOINTS: {
|
|
76
78
|
readonly LIST: "/api/chat";
|
|
@@ -284,6 +286,8 @@ export declare const API_ENDPOINTS: {
|
|
|
284
286
|
readonly EVENT_ENTRY_BY_ID: (eventId: string, entryId: string) => string;
|
|
285
287
|
readonly COUPONS: "/api/admin/coupons";
|
|
286
288
|
readonly SECTIONS: "/api/admin/sections";
|
|
289
|
+
readonly NEWSLETTER: "/api/admin/newsletter";
|
|
290
|
+
readonly CONTACT_SUBMISSIONS: "/api/admin/contact-submissions";
|
|
287
291
|
};
|
|
288
292
|
readonly CHAT: {
|
|
289
293
|
readonly LIST: "/api/chat";
|
|
@@ -89,6 +89,8 @@ export const ADMIN_ENDPOINTS = {
|
|
|
89
89
|
EVENT_ENTRY_BY_ID: (eventId, entryId) => `/api/admin/events/${eventId}/entries/${entryId}`,
|
|
90
90
|
COUPONS: "/api/admin/coupons",
|
|
91
91
|
SECTIONS: "/api/admin/sections",
|
|
92
|
+
NEWSLETTER: "/api/admin/newsletter",
|
|
93
|
+
CONTACT_SUBMISSIONS: "/api/admin/contact-submissions",
|
|
92
94
|
};
|
|
93
95
|
// ---------------------------------------------------------------------------
|
|
94
96
|
// Chat
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IRepository, PagedResult } from "../contracts/repository";
|
|
2
|
+
export interface ContactSubmissionDocument {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
email: string;
|
|
6
|
+
subject: string;
|
|
7
|
+
message: string;
|
|
8
|
+
status: "new" | "read" | "resolved";
|
|
9
|
+
ipAddress?: string;
|
|
10
|
+
createdAt: Date;
|
|
11
|
+
updatedAt?: Date;
|
|
12
|
+
}
|
|
13
|
+
export type ContactSubmissionCreateInput = Omit<ContactSubmissionDocument, "id" | "status" | "createdAt" | "updatedAt">;
|
|
14
|
+
export interface ContactSubmissionListModel {
|
|
15
|
+
filters?: string;
|
|
16
|
+
sorts?: string;
|
|
17
|
+
page?: string;
|
|
18
|
+
pageSize?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const CONTACT_SUBMISSIONS_COLLECTION: "contactSubmissions";
|
|
21
|
+
export declare class ContactSubmissionsRepository {
|
|
22
|
+
private _repo;
|
|
23
|
+
constructor(repo?: IRepository<ContactSubmissionDocument> | null);
|
|
24
|
+
private get repo();
|
|
25
|
+
list(model: ContactSubmissionListModel): Promise<PagedResult<ContactSubmissionDocument>>;
|
|
26
|
+
findById(id: string): Promise<ContactSubmissionDocument | null>;
|
|
27
|
+
save(input: ContactSubmissionCreateInput): Promise<ContactSubmissionDocument>;
|
|
28
|
+
markRead(id: string): Promise<void>;
|
|
29
|
+
markResolved(id: string): Promise<void>;
|
|
30
|
+
deleteById(id: string): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare const contactSubmissionsRepository: ContactSubmissionsRepository;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getProviders } from "../contracts/registry";
|
|
2
|
+
export const CONTACT_SUBMISSIONS_COLLECTION = "contactSubmissions";
|
|
3
|
+
function resolveRepository() {
|
|
4
|
+
const provider = getProviders().db;
|
|
5
|
+
if (!provider) {
|
|
6
|
+
throw new Error("DB provider is not registered. Configure providers before using ContactSubmissionsRepository.");
|
|
7
|
+
}
|
|
8
|
+
return provider.getRepository(CONTACT_SUBMISSIONS_COLLECTION);
|
|
9
|
+
}
|
|
10
|
+
export class ContactSubmissionsRepository {
|
|
11
|
+
constructor(repo = null) {
|
|
12
|
+
this._repo = repo;
|
|
13
|
+
}
|
|
14
|
+
get repo() {
|
|
15
|
+
if (!this._repo) {
|
|
16
|
+
this._repo = resolveRepository();
|
|
17
|
+
}
|
|
18
|
+
return this._repo;
|
|
19
|
+
}
|
|
20
|
+
async list(model) {
|
|
21
|
+
const page = Number(model.page || "1");
|
|
22
|
+
const perPage = Number(model.pageSize || "50");
|
|
23
|
+
return this.repo.findAll({
|
|
24
|
+
filters: model.filters,
|
|
25
|
+
sort: model.sorts || "-createdAt",
|
|
26
|
+
page: Number.isFinite(page) ? page : 1,
|
|
27
|
+
perPage: Number.isFinite(perPage) ? perPage : 50,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async findById(id) {
|
|
31
|
+
return this.repo.findById(id);
|
|
32
|
+
}
|
|
33
|
+
async save(input) {
|
|
34
|
+
return this.repo.create({
|
|
35
|
+
...input,
|
|
36
|
+
status: "new",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async markRead(id) {
|
|
40
|
+
await this.repo.update(id, { status: "read", updatedAt: new Date() });
|
|
41
|
+
}
|
|
42
|
+
async markResolved(id) {
|
|
43
|
+
await this.repo.update(id, { status: "resolved", updatedAt: new Date() });
|
|
44
|
+
}
|
|
45
|
+
async deleteById(id) {
|
|
46
|
+
await this.repo.delete(id);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export const contactSubmissionsRepository = new ContactSubmissionsRepository();
|
package/dist/core/index.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export { COPILOT_LOGS_COLLECTION, COPILOT_LOGS_INDEXED_FIELDS, copilotLogQueryHe
|
|
|
22
22
|
export { useSiteSettings } from "./hooks/useSiteSettings";
|
|
23
23
|
export { NEWSLETTER_SUBSCRIBER_FIELDS, NEWSLETTER_SUBSCRIBERS_COLLECTION, NEWSLETTER_SUBSCRIBER_INDEXED_FIELDS, newsletterRepository, } from "./newsletter.repository";
|
|
24
24
|
export type { NewsletterSubscriberDocument, NewsletterSubscriberCreateInput, NewsletterSubscriberUpdateInput, } from "./newsletter.repository";
|
|
25
|
+
export { CONTACT_SUBMISSIONS_COLLECTION, contactSubmissionsRepository, } from "./contact-submissions.repository";
|
|
26
|
+
export type { ContactSubmissionDocument, ContactSubmissionCreateInput, } from "./contact-submissions.repository";
|
|
25
27
|
export { subscribeNewsletter, type SubscribeNewsletterActionInput, type SupportedNewsletterSource, } from "./newsletter-actions";
|
|
26
28
|
export { unitOfWork } from "./unit-of-work";
|
|
27
29
|
export type { UnitOfWork } from "./unit-of-work";
|
package/dist/core/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export { CopilotLogRepository, copilotLogRepository, } from "./copilot-log.repos
|
|
|
14
14
|
export { COPILOT_LOGS_COLLECTION, COPILOT_LOGS_INDEXED_FIELDS, copilotLogQueryHelpers, } from "./copilot-log.repository";
|
|
15
15
|
export { useSiteSettings } from "./hooks/useSiteSettings";
|
|
16
16
|
export { NEWSLETTER_SUBSCRIBER_FIELDS, NEWSLETTER_SUBSCRIBERS_COLLECTION, NEWSLETTER_SUBSCRIBER_INDEXED_FIELDS, newsletterRepository, } from "./newsletter.repository";
|
|
17
|
+
export { CONTACT_SUBMISSIONS_COLLECTION, contactSubmissionsRepository, } from "./contact-submissions.repository";
|
|
17
18
|
export { subscribeNewsletter, } from "./newsletter-actions";
|
|
18
19
|
export { unitOfWork } from "./unit-of-work";
|
|
19
20
|
export { createServerAction, setActionMiddleware, _resetActionMiddleware, } from "./server-action";
|
|
@@ -83,5 +83,5 @@ export async function HowPayoutsWorkView({ heroBannerClass = DEFAULT_HERO_CLASS,
|
|
|
83
83
|
desc: t("diagramStep5Desc"),
|
|
84
84
|
},
|
|
85
85
|
];
|
|
86
|
-
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "howpayoutsworkview-div-151", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.md} text-center`, "data-section": "howpayoutsworkview-div-152", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-4 text-white", children: t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 max-w-2xl mx-auto", children: t("subtitle") })] }) }), _jsxs("div", { className: `${page.container.md} py-10 md:py-12 lg:py-16 space-y-14`, "data-section": "howpayoutsworkview-div-153", children: [_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-8 text-center", children: t("stepsTitle") }), _jsx(Stack, { gap: "md", className: "gap-5", children: STEPS.map(({ number, icon, title, text }) => (_jsxs("div", { className: `flex items-start gap-4 p-5 rounded-xl border ${themed.border} ${themed.bgPrimary}`, "data-section": "howpayoutsworkview-div-154", children: [_jsx("div", { className: `flex-shrink-0 w-10 h-10 rounded-full bg-primary/10 dark:bg-primary/15 ${flex.center} text-xl`, "data-section": "howpayoutsworkview-div-155", children: icon }), _jsxs("div", { "data-section": "howpayoutsworkview-div-156", children: [_jsxs(Text, { className: "font-semibold mb-0.5", children: [number, ". ", title] }), _jsx(Text, { variant: "secondary", className: "text-sm leading-relaxed", children: text })] })] }, number))) })] }), _jsx(Section, { children: _jsx(FlowDiagram, { title: `💸 ${t("diagramTitle")}`, titleClass: "text-primary", connectorClass: "bg-primary/20 dark:bg-primary/30", steps: DIAGRAM_STEPS, centered: true }) }), _jsx(Section, { children: _jsx("div", { className: "grid gap-5 md:grid-cols-2", "data-section": "howpayoutsworkview-div-157", children: INFO_CARDS.map(({ icon: Icon, title, text, color, iconColor }) => (_jsxs("div", { className: `rounded-xl border p-5 ${color}`, "data-section": "howpayoutsworkview-div-158", children: [_jsx("div", { className: `w-10 h-10 rounded-lg bg-white/60 dark:bg-white/10 ${flex.center} mb-3`, "data-section": "howpayoutsworkview-div-159", children: _jsx(Icon, { className: `w-5 h-5 ${iconColor}` }) }), _jsx(Text, { className: "font-semibold mb-1", children: title }), _jsx(Text, { variant: "secondary", className: "text-sm leading-relaxed", children: text })] }, title))) }) }), _jsxs(Section, { className: `rounded-2xl p-8 text-center ${themed.bgSecondary} border ${themed.border}`, children: [_jsx(Heading, { level: 2, className: "mb-3", children: t("ctaTitle") }), _jsx(Text, { variant: "secondary", className: "mb-6 max-w-lg mx-auto", children: t("ctaText") }), _jsxs("div", { className: `${flex.center} gap-4 flex-wrap`, "data-section": "howpayoutsworkview-div-160", children: [_jsx(TextLink, { href: String(ROUTES.
|
|
86
|
+
return (_jsxs("div", { className: "-mx-4 md:-mx-6 lg:-mx-8 -mt-6 sm:-mt-8 lg:-mt-10", "data-section": "howpayoutsworkview-div-151", children: [_jsx(Section, { className: `${heroBannerClass} text-white py-14 md:py-16 lg:py-20`, children: _jsxs("div", { className: `${page.container.md} text-center`, "data-section": "howpayoutsworkview-div-152", children: [_jsx(Heading, { level: 1, variant: "none", className: "mb-4 text-white", children: t("title") }), _jsx(Text, { variant: "none", className: "text-white/80 max-w-2xl mx-auto", children: t("subtitle") })] }) }), _jsxs("div", { className: `${page.container.md} py-10 md:py-12 lg:py-16 space-y-14`, "data-section": "howpayoutsworkview-div-153", children: [_jsxs(Section, { children: [_jsx(Heading, { level: 2, className: "mb-8 text-center", children: t("stepsTitle") }), _jsx(Stack, { gap: "md", className: "gap-5", children: STEPS.map(({ number, icon, title, text }) => (_jsxs("div", { className: `flex items-start gap-4 p-5 rounded-xl border ${themed.border} ${themed.bgPrimary}`, "data-section": "howpayoutsworkview-div-154", children: [_jsx("div", { className: `flex-shrink-0 w-10 h-10 rounded-full bg-primary/10 dark:bg-primary/15 ${flex.center} text-xl`, "data-section": "howpayoutsworkview-div-155", children: icon }), _jsxs("div", { "data-section": "howpayoutsworkview-div-156", children: [_jsxs(Text, { className: "font-semibold mb-0.5", children: [number, ". ", title] }), _jsx(Text, { variant: "secondary", className: "text-sm leading-relaxed", children: text })] })] }, number))) })] }), _jsx(Section, { children: _jsx(FlowDiagram, { title: `💸 ${t("diagramTitle")}`, titleClass: "text-primary", connectorClass: "bg-primary/20 dark:bg-primary/30", steps: DIAGRAM_STEPS, centered: true }) }), _jsx(Section, { children: _jsx("div", { className: "grid gap-5 md:grid-cols-2", "data-section": "howpayoutsworkview-div-157", children: INFO_CARDS.map(({ icon: Icon, title, text, color, iconColor }) => (_jsxs("div", { className: `rounded-xl border p-5 ${color}`, "data-section": "howpayoutsworkview-div-158", children: [_jsx("div", { className: `w-10 h-10 rounded-lg bg-white/60 dark:bg-white/10 ${flex.center} mb-3`, "data-section": "howpayoutsworkview-div-159", children: _jsx(Icon, { className: `w-5 h-5 ${iconColor}` }) }), _jsx(Text, { className: "font-semibold mb-1", children: title }), _jsx(Text, { variant: "secondary", className: "text-sm leading-relaxed", children: text })] }, title))) }) }), _jsxs(Section, { className: `rounded-2xl p-8 text-center ${themed.bgSecondary} border ${themed.border}`, children: [_jsx(Heading, { level: 2, className: "mb-3", children: t("ctaTitle") }), _jsx(Text, { variant: "secondary", className: "mb-6 max-w-lg mx-auto", children: t("ctaText") }), _jsxs("div", { className: `${flex.center} gap-4 flex-wrap`, "data-section": "howpayoutsworkview-div-160", children: [_jsx(TextLink, { href: String(ROUTES.STORE.PAYOUT_SETTINGS), children: t("ctaPayoutSettings") }), _jsx(TextLink, { href: String(ROUTES.PUBLIC.FEES), variant: "muted", children: t("ctaFees") })] })] })] })] }));
|
|
87
87
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslations } from "next-intl";
|
|
3
|
+
import { FilterFacetSection } from "../../filters/FilterFacetSection";
|
|
4
|
+
import { SwitchFilter } from "../../filters/SwitchFilter";
|
|
5
|
+
import { Div } from "../../../ui";
|
|
6
|
+
export function AddressFilters({ table }) {
|
|
7
|
+
const t = useTranslations("filters");
|
|
8
|
+
const typeOptions = [
|
|
9
|
+
{ value: "home", label: t("addressTypeHome") },
|
|
10
|
+
{ value: "work", label: t("addressTypeWork") },
|
|
11
|
+
{ value: "shipping", label: t("addressTypeShipping") },
|
|
12
|
+
{ value: "billing", label: t("addressTypeBilling") },
|
|
13
|
+
{ value: "business", label: t("addressTypeBusiness") },
|
|
14
|
+
{ value: "other", label: t("addressTypeOther") },
|
|
15
|
+
];
|
|
16
|
+
const selectedTypes = table.get("addressType")
|
|
17
|
+
? table.get("addressType").split("|").filter(Boolean)
|
|
18
|
+
: [];
|
|
19
|
+
return (_jsxs(Div, { children: [_jsx(FilterFacetSection, { title: t("addressType"), options: typeOptions, selected: selectedTypes, onChange: (vals) => table.set("addressType", vals.join("|")), searchable: false, defaultCollapsed: false }), _jsx(SwitchFilter, { title: t("addressVerified"), label: t("showVerifiedAddressOnly"), checked: table.get("verified") === "true", onChange: (v) => table.set("verified", v ? "true" : ""), defaultCollapsed: true }), _jsx(SwitchFilter, { title: t("addressActive"), label: t("showActiveAddressOnly"), checked: table.get("activeOnly") === "true", onChange: (v) => table.set("activeOnly", v ? "true" : ""), defaultCollapsed: true })] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface AddressesIndexListingProps {
|
|
2
|
+
onAdd?: () => void;
|
|
3
|
+
onEdit?: (address: any) => void;
|
|
4
|
+
onDelete?: (id: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function AddressesIndexListing({ onAdd, onEdit, onDelete, }: AddressesIndexListingProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Search, SlidersHorizontal, X } from "lucide-react";
|
|
5
|
+
import { useAddresses } from "../hooks/useAddresses";
|
|
6
|
+
import { AddressBook } from "./AddressBook";
|
|
7
|
+
import { AddressFilters } from "./AddressFilters";
|
|
8
|
+
function createLocalTable(params, setParams) {
|
|
9
|
+
return {
|
|
10
|
+
get: (key) => params[key] ?? "",
|
|
11
|
+
set: (key, value) => setParams({ ...params, [key]: value }),
|
|
12
|
+
setMany: (updates) => setParams({ ...params, ...updates }),
|
|
13
|
+
getNumber: (key, def) => {
|
|
14
|
+
const v = params[key];
|
|
15
|
+
return v ? Number(v) : def;
|
|
16
|
+
},
|
|
17
|
+
setPage: (page) => setParams({ ...params, page: String(page) }),
|
|
18
|
+
setSort: (sort) => setParams({ ...params, sort }),
|
|
19
|
+
setPageSize: (size) => setParams({ ...params, pageSize: String(size) }),
|
|
20
|
+
clear: (keys) => {
|
|
21
|
+
const next = { ...params };
|
|
22
|
+
(Array.isArray(keys) ? keys : [keys]).forEach((k) => delete next[k]);
|
|
23
|
+
setParams(next);
|
|
24
|
+
},
|
|
25
|
+
buildSieveParams: () => ({}),
|
|
26
|
+
buildSearchParams: () => new URLSearchParams(),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function AddressesIndexListing({ onAdd, onEdit, onDelete, }) {
|
|
30
|
+
const [searchInput, setSearchInput] = useState("");
|
|
31
|
+
const [activeSearch, setActiveSearch] = useState("");
|
|
32
|
+
const [filterOpen, setFilterOpen] = useState(false);
|
|
33
|
+
const [filterParams, setFilterParams] = useState({});
|
|
34
|
+
const table = createLocalTable(filterParams, setFilterParams);
|
|
35
|
+
const { data: addresses = [], isLoading } = useAddresses({
|
|
36
|
+
filters: {
|
|
37
|
+
q: activeSearch || undefined,
|
|
38
|
+
addressType: filterParams.addressType || undefined,
|
|
39
|
+
verified: filterParams.verified === "true" || undefined,
|
|
40
|
+
activeOnly: filterParams.activeOnly === "true" || undefined,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const commitSearch = () => {
|
|
44
|
+
setActiveSearch(searchInput.trim());
|
|
45
|
+
};
|
|
46
|
+
const closeFilters = () => setFilterOpen(false);
|
|
47
|
+
if (isLoading) {
|
|
48
|
+
return (_jsx("div", { className: "grid sm:grid-cols-2 gap-4", children: Array.from({ length: 4 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-200 dark:border-slate-700 animate-pulse p-4 space-y-2", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" }), _jsx("div", { className: "h-3 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" })] }, i))) }));
|
|
49
|
+
}
|
|
50
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: () => setFilterOpen(true), className: "flex shrink-0 items-center gap-1.5 rounded-lg border border-zinc-300 dark:border-slate-600 px-3 py-2 text-sm font-medium text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800 transition-colors", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsx("span", { className: "hidden sm:inline", children: "Filters" })] }), _jsxs("div", { className: "flex flex-1 items-center overflow-hidden rounded-lg border border-zinc-300 dark:border-slate-600 bg-white dark:bg-slate-900", children: [_jsx("input", { type: "text", value: searchInput, onChange: (e) => setSearchInput(e.target.value), onKeyDown: (e) => e.key === "Enter" && commitSearch(), placeholder: "Search by address, postcode or label...", className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 outline-none" }), searchInput && (_jsx("button", { type: "button", onClick: () => { setSearchInput(""); setActiveSearch(""); }, className: "px-2 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300", "aria-label": "Clear", children: _jsx(X, { className: "h-3.5 w-3.5" }) })), _jsx("button", { type: "button", onClick: commitSearch, className: "flex shrink-0 items-center justify-center px-3 py-2 text-zinc-400 hover:text-primary transition-colors", "aria-label": "Search", children: _jsx(Search, { className: "h-4 w-4" }) })] })] }), addresses.length === 0 ? (_jsx("p", { className: "py-8 text-center text-sm text-zinc-500 dark:text-zinc-400", children: activeSearch ? `No addresses matching "${activeSearch}"` : "No saved addresses." })) : (_jsx(AddressBook, { addresses: addresses, onEdit: onEdit, onDelete: onDelete, onAdd: onAdd })), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: closeFilters }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsx("button", { type: "button", onClick: closeFilters, "aria-label": "Close filters", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(AddressFilters, { table: table }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsx("button", { type: "button", onClick: closeFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors", children: "Apply filters" }) })] })] }))] }));
|
|
51
|
+
}
|
|
@@ -4,12 +4,16 @@ export interface UserNavItem {
|
|
|
4
4
|
label: string;
|
|
5
5
|
icon?: React.ReactNode;
|
|
6
6
|
}
|
|
7
|
+
export interface UserNavGroup {
|
|
8
|
+
title: string;
|
|
9
|
+
items: UserNavItem[];
|
|
10
|
+
defaultOpen?: boolean;
|
|
11
|
+
}
|
|
7
12
|
export interface UserSidebarProps {
|
|
8
13
|
items: UserNavItem[];
|
|
9
|
-
|
|
14
|
+
groups?: UserNavGroup[];
|
|
10
15
|
mobileOpen?: boolean;
|
|
11
|
-
/** Called when the mobile drawer should close */
|
|
12
16
|
onCloseMobile?: () => void;
|
|
13
17
|
className?: string;
|
|
14
18
|
}
|
|
15
|
-
export declare function UserSidebar({ items, mobileOpen, onCloseMobile, className, }: UserSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function UserSidebar({ items, groups, mobileOpen, onCloseMobile, className, }: UserSidebarProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,18 +1,66 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
4
|
import Link from "next/link";
|
|
4
5
|
import { usePathname } from "next/navigation";
|
|
5
6
|
import { Aside, Li, Nav, Span, Ul } from "../../../ui";
|
|
6
7
|
import { BottomSheet } from "../../layout/BottomSheet";
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const STORAGE_KEY = "user-sidebar-collapsed";
|
|
9
|
+
function NavLink({ item, isActive, collapsed, onClick, }) {
|
|
10
|
+
return (_jsxs(Link, { href: item.href, onClick: onClick, title: collapsed ? item.label : undefined, className: `flex items-center rounded-lg py-2 text-sm transition-colors ${collapsed ? "justify-center px-2" : "gap-3 px-3"} ${isActive
|
|
11
|
+
? "bg-primary-50 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400 font-medium"
|
|
12
|
+
: "text-zinc-600 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-slate-800 hover:text-zinc-900 dark:hover:text-zinc-100"}`, children: [item.icon && _jsx(Span, { className: "shrink-0 text-[1.1rem]", children: item.icon }), !collapsed && _jsx(Span, { className: "flex-1 truncate", children: item.label })] }));
|
|
13
|
+
}
|
|
14
|
+
function DesktopContent({ items, activeHref, collapsed, }) {
|
|
15
|
+
return (_jsx(Nav, { "aria-label": "User navigation", className: "flex-1 overflow-y-auto py-2", children: _jsx(Ul, { className: `space-y-0.5 ${collapsed ? "px-1" : "px-2"}`, children: items.map((item) => {
|
|
9
16
|
const isActive = activeHref === item.href || activeHref.startsWith(item.href + "/");
|
|
10
|
-
return (_jsx(Li, { children:
|
|
11
|
-
? "bg-primary-50 dark:bg-primary-900/20 text-primary-600 dark:text-primary-400 font-medium"
|
|
12
|
-
: "text-zinc-600 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-slate-800 hover:text-zinc-900 dark:hover:text-zinc-100"}`, children: [item.icon && (_jsx(Span, { className: "shrink-0 text-[1.1rem]", children: item.icon })), _jsx(Span, { className: "flex-1 truncate", children: item.label })] }) }, item.href));
|
|
17
|
+
return (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isActive, collapsed: collapsed }) }, item.href));
|
|
13
18
|
}) }) }));
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
function MobileContent({ groups, items, activeHref, onItemClick, }) {
|
|
21
|
+
const [openGroups, setOpenGroups] = useState(() => {
|
|
22
|
+
if (!groups)
|
|
23
|
+
return {};
|
|
24
|
+
return Object.fromEntries(groups.map((g) => [g.title, g.defaultOpen ?? true]));
|
|
25
|
+
});
|
|
26
|
+
const toggle = useCallback((title) => setOpenGroups((prev) => ({ ...prev, [title]: !prev[title] })), []);
|
|
27
|
+
if (!groups || groups.length === 0) {
|
|
28
|
+
return (_jsx(Nav, { "aria-label": "User navigation", className: "py-2", children: _jsx(Ul, { className: "space-y-0.5 px-2", children: items.map((item) => {
|
|
29
|
+
const isActive = activeHref === item.href || activeHref.startsWith(item.href + "/");
|
|
30
|
+
return (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isActive, onClick: onItemClick }) }, item.href));
|
|
31
|
+
}) }) }));
|
|
32
|
+
}
|
|
33
|
+
return (_jsx(Nav, { "aria-label": "User navigation", className: "py-2 space-y-1", children: groups.map((group) => {
|
|
34
|
+
const isOpen = openGroups[group.title] ?? true;
|
|
35
|
+
return (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => toggle(group.title), className: "flex w-full items-center justify-between px-4 py-2 text-xs font-semibold uppercase tracking-wider text-zinc-400 dark:text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 transition-colors", children: [_jsx("span", { children: group.title }), _jsx("span", { className: `transition-transform duration-150 text-[0.65rem] ${isOpen ? "rotate-180" : ""}`, children: "\u25BE" })] }), isOpen && (_jsx(Ul, { className: "space-y-0.5 px-2 pb-2", children: group.items.map((item) => {
|
|
36
|
+
const isActive = activeHref === item.href ||
|
|
37
|
+
activeHref.startsWith(item.href + "/");
|
|
38
|
+
return (_jsx(Li, { children: _jsx(NavLink, { item: item, isActive: isActive, onClick: onItemClick }) }, item.href));
|
|
39
|
+
}) }))] }, group.title));
|
|
40
|
+
}) }));
|
|
41
|
+
}
|
|
42
|
+
export function UserSidebar({ items, groups, mobileOpen = false, onCloseMobile, className = "", }) {
|
|
16
43
|
const pathname = usePathname();
|
|
17
|
-
|
|
44
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
try {
|
|
47
|
+
setCollapsed(localStorage.getItem(STORAGE_KEY) === "true");
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// ignore
|
|
51
|
+
}
|
|
52
|
+
}, []);
|
|
53
|
+
const toggleCollapsed = useCallback(() => {
|
|
54
|
+
setCollapsed((prev) => {
|
|
55
|
+
const next = !prev;
|
|
56
|
+
try {
|
|
57
|
+
localStorage.setItem(STORAGE_KEY, String(next));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// ignore
|
|
61
|
+
}
|
|
62
|
+
return next;
|
|
63
|
+
});
|
|
64
|
+
}, []);
|
|
65
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Aside, { className: `hidden md:flex flex-col bg-white dark:bg-slate-900 border-l border-zinc-200 dark:border-slate-700 shrink-0 transition-[width] duration-200 overflow-hidden ${collapsed ? "w-12" : "w-56"} ${className}`, children: [_jsx("div", { className: `flex pt-3 pb-1 ${collapsed ? "justify-center px-1" : "justify-end px-3"}`, children: _jsx("button", { type: "button", onClick: toggleCollapsed, title: collapsed ? "Expand menu" : "Collapse menu", className: "rounded-md p-1.5 text-zinc-400 hover:bg-zinc-100 dark:hover:bg-slate-800 hover:text-zinc-600 dark:hover:text-zinc-300 transition-colors text-xs leading-none", children: collapsed ? "›" : "‹" }) }), _jsx(DesktopContent, { items: items, activeHref: pathname, collapsed: collapsed })] }), _jsx(BottomSheet, { open: mobileOpen, onClose: onCloseMobile ?? (() => { }), title: "My Account", children: _jsx(MobileContent, { groups: groups, items: items, activeHref: pathname, onItemClick: onCloseMobile }) })] }));
|
|
18
66
|
}
|
|
@@ -26,9 +26,16 @@ export interface AddressFormData {
|
|
|
26
26
|
interface SetDefaultAddressData {
|
|
27
27
|
addressId: string;
|
|
28
28
|
}
|
|
29
|
+
export interface AddressFilterParams {
|
|
30
|
+
q?: string;
|
|
31
|
+
addressType?: string;
|
|
32
|
+
verified?: boolean;
|
|
33
|
+
activeOnly?: boolean;
|
|
34
|
+
}
|
|
29
35
|
export declare function useAddresses(options?: {
|
|
30
36
|
enabled?: boolean;
|
|
31
37
|
listEndpoint?: string;
|
|
38
|
+
filters?: AddressFilterParams;
|
|
32
39
|
}): import("@tanstack/react-query").UseQueryResult<Address[], Error>;
|
|
33
40
|
export declare function useAddress(id: string, options?: {
|
|
34
41
|
enabled?: boolean;
|
|
@@ -7,7 +7,18 @@ const DEFAULT_ENDPOINTS = {
|
|
|
7
7
|
setDefault: ACCOUNT_ENDPOINTS.ADDRESS_SET_DEFAULT,
|
|
8
8
|
};
|
|
9
9
|
export function useAddresses(options) {
|
|
10
|
-
const
|
|
10
|
+
const sp = new URLSearchParams();
|
|
11
|
+
if (options?.filters?.q)
|
|
12
|
+
sp.set("q", options.filters.q);
|
|
13
|
+
if (options?.filters?.addressType)
|
|
14
|
+
sp.set("addressType", options.filters.addressType);
|
|
15
|
+
if (options?.filters?.verified)
|
|
16
|
+
sp.set("verified", "true");
|
|
17
|
+
if (options?.filters?.activeOnly)
|
|
18
|
+
sp.set("activeOnly", "true");
|
|
19
|
+
const qs = sp.toString();
|
|
20
|
+
const base = options?.listEndpoint ?? DEFAULT_ENDPOINTS.list;
|
|
21
|
+
const endpoint = qs ? `${base}?${qs}` : base;
|
|
11
22
|
return useQuery({
|
|
12
23
|
queryKey: ["addresses", endpoint],
|
|
13
24
|
queryFn: () => apiClient.get(endpoint),
|
|
@@ -103,3 +103,15 @@ export declare function listAdminSessions(params?: {
|
|
|
103
103
|
recentActivity: number;
|
|
104
104
|
};
|
|
105
105
|
}>;
|
|
106
|
+
export declare function listAdminNewsletterSubscribers(params?: {
|
|
107
|
+
filters?: string;
|
|
108
|
+
sorts?: string;
|
|
109
|
+
page?: number;
|
|
110
|
+
pageSize?: number;
|
|
111
|
+
}): Promise<import("../../..").PagedResult<import("../../..").NewsletterSubscriberDocument>>;
|
|
112
|
+
export declare function listAdminContactSubmissions(params?: {
|
|
113
|
+
filters?: string;
|
|
114
|
+
sorts?: string;
|
|
115
|
+
page?: number;
|
|
116
|
+
pageSize?: number;
|
|
117
|
+
}): Promise<import("../../..").PagedResult<import("../server").ContactSubmissionDocument>>;
|
|
@@ -11,6 +11,8 @@ import { blogRepository } from "../../blog/repository/blog.repository";
|
|
|
11
11
|
import { storeRepository } from "../../stores/repository/store.repository";
|
|
12
12
|
import { bidRepository } from "../../auctions/repository/bid.repository";
|
|
13
13
|
import { payoutRepository } from "../../payments/repository/payout.repository";
|
|
14
|
+
import { newsletterRepository } from "../../../core/newsletter.repository";
|
|
15
|
+
import { contactSubmissionsRepository } from "../../../core/contact-submissions.repository";
|
|
14
16
|
import { formatMonthYear } from "../../../utils";
|
|
15
17
|
import { ProductStatusValues } from "../../products/schemas";
|
|
16
18
|
export async function getAdminDashboardStats() {
|
|
@@ -170,3 +172,19 @@ export async function listAdminSessions(params) {
|
|
|
170
172
|
limit: params?.limit ?? 100,
|
|
171
173
|
});
|
|
172
174
|
}
|
|
175
|
+
export async function listAdminNewsletterSubscribers(params) {
|
|
176
|
+
return newsletterRepository.list({
|
|
177
|
+
filters: params?.filters,
|
|
178
|
+
sorts: params?.sorts,
|
|
179
|
+
page: String(params?.page ?? 1),
|
|
180
|
+
pageSize: String(params?.pageSize ?? 50),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
export async function listAdminContactSubmissions(params) {
|
|
184
|
+
return contactSubmissionsRepository.list({
|
|
185
|
+
filters: params?.filters,
|
|
186
|
+
sorts: params?.sorts,
|
|
187
|
+
page: String(params?.page ?? 1),
|
|
188
|
+
pageSize: String(params?.pageSize ?? 50),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
@@ -7,9 +7,20 @@ import { toRecordArray, toRelativeDate, toStringValue, useAdminListingData, } fr
|
|
|
7
7
|
import { AdminListingScaffold } from "./AdminListingScaffold";
|
|
8
8
|
export function AdminBlogView({ children, ...props }) {
|
|
9
9
|
const hasChildren = React.Children.count(children) > 0;
|
|
10
|
+
const [q, setQ] = React.useState("");
|
|
11
|
+
const [statusFilter, setStatusFilter] = React.useState("");
|
|
12
|
+
const [featuredFilter, setFeaturedFilter] = React.useState("");
|
|
13
|
+
const filterParts = [];
|
|
14
|
+
if (statusFilter && statusFilter !== "All")
|
|
15
|
+
filterParts.push(`status==${statusFilter}`);
|
|
16
|
+
if (featuredFilter === "Featured Only")
|
|
17
|
+
filterParts.push("isFeatured==true");
|
|
18
|
+
const filters = filterParts.join(",") || undefined;
|
|
10
19
|
const { rows, total, isLoading, errorMessage } = useAdminListingData({
|
|
11
|
-
queryKey: ["admin", "blog", "listing"],
|
|
20
|
+
queryKey: ["admin", "blog", "listing", q, filters ?? ""],
|
|
12
21
|
endpoint: ADMIN_ENDPOINTS.BLOG,
|
|
22
|
+
filters,
|
|
23
|
+
q,
|
|
13
24
|
mapRows: (response) => toRecordArray(response.posts).map((item, index) => ({
|
|
14
25
|
id: toStringValue(item.id, `post-${index}`),
|
|
15
26
|
primary: toStringValue(item.title, "Untitled post"),
|
|
@@ -33,5 +44,18 @@ export function AdminBlogView({ children, ...props }) {
|
|
|
33
44
|
if (hasChildren) {
|
|
34
45
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
35
46
|
}
|
|
36
|
-
return (_jsx(AdminListingScaffold, { portal: "admin", ...props, title: "Blog Publishing", subtitle: "Manage editorial drafts, featured placement, and publish readiness in the shared listing frame.", actionLabel: "New article", searchPlaceholder: "Search articles, authors, or tags", rows: rows, isLoading: isLoading, errorMessage: errorMessage, emptyLabel: "No blog posts found", resultSummary: `Showing ${rows.length} of ${total} posts
|
|
47
|
+
return (_jsx(AdminListingScaffold, { portal: "admin", ...props, title: "Blog Publishing", subtitle: "Manage editorial drafts, featured placement, and publish readiness in the shared listing frame.", actionLabel: "New article", searchPlaceholder: "Search articles, authors, or tags", onSearch: setQ, searchValue: q, rows: rows, isLoading: isLoading, errorMessage: errorMessage, emptyLabel: "No blog posts found", resultSummary: `Showing ${rows.length} of ${total} posts`, filterGroups: [
|
|
48
|
+
{
|
|
49
|
+
title: "Status",
|
|
50
|
+
options: ["All", "published", "draft", "archived"],
|
|
51
|
+
active: statusFilter || "All",
|
|
52
|
+
onSelect: (opt) => setStatusFilter(opt === "All" ? "" : opt),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: "Featured",
|
|
56
|
+
options: ["All", "Featured Only"],
|
|
57
|
+
active: featuredFilter || "All",
|
|
58
|
+
onSelect: (opt) => setFeaturedFilter(opt === "All" ? "" : opt),
|
|
59
|
+
},
|
|
60
|
+
] }));
|
|
37
61
|
}
|
|
@@ -7,9 +7,18 @@ import { toRecordArray, toRelativeDate, toStringValue, useAdminListingData, } fr
|
|
|
7
7
|
import { AdminListingScaffold } from "./AdminListingScaffold";
|
|
8
8
|
export function AdminCarouselView({ children, ...props }) {
|
|
9
9
|
const hasChildren = React.Children.count(children) > 0;
|
|
10
|
+
const [q, setQ] = React.useState("");
|
|
11
|
+
const [statusFilter, setStatusFilter] = React.useState("");
|
|
12
|
+
const filterParts = [];
|
|
13
|
+
if (statusFilter && statusFilter !== "All") {
|
|
14
|
+
filterParts.push(statusFilter === "Active" ? "active==true" : "active==false");
|
|
15
|
+
}
|
|
16
|
+
const filters = filterParts.join(",") || undefined;
|
|
10
17
|
const { rows, total, isLoading, errorMessage } = useAdminListingData({
|
|
11
|
-
queryKey: ["admin", "carousel", "listing"],
|
|
18
|
+
queryKey: ["admin", "carousel", "listing", q, filters ?? ""],
|
|
12
19
|
endpoint: `${HOMEPAGE_ENDPOINTS.CAROUSEL}?includeInactive=true`,
|
|
20
|
+
filters,
|
|
21
|
+
q,
|
|
13
22
|
mapRows: (response) => {
|
|
14
23
|
const sourceItems = Array.isArray(response.data)
|
|
15
24
|
? response.data
|
|
@@ -36,5 +45,12 @@ export function AdminCarouselView({ children, ...props }) {
|
|
|
36
45
|
if (hasChildren) {
|
|
37
46
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
38
47
|
}
|
|
39
|
-
return (_jsx(AdminListingScaffold, { portal: "admin", ...props, title: "Homepage Carousel", subtitle: "Manage hero slide ordering, activation state, and destination links in one listing workflow.", actionLabel: "New slide", searchPlaceholder: "Search slide titles or link URLs", rows: rows, isLoading: isLoading, errorMessage: errorMessage, emptyLabel: "No carousel slides found", resultSummary: `Showing ${rows.length} of ${total} slides
|
|
48
|
+
return (_jsx(AdminListingScaffold, { portal: "admin", ...props, title: "Homepage Carousel", subtitle: "Manage hero slide ordering, activation state, and destination links in one listing workflow.", actionLabel: "New slide", searchPlaceholder: "Search slide titles or link URLs", onSearch: setQ, searchValue: q, rows: rows, isLoading: isLoading, errorMessage: errorMessage, emptyLabel: "No carousel slides found", resultSummary: `Showing ${rows.length} of ${total} slides`, filterGroups: [
|
|
49
|
+
{
|
|
50
|
+
title: "Status",
|
|
51
|
+
options: ["All", "Active", "Inactive"],
|
|
52
|
+
active: statusFilter || "All",
|
|
53
|
+
onSelect: (opt) => setStatusFilter(opt === "All" ? "" : opt),
|
|
54
|
+
},
|
|
55
|
+
] }));
|
|
40
56
|
}
|