@mohasinac/appkit 2.7.26 → 2.7.30
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 +2 -2
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +2 -2
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +1 -1
- package/dist/_internal/server/features/checkout/actions.js +42 -35
- package/dist/_internal/server/features/classified/adapters.d.ts +21 -0
- package/dist/_internal/server/features/classified/adapters.js +24 -0
- package/dist/_internal/server/features/classified/index.d.ts +3 -0
- package/dist/_internal/server/features/classified/index.js +3 -0
- package/dist/_internal/server/features/classified/metadata.d.ts +8 -0
- package/dist/_internal/server/features/classified/metadata.js +43 -0
- package/dist/_internal/server/features/classified/og.d.ts +30 -0
- package/dist/_internal/server/features/classified/og.js +76 -0
- package/dist/_internal/server/features/digital-code/adapters.d.ts +21 -0
- package/dist/_internal/server/features/digital-code/adapters.js +29 -0
- package/dist/_internal/server/features/digital-code/index.d.ts +3 -0
- package/dist/_internal/server/features/digital-code/index.js +3 -0
- package/dist/_internal/server/features/digital-code/metadata.d.ts +8 -0
- package/dist/_internal/server/features/digital-code/metadata.js +36 -0
- package/dist/_internal/server/features/digital-code/og.d.ts +27 -0
- package/dist/_internal/server/features/digital-code/og.js +77 -0
- package/dist/_internal/server/features/live/adapters.d.ts +21 -0
- package/dist/_internal/server/features/live/adapters.js +34 -0
- package/dist/_internal/server/features/live/index.d.ts +3 -0
- package/dist/_internal/server/features/live/index.js +3 -0
- package/dist/_internal/server/features/live/metadata.d.ts +8 -0
- package/dist/_internal/server/features/live/metadata.js +39 -0
- package/dist/_internal/server/features/live/og.d.ts +27 -0
- package/dist/_internal/server/features/live/og.js +72 -0
- package/dist/_internal/server/features/promotions/actions.js +4 -3
- package/dist/_internal/server/jobs/core/onOrderCreate.js +19 -16
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +25 -22
- package/dist/_internal/server/jobs/core/onProductWrite.js +48 -58
- package/dist/_internal/shared/actions/action-registry.js +310 -8
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/brands/schema.d.ts +5 -5
- package/dist/_internal/shared/features/cart/schema.d.ts +18 -18
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +38 -38
- package/dist/_internal/shared/features/events/schema.d.ts +8 -8
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/features/products/schema.d.ts +42 -42
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
- package/dist/_internal/shared/media/limits.js +4 -3
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/configs/next.js +4 -0
- package/dist/constants/table-keys.d.ts +6 -0
- package/dist/constants/table-keys.js +9 -0
- package/dist/core/hooks/useSyncManager.js +9 -8
- package/dist/features/about/components/FeesView.js +10 -7
- package/dist/features/about/components/HelpPageView.js +10 -1
- package/dist/features/about/components/HowAuctionsWorkView.js +10 -1
- package/dist/features/about/components/HowCheckoutWorksView.js +10 -1
- package/dist/features/about/components/HowOffersWorkView.js +10 -1
- package/dist/features/about/components/HowOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowPayoutsWorkView.js +10 -1
- package/dist/features/about/components/HowPreOrdersWorkView.js +10 -1
- package/dist/features/about/components/HowReviewsWorkView.js +10 -1
- package/dist/features/about/components/PublicProfileView.js +44 -14
- package/dist/features/about/components/SecurityPrivacyView.js +7 -1
- package/dist/features/account/components/AddressesIndexListing.js +2 -2
- package/dist/features/account/components/NotificationBell.js +27 -16
- package/dist/features/account/components/NotificationPreferencesPanel.d.ts +9 -0
- package/dist/features/account/components/NotificationPreferencesPanel.js +91 -0
- package/dist/features/account/components/UserSidebar.js +4 -4
- package/dist/features/account/components/UserSupportView.js +16 -6
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/account/schemas/index.d.ts +4 -4
- package/dist/features/account/types/index.d.ts +34 -0
- package/dist/features/admin/actions/admin-actions.js +4 -3
- package/dist/features/admin/actions/notification-actions.d.ts +24 -22
- package/dist/features/admin/actions/notification-actions.js +122 -22
- package/dist/features/admin/components/AdminAdEditorView.js +29 -15
- package/dist/features/admin/components/AdminAdsView.js +22 -28
- package/dist/features/admin/components/AdminAllEventEntriesView.js +6 -1
- package/dist/features/admin/components/AdminBidsView.js +10 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
- package/dist/features/admin/components/AdminBlogView.js +8 -3
- package/dist/features/admin/components/AdminBrandsView.js +7 -2
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +6 -3
- package/dist/features/admin/components/AdminCarouselView.js +13 -7
- package/dist/features/admin/components/AdminCategoriesView.js +8 -3
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminContactView.js +6 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +8 -2
- package/dist/features/admin/components/AdminCouponsView.js +6 -1
- package/dist/features/admin/components/AdminEmployeeEditorView.js +12 -9
- package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
- package/dist/features/admin/components/AdminFaqsView.js +7 -2
- package/dist/features/admin/components/AdminFeaturesView.js +4 -3
- package/dist/features/admin/components/AdminMediaView.js +9 -8
- package/dist/features/admin/components/AdminNavigationView.js +10 -17
- package/dist/features/admin/components/AdminNewsletterView.js +6 -1
- package/dist/features/admin/components/AdminNotificationsView.js +11 -3
- package/dist/features/admin/components/AdminOrdersView.js +6 -1
- package/dist/features/admin/components/AdminPayoutsView.js +10 -3
- package/dist/features/admin/components/AdminPrizeDrawsView.js +10 -3
- package/dist/features/admin/components/AdminProductsView.js +18 -12
- package/dist/features/admin/components/AdminReviewsView.js +33 -24
- package/dist/features/admin/components/AdminScammerEditorView.js +3 -2
- package/dist/features/admin/components/AdminScammersView.js +28 -26
- package/dist/features/admin/components/AdminSectionsView.js +112 -99
- package/dist/features/admin/components/AdminSessionsView.js +10 -3
- package/dist/features/admin/components/AdminSidebar.js +4 -4
- package/dist/features/admin/components/AdminSiteSettingsView.js +45 -4
- package/dist/features/admin/components/AdminStoresView.js +6 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +0 -1
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +32 -34
- package/dist/features/admin/components/AdminTeamView.js +6 -1
- package/dist/features/admin/components/AdminUserEditorView.js +8 -15
- package/dist/features/admin/components/AdminUsersView.js +6 -1
- package/dist/features/admin/components/AdminViewCards.js +4 -3
- package/dist/features/admin/components/DashboardStats.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/sections/adminSectionsTypes.js +4 -3
- package/dist/features/admin/repository/chat.repository.js +8 -8
- package/dist/features/admin/repository/site-settings.repository.d.ts +1 -0
- package/dist/features/admin/repository/site-settings.repository.js +11 -9
- package/dist/features/admin/schemas/firestore.d.ts +38 -0
- package/dist/features/admin/schemas/firestore.js +15 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +13 -19
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +18 -9
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +3 -2
- package/dist/features/auctions/components/index.d.ts +0 -1
- package/dist/features/auctions/components/index.js +0 -1
- package/dist/features/auctions/schemas/index.d.ts +14 -14
- package/dist/features/auth/actions/realtime-token-actions.js +19 -4
- package/dist/features/auth/components/RegisterForm.js +8 -4
- package/dist/features/auth/consent-otp.d.ts +2 -0
- package/dist/features/auth/consent-otp.js +8 -0
- package/dist/features/auth/schemas/firestore.d.ts +2 -0
- package/dist/features/auth/schemas/firestore.js +18 -25
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/before-after/api/[id]/route.js +8 -6
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +3 -3
- package/dist/features/blog/components/BlogIndexListing.js +21 -2
- package/dist/features/blog/components/BlogPostForm.js +11 -5
- package/dist/features/blog/components/BlogPostView.js +10 -2
- package/dist/features/blog/schemas/index.d.ts +18 -18
- package/dist/features/cart/components/CartDrawer.js +3 -2
- package/dist/features/cart/repository/cart.repository.js +4 -3
- package/dist/features/cart/utils/pending-ops.d.ts +1 -1
- package/dist/features/categories/api/[id]/route.js +4 -3
- package/dist/features/categories/api/route.js +4 -3
- package/dist/features/categories/components/BrandDetailPageView.js +2 -2
- package/dist/features/categories/components/BrandDetailTabs.js +2 -2
- package/dist/features/categories/components/BundleCollage.d.ts +8 -0
- package/dist/features/categories/components/BundleCollage.js +50 -0
- package/dist/features/categories/components/BundleDetailView.js +2 -10
- package/dist/features/categories/components/BundleItemsPicker.js +20 -13
- package/dist/features/categories/components/CategoriesIndexListing.js +28 -9
- package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
- package/dist/features/categories/components/CategoryProductsListing.js +52 -13
- package/dist/features/categories/components/index.d.ts +2 -0
- package/dist/features/categories/components/index.js +1 -0
- package/dist/features/categories/schemas/index.d.ts +6 -6
- package/dist/features/checkout/actions/checkout-actions.js +4 -3
- package/dist/features/checkout/hooks/usePaymentCheckout.js +31 -22
- package/dist/features/classified/components/ClassifiedFilters.d.ts +8 -0
- package/dist/features/classified/components/ClassifiedFilters.js +19 -0
- package/dist/features/classified/components/ClassifiedIndexListing.d.ts +4 -0
- package/dist/features/classified/components/ClassifiedIndexListing.js +110 -0
- package/dist/features/classified/components/ClassifiedListView.d.ts +6 -0
- package/dist/features/classified/components/ClassifiedListView.js +43 -0
- package/dist/features/classified/components/index.d.ts +6 -0
- package/dist/features/classified/components/index.js +3 -0
- package/dist/features/collections/api/[slug]/route.js +16 -12
- package/dist/features/collections/schemas/index.d.ts +5 -5
- package/dist/features/consultation/api/[id]/route.js +12 -9
- package/dist/features/consultation/components/ConsultationForm.js +3 -2
- package/dist/features/consultation/schemas/index.d.ts +6 -6
- package/dist/features/contact/email.js +77 -116
- package/dist/features/copilot/components/AdminCopilotView.js +12 -2
- package/dist/features/corporate/api/[id]/route.js +12 -9
- package/dist/features/corporate/components/CorporateInquiryForm.js +2 -1
- package/dist/features/digital-codes/components/DigitalCodeFilters.d.ts +8 -0
- package/dist/features/digital-codes/components/DigitalCodeFilters.js +16 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +4 -0
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +107 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +6 -0
- package/dist/features/digital-codes/components/DigitalCodesListView.js +37 -0
- package/dist/features/digital-codes/components/index.d.ts +6 -0
- package/dist/features/digital-codes/components/index.js +3 -0
- package/dist/features/events/actions/event-actions.js +4 -3
- package/dist/features/events/components/AdminEventEditorView.js +3 -2
- package/dist/features/events/components/AdminEventsView.js +4 -2
- package/dist/features/events/components/EventPollWidget.js +5 -5
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/schemas/index.d.ts +20 -20
- package/dist/features/faq/actions/faq-actions.d.ts +8 -8
- package/dist/features/faq/components/ContactCTA.js +3 -1
- package/dist/features/faq/components/FAQAccordion.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/filters/AsyncFacetSection.d.ts +18 -0
- package/dist/features/filters/AsyncFacetSection.js +65 -0
- package/dist/features/forms/Checkbox.js +2 -2
- package/dist/features/forms/Input.js +2 -2
- package/dist/features/forms/Radio.js +5 -5
- package/dist/features/forms/Select.js +2 -2
- package/dist/features/forms/Slider.js +2 -2
- package/dist/features/forms/Textarea.js +2 -2
- package/dist/features/homepage/api/[id]/route.js +4 -3
- package/dist/features/homepage/api/sections/[id]/route.js +12 -9
- package/dist/features/homepage/components/AdSlot.js +2 -1
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -3
- package/dist/features/homepage/components/BrandsSection.js +2 -2
- package/dist/features/homepage/components/CTABannerSection.js +2 -2
- package/dist/features/homepage/components/CharacterHotspot.d.ts +2 -2
- package/dist/features/homepage/components/CharacterHotspot.js +119 -157
- package/dist/features/homepage/components/CharacterHotspotForm.js +25 -20
- package/dist/features/homepage/components/CustomCardsSection.js +8 -6
- package/dist/features/homepage/components/FeaturedProductsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +3 -3
- package/dist/features/homepage/components/HeroBanner.js +5 -4
- package/dist/features/homepage/components/HeroCarousel.js +13 -26
- package/dist/features/homepage/components/HowItWorksSection.js +4 -2
- package/dist/features/homepage/components/SocialFeedSection.js +2 -2
- package/dist/features/homepage/components/SocialPostCard.js +3 -2
- package/dist/features/homepage/lib/social-feed-fetcher.js +6 -3
- package/dist/features/layout/AppLayoutShell.d.ts +8 -2
- package/dist/features/layout/AppLayoutShell.js +55 -84
- package/dist/features/layout/BottomActions.js +43 -48
- package/dist/features/layout/NavbarWithSettings.d.ts +6 -0
- package/dist/features/layout/NavbarWithSettings.js +11 -0
- package/dist/features/live/components/LiveItemFilters.d.ts +8 -0
- package/dist/features/live/components/LiveItemFilters.js +23 -0
- package/dist/features/live/components/LiveItemsIndexListing.d.ts +4 -0
- package/dist/features/live/components/LiveItemsIndexListing.js +108 -0
- package/dist/features/live/components/LiveItemsListView.d.ts +6 -0
- package/dist/features/live/components/LiveItemsListView.js +43 -0
- package/dist/features/live/components/index.d.ts +6 -0
- package/dist/features/live/components/index.js +3 -0
- package/dist/features/media/MediaLightbox.js +8 -14
- package/dist/features/media/types/index.d.ts +2 -2
- package/dist/features/media/upload/CameraCapture.js +2 -2
- package/dist/features/media/upload/ImageUpload.js +4 -2
- package/dist/features/media/upload/MediaUploadField.js +24 -8
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/orders/actions/order-actions.js +4 -3
- package/dist/features/orders/components/MarketplaceOrderCard.js +2 -1
- package/dist/features/orders/components/OrderFilters.js +12 -9
- package/dist/features/orders/schemas/index.d.ts +6 -6
- package/dist/features/pre-orders/api/[id]/route.js +12 -9
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -4
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +27 -20
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +17 -52
- package/dist/features/pre-orders/components/PreorderCard.d.ts +0 -9
- package/dist/features/pre-orders/components/PreorderCard.js +2 -13
- package/dist/features/pre-orders/components/index.d.ts +1 -1
- package/dist/features/pre-orders/components/index.js +1 -1
- package/dist/features/pre-orders/schemas/index.d.ts +10 -10
- package/dist/features/products/api/[id]/route.js +9 -7
- package/dist/features/products/api/route.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +15 -51
- package/dist/features/products/components/BidHistory.js +2 -2
- package/dist/features/products/components/CompareOverlay.js +3 -2
- package/dist/features/products/components/MakeOfferButton.js +20 -14
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -1
- package/dist/features/products/components/PrizeDrawCollage.d.ts +1 -15
- package/dist/features/products/components/PrizeDrawCollage.js +54 -14
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +2 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +9 -7
- package/dist/features/products/components/PrizeDrawsIndexListing.js +18 -51
- package/dist/features/products/components/PrizeRevealModal.js +24 -14
- package/dist/features/products/components/ProductDetailPageView.js +2 -1
- package/dist/features/products/components/ProductFilters.js +8 -6
- package/dist/features/products/components/ProductForm.js +12 -10
- package/dist/features/products/components/ProductGalleryClient.js +2 -1
- package/dist/features/products/components/ProductGrid.js +11 -14
- package/dist/features/products/components/ProductsIndexListing.js +16 -52
- package/dist/features/products/components/ProductsIndexPageView.js +2 -2
- package/dist/features/products/schemas/index.d.ts +56 -56
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/reviews/actions/review-actions.js +6 -5
- package/dist/features/reviews/api/[id]/route.js +4 -3
- package/dist/features/reviews/components/ReviewDetailPageView.js +2 -2
- package/dist/features/reviews/components/ReviewDetailShell.js +6 -3
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +6 -6
- package/dist/features/scams/components/ScamProfileView.js +19 -10
- package/dist/features/scams/components/ScamRegistryView.js +2 -1
- package/dist/features/search/components/Search.d.ts +1 -1
- package/dist/features/search/components/Search.js +56 -49
- package/dist/features/search/schemas/index.d.ts +5 -5
- package/dist/features/seller/actions/offer-actions.js +11 -9
- package/dist/features/seller/components/SellerAddressesView.js +6 -4
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerCouponsView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +6 -1
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +3 -3
- package/dist/features/seller/components/SellerPreOrdersView.js +5 -4
- package/dist/features/seller/components/SellerPrizeDrawsView.js +5 -4
- package/dist/features/seller/components/SellerProductShell.d.ts +19 -1
- package/dist/features/seller/components/SellerProductShell.js +75 -9
- package/dist/features/seller/components/SellerProductsView.js +10 -11
- package/dist/features/seller/components/SellerShippingView.js +3 -3
- package/dist/features/seller/components/SellerSidebar.js +10 -7
- package/dist/features/seller/components/SellerStorefrontView.js +3 -3
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/shell/FormShell.js +2 -1
- package/dist/features/shell/QuickFormDrawer.js +4 -3
- package/dist/features/shell/StepForm.js +4 -3
- package/dist/features/stores/actions/store-query-actions.js +4 -3
- package/dist/features/stores/components/StoreAboutView.js +2 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +43 -64
- package/dist/features/stores/components/StoreDetailLayoutView.js +2 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +33 -57
- package/dist/features/stores/components/StoreProductsListing.js +16 -49
- package/dist/features/stores/components/StoresIndexListing.js +2 -2
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +8 -7
- package/dist/features/wishlist/hooks/useGuestWishlist.d.ts +5 -5
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +6 -6
- package/dist/features/wishlist/utils/guest-wishlist.d.ts +5 -5
- package/dist/index.d.ts +21 -3
- package/dist/index.js +1737 -1725
- package/dist/monitoring/server-logger.js +5 -9
- package/dist/next/api/apiHandler.js +56 -37
- package/dist/next/components/GlobalError.js +2 -1
- package/dist/next/routing/route-map.d.ts +27 -0
- package/dist/next/routing/route-map.js +10 -0
- package/dist/react/ErrorBoundary.js +2 -1
- package/dist/react/contexts/SessionContext.js +38 -28
- package/dist/react/hooks/useCamera.d.ts +1 -1
- package/dist/react/hooks/useCamera.js +8 -7
- package/dist/seed/site-settings-seed-data.js +6 -0
- package/dist/server-entry.d.ts +3 -0
- package/dist/server-entry.js +3 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +15 -0
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/DataTable.js +28 -7
- package/dist/ui/components/Button.d.ts +8 -1
- package/dist/ui/components/Button.js +47 -8
- package/dist/ui/components/CollageLightbox.d.ts +18 -0
- package/dist/ui/components/CollageLightbox.js +41 -0
- package/dist/ui/components/Dropdown.js +7 -6
- package/dist/ui/components/ImageLightbox.d.ts +7 -1
- package/dist/ui/components/ImageLightbox.js +15 -5
- package/dist/ui/components/PageLoader.js +4 -3
- package/dist/ui/components/PaginatedMultiSelect.d.ts +28 -0
- package/dist/ui/components/PaginatedMultiSelect.js +141 -0
- package/dist/ui/components/PaginatedMultiSelect.style.css +272 -0
- package/dist/ui/components/Semantic.js +1 -1
- package/dist/ui/components/SideDrawer.js +17 -15
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +1 -0
- package/dist/utils/number.formatter.js +5 -13
- package/dist/utils/string.formatter.js +21 -18
- package/dist/validation/schemas.d.ts +2 -2
- package/package.json +2 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
3
|
-
import { useState, useCallback
|
|
4
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from "react";
|
|
4
|
+
import { ShoppingCart, Heart, Columns } from "lucide-react";
|
|
5
5
|
import { useRouter } from "next/navigation";
|
|
6
6
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
7
7
|
import { useProducts } from "../hooks/useProducts";
|
|
8
|
-
import { Pagination, useToast, BulkActionBar, ListingToolbar, LoginRequiredModal } from "../../../ui";
|
|
8
|
+
import { Pagination, useToast, BulkActionBar, ListingToolbar, LoginRequiredModal, FilterDrawer } from "../../../ui";
|
|
9
|
+
import { usePendingTable } from "../../../react/hooks/usePendingTable";
|
|
9
10
|
import { useAuthGate } from "../../../react/hooks/useAuthGate";
|
|
10
11
|
import { ACTION_ID, ACTION_META, COMPARE_MAX_ITEMS } from "../constants/action-defs";
|
|
11
12
|
import { CompareOverlay } from "./CompareOverlay";
|
|
@@ -31,61 +32,24 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
31
32
|
const [compareIds, setCompareIds] = useState([]);
|
|
32
33
|
const showSold = table.get(TABLE_KEYS.SHOW_SOLD) === "true";
|
|
33
34
|
const [view, setView] = useState(table.get(TABLE_KEYS.VIEW) || VIEW_MODE.GRID);
|
|
34
|
-
|
|
35
|
-
const [pendingFilters, setPendingFilters] = useState(() => Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
|
|
36
|
-
const pendingTable = useMemo(() => ({
|
|
37
|
-
get: (key) => pendingFilters[key] ?? "",
|
|
38
|
-
getNumber: (key, fallback = 0) => {
|
|
39
|
-
const v = pendingFilters[key];
|
|
40
|
-
if (!v)
|
|
41
|
-
return fallback;
|
|
42
|
-
const n = Number(v);
|
|
43
|
-
return isNaN(n) ? fallback : n;
|
|
44
|
-
},
|
|
45
|
-
set: (key, value) => setPendingFilters((p) => ({ ...p, [key]: value })),
|
|
46
|
-
setMany: (updates) => setPendingFilters((p) => ({ ...p, ...updates })),
|
|
47
|
-
clear: (keys) => {
|
|
48
|
-
const ks = keys ?? FILTER_KEYS;
|
|
49
|
-
setPendingFilters((p) => ({
|
|
50
|
-
...p,
|
|
51
|
-
...Object.fromEntries(ks.map((k) => [k, ""])),
|
|
52
|
-
}));
|
|
53
|
-
},
|
|
54
|
-
setPage: (_) => { },
|
|
55
|
-
setPageSize: (_) => { },
|
|
56
|
-
setSort: (_) => { },
|
|
57
|
-
buildSieveParams: () => "",
|
|
58
|
-
buildSearchParams: () => "",
|
|
59
|
-
params: new URLSearchParams(),
|
|
60
|
-
}), [pendingFilters]);
|
|
35
|
+
const { pendingTable, filterActiveCount, onFilterApply, onFilterClear, onFilterReset } = usePendingTable(table, FILTER_KEYS);
|
|
61
36
|
const openFilters = useCallback(() => {
|
|
62
|
-
|
|
63
|
-
setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, table.get(k)])));
|
|
37
|
+
onFilterReset();
|
|
64
38
|
setFilterOpen(true);
|
|
65
|
-
}, [
|
|
39
|
+
}, [onFilterReset]);
|
|
66
40
|
const applyFilters = useCallback(() => {
|
|
67
|
-
|
|
68
|
-
for (const k of FILTER_KEYS)
|
|
69
|
-
updates[k] = pendingFilters[k] ?? "";
|
|
70
|
-
table.setMany(updates);
|
|
41
|
+
onFilterApply();
|
|
71
42
|
setFilterOpen(false);
|
|
72
|
-
}, [
|
|
73
|
-
const clearFilters = useCallback(() => {
|
|
74
|
-
setPendingFilters(Object.fromEntries(FILTER_KEYS.map((k) => [k, ""])));
|
|
75
|
-
}, []);
|
|
43
|
+
}, [onFilterApply]);
|
|
76
44
|
const resetAll = useCallback(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
updates[k] = "";
|
|
80
|
-
table.setMany(updates);
|
|
45
|
+
table.setMany({ [TABLE_KEYS.QUERY]: "", [TABLE_KEYS.SORT]: "", [TABLE_KEYS.SHOW_SOLD]: "" });
|
|
46
|
+
onFilterClear();
|
|
81
47
|
setSearchInput("");
|
|
82
|
-
}, [table]);
|
|
83
|
-
const activeFilterCount = FILTER_KEYS.filter((k) => !!table.get(k)).length;
|
|
84
|
-
const pendingFilterCount = FILTER_KEYS.filter((k) => !!pendingFilters[k]).length;
|
|
48
|
+
}, [table, onFilterClear]);
|
|
85
49
|
const hasActiveState = !!table.get(TABLE_KEYS.QUERY) ||
|
|
86
50
|
table.get(TABLE_KEYS.SHOW_SOLD) === "true" ||
|
|
87
51
|
table.get(TABLE_KEYS.SORT) !== DEFAULT_SORT ||
|
|
88
|
-
|
|
52
|
+
filterActiveCount > 0;
|
|
89
53
|
const localCart = useGuestCart();
|
|
90
54
|
const localWishlist = useGuestWishlist();
|
|
91
55
|
const wishlistedIds = new Set(localWishlist.items.filter((i) => i.type === "product").map((i) => i.itemId));
|
|
@@ -158,7 +122,7 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
158
122
|
router.push(String(ROUTES.USER.CART));
|
|
159
123
|
});
|
|
160
124
|
}, [localCart, router, requireAuth]);
|
|
161
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount:
|
|
125
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search products...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, onSearchKeyDown: handleSearchKeyDown, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: PRODUCT_PUBLIC_SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, onResetAll: resetAll, hasActiveState: hasActiveState, bulkMode: selection.isSelecting, bulkSelectedCount: selection.selectedCount, bulkTotalCount: products.length, onBulkSelectAll: selection.toggleAll, onBulkClear: selection.clearSelection, extra: _jsxs("label", { className: "flex items-center gap-1.5 cursor-pointer select-none shrink-0", children: [_jsx("span", { className: "hidden sm:inline text-xs text-zinc-600 dark:text-zinc-300 whitespace-nowrap", children: "Show sold" }), _jsx("button", { type: "button", role: "switch", "aria-checked": showSold, onClick: () => table.set(TABLE_KEYS.SHOW_SOLD, showSold ? "" : "true"), className: `relative inline-flex h-5 w-9 flex-shrink-0 items-center rounded-full transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 ${showSold ? "bg-primary" : "bg-zinc-300 dark:bg-slate-600"}`, children: _jsx("span", { className: `inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow-sm transition-transform duration-200 ${showSold ? "translate-x-[19px]" : "translate-x-[3px]"}` }) })] }) }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
162
126
|
{
|
|
163
127
|
id: ACTION_ID.ADD_TO_CART,
|
|
164
128
|
label: ACTION_META[ACTION_ID.ADD_TO_CART].label,
|
|
@@ -205,5 +169,5 @@ export function ProductsIndexListing({ initialData }) {
|
|
|
205
169
|
] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: page, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsx("div", { className: "py-6", children: isLoading ? (_jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-4", children: Array.from({ length: 10 }).map((_, i) => (_jsxs("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: [_jsx("div", { className: "aspect-square bg-zinc-200 dark:bg-slate-700" }), _jsxs("div", { className: "p-3 space-y-2", children: [_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" }), _jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-1/3" })] })] }, i))) })) : (_jsx(ProductGrid, { products: products, getProductHref: (p) => String(ROUTES.PUBLIC.PRODUCT_DETAIL(p.slug || p.id)), view: view === "grid" ? "card" : "list", onWishlistToggle: handleWishlistToggle, wishlistedIds: wishlistedIds, onAddToCart: handleAddToCart, onBuyNow: handleBuyNow, selectionMode: selection.isSelecting, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle })) }), _jsx(CompareOverlay, { isOpen: compareIds.length > 0, productIds: compareIds, productType: "product", onClose: () => {
|
|
206
170
|
setCompareIds([]);
|
|
207
171
|
selection.clearSelection();
|
|
208
|
-
}, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }),
|
|
172
|
+
}, onRemove: (id) => setCompareIds((ids) => ids.filter((i) => i !== id)) }), _jsx(FilterDrawer, { open: filterOpen, onOpen: openFilters, onClose: () => setFilterOpen(false), onApply: applyFilters, onReset: onFilterClear, activeCount: filterActiveCount, hideTrigger: true, children: _jsx(ProductFilters, { table: pendingTable, currencyPrefix: "\u20B9", categoryOptions: categoryOptions }) }), _jsx(LoginRequiredModal, { isOpen: modalOpen, onClose: closeModal, message: modalMessage })] }));
|
|
209
173
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { productRepository } from "../../../repositories";
|
|
3
3
|
import { ROUTES } from "../../../constants";
|
|
4
|
-
import { Container, Heading, Main, Section } from "../../../ui";
|
|
4
|
+
import { Container, Heading, Main, Section, Text } from "../../../ui";
|
|
5
5
|
import { AdSlot } from "../../homepage/components/AdSlot";
|
|
6
6
|
import { parseListingSearchParams } from "../../../utils/listing-params";
|
|
7
7
|
import { ProductsIndexListing } from "./ProductsIndexListing";
|
|
@@ -59,5 +59,5 @@ export async function ProductsIndexPageView({ searchParams = {} }) {
|
|
|
59
59
|
})
|
|
60
60
|
.catch(() => null);
|
|
61
61
|
const products = result ?? null;
|
|
62
|
-
return (_jsxs(Main, { children: [_jsx(Section, { className: "pt-8 pb-4 border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "text-3xl font-bold text-zinc-900 dark:text-zinc-100", children: "Products" }), _jsx(
|
|
62
|
+
return (_jsxs(Main, { children: [_jsx(Section, { className: "pt-8 pb-4 border-b border-zinc-100 dark:border-slate-800", children: _jsxs(Container, { size: "xl", children: [_jsx(Heading, { level: 1, className: "text-3xl font-bold text-zinc-900 dark:text-zinc-100", children: "Products" }), _jsx(Text, { className: "mt-1 text-sm text-zinc-500 dark:text-zinc-400", children: "Discover amazing products and deals" }), _jsx("div", { className: "mt-3", children: _jsx("a", { href: ROUTES.PUBLIC.AUCTIONS, className: "inline-flex items-center gap-1.5 rounded-full border border-primary/30 bg-primary/10 px-4 py-1.5 text-xs font-medium text-primary-700 dark:text-primary-400 hover:bg-primary/15 transition-colors", children: "\uD83C\uDFF7\uFE0F Looking for unique deals? Browse Auctions \u2192" }) })] }) }), _jsxs(Container, { size: "xl", className: "px-4", children: [_jsx(AdSlot, { id: "listing-sidebar-top", className: "mb-4 mt-4" }), _jsx(ProductsIndexListing, { initialData: products }), _jsx(AdSlot, { id: "listing-sidebar-bottom", className: "mt-8" })] })] }));
|
|
63
63
|
}
|
|
@@ -8,13 +8,13 @@ export declare const productImageSchema: z.ZodObject<{
|
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
9
|
url: string;
|
|
10
10
|
alt?: string | undefined;
|
|
11
|
-
order?: number | undefined;
|
|
12
11
|
thumbnailUrl?: string | undefined;
|
|
12
|
+
order?: number | undefined;
|
|
13
13
|
}, {
|
|
14
14
|
url: string;
|
|
15
15
|
alt?: string | undefined;
|
|
16
|
-
order?: number | undefined;
|
|
17
16
|
thumbnailUrl?: string | undefined;
|
|
17
|
+
order?: number | undefined;
|
|
18
18
|
}>;
|
|
19
19
|
export declare const productSeoSchema: z.ZodObject<{
|
|
20
20
|
title: z.ZodOptional<z.ZodString>;
|
|
@@ -62,14 +62,14 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
62
62
|
}, "strip", z.ZodTypeAny, {
|
|
63
63
|
type: "video" | "image" | "file";
|
|
64
64
|
url: string;
|
|
65
|
-
source?: "
|
|
65
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
66
66
|
alt?: string | undefined;
|
|
67
67
|
thumbnailUrl?: string | undefined;
|
|
68
68
|
youtubeId?: string | undefined;
|
|
69
69
|
}, {
|
|
70
70
|
type: "video" | "image" | "file";
|
|
71
71
|
url: string;
|
|
72
|
-
source?: "
|
|
72
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
73
73
|
alt?: string | undefined;
|
|
74
74
|
thumbnailUrl?: string | undefined;
|
|
75
75
|
youtubeId?: string | undefined;
|
|
@@ -117,8 +117,8 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
117
117
|
isWon: z.ZodBoolean;
|
|
118
118
|
}, "strip", z.ZodTypeAny, {
|
|
119
119
|
title: string;
|
|
120
|
-
condition: string;
|
|
121
120
|
images: string[];
|
|
121
|
+
condition: string;
|
|
122
122
|
itemNumber: number;
|
|
123
123
|
isWon: boolean;
|
|
124
124
|
video?: {
|
|
@@ -129,8 +129,8 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
129
129
|
estimatedValue?: number | undefined;
|
|
130
130
|
}, {
|
|
131
131
|
title: string;
|
|
132
|
-
condition: string;
|
|
133
132
|
images: string[];
|
|
133
|
+
condition: string;
|
|
134
134
|
itemNumber: number;
|
|
135
135
|
isWon: boolean;
|
|
136
136
|
video?: {
|
|
@@ -296,41 +296,28 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
296
296
|
url: string;
|
|
297
297
|
thumbnailUrl?: string | undefined;
|
|
298
298
|
} | undefined;
|
|
299
|
-
media?: {
|
|
300
|
-
type: "video" | "image" | "file";
|
|
301
|
-
url: string;
|
|
302
|
-
source?: "external" | "upload" | "youtube" | undefined;
|
|
303
|
-
alt?: string | undefined;
|
|
304
|
-
thumbnailUrl?: string | undefined;
|
|
305
|
-
youtubeId?: string | undefined;
|
|
306
|
-
}[] | undefined;
|
|
307
299
|
category?: string | undefined;
|
|
308
|
-
brand?: string | undefined;
|
|
309
|
-
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
310
|
-
tags?: string[] | undefined;
|
|
311
300
|
featured?: boolean | undefined;
|
|
312
|
-
listingType?: "
|
|
313
|
-
inStock?: boolean | undefined;
|
|
314
|
-
rating?: number | undefined;
|
|
315
|
-
preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
|
|
316
|
-
prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
|
|
317
|
-
categorySlug?: string | undefined;
|
|
318
|
-
features?: string[] | undefined;
|
|
319
|
-
images?: string[] | undefined;
|
|
320
|
-
description?: string | undefined;
|
|
301
|
+
listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
321
302
|
isPromoted?: boolean | undefined;
|
|
303
|
+
description?: string | undefined;
|
|
322
304
|
slug?: string | undefined;
|
|
323
305
|
subcategory?: string | undefined;
|
|
306
|
+
brand?: string | undefined;
|
|
324
307
|
stockQuantity?: number | undefined;
|
|
325
308
|
availableQuantity?: number | undefined;
|
|
326
309
|
mainImage?: string | undefined;
|
|
310
|
+
images?: string[] | undefined;
|
|
311
|
+
tags?: string[] | undefined;
|
|
327
312
|
specifications?: {
|
|
328
313
|
value: string;
|
|
329
314
|
name: string;
|
|
330
315
|
unit?: string | undefined;
|
|
331
316
|
}[] | undefined;
|
|
317
|
+
features?: string[] | undefined;
|
|
332
318
|
shippingInfo?: string | undefined;
|
|
333
319
|
returnPolicy?: string | undefined;
|
|
320
|
+
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
334
321
|
insurance?: boolean | undefined;
|
|
335
322
|
insuranceCost?: number | undefined;
|
|
336
323
|
shippingPaidBy?: "seller" | "buyer" | undefined;
|
|
@@ -349,6 +336,7 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
349
336
|
preOrderDepositAmount?: number | undefined;
|
|
350
337
|
preOrderMaxQuantity?: number | undefined;
|
|
351
338
|
preOrderCurrentCount?: number | undefined;
|
|
339
|
+
preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
|
|
352
340
|
preOrderCancellable?: boolean | undefined;
|
|
353
341
|
pickupAddressId?: string | undefined;
|
|
354
342
|
viewCount?: number | undefined;
|
|
@@ -384,8 +372,8 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
384
372
|
partOfBundleTitles?: string[] | undefined;
|
|
385
373
|
prizeDrawItems?: {
|
|
386
374
|
title: string;
|
|
387
|
-
condition: string;
|
|
388
375
|
images: string[];
|
|
376
|
+
condition: string;
|
|
389
377
|
itemNumber: number;
|
|
390
378
|
isWon: boolean;
|
|
391
379
|
video?: {
|
|
@@ -400,8 +388,20 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
400
388
|
prizeCurrentEntries?: number | undefined;
|
|
401
389
|
prizeRevealWindowStart?: string | Date | undefined;
|
|
402
390
|
prizeRevealWindowEnd?: string | Date | undefined;
|
|
391
|
+
prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
|
|
403
392
|
prizeRevealDeadlineDays?: number | undefined;
|
|
404
393
|
prizeGithubFileUrl?: string | undefined;
|
|
394
|
+
media?: {
|
|
395
|
+
type: "video" | "image" | "file";
|
|
396
|
+
url: string;
|
|
397
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
398
|
+
alt?: string | undefined;
|
|
399
|
+
thumbnailUrl?: string | undefined;
|
|
400
|
+
youtubeId?: string | undefined;
|
|
401
|
+
}[] | undefined;
|
|
402
|
+
inStock?: boolean | undefined;
|
|
403
|
+
rating?: number | undefined;
|
|
404
|
+
categorySlug?: string | undefined;
|
|
405
405
|
originalPrice?: number | undefined;
|
|
406
406
|
sellerAvatar?: string | undefined;
|
|
407
407
|
stockCount?: number | undefined;
|
|
@@ -425,41 +425,28 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
425
425
|
url: string;
|
|
426
426
|
thumbnailUrl?: string | undefined;
|
|
427
427
|
} | undefined;
|
|
428
|
-
media?: {
|
|
429
|
-
type: "video" | "image" | "file";
|
|
430
|
-
url: string;
|
|
431
|
-
source?: "external" | "upload" | "youtube" | undefined;
|
|
432
|
-
alt?: string | undefined;
|
|
433
|
-
thumbnailUrl?: string | undefined;
|
|
434
|
-
youtubeId?: string | undefined;
|
|
435
|
-
}[] | undefined;
|
|
436
428
|
category?: string | undefined;
|
|
437
|
-
brand?: string | undefined;
|
|
438
|
-
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
439
|
-
tags?: string[] | undefined;
|
|
440
429
|
featured?: boolean | undefined;
|
|
441
|
-
listingType?: "
|
|
442
|
-
inStock?: boolean | undefined;
|
|
443
|
-
rating?: number | undefined;
|
|
444
|
-
preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
|
|
445
|
-
prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
|
|
446
|
-
categorySlug?: string | undefined;
|
|
447
|
-
features?: string[] | undefined;
|
|
448
|
-
images?: string[] | undefined;
|
|
449
|
-
description?: string | undefined;
|
|
430
|
+
listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
450
431
|
isPromoted?: boolean | undefined;
|
|
432
|
+
description?: string | undefined;
|
|
451
433
|
slug?: string | undefined;
|
|
452
434
|
subcategory?: string | undefined;
|
|
435
|
+
brand?: string | undefined;
|
|
453
436
|
stockQuantity?: number | undefined;
|
|
454
437
|
availableQuantity?: number | undefined;
|
|
455
438
|
mainImage?: string | undefined;
|
|
439
|
+
images?: string[] | undefined;
|
|
440
|
+
tags?: string[] | undefined;
|
|
456
441
|
specifications?: {
|
|
457
442
|
value: string;
|
|
458
443
|
name: string;
|
|
459
444
|
unit?: string | undefined;
|
|
460
445
|
}[] | undefined;
|
|
446
|
+
features?: string[] | undefined;
|
|
461
447
|
shippingInfo?: string | undefined;
|
|
462
448
|
returnPolicy?: string | undefined;
|
|
449
|
+
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
463
450
|
insurance?: boolean | undefined;
|
|
464
451
|
insuranceCost?: number | undefined;
|
|
465
452
|
shippingPaidBy?: "seller" | "buyer" | undefined;
|
|
@@ -478,6 +465,7 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
478
465
|
preOrderDepositAmount?: number | undefined;
|
|
479
466
|
preOrderMaxQuantity?: number | undefined;
|
|
480
467
|
preOrderCurrentCount?: number | undefined;
|
|
468
|
+
preOrderProductionStatus?: "upcoming" | "in_production" | "ready_to_ship" | undefined;
|
|
481
469
|
preOrderCancellable?: boolean | undefined;
|
|
482
470
|
pickupAddressId?: string | undefined;
|
|
483
471
|
viewCount?: number | undefined;
|
|
@@ -513,8 +501,8 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
513
501
|
partOfBundleTitles?: string[] | undefined;
|
|
514
502
|
prizeDrawItems?: {
|
|
515
503
|
title: string;
|
|
516
|
-
condition: string;
|
|
517
504
|
images: string[];
|
|
505
|
+
condition: string;
|
|
518
506
|
itemNumber: number;
|
|
519
507
|
isWon: boolean;
|
|
520
508
|
video?: {
|
|
@@ -529,8 +517,20 @@ export declare const productItemSchema: z.ZodObject<{
|
|
|
529
517
|
prizeCurrentEntries?: number | undefined;
|
|
530
518
|
prizeRevealWindowStart?: string | Date | undefined;
|
|
531
519
|
prizeRevealWindowEnd?: string | Date | undefined;
|
|
520
|
+
prizeRevealStatus?: "pending" | "closed" | "open" | undefined;
|
|
532
521
|
prizeRevealDeadlineDays?: number | undefined;
|
|
533
522
|
prizeGithubFileUrl?: string | undefined;
|
|
523
|
+
media?: {
|
|
524
|
+
type: "video" | "image" | "file";
|
|
525
|
+
url: string;
|
|
526
|
+
source?: "upload" | "youtube" | "external" | undefined;
|
|
527
|
+
alt?: string | undefined;
|
|
528
|
+
thumbnailUrl?: string | undefined;
|
|
529
|
+
youtubeId?: string | undefined;
|
|
530
|
+
}[] | undefined;
|
|
531
|
+
inStock?: boolean | undefined;
|
|
532
|
+
rating?: number | undefined;
|
|
533
|
+
categorySlug?: string | undefined;
|
|
534
534
|
originalPrice?: number | undefined;
|
|
535
535
|
sellerAvatar?: string | undefined;
|
|
536
536
|
stockCount?: number | undefined;
|
|
@@ -563,13 +563,13 @@ export declare const productListParamsSchema: z.ZodObject<{
|
|
|
563
563
|
storeId?: string | undefined;
|
|
564
564
|
status?: "draft" | "published" | "archived" | "sold" | "out_of_stock" | "discontinued" | undefined;
|
|
565
565
|
q?: string | undefined;
|
|
566
|
-
page?: number | undefined;
|
|
567
566
|
category?: string | undefined;
|
|
567
|
+
featured?: boolean | undefined;
|
|
568
|
+
listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
569
|
+
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
570
|
+
page?: number | undefined;
|
|
568
571
|
minPrice?: number | undefined;
|
|
569
572
|
maxPrice?: number | undefined;
|
|
570
|
-
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
571
|
-
featured?: boolean | undefined;
|
|
572
|
-
listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
573
573
|
inStock?: boolean | undefined;
|
|
574
574
|
}, {
|
|
575
575
|
sort?: string | undefined;
|
|
@@ -577,12 +577,12 @@ export declare const productListParamsSchema: z.ZodObject<{
|
|
|
577
577
|
storeId?: string | undefined;
|
|
578
578
|
status?: "draft" | "published" | "archived" | "sold" | "out_of_stock" | "discontinued" | undefined;
|
|
579
579
|
q?: string | undefined;
|
|
580
|
-
page?: number | undefined;
|
|
581
580
|
category?: string | undefined;
|
|
581
|
+
featured?: boolean | undefined;
|
|
582
|
+
listingType?: "standard" | "auction" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
583
|
+
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
584
|
+
page?: number | undefined;
|
|
582
585
|
minPrice?: number | undefined;
|
|
583
586
|
maxPrice?: number | undefined;
|
|
584
|
-
condition?: "new" | "used" | "refurbished" | "broken" | "like_new" | "good" | "fair" | "poor" | undefined;
|
|
585
|
-
featured?: boolean | undefined;
|
|
586
|
-
listingType?: "auction" | "standard" | "pre-order" | "prize-draw" | "bundle" | undefined;
|
|
587
587
|
inStock?: boolean | undefined;
|
|
588
588
|
}>;
|
|
@@ -24,22 +24,22 @@ export declare const productFeatureAdminCreateSchema: z.ZodObject<{
|
|
|
24
24
|
}, "strip", z.ZodTypeAny, {
|
|
25
25
|
label: string;
|
|
26
26
|
scope: "store" | "platform";
|
|
27
|
+
category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
|
|
27
28
|
icon: string;
|
|
28
29
|
isActive: boolean;
|
|
29
|
-
category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
|
|
30
30
|
displayOrder: number;
|
|
31
|
-
productTypes: ("
|
|
31
|
+
productTypes: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[];
|
|
32
32
|
storeId?: string | undefined;
|
|
33
33
|
description?: string | undefined;
|
|
34
34
|
iconColor?: string | undefined;
|
|
35
35
|
}, {
|
|
36
36
|
label: string;
|
|
37
37
|
scope: "store" | "platform";
|
|
38
|
+
category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
|
|
38
39
|
icon: string;
|
|
39
40
|
isActive: boolean;
|
|
40
|
-
category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
|
|
41
41
|
displayOrder: number;
|
|
42
|
-
productTypes: ("
|
|
42
|
+
productTypes: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[];
|
|
43
43
|
storeId?: string | undefined;
|
|
44
44
|
description?: string | undefined;
|
|
45
45
|
iconColor?: string | undefined;
|
|
@@ -56,20 +56,20 @@ export declare const productFeatureStoreCreateSchema: z.ZodObject<{
|
|
|
56
56
|
displayOrder: z.ZodNumber;
|
|
57
57
|
}, "strip", z.ZodTypeAny, {
|
|
58
58
|
label: string;
|
|
59
|
+
category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
|
|
59
60
|
icon: string;
|
|
60
61
|
isActive: boolean;
|
|
61
|
-
category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
|
|
62
62
|
displayOrder: number;
|
|
63
|
-
productTypes: ("
|
|
63
|
+
productTypes: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[];
|
|
64
64
|
description?: string | undefined;
|
|
65
65
|
iconColor?: string | undefined;
|
|
66
66
|
}, {
|
|
67
67
|
label: string;
|
|
68
|
+
category: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform";
|
|
68
69
|
icon: string;
|
|
69
70
|
isActive: boolean;
|
|
70
|
-
category: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform";
|
|
71
71
|
displayOrder: number;
|
|
72
|
-
productTypes: ("
|
|
72
|
+
productTypes: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[];
|
|
73
73
|
description?: string | undefined;
|
|
74
74
|
iconColor?: string | undefined;
|
|
75
75
|
}>;
|
|
@@ -85,22 +85,22 @@ export declare const productFeatureUpdateSchema: z.ZodObject<{
|
|
|
85
85
|
displayOrder: z.ZodOptional<z.ZodNumber>;
|
|
86
86
|
}, "strip", z.ZodTypeAny, {
|
|
87
87
|
label?: string | undefined;
|
|
88
|
+
category?: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
|
|
89
|
+
description?: string | undefined;
|
|
88
90
|
icon?: string | undefined;
|
|
89
91
|
isActive?: boolean | undefined;
|
|
90
|
-
category?: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform" | undefined;
|
|
91
|
-
description?: string | undefined;
|
|
92
92
|
iconColor?: string | undefined;
|
|
93
93
|
displayOrder?: number | undefined;
|
|
94
|
-
productTypes?: ("
|
|
94
|
+
productTypes?: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[] | undefined;
|
|
95
95
|
}, {
|
|
96
96
|
label?: string | undefined;
|
|
97
|
+
category?: "seller" | "custom" | "auction" | "condition" | "shipping" | "preorder" | "platform" | undefined;
|
|
98
|
+
description?: string | undefined;
|
|
97
99
|
icon?: string | undefined;
|
|
98
100
|
isActive?: boolean | undefined;
|
|
99
|
-
category?: "seller" | "auction" | "preorder" | "condition" | "shipping" | "custom" | "platform" | undefined;
|
|
100
|
-
description?: string | undefined;
|
|
101
101
|
iconColor?: string | undefined;
|
|
102
102
|
displayOrder?: number | undefined;
|
|
103
|
-
productTypes?: ("
|
|
103
|
+
productTypes?: ("auction" | "prize-draw" | "classified" | "digital-code" | "live" | "all" | "product" | "preorder")[] | undefined;
|
|
104
104
|
}>;
|
|
105
105
|
export type ProductFeatureAdminCreatePayload = z.infer<typeof productFeatureAdminCreateSchema>;
|
|
106
106
|
export type ProductFeatureStoreCreatePayload = z.infer<typeof productFeatureStoreCreateSchema>;
|
|
@@ -97,5 +97,5 @@ export function CouponsIndexListing({ initialCoupons, storeSlug, storeId, }) {
|
|
|
97
97
|
minOrder: "Min. order",
|
|
98
98
|
off: "OFF",
|
|
99
99
|
freeShipping: "Free Shipping",
|
|
100
|
-
} }, coupon.id))) })), totalPages > 1 && (_jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-center", children: _jsxs(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500", children: [total, " coupon", total !== 1 ? "s" : "", " available"] }) }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _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: () => setFilterOpen(false), "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" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-6", children: [_jsxs(
|
|
100
|
+
} }, coupon.id))) })), totalPages > 1 && (_jsx("div", { className: "mt-8 flex justify-center", children: _jsx(Pagination, { currentPage: table.getNumber("page", 1), totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), !isLoading && total > 0 && (_jsx(Div, { className: "mt-4 text-center", children: _jsxs(Text, { className: "text-xs text-zinc-400 dark:text-zinc-500", children: [total, " coupon", total !== 1 ? "s" : "", " available"] }) }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _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: () => setFilterOpen(false), "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" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-6", children: [_jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: "Discount Type" }), _jsxs("div", { className: "space-y-2", children: [COUPON_TYPES.map((t) => (_jsxs("label", { className: "flex items-center gap-2 cursor-pointer text-sm text-zinc-700 dark:text-zinc-300", children: [_jsx("input", { type: "radio", name: "coupon-type", value: t.value, checked: pendingTable.get(TABLE_KEYS.TYPE) === t.value, onChange: () => { pendingTable.set(TABLE_KEYS.TYPE, t.value); }, className: "accent-primary" }), t.label] }, t.value))), pendingTable.get(TABLE_KEYS.TYPE) && (_jsx("button", { type: "button", onClick: () => { pendingTable.set(TABLE_KEYS.TYPE, ""); }, className: "text-xs text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300 underline", children: "Clear type" }))] })] }), _jsxs(_Fragment, { children: [_jsx(Heading, { level: 6, className: "text-xs font-semibold uppercase tracking-wider text-zinc-500 dark:text-zinc-400 mb-3", children: "Valid Date Range" }), _jsxs("div", { className: "space-y-3", children: [_jsxs(_Fragment, { children: [_jsx("label", { className: "block text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: "From date" }), _jsx("input", { type: "date", value: pendingTable.get(TABLE_KEYS.DATE_FROM) || "", onChange: (e) => { pendingTable.set(TABLE_KEYS.DATE_FROM, e.target.value); }, className: "w-full 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 outline-none focus:ring-2 focus:ring-primary" })] }), _jsxs(_Fragment, { children: [_jsx("label", { className: "block text-xs text-zinc-500 dark:text-zinc-400 mb-1", children: "To date" }), _jsx("input", { type: "date", value: pendingTable.get(TABLE_KEYS.DATE_TO) || "", onChange: (e) => { pendingTable.set(TABLE_KEYS.DATE_TO, e.target.value); }, className: "w-full 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 outline-none focus:ring-2 focus:ring-primary" })] })] })] })] }), _jsxs("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5 flex gap-2", children: [_jsx("button", { type: "button", onClick: clearPending, className: "flex-1 rounded-lg border border-zinc-300 dark:border-slate-600 py-2.5 text-sm font-medium text-zinc-700 dark:text-zinc-200 hover:bg-zinc-50 dark:hover:bg-slate-800 transition-colors", children: "Clear all" }), _jsx("button", { type: "button", onClick: applyFilters, className: "flex-1 rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors", children: "Apply Filters" })] })] })] }))] }));
|
|
101
101
|
}
|
|
@@ -44,11 +44,11 @@ export declare const couponItemSchema: z.ZodObject<{
|
|
|
44
44
|
updatedAt: string;
|
|
45
45
|
code: string;
|
|
46
46
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
47
|
-
scope: "
|
|
47
|
+
scope: "seller" | "admin";
|
|
48
|
+
description: string;
|
|
48
49
|
name: string;
|
|
49
50
|
isActive: boolean;
|
|
50
51
|
isPublic: boolean;
|
|
51
|
-
description: string;
|
|
52
52
|
usageCount: number;
|
|
53
53
|
discountValue: number;
|
|
54
54
|
storeId?: string | undefined;
|
|
@@ -68,11 +68,11 @@ export declare const couponItemSchema: z.ZodObject<{
|
|
|
68
68
|
updatedAt: string;
|
|
69
69
|
code: string;
|
|
70
70
|
type: "fixed" | "percentage" | "free_shipping" | "buy_x_get_y";
|
|
71
|
-
scope: "
|
|
71
|
+
scope: "seller" | "admin";
|
|
72
|
+
description: string;
|
|
72
73
|
name: string;
|
|
73
74
|
isActive: boolean;
|
|
74
75
|
isPublic: boolean;
|
|
75
|
-
description: string;
|
|
76
76
|
usageCount: number;
|
|
77
77
|
discountValue: number;
|
|
78
78
|
storeId?: string | undefined;
|
|
@@ -99,7 +99,7 @@ export declare const promotionsListParamsSchema: z.ZodObject<{
|
|
|
99
99
|
sort?: string | undefined;
|
|
100
100
|
pageSize?: number | undefined;
|
|
101
101
|
storeId?: string | undefined;
|
|
102
|
-
scope?: "
|
|
102
|
+
scope?: "seller" | "admin" | undefined;
|
|
103
103
|
page?: number | undefined;
|
|
104
104
|
isActive?: boolean | undefined;
|
|
105
105
|
filters?: string | undefined;
|
|
@@ -107,7 +107,7 @@ export declare const promotionsListParamsSchema: z.ZodObject<{
|
|
|
107
107
|
sort?: string | undefined;
|
|
108
108
|
pageSize?: number | undefined;
|
|
109
109
|
storeId?: string | undefined;
|
|
110
|
-
scope?: "
|
|
110
|
+
scope?: "seller" | "admin" | undefined;
|
|
111
111
|
page?: number | undefined;
|
|
112
112
|
isActive?: boolean | undefined;
|
|
113
113
|
filters?: string | undefined;
|
|
@@ -12,6 +12,7 @@ import { reviewRepository } from "../repository/reviews.repository";
|
|
|
12
12
|
import { productRepository } from "../../products/repository/products.repository";
|
|
13
13
|
import { ProductStatusValues } from "../../products/schemas";
|
|
14
14
|
import { userRepository } from "../../auth/repository/user.repository";
|
|
15
|
+
const ERR_REVIEW_ID_REQUIRED = "Review ID is required";
|
|
15
16
|
export async function createReview(userId, input) {
|
|
16
17
|
const product = await productRepository.findById(input.productId);
|
|
17
18
|
if (!product) {
|
|
@@ -51,7 +52,7 @@ export async function createReview(userId, input) {
|
|
|
51
52
|
}
|
|
52
53
|
export async function updateReview(userId, reviewId, input) {
|
|
53
54
|
if (!reviewId?.trim()) {
|
|
54
|
-
throw new ValidationError(
|
|
55
|
+
throw new ValidationError(ERR_REVIEW_ID_REQUIRED);
|
|
55
56
|
}
|
|
56
57
|
const existing = await reviewRepository.findById(reviewId);
|
|
57
58
|
if (!existing) {
|
|
@@ -78,7 +79,7 @@ export async function updateReview(userId, reviewId, input) {
|
|
|
78
79
|
}
|
|
79
80
|
export async function deleteReview(userId, reviewId) {
|
|
80
81
|
if (!reviewId?.trim()) {
|
|
81
|
-
throw new ValidationError(
|
|
82
|
+
throw new ValidationError(ERR_REVIEW_ID_REQUIRED);
|
|
82
83
|
}
|
|
83
84
|
const existing = await reviewRepository.findById(reviewId);
|
|
84
85
|
if (!existing) {
|
|
@@ -91,7 +92,7 @@ export async function deleteReview(userId, reviewId) {
|
|
|
91
92
|
}
|
|
92
93
|
export async function adminUpdateReview(adminId, reviewId, input) {
|
|
93
94
|
if (!reviewId?.trim()) {
|
|
94
|
-
throw new ValidationError(
|
|
95
|
+
throw new ValidationError(ERR_REVIEW_ID_REQUIRED);
|
|
95
96
|
}
|
|
96
97
|
const existing = await reviewRepository.findById(reviewId);
|
|
97
98
|
if (!existing) {
|
|
@@ -119,7 +120,7 @@ export async function adminUpdateReview(adminId, reviewId, input) {
|
|
|
119
120
|
}
|
|
120
121
|
export async function adminDeleteReview(adminId, reviewId) {
|
|
121
122
|
if (!reviewId?.trim()) {
|
|
122
|
-
throw new ValidationError(
|
|
123
|
+
throw new ValidationError(ERR_REVIEW_ID_REQUIRED);
|
|
123
124
|
}
|
|
124
125
|
const existing = await reviewRepository.findById(reviewId);
|
|
125
126
|
if (!existing) {
|
|
@@ -133,7 +134,7 @@ export async function adminDeleteReview(adminId, reviewId) {
|
|
|
133
134
|
}
|
|
134
135
|
export async function voteReviewHelpful(reviewId, helpful) {
|
|
135
136
|
if (!reviewId?.trim()) {
|
|
136
|
-
throw new ValidationError(
|
|
137
|
+
throw new ValidationError(ERR_REVIEW_ID_REQUIRED);
|
|
137
138
|
}
|
|
138
139
|
if (helpful) {
|
|
139
140
|
await reviewRepository.incrementHelpful(reviewId);
|
|
@@ -12,6 +12,7 @@ import { NextResponse } from "next/server.js";
|
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { getProviders } from "../../../../contracts";
|
|
14
14
|
import { createRouteHandler } from "../../../../next";
|
|
15
|
+
const ERR_REVIEW_NOT_FOUND = "Review not found";
|
|
15
16
|
// ---- GET /api/reviews/[id] ---------------------------------------------------
|
|
16
17
|
export async function GET(_request, context) {
|
|
17
18
|
try {
|
|
@@ -23,7 +24,7 @@ export async function GET(_request, context) {
|
|
|
23
24
|
const repo = db.getRepository("reviews");
|
|
24
25
|
const review = await repo.findById(id);
|
|
25
26
|
if (!review) {
|
|
26
|
-
return NextResponse.json({ success: false, error:
|
|
27
|
+
return NextResponse.json({ success: false, error: ERR_REVIEW_NOT_FOUND }, { status: 404 });
|
|
27
28
|
}
|
|
28
29
|
return NextResponse.json({ success: true, data: review });
|
|
29
30
|
}
|
|
@@ -65,7 +66,7 @@ export const reviewItemPATCH = createRouteHandler({
|
|
|
65
66
|
const repo = db.getRepository("reviews");
|
|
66
67
|
const review = await repo.findById(id);
|
|
67
68
|
if (!review)
|
|
68
|
-
return NextResponse.json({ success: false, error:
|
|
69
|
+
return NextResponse.json({ success: false, error: ERR_REVIEW_NOT_FOUND }, { status: 404 });
|
|
69
70
|
const isOwner = review.userId === user.uid;
|
|
70
71
|
const isModerator = user.role === "moderator";
|
|
71
72
|
const isAdmin = user.role === "admin";
|
|
@@ -96,7 +97,7 @@ export const reviewItemDELETE = createRouteHandler({
|
|
|
96
97
|
const repo = db.getRepository("reviews");
|
|
97
98
|
const review = await repo.findById(id);
|
|
98
99
|
if (!review)
|
|
99
|
-
return NextResponse.json({ success: false, error:
|
|
100
|
+
return NextResponse.json({ success: false, error: ERR_REVIEW_NOT_FOUND }, { status: 404 });
|
|
100
101
|
const isOwner = review.userId === user.uid;
|
|
101
102
|
const isModerator = user.role === "moderator";
|
|
102
103
|
const isAdmin = user.role === "admin";
|