@mohasinac/appkit 2.3.2 → 2.4.0
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 +44 -12
- package/dist/client.js +22 -6
- package/dist/constants/api-endpoints.d.ts +380 -22
- package/dist/constants/api-endpoints.js +66 -13
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.js +1 -1
- package/dist/core/hooks/useSyncManager.d.ts +1 -0
- package/dist/core/hooks/useSyncManager.js +83 -0
- package/dist/core/integration-keys.d.ts +4 -0
- package/dist/core/integration-keys.js +8 -0
- package/dist/features/about/components/FAQPageView.js +9 -11
- package/dist/features/about/components/PolicyPageView.js +32 -11
- package/dist/features/about/components/PublicProfileView.js +77 -11
- package/dist/features/account/components/AddressesIndexListing.js +63 -38
- package/dist/features/account/components/UserOffersPanel.d.ts +8 -0
- package/dist/features/account/components/UserOffersPanel.js +81 -0
- package/dist/features/account/components/UserSettingsView.d.ts +2 -1
- package/dist/features/account/components/UserSettingsView.js +2 -1
- package/dist/features/account/components/UserSidebar.d.ts +6 -1
- package/dist/features/account/components/UserSidebar.js +48 -42
- package/dist/features/account/components/index.d.ts +2 -0
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/admin/actions/admin-actions.d.ts +1 -1
- package/dist/features/admin/actions/admin-actions.js +13 -3
- package/dist/features/admin/components/AdminAdEditorView.js +6 -7
- package/dist/features/admin/components/AdminAllEventEntriesView.d.ts +4 -0
- package/dist/features/admin/components/AdminAllEventEntriesView.js +102 -0
- package/dist/features/admin/components/AdminBidsView.js +94 -8
- package/dist/features/admin/components/AdminBlogEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminBlogEditorView.js +162 -0
- package/dist/features/admin/components/AdminBlogView.d.ts +4 -1
- package/dist/features/admin/components/AdminBlogView.js +61 -31
- package/dist/features/admin/components/AdminBrandEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminBrandEditorView.js +104 -0
- package/dist/features/admin/components/AdminBrandsView.d.ts +4 -0
- package/dist/features/admin/components/AdminBrandsView.js +76 -0
- package/dist/features/admin/components/AdminCarouselEditorView.d.ts +8 -0
- package/dist/features/admin/components/AdminCarouselEditorView.js +204 -0
- package/dist/features/admin/components/AdminCarouselView.js +153 -34
- package/dist/features/admin/components/AdminCartsView.d.ts +4 -0
- package/dist/features/admin/components/AdminCartsView.js +82 -0
- package/dist/features/admin/components/AdminCategoriesView.d.ts +4 -1
- package/dist/features/admin/components/AdminCategoriesView.js +66 -48
- package/dist/features/admin/components/AdminCategoryEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminCategoryEditorView.js +115 -0
- package/dist/features/admin/components/AdminContactEditorView.d.ts +11 -0
- package/dist/features/admin/components/AdminContactEditorView.js +32 -0
- package/dist/features/admin/components/AdminContactView.js +111 -20
- package/dist/features/admin/components/AdminCouponEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminCouponEditorView.js +179 -0
- package/dist/features/admin/components/AdminCouponsView.d.ts +4 -1
- package/dist/features/admin/components/AdminCouponsView.js +57 -9
- package/dist/features/admin/components/AdminDashboardView.js +3 -0
- package/dist/features/admin/components/AdminFaqEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminFaqEditorView.js +128 -0
- package/dist/features/admin/components/AdminFaqsView.d.ts +4 -1
- package/dist/features/admin/components/AdminFaqsView.js +55 -23
- package/dist/features/admin/components/AdminFeatureFlagsView.js +33 -24
- package/dist/features/admin/components/AdminListingScaffold.d.ts +7 -1
- package/dist/features/admin/components/AdminListingScaffold.js +2 -2
- package/dist/features/admin/components/AdminMediaView.js +18 -8
- package/dist/features/admin/components/AdminNavEditorView.d.ts +20 -0
- package/dist/features/admin/components/AdminNavEditorView.js +84 -0
- package/dist/features/admin/components/AdminNavigationView.d.ts +1 -7
- package/dist/features/admin/components/AdminNavigationView.js +84 -72
- package/dist/features/admin/components/AdminNewsletterView.js +102 -20
- package/dist/features/admin/components/AdminNotificationsView.d.ts +4 -0
- package/dist/features/admin/components/AdminNotificationsView.js +119 -0
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +8 -0
- package/dist/features/admin/components/AdminOrderEditorView.js +74 -0
- package/dist/features/admin/components/AdminOrdersView.js +64 -8
- package/dist/features/admin/components/AdminPayoutsView.js +122 -13
- package/dist/features/admin/components/AdminProductEditorView.d.ts +7 -0
- package/dist/features/admin/components/AdminProductEditorView.js +143 -0
- package/dist/features/admin/components/AdminProductsView.d.ts +4 -1
- package/dist/features/admin/components/AdminProductsView.js +119 -30
- package/dist/features/admin/components/AdminReturnRequestsView.d.ts +5 -0
- package/dist/features/admin/components/AdminReturnRequestsView.js +101 -0
- package/dist/features/admin/components/AdminReviewsView.js +138 -28
- package/dist/features/admin/components/AdminSectionsView.js +361 -472
- package/dist/features/admin/components/AdminSessionsView.d.ts +4 -0
- package/dist/features/admin/components/AdminSessionsView.js +119 -0
- package/dist/features/admin/components/AdminSidebar.d.ts +18 -3
- package/dist/features/admin/components/AdminSidebar.js +51 -4
- package/dist/features/admin/components/AdminSiteSettingsView.d.ts +7 -0
- package/dist/features/admin/components/AdminSiteSettingsView.js +319 -0
- package/dist/features/admin/components/AdminStoreAddressesView.d.ts +5 -0
- package/dist/features/admin/components/AdminStoreAddressesView.js +52 -0
- package/dist/features/admin/components/AdminStoreEditorView.d.ts +9 -0
- package/dist/features/admin/components/AdminStoreEditorView.js +55 -0
- package/dist/features/admin/components/AdminStoresView.js +62 -20
- package/dist/features/admin/components/AdminUserEditorView.d.ts +10 -0
- package/dist/features/admin/components/AdminUserEditorView.js +72 -0
- package/dist/features/admin/components/AdminUsersView.js +70 -36
- package/dist/features/admin/components/AdminWishlistsView.d.ts +4 -0
- package/dist/features/admin/components/AdminWishlistsView.js +53 -0
- package/dist/features/admin/components/BrandQuickCreateForm.d.ts +5 -0
- package/dist/features/admin/components/BrandQuickCreateForm.js +36 -0
- package/dist/features/admin/components/CategoryQuickCreateForm.d.ts +5 -0
- package/dist/features/admin/components/CategoryQuickCreateForm.js +35 -0
- package/dist/features/admin/components/DataTable.d.ts +4 -2
- package/dist/features/admin/components/DataTable.js +26 -6
- package/dist/features/admin/components/index.d.ts +47 -1
- package/dist/features/admin/components/index.js +23 -0
- package/dist/features/admin/components/sections/adminSectionsBuildParse.d.ts +48 -0
- package/dist/features/admin/components/sections/adminSectionsBuildParse.js +653 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.d.ts +298 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +278 -0
- package/dist/features/admin/schemas/firestore.d.ts +26 -0
- package/dist/features/admin/schemas/firestore.js +1 -0
- package/dist/features/admin/types/product.types.d.ts +2 -3
- package/dist/features/auctions/actions/bid-actions.js +6 -2
- package/dist/features/auctions/components/AuctionDetailPageView.d.ts +3 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +38 -12
- package/dist/features/auctions/components/AuctionFilters.d.ts +3 -1
- package/dist/features/auctions/components/AuctionFilters.js +6 -2
- package/dist/features/auctions/components/CollapsibleBidHistory.d.ts +7 -0
- package/dist/features/auctions/components/CollapsibleBidHistory.js +8 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +4 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +43 -9
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +1 -0
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +18 -0
- package/dist/features/auctions/components/PlaceBidFormClient.js +33 -0
- package/dist/features/auctions/hooks/useAuctions.d.ts +1 -0
- package/dist/features/auctions/hooks/useAuctions.js +1 -0
- package/dist/features/auctions/schemas/index.d.ts +22 -12
- package/dist/features/auth/actions/profile-actions.d.ts +5 -3
- package/dist/features/auth/actions/profile-actions.js +30 -11
- package/dist/features/auth/auth-helpers.js +1 -0
- package/dist/features/auth/components/LoginForm.js +2 -1
- package/dist/features/auth/hooks/useAuth.js +16 -4
- package/dist/features/auth/permissions/constants.d.ts +63 -0
- package/dist/features/auth/permissions/constants.js +323 -0
- package/dist/features/auth/schemas/firestore.d.ts +20 -0
- package/dist/features/auth/schemas/index.d.ts +4 -4
- package/dist/features/auth/schemas/index.js +3 -2
- package/dist/features/auth/types/index.d.ts +1 -1
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +15 -15
- package/dist/features/blog/components/BlogFilters.js +1 -1
- package/dist/features/blog/components/BlogIndexListing.js +57 -5
- package/dist/features/blog/components/BlogIndexPageView.js +14 -2
- package/dist/features/blog/components/BlogPostForm.js +6 -2
- package/dist/features/blog/components/BlogPostView.js +2 -1
- package/dist/features/blog/hooks/useBlog.d.ts +2 -0
- package/dist/features/blog/hooks/useBlog.js +2 -0
- package/dist/features/blog/schemas/index.d.ts +46 -12
- package/dist/features/brands/actions/brand-actions.d.ts +2 -0
- package/dist/features/brands/actions/brand-actions.js +5 -0
- package/dist/features/brands/index.d.ts +3 -0
- package/dist/features/brands/index.js +3 -0
- package/dist/features/brands/repository/brands.repository.d.ts +13 -0
- package/dist/features/brands/repository/brands.repository.js +60 -0
- package/dist/features/brands/schemas/index.d.ts +33 -0
- package/dist/features/brands/schemas/index.js +15 -0
- package/dist/features/brands/server.d.ts +7 -0
- package/dist/features/brands/server.js +7 -0
- package/dist/features/cart/actions/cart-actions.js +2 -2
- package/dist/features/cart/components/CartDrawer.d.ts +5 -1
- package/dist/features/cart/components/CartDrawer.js +3 -3
- package/dist/features/cart/hooks/useCartCount.d.ts +3 -2
- package/dist/features/cart/hooks/useCartCount.js +4 -2
- package/dist/features/cart/hooks/useGuestCartMerge.js +1 -1
- package/dist/features/cart/index.d.ts +1 -0
- package/dist/features/cart/index.js +1 -0
- package/dist/features/cart/repository/cart.repository.d.ts +5 -1
- package/dist/features/cart/repository/cart.repository.js +36 -5
- package/dist/features/cart/schemas/firestore.d.ts +25 -6
- package/dist/features/cart/schemas/firestore.js +2 -2
- package/dist/features/cart/schemas/index.d.ts +9 -9
- package/dist/features/cart/schemas/index.js +1 -1
- package/dist/features/cart/types/index.d.ts +1 -1
- package/dist/features/cart/utils/pending-ops.d.ts +33 -0
- package/dist/features/cart/utils/pending-ops.js +102 -0
- package/dist/features/categories/components/BrandDetailPageView.d.ts +4 -0
- package/dist/features/categories/components/BrandDetailPageView.js +54 -0
- package/dist/features/categories/components/BrandDetailTabs.d.ts +10 -0
- package/dist/features/categories/components/BrandDetailTabs.js +22 -0
- package/dist/features/categories/components/CategoriesIndexListing.d.ts +3 -1
- package/dist/features/categories/components/CategoriesIndexListing.js +83 -7
- package/dist/features/categories/components/CategoryDetailPageView.js +42 -21
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +12 -7
- package/dist/features/categories/components/CategoryFilters.js +1 -1
- package/dist/features/categories/components/CategoryForm.js +10 -4
- package/dist/features/categories/components/CategoryProductsListing.d.ts +4 -1
- package/dist/features/categories/components/CategoryProductsListing.js +34 -5
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/hooks/useCategories.js +2 -0
- package/dist/features/categories/repository/categories.repository.js +2 -3
- package/dist/features/categories/schemas/firestore.d.ts +23 -2
- package/dist/features/categories/schemas/firestore.js +8 -0
- package/dist/features/categories/schemas/index.d.ts +8 -8
- package/dist/features/categories/types/index.d.ts +1 -0
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/events/components/AdminEventEditorView.js +2 -2
- package/dist/features/events/components/AdminEventsView.d.ts +4 -1
- package/dist/features/events/components/AdminEventsView.js +64 -38
- package/dist/features/events/components/EventCard.js +1 -1
- package/dist/features/events/components/EventFilters.js +1 -1
- package/dist/features/events/components/EventPollWidget.d.ts +12 -0
- package/dist/features/events/components/EventPollWidget.js +62 -0
- package/dist/features/events/components/EventsIndexListing.js +57 -5
- package/dist/features/events/components/EventsListPageView.js +1 -1
- 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.d.ts +1 -0
- package/dist/features/events/hooks/useEvents.js +1 -0
- package/dist/features/events/repository/events.repository.js +3 -0
- package/dist/features/events/schemas/firestore.d.ts +1 -0
- package/dist/features/events/schemas/index.d.ts +44 -0
- package/dist/features/events/types/index.d.ts +2 -0
- package/dist/features/faq/actions/faq-actions.d.ts +16 -16
- package/dist/features/faq/hooks/useFaqList.js +1 -1
- package/dist/features/faq/schemas/firestore.d.ts +2 -2
- package/dist/features/faq/schemas/firestore.js +2 -1
- package/dist/features/faq/schemas/index.d.ts +4 -4
- package/dist/features/filters/FilterFacetSection.d.ts +1 -0
- package/dist/features/filters/FilterFacetSection.js +13 -1
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/grouped/schemas/firestore.d.ts +32 -0
- package/dist/features/grouped/schemas/firestore.js +19 -0
- package/dist/features/homepage/components/AdSlot.d.ts +1 -3
- package/dist/features/homepage/components/AdSlot.js +15 -14
- package/dist/features/homepage/components/BlogArticlesSection.d.ts +3 -1
- package/dist/features/homepage/components/BlogArticlesSection.js +2 -2
- package/dist/features/homepage/components/BrandsSection.d.ts +3 -1
- package/dist/features/homepage/components/BrandsSection.js +4 -3
- package/dist/features/homepage/components/CustomCardsSection.d.ts +3 -0
- package/dist/features/homepage/components/CustomCardsSection.js +76 -0
- package/dist/features/homepage/components/EventsSection.d.ts +3 -1
- package/dist/features/homepage/components/EventsSection.js +2 -2
- package/dist/features/homepage/components/FeaturedAuctionsSection.d.ts +4 -1
- package/dist/features/homepage/components/FeaturedAuctionsSection.js +2 -2
- package/dist/features/homepage/components/FeaturedPreOrdersSection.d.ts +4 -1
- package/dist/features/homepage/components/FeaturedPreOrdersSection.js +2 -2
- package/dist/features/homepage/components/FeaturedProductsSection.d.ts +4 -1
- package/dist/features/homepage/components/FeaturedProductsSection.js +8 -3
- package/dist/features/homepage/components/FeaturedStoresSection.d.ts +3 -1
- package/dist/features/homepage/components/FeaturedStoresSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.d.ts +3 -0
- package/dist/features/homepage/components/GoogleReviewsSection.js +65 -0
- package/dist/features/homepage/components/HeroCarousel.js +128 -84
- package/dist/features/homepage/components/MarketplaceHomepageView.d.ts +2 -20
- package/dist/features/homepage/components/MarketplaceHomepageView.js +73 -230
- package/dist/features/homepage/components/SectionCarousel.d.ts +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +2 -0
- package/dist/features/homepage/components/ShopByCategorySection.d.ts +3 -1
- package/dist/features/homepage/components/ShopByCategorySection.js +8 -4
- package/dist/features/homepage/components/SocialFeedSection.d.ts +3 -0
- package/dist/features/homepage/components/SocialFeedSection.js +86 -0
- package/dist/features/homepage/components/SocialPostCard.d.ts +7 -0
- package/dist/features/homepage/components/SocialPostCard.js +39 -0
- package/dist/features/homepage/components/StatsCounterSection.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/hooks/useActiveAd.d.ts +23 -0
- package/dist/features/homepage/hooks/useActiveAd.js +20 -0
- package/dist/features/homepage/hooks/useBlogArticles.d.ts +1 -0
- package/dist/features/homepage/hooks/useBlogArticles.js +10 -0
- package/dist/features/homepage/hooks/useFeaturedAuctions.d.ts +4 -1
- package/dist/features/homepage/hooks/useFeaturedAuctions.js +8 -4
- package/dist/features/homepage/hooks/useFeaturedPreOrders.d.ts +4 -1
- package/dist/features/homepage/hooks/useFeaturedPreOrders.js +8 -4
- package/dist/features/homepage/hooks/useFeaturedProducts.d.ts +1 -0
- package/dist/features/homepage/hooks/useFeaturedProducts.js +6 -3
- package/dist/features/homepage/hooks/useFeaturedStores.d.ts +3 -1
- package/dist/features/homepage/hooks/useFeaturedStores.js +2 -1
- package/dist/features/homepage/hooks/useHomepageEvents.d.ts +3 -1
- package/dist/features/homepage/hooks/useHomepageEvents.js +2 -1
- package/dist/features/homepage/hooks/useTopBrands.d.ts +3 -1
- package/dist/features/homepage/hooks/useTopBrands.js +2 -1
- package/dist/features/homepage/index.d.ts +2 -0
- package/dist/features/homepage/index.js +1 -0
- package/dist/features/homepage/lib/google-reviews-fetcher.d.ts +14 -0
- package/dist/features/homepage/lib/google-reviews-fetcher.js +27 -0
- package/dist/features/homepage/lib/live-stats.d.ts +14 -0
- package/dist/features/homepage/lib/live-stats.js +62 -0
- package/dist/features/homepage/lib/section-defaults.d.ts +11 -0
- package/dist/features/homepage/lib/section-defaults.js +45 -0
- package/dist/features/homepage/lib/section-helpers.d.ts +5 -0
- package/dist/features/homepage/lib/section-helpers.js +25 -0
- package/dist/features/homepage/lib/section-renderer.d.ts +33 -0
- package/dist/features/homepage/lib/section-renderer.js +164 -0
- package/dist/features/homepage/lib/social-feed-fetcher.d.ts +5 -0
- package/dist/features/homepage/lib/social-feed-fetcher.js +193 -0
- package/dist/features/homepage/schemas/firestore.d.ts +180 -29
- package/dist/features/homepage/schemas/firestore.js +5 -0
- package/dist/features/homepage/types/index.d.ts +48 -19
- package/dist/features/layout/AppLayoutShell.d.ts +6 -1
- package/dist/features/layout/AppLayoutShell.js +25 -9
- package/dist/features/layout/BottomActions.js +1 -1
- package/dist/features/layout/BottomNavbar.d.ts +15 -1
- package/dist/features/layout/BottomNavbar.js +8 -2
- package/dist/features/layout/FooterLayout.d.ts +7 -1
- package/dist/features/layout/FooterLayout.js +3 -3
- package/dist/features/layout/ListingLayout.js +2 -2
- package/dist/features/layout/MainNavbar.d.ts +6 -14
- package/dist/features/layout/MainNavbar.js +4 -16
- package/dist/features/layout/NavItem.js +1 -1
- package/dist/features/layout/NavbarLayout.d.ts +3 -1
- package/dist/features/layout/NavbarLayout.js +5 -5
- package/dist/features/layout/TitleBar.d.ts +4 -2
- package/dist/features/layout/TitleBar.js +5 -3
- package/dist/features/layout/TitleBarLayout.d.ts +3 -1
- package/dist/features/layout/TitleBarLayout.js +2 -2
- package/dist/features/layout/index.d.ts +1 -1
- package/dist/features/media/MediaPickerModal.d.ts +30 -0
- package/dist/features/media/MediaPickerModal.js +72 -0
- package/dist/features/media/index.d.ts +3 -1
- package/dist/features/media/index.js +1 -0
- package/dist/features/media/types/index.d.ts +12 -0
- package/dist/features/media/types/index.js +4 -2
- package/dist/features/media/upload/MediaUploadField.d.ts +5 -1
- package/dist/features/media/upload/MediaUploadField.js +56 -3
- package/dist/features/messages/schemas/firestore.d.ts +36 -0
- package/dist/features/messages/schemas/firestore.js +16 -0
- package/dist/features/orders/repository/orders.repository.d.ts +2 -2
- package/dist/features/orders/repository/orders.repository.js +2 -2
- package/dist/features/orders/schemas/firestore.d.ts +17 -4
- package/dist/features/orders/schemas/firestore.js +2 -2
- package/dist/features/orders/schemas/index.d.ts +18 -18
- package/dist/features/orders/schemas/index.js +3 -3
- package/dist/features/orders/types/index.d.ts +1 -1
- package/dist/features/orders/utils/order-splitter.d.ts +1 -1
- package/dist/features/orders/utils/order-splitter.js +2 -2
- package/dist/features/payments/repository/payout.repository.d.ts +4 -4
- package/dist/features/payments/repository/payout.repository.js +7 -7
- package/dist/features/payments/schemas/firestore.d.ts +6 -6
- package/dist/features/payments/schemas/firestore.js +6 -6
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +11 -10
- package/dist/features/pre-orders/components/PreOrderActionsClient.d.ts +11 -0
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +28 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.d.ts +2 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +27 -9
- package/dist/features/pre-orders/components/PreOrderFilters.d.ts +3 -1
- package/dist/features/pre-orders/components/PreOrderFilters.js +9 -6
- package/dist/features/pre-orders/components/PreOrdersIndexListing.d.ts +3 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +132 -36
- package/dist/features/pre-orders/components/PreOrdersListView.js +3 -3
- package/dist/features/pre-orders/components/PreorderCard.js +1 -1
- package/dist/features/pre-orders/schemas/index.d.ts +10 -0
- package/dist/features/products/actions/product-actions.d.ts +2 -2
- package/dist/features/products/actions/product-actions.js +5 -5
- package/dist/features/products/api/[id]/route.js +5 -2
- package/dist/features/products/api/route.js +10 -14
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionDetailView.d.ts +2 -1
- package/dist/features/products/components/AuctionDetailView.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.d.ts +3 -1
- package/dist/features/products/components/AuctionsIndexListing.js +93 -31
- package/dist/features/products/components/BidHistory.d.ts +2 -1
- package/dist/features/products/components/BidHistory.js +18 -2
- package/dist/features/products/components/MakeOfferButton.d.ts +10 -0
- package/dist/features/products/components/MakeOfferButton.js +68 -0
- package/dist/features/products/components/ProductDetailPageView.d.ts +11 -1
- package/dist/features/products/components/ProductDetailPageView.js +27 -8
- package/dist/features/products/components/ProductFilters.d.ts +7 -1
- package/dist/features/products/components/ProductFilters.js +4 -2
- package/dist/features/products/components/ProductForm.d.ts +19 -1
- package/dist/features/products/components/ProductForm.js +24 -6
- package/dist/features/products/components/ProductGrid.d.ts +10 -2
- package/dist/features/products/components/ProductGrid.js +76 -29
- package/dist/features/products/components/ProductsIndexListing.js +131 -45
- package/dist/features/products/components/RelatedProductsCarousel.js +1 -1
- package/dist/features/products/components/ShareButton.d.ts +7 -0
- package/dist/features/products/components/ShareButton.js +22 -0
- package/dist/features/products/components/index.d.ts +2 -0
- package/dist/features/products/components/index.js +1 -0
- package/dist/features/products/hooks/useProducts.d.ts +7 -0
- package/dist/features/products/hooks/useProducts.js +6 -4
- package/dist/features/products/repository/products.repository.d.ts +4 -8
- package/dist/features/products/repository/products.repository.js +17 -50
- package/dist/features/products/schemas/firestore.d.ts +11 -9
- package/dist/features/products/schemas/firestore.js +11 -3
- package/dist/features/products/schemas/index.d.ts +51 -50
- package/dist/features/products/schemas/index.js +2 -5
- package/dist/features/products/types/index.d.ts +13 -5
- package/dist/features/promotions/actions/coupon-actions.d.ts +2 -2
- package/dist/features/promotions/actions/coupon-actions.js +1 -1
- package/dist/features/promotions/actions/seller-coupon-actions.js +11 -6
- package/dist/features/promotions/api/route.js +3 -3
- package/dist/features/promotions/components/CouponCard.js +16 -7
- package/dist/features/promotions/components/CouponsIndexListing.js +3 -9
- package/dist/features/promotions/hooks/useCouponValidate.d.ts +1 -1
- package/dist/features/promotions/hooks/usePromotions.js +2 -2
- package/dist/features/promotions/repository/coupons.repository.d.ts +21 -15
- package/dist/features/promotions/repository/coupons.repository.js +97 -125
- package/dist/features/promotions/schemas/firestore.d.ts +31 -2
- package/dist/features/promotions/schemas/firestore.js +29 -0
- package/dist/features/promotions/schemas/index.d.ts +9 -12
- package/dist/features/promotions/schemas/index.js +1 -2
- package/dist/features/promotions/types/index.d.ts +1 -2
- package/dist/features/reviews/actions/review-actions.js +3 -2
- package/dist/features/reviews/components/ReviewDetailPageView.js +5 -9
- package/dist/features/reviews/components/ReviewFilters.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +58 -7
- package/dist/features/reviews/components/ReviewsList.js +2 -2
- package/dist/features/reviews/hooks/useReviews.d.ts +1 -0
- package/dist/features/reviews/hooks/useReviews.js +2 -1
- package/dist/features/reviews/repository/reviews.repository.d.ts +9 -4
- package/dist/features/reviews/repository/reviews.repository.js +18 -7
- package/dist/features/reviews/schemas/firestore.d.ts +5 -2
- package/dist/features/reviews/schemas/firestore.js +1 -0
- package/dist/features/reviews/schemas/index.d.ts +19 -16
- package/dist/features/reviews/schemas/index.js +3 -2
- package/dist/features/reviews/types/index.d.ts +3 -2
- package/dist/features/scams/actions/scam-actions.d.ts +29 -0
- package/dist/features/scams/actions/scam-actions.js +62 -0
- package/dist/features/scams/components/ScamProfileView.d.ts +7 -0
- package/dist/features/scams/components/ScamProfileView.js +49 -0
- package/dist/features/scams/components/ScamRegistryView.d.ts +6 -0
- package/dist/features/scams/components/ScamRegistryView.js +41 -0
- package/dist/features/scams/components/index.d.ts +4 -0
- package/dist/features/scams/components/index.js +2 -0
- package/dist/features/scams/constants/scam-types.d.ts +38 -0
- package/dist/features/scams/constants/scam-types.js +443 -0
- package/dist/features/scams/repository/scammer.repository.d.ts +67 -0
- package/dist/features/scams/repository/scammer.repository.js +160 -0
- package/dist/features/scams/schemas/firestore.d.ts +362 -0
- package/dist/features/scams/schemas/firestore.js +233 -0
- package/dist/features/search/components/Search.d.ts +12 -2
- package/dist/features/search/components/Search.js +26 -7
- package/dist/features/search/components/index.d.ts +1 -1
- package/dist/features/search/hooks/useNavSuggestions.d.ts +1 -1
- package/dist/features/search/hooks/useNavSuggestions.js +2 -2
- package/dist/features/search/schemas/index.d.ts +7 -7
- package/dist/features/seller/actions/offer-actions.js +52 -36
- package/dist/features/seller/actions/seller-actions.js +19 -13
- package/dist/features/seller/api/products/route.js +9 -4
- package/dist/features/seller/components/SellerAddressesView.d.ts +3 -12
- package/dist/features/seller/components/SellerAddressesView.js +144 -4
- package/dist/features/seller/components/SellerAuctionsView.js +58 -5
- package/dist/features/seller/components/SellerBidsView.d.ts +4 -0
- package/dist/features/seller/components/SellerBidsView.js +131 -0
- package/dist/features/seller/components/SellerCouponEditorView.d.ts +19 -0
- package/dist/features/seller/components/SellerCouponEditorView.js +67 -0
- package/dist/features/seller/components/SellerCouponsView.d.ts +5 -3
- package/dist/features/seller/components/SellerCouponsView.js +135 -13
- package/dist/features/seller/components/SellerCreateProductView.d.ts +4 -10
- package/dist/features/seller/components/SellerCreateProductView.js +4 -3
- package/dist/features/seller/components/SellerEditProductView.d.ts +4 -10
- package/dist/features/seller/components/SellerEditProductView.js +4 -3
- package/dist/features/seller/components/SellerOffersPanel.d.ts +20 -0
- package/dist/features/seller/components/SellerOffersPanel.js +138 -0
- package/dist/features/seller/components/SellerOffersView.js +56 -5
- package/dist/features/seller/components/SellerOrdersView.d.ts +2 -1
- package/dist/features/seller/components/SellerOrdersView.js +185 -16
- package/dist/features/seller/components/SellerPayoutRequestView.d.ts +7 -0
- package/dist/features/seller/components/SellerPayoutRequestView.js +63 -0
- package/dist/features/seller/components/SellerPayoutSettingsView.d.ts +3 -10
- package/dist/features/seller/components/SellerPayoutSettingsView.js +89 -3
- package/dist/features/seller/components/SellerPayoutsView.js +56 -5
- package/dist/features/seller/components/SellerProductShell.d.ts +68 -0
- package/dist/features/seller/components/SellerProductShell.js +179 -0
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -3
- package/dist/features/seller/components/SellerProductsView.js +194 -18
- package/dist/features/seller/components/SellerReviewsView.d.ts +5 -0
- package/dist/features/seller/components/SellerReviewsView.js +100 -0
- package/dist/features/seller/components/SellerShippingView.d.ts +3 -11
- package/dist/features/seller/components/SellerShippingView.js +87 -3
- package/dist/features/seller/components/SellerSidebar.d.ts +11 -3
- package/dist/features/seller/components/SellerSidebar.js +52 -8
- package/dist/features/seller/components/SellerStorefrontView.d.ts +26 -11
- package/dist/features/seller/components/SellerStorefrontView.js +45 -7
- package/dist/features/seller/components/index.d.ts +16 -2
- package/dist/features/seller/components/index.js +7 -0
- package/dist/features/seller/hooks/useSellerListingData.d.ts +3 -1
- package/dist/features/seller/hooks/useSellerListingData.js +6 -4
- package/dist/features/seller/repository/offer.repository.d.ts +3 -3
- package/dist/features/seller/repository/offer.repository.js +6 -6
- package/dist/features/seller/schemas/firestore.d.ts +7 -7
- package/dist/features/seller/schemas/firestore.js +4 -4
- package/dist/features/seller/schemas/index.d.ts +16 -16
- package/dist/features/shell/FormShell.d.ts +29 -0
- package/dist/features/shell/FormShell.js +103 -0
- package/dist/features/shell/QuickFormDrawer.d.ts +29 -0
- package/dist/features/shell/QuickFormDrawer.js +117 -0
- package/dist/features/shell/StepForm.d.ts +44 -0
- package/dist/features/shell/StepForm.js +81 -0
- package/dist/features/shell/index.d.ts +6 -0
- package/dist/features/shell/index.js +3 -0
- package/dist/features/stores/actions/store-query-actions.js +3 -3
- package/dist/features/stores/api/[storeSlug]/auctions/route.js +1 -1
- package/dist/features/stores/api/[storeSlug]/products/route.js +1 -1
- package/dist/features/stores/api/[storeSlug]/reviews/route.js +1 -1
- package/dist/features/stores/components/InteractiveStoreCard.d.ts +2 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +21 -7
- package/dist/features/stores/components/StoreAboutView.js +1 -1
- package/dist/features/stores/components/StoreAuctionsListing.d.ts +5 -2
- package/dist/features/stores/components/StoreAuctionsListing.js +81 -8
- package/dist/features/stores/components/StoreAuctionsPageView.js +8 -7
- package/dist/features/stores/components/StoreDetailLayoutView.d.ts +1 -0
- package/dist/features/stores/components/StoreDetailLayoutView.js +29 -5
- package/dist/features/stores/components/StoreHeader.js +2 -1
- package/dist/features/stores/components/StorePreOrdersListing.d.ts +4 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +59 -7
- package/dist/features/stores/components/StorePreOrdersPageView.js +8 -7
- package/dist/features/stores/components/StoreProductsListing.d.ts +5 -2
- package/dist/features/stores/components/StoreProductsListing.js +97 -8
- package/dist/features/stores/components/StoreProductsPageView.js +8 -7
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +74 -11
- package/dist/features/stores/components/StoresListView.js +1 -1
- package/dist/features/stores/hooks/useStores.d.ts +1 -0
- package/dist/features/stores/hooks/useStores.js +1 -0
- package/dist/features/stores/schemas/firestore.d.ts +34 -0
- package/dist/features/stores/schemas/index.d.ts +8 -8
- package/dist/features/sublisting/schemas/firestore.d.ts +30 -0
- package/dist/features/sublisting/schemas/firestore.js +19 -0
- package/dist/features/support/schemas/firestore.d.ts +113 -0
- package/dist/features/support/schemas/firestore.js +95 -0
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +5 -0
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +143 -0
- package/dist/features/whatsapp-bot/components/index.d.ts +2 -0
- package/dist/features/whatsapp-bot/components/index.js +1 -0
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +23 -1
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +104 -0
- package/dist/features/whatsapp-bot/server.d.ts +1 -0
- package/dist/features/whatsapp-bot/server.js +1 -0
- package/dist/features/whatsapp-bot/types/index.d.ts +49 -0
- package/dist/features/wishlist/components/WishlistView.d.ts +0 -10
- package/dist/features/wishlist/components/WishlistView.js +13 -6
- package/dist/features/wishlist/hooks/useWishlist.js +2 -0
- package/dist/features/wishlist/hooks/useWishlistCount.d.ts +11 -3
- package/dist/features/wishlist/hooks/useWishlistCount.js +89 -25
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/features/wishlist/schemas/index.d.ts +2 -2
- package/dist/features/wishlist/types/index.d.ts +16 -0
- package/dist/http/api-handler.js +8 -1
- package/dist/index.d.ts +112 -16
- package/dist/index.js +133 -28
- package/dist/monitoring/server-logger.js +9 -3
- package/dist/next/routing/route-map.d.ts +120 -6
- package/dist/next/routing/route-map.js +53 -2
- package/dist/providers/db-firebase/realtime.d.ts +1 -1
- package/dist/react/contexts/SessionContext.js +17 -26
- package/dist/react/hooks/useBulkSelection.d.ts +7 -24
- package/dist/react/hooks/useBulkSelection.js +27 -34
- package/dist/react/hooks/useLongPress.d.ts +3 -16
- package/dist/react/hooks/useLongPress.js +6 -25
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +2 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.js +2 -0
- package/dist/seed/actions/demo-seed-actions.d.ts +2 -2
- package/dist/seed/actions/demo-seed-actions.js +1 -1
- package/dist/seed/anime-figures-seed-data.d.ts +8 -0
- package/dist/seed/anime-figures-seed-data.js +1033 -0
- package/dist/seed/beyblade-seed-data.js +206 -24
- package/dist/seed/bids-seed-data.d.ts +4 -10
- package/dist/seed/bids-seed-data.js +365 -238
- package/dist/seed/blog-posts-seed-data.d.ts +3 -2
- package/dist/seed/blog-posts-seed-data.js +250 -511
- package/dist/seed/brands-seed-data.d.ts +7 -0
- package/dist/seed/brands-seed-data.js +410 -0
- package/dist/seed/carousel-slides-seed-data.d.ts +3 -2
- package/dist/seed/carousel-slides-seed-data.js +177 -216
- package/dist/seed/cart-seed-data.d.ts +9 -9
- package/dist/seed/cart-seed-data.js +73 -73
- package/dist/seed/categories-seed-data.d.ts +4 -2
- package/dist/seed/categories-seed-data.js +720 -879
- package/dist/seed/conversations-seed-data.d.ts +8 -0
- package/dist/seed/conversations-seed-data.js +388 -0
- package/dist/seed/cosplay-accessories-seed-data.d.ts +8 -0
- package/dist/seed/cosplay-accessories-seed-data.js +647 -0
- package/dist/seed/coupon-usage-seed-data.d.ts +25 -0
- package/dist/seed/coupon-usage-seed-data.js +69 -0
- package/dist/seed/coupons-seed-data.d.ts +6 -3
- package/dist/seed/coupons-seed-data.js +375 -3
- package/dist/seed/events-seed-data.d.ts +4 -2
- package/dist/seed/events-seed-data.js +128 -430
- package/dist/seed/factories/cart.factory.d.ts +0 -1
- package/dist/seed/factories/cart.factory.js +2 -2
- package/dist/seed/faq-seed-data.d.ts +11 -18
- package/dist/seed/faq-seed-data.js +786 -1817
- package/dist/seed/grouped-listings-seed-data.d.ts +8 -0
- package/dist/seed/grouped-listings-seed-data.js +201 -0
- package/dist/seed/homepage-sections-seed-data.d.ts +3 -13
- package/dist/seed/homepage-sections-seed-data.js +228 -252
- package/dist/seed/hot-wheels-seed-data.js +285 -38
- package/dist/seed/index.d.ts +12 -11
- package/dist/seed/index.js +10 -12
- package/dist/seed/letitrip-official-seed-data.d.ts +8 -0
- package/dist/seed/letitrip-official-seed-data.js +399 -0
- package/dist/seed/manifest.d.ts +15 -0
- package/dist/seed/manifest.js +140 -0
- package/dist/seed/notifications-seed-data.d.ts +4 -2
- package/dist/seed/notifications-seed-data.js +117 -440
- package/dist/seed/orders-seed-data.d.ts +4 -2
- package/dist/seed/orders-seed-data.js +1090 -521
- package/dist/seed/payouts-seed-data.d.ts +4 -2
- package/dist/seed/payouts-seed-data.js +522 -145
- package/dist/seed/pokemon-carousel-slides-seed-data.js +6 -1
- package/dist/seed/pokemon-categories-seed-data.js +81 -81
- package/dist/seed/pokemon-homepage-sections-seed-data.d.ts +1 -1
- package/dist/seed/pokemon-homepage-sections-seed-data.js +116 -23
- package/dist/seed/pokemon-products-seed-data.d.ts +1 -1
- package/dist/seed/pokemon-products-seed-data.js +83 -73
- package/dist/seed/pokemon-seed-bundle.d.ts +5 -1
- package/dist/seed/pokemon-seed-bundle.js +21 -2
- package/dist/seed/pokemon-stores-seed-data.js +85 -9
- package/dist/seed/pokemon-users-seed-data.js +107 -8
- package/dist/seed/products-auctions-seed-data.d.ts +10 -0
- package/dist/seed/products-auctions-seed-data.js +689 -0
- package/dist/seed/products-preorders-seed-data.d.ts +9 -0
- package/dist/seed/products-preorders-seed-data.js +483 -0
- package/dist/seed/products-seed-data.js +34 -13
- package/dist/seed/products-standard-seed-data.d.ts +8 -0
- package/dist/seed/products-standard-seed-data.js +4179 -0
- package/dist/seed/retro-gaming-seed-data.d.ts +8 -0
- package/dist/seed/retro-gaming-seed-data.js +801 -0
- package/dist/seed/reviews-seed-data.d.ts +4 -17
- package/dist/seed/reviews-seed-data.js +1043 -515
- package/dist/seed/scammers-seed-data.d.ts +17 -0
- package/dist/seed/scammers-seed-data.js +118 -0
- package/dist/seed/site-settings-seed-data.js +25 -2
- package/dist/seed/store-addresses-seed-data.js +188 -84
- package/dist/seed/stores-seed-data.d.ts +3 -9
- package/dist/seed/stores-seed-data.js +212 -102
- package/dist/seed/sublisting-categories-seed-data.d.ts +7 -0
- package/dist/seed/sublisting-categories-seed-data.js +315 -0
- package/dist/seed/transformers-seed-data.js +34 -14
- package/dist/seed/users-seed-data.d.ts +3 -2
- package/dist/seed/users-seed-data.js +531 -440
- package/dist/seed/wishlists-seed-data.js +13 -13
- package/dist/server.d.ts +9 -2
- package/dist/server.js +12 -4
- package/dist/tokens/tokens.css +76 -31
- package/dist/ui/components/Avatar.style.css +10 -12
- package/dist/ui/components/BaseListingCard.d.ts +8 -3
- package/dist/ui/components/BaseListingCard.js +17 -6
- package/dist/ui/components/BaseListingCard.style.css +3 -1
- package/dist/ui/components/BulkActionsBar.d.ts +16 -0
- package/dist/ui/components/BulkActionsBar.js +22 -0
- package/dist/ui/components/Button.style.css +23 -23
- package/dist/ui/components/Card.style.css +60 -62
- package/dist/ui/components/Checkbox.style.css +19 -21
- package/dist/ui/components/DashboardStatsCard.style.css +12 -14
- package/dist/ui/components/Drawer.style.css +18 -14
- package/dist/ui/components/Dropdown.style.css +25 -27
- package/dist/ui/components/EmptyState.style.css +2 -4
- package/dist/ui/components/HorizontalScroller.d.ts +3 -1
- package/dist/ui/components/HorizontalScroller.js +116 -21
- package/dist/ui/components/HorizontalScroller.style.css +2 -2
- package/dist/ui/components/ImageLightbox.d.ts +0 -9
- package/dist/ui/components/ImageLightbox.js +43 -9
- package/dist/ui/components/InlineCreateSelect.d.ts +38 -0
- package/dist/ui/components/InlineCreateSelect.js +70 -0
- package/dist/ui/components/ListingLayout.style.css +41 -77
- package/dist/ui/components/ListingToolbar.d.ts +54 -0
- package/dist/ui/components/ListingToolbar.js +34 -0
- package/dist/ui/components/Modal.style.css +14 -10
- package/dist/ui/components/PageLoader.d.ts +11 -0
- package/dist/ui/components/PageLoader.js +21 -0
- package/dist/ui/components/Radio.style.css +34 -36
- package/dist/ui/components/RichTextEditor.js +1 -1
- package/dist/ui/components/RowActionMenu.d.ts +1 -0
- package/dist/ui/components/RowActionMenu.js +4 -2
- package/dist/ui/components/SectionTabs.js +1 -1
- package/dist/ui/components/SectionTabs.style.css +1 -0
- package/dist/ui/components/SideModal.style.css +4 -8
- package/dist/ui/components/Slider.style.css +2 -4
- package/dist/ui/components/Tabs.style.css +8 -10
- package/dist/ui/components/Toast.style.css +22 -24
- package/dist/ui/components/Toggle.style.css +11 -13
- package/dist/ui/index.d.ts +9 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/rich-text/RichText.js +2 -1
- package/dist/ui/rich-text/RichText.style.css +292 -5
- package/dist/ui/rich-text/RichTextRenderer.d.ts +15 -0
- package/dist/ui/rich-text/RichTextRenderer.js +15 -0
- package/dist/utils/id-generators.d.ts +10 -0
- package/dist/utils/id-generators.js +12 -0
- package/dist/validation/schemas.d.ts +9 -9
- package/package.json +5 -1
- package/README.md +0 -116
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scam Registry Firestore Document Types & Constants
|
|
3
|
+
*
|
|
4
|
+
* Data model:
|
|
5
|
+
* scammerProfiles/{id} — canonical scammer identity (one per person)
|
|
6
|
+
* scammerProfiles/{id}/incidents/{id} — individual victim reports linked to this profile
|
|
7
|
+
* scammerProfiles/{id}/comments/{id} — public discussion; accused can post here
|
|
8
|
+
* scammerProfiles/{id}/contests/{id} — dispute submissions (accused or any user)
|
|
9
|
+
*
|
|
10
|
+
* SEO design intent: phones, UPI IDs, and emails are stored as plaintext and
|
|
11
|
+
* rendered as HTML text nodes so search engines index them. When a victim googles
|
|
12
|
+
* the number/UPI they received, this page must surface.
|
|
13
|
+
*
|
|
14
|
+
* Submission rules (enforced server-side):
|
|
15
|
+
* - Requires authentication (no guest submissions)
|
|
16
|
+
* - Requires scamAwarenessAcknowledgedAt on UserDocument
|
|
17
|
+
* - No submission if user has report_scammers soft ban
|
|
18
|
+
* - Max 5 pending submissions per user (prevents spam flooding)
|
|
19
|
+
* - All submissions start as "pending_review" — admin must verify before public display
|
|
20
|
+
*
|
|
21
|
+
* Suggestion matching (duplicate detection):
|
|
22
|
+
* - On new report submission, API queries existing profiles for overlapping
|
|
23
|
+
* phones[], upiIds[], emails[], displayNames[]
|
|
24
|
+
* - If matches found → suggest linking to existing profile (new incident) instead of new profile
|
|
25
|
+
* - SCAMMER_MATCH_FIELDS lists the Firestore array-contains fields used for this query
|
|
26
|
+
*/
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// ENUMS — SCAMMER PROFILE
|
|
29
|
+
// ============================================================================
|
|
30
|
+
export const ScammerStatusValues = {
|
|
31
|
+
PENDING_REVIEW: "pending_review",
|
|
32
|
+
VERIFIED: "verified",
|
|
33
|
+
REJECTED: "rejected",
|
|
34
|
+
REMOVED: "removed",
|
|
35
|
+
};
|
|
36
|
+
export const ScamPlatformValues = {
|
|
37
|
+
WHATSAPP: "whatsapp",
|
|
38
|
+
INSTAGRAM: "instagram",
|
|
39
|
+
FACEBOOK: "facebook",
|
|
40
|
+
TELEGRAM: "telegram",
|
|
41
|
+
TWITTER: "twitter",
|
|
42
|
+
OLX: "olx",
|
|
43
|
+
FACEBOOK_MARKETPLACE: "facebook_marketplace",
|
|
44
|
+
LETITRIP: "letitrip",
|
|
45
|
+
IN_PERSON: "in_person",
|
|
46
|
+
PHONE_CALL: "phone_call",
|
|
47
|
+
OTHER: "other",
|
|
48
|
+
};
|
|
49
|
+
export const SocialPlatformValues = {
|
|
50
|
+
INSTAGRAM: "instagram",
|
|
51
|
+
FACEBOOK: "facebook",
|
|
52
|
+
TWITTER: "twitter",
|
|
53
|
+
YOUTUBE: "youtube",
|
|
54
|
+
TELEGRAM: "telegram",
|
|
55
|
+
WHATSAPP: "whatsapp",
|
|
56
|
+
LINKEDIN: "linkedin",
|
|
57
|
+
OLX: "olx",
|
|
58
|
+
OTHER: "other",
|
|
59
|
+
};
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// ENUMS — CONTESTS
|
|
62
|
+
// ============================================================================
|
|
63
|
+
export const ContestTypeValues = {
|
|
64
|
+
/** The named person claims they never scammed anyone. */
|
|
65
|
+
ACCUSED_CONTESTING: "accused_contesting",
|
|
66
|
+
/** Any user flags the entire report as fabricated. */
|
|
67
|
+
FALSE_REPORT: "false_report",
|
|
68
|
+
/** A detail is wrong (wrong phone, wrong name) but the scam is real. */
|
|
69
|
+
INACCURATE_DETAILS: "inaccurate_details",
|
|
70
|
+
/** The name/alias matches but it's a different person entirely. */
|
|
71
|
+
IDENTITY_MISTAKEN: "identity_mistaken",
|
|
72
|
+
};
|
|
73
|
+
export const ContestStatusValues = {
|
|
74
|
+
PENDING: "pending",
|
|
75
|
+
/** Contest accepted — profile edited or removed. */
|
|
76
|
+
UPHELD: "upheld",
|
|
77
|
+
/** Contest rejected — report stands as verified. */
|
|
78
|
+
DISMISSED: "dismissed",
|
|
79
|
+
};
|
|
80
|
+
export const SCAMMER_INCIDENTS_SUBCOLLECTION = "incidents";
|
|
81
|
+
export const DEFAULT_SCAMMER_INCIDENT_DATA = {
|
|
82
|
+
status: "pending_review",
|
|
83
|
+
evidence: [],
|
|
84
|
+
reportedByAnon: false,
|
|
85
|
+
};
|
|
86
|
+
export const SCAMMER_COMMENTS_SUBCOLLECTION = "comments";
|
|
87
|
+
export const DEFAULT_SCAMMER_COMMENT_DATA = {
|
|
88
|
+
upvotes: 0,
|
|
89
|
+
isHidden: false,
|
|
90
|
+
isAccused: false,
|
|
91
|
+
isAccusedVerified: false,
|
|
92
|
+
isVerifiedVictim: false,
|
|
93
|
+
};
|
|
94
|
+
/** Max comment length enforced at API level. */
|
|
95
|
+
export const MAX_COMMENT_BODY_LENGTH = 500;
|
|
96
|
+
export const SCAMMER_CONTESTS_SUBCOLLECTION = "contests";
|
|
97
|
+
export const DEFAULT_SCAMMER_CONTEST_DATA = {
|
|
98
|
+
status: "pending",
|
|
99
|
+
evidence: [],
|
|
100
|
+
contestedByAnon: false,
|
|
101
|
+
};
|
|
102
|
+
export const CONTEST_TYPE_LABELS = {
|
|
103
|
+
accused_contesting: "I am falsely accused",
|
|
104
|
+
false_report: "This report is fabricated",
|
|
105
|
+
inaccurate_details: "Some details are wrong",
|
|
106
|
+
identity_mistaken: "Wrong person — same name/number",
|
|
107
|
+
};
|
|
108
|
+
export const CONTEST_STATUS_LABELS = {
|
|
109
|
+
pending: "Pending Review",
|
|
110
|
+
upheld: "Upheld — Profile Updated",
|
|
111
|
+
dismissed: "Dismissed — Report Stands",
|
|
112
|
+
};
|
|
113
|
+
// ============================================================================
|
|
114
|
+
// SUGGESTION MATCHING
|
|
115
|
+
// ============================================================================
|
|
116
|
+
/**
|
|
117
|
+
* Fields used to detect duplicate scammer profiles when a new report is submitted.
|
|
118
|
+
* API queries array-contains on each of these fields against the new report's values.
|
|
119
|
+
* Results are returned as "suggested existing profiles" for the reporter to confirm.
|
|
120
|
+
*
|
|
121
|
+
* Priority order: phones > upiIds > emails > displayNames
|
|
122
|
+
* A match on phones or upiIds is considered a strong match (likely same person).
|
|
123
|
+
* A match on displayNames only is a weak match (shown as "possibly same person").
|
|
124
|
+
*/
|
|
125
|
+
export const SCAMMER_MATCH_FIELDS = [
|
|
126
|
+
"phones",
|
|
127
|
+
"upiIds",
|
|
128
|
+
"emails",
|
|
129
|
+
"displayNames",
|
|
130
|
+
];
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// PRIMARY COLLECTION CONSTANTS
|
|
133
|
+
// ============================================================================
|
|
134
|
+
export const SCAMMER_COLLECTION = "scammerProfiles";
|
|
135
|
+
export const SCAMMER_ID_PREFIX = "scammer-";
|
|
136
|
+
export const SCAMMER_INDEXED_FIELDS = [
|
|
137
|
+
"status",
|
|
138
|
+
"scamType",
|
|
139
|
+
"scamPlatform",
|
|
140
|
+
"reportedBy",
|
|
141
|
+
"verifiedBy",
|
|
142
|
+
"isContested",
|
|
143
|
+
"views",
|
|
144
|
+
"incidentCount",
|
|
145
|
+
"createdAt",
|
|
146
|
+
"updatedAt",
|
|
147
|
+
];
|
|
148
|
+
export const DEFAULT_SCAMMER_DATA = {
|
|
149
|
+
status: "pending_review",
|
|
150
|
+
phones: [],
|
|
151
|
+
upiIds: [],
|
|
152
|
+
emails: [],
|
|
153
|
+
socialMedia: [],
|
|
154
|
+
evidence: [],
|
|
155
|
+
relatedScammerIds: [],
|
|
156
|
+
mergedFromIds: [],
|
|
157
|
+
tags: [],
|
|
158
|
+
views: 0,
|
|
159
|
+
incidentCount: 0,
|
|
160
|
+
commentCount: 0,
|
|
161
|
+
contestCount: 0,
|
|
162
|
+
isContested: false,
|
|
163
|
+
reportedByAnon: false,
|
|
164
|
+
};
|
|
165
|
+
/** Max pending submissions per user — prevents spam flooding. */
|
|
166
|
+
export const MAX_PENDING_SCAMMER_REPORTS_PER_USER = 5;
|
|
167
|
+
// ============================================================================
|
|
168
|
+
// FIELD CONSTANTS
|
|
169
|
+
// ============================================================================
|
|
170
|
+
export const SCAMMER_FIELDS = {
|
|
171
|
+
ID: "id",
|
|
172
|
+
SEO_SLUG: "seoSlug",
|
|
173
|
+
DISPLAY_NAMES: "displayNames",
|
|
174
|
+
PHONES: "phones",
|
|
175
|
+
UPI_IDS: "upiIds",
|
|
176
|
+
EMAILS: "emails",
|
|
177
|
+
SOCIAL_MEDIA: "socialMedia",
|
|
178
|
+
SCAM_TYPE: "scamType",
|
|
179
|
+
SCAM_PLATFORM: "scamPlatform",
|
|
180
|
+
DESCRIPTION: "description",
|
|
181
|
+
AMOUNT_LOST: "amountLost",
|
|
182
|
+
ITEM_INVOLVED: "itemInvolved",
|
|
183
|
+
EVIDENCE: "evidence",
|
|
184
|
+
REPORTED_BY: "reportedBy",
|
|
185
|
+
REPORTED_BY_ANON: "reportedByAnon",
|
|
186
|
+
STATUS: "status",
|
|
187
|
+
VERIFIED_BY: "verifiedBy",
|
|
188
|
+
VERIFIED_AT: "verifiedAt",
|
|
189
|
+
VERIFICATION_NOTE: "verificationNote",
|
|
190
|
+
RELATED_SCAMMER_IDS: "relatedScammerIds",
|
|
191
|
+
MERGED_FROM_IDS: "mergedFromIds",
|
|
192
|
+
TAGS: "tags",
|
|
193
|
+
VIEWS: "views",
|
|
194
|
+
INCIDENT_COUNT: "incidentCount",
|
|
195
|
+
COMMENT_COUNT: "commentCount",
|
|
196
|
+
CONTEST_COUNT: "contestCount",
|
|
197
|
+
IS_CONTESTED: "isContested",
|
|
198
|
+
CREATED_AT: "createdAt",
|
|
199
|
+
UPDATED_AT: "updatedAt",
|
|
200
|
+
};
|
|
201
|
+
// ============================================================================
|
|
202
|
+
// LABEL MAPS
|
|
203
|
+
// ============================================================================
|
|
204
|
+
export const SCAM_PLATFORM_LABELS = {
|
|
205
|
+
whatsapp: "WhatsApp",
|
|
206
|
+
instagram: "Instagram",
|
|
207
|
+
facebook: "Facebook",
|
|
208
|
+
telegram: "Telegram",
|
|
209
|
+
twitter: "X (Twitter)",
|
|
210
|
+
olx: "OLX",
|
|
211
|
+
facebook_marketplace: "Facebook Marketplace",
|
|
212
|
+
letitrip: "LetItRip",
|
|
213
|
+
in_person: "In Person",
|
|
214
|
+
phone_call: "Phone Call",
|
|
215
|
+
other: "Other",
|
|
216
|
+
};
|
|
217
|
+
export const SOCIAL_PLATFORM_LABELS = {
|
|
218
|
+
instagram: "Instagram",
|
|
219
|
+
facebook: "Facebook",
|
|
220
|
+
twitter: "X (Twitter)",
|
|
221
|
+
youtube: "YouTube",
|
|
222
|
+
telegram: "Telegram",
|
|
223
|
+
whatsapp: "WhatsApp",
|
|
224
|
+
linkedin: "LinkedIn",
|
|
225
|
+
olx: "OLX",
|
|
226
|
+
other: "Other",
|
|
227
|
+
};
|
|
228
|
+
export const SCAMMER_STATUS_LABELS = {
|
|
229
|
+
pending_review: "Pending Review",
|
|
230
|
+
verified: "Verified",
|
|
231
|
+
rejected: "Rejected",
|
|
232
|
+
removed: "Removed",
|
|
233
|
+
};
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { LucideIcon } from "lucide-react";
|
|
2
2
|
import type { NavSuggestionRecord } from "../hooks/useNavSuggestions";
|
|
3
|
+
export type SearchResourceType = "products" | "auctions" | "pre-orders" | "stores" | "categories" | "brands" | "events" | "blog" | "faqs";
|
|
4
|
+
export interface SearchResourceTypeOption {
|
|
5
|
+
value: SearchResourceType;
|
|
6
|
+
label: string;
|
|
7
|
+
shortLabel?: string;
|
|
8
|
+
}
|
|
3
9
|
export interface SearchQuickLink {
|
|
4
10
|
href: string;
|
|
5
11
|
label: string;
|
|
@@ -18,11 +24,12 @@ export interface SearchLabels {
|
|
|
18
24
|
clearAriaLabel: string;
|
|
19
25
|
ariaLabel: string;
|
|
20
26
|
browseProducts: (query: string) => string;
|
|
27
|
+
resourceTypeLabel?: string;
|
|
21
28
|
}
|
|
22
29
|
export interface SearchProps {
|
|
23
30
|
isOpen?: boolean;
|
|
24
31
|
onClose?: () => void;
|
|
25
|
-
onSearch?: (query: string) => void;
|
|
32
|
+
onSearch?: (query: string, type: SearchResourceType) => void;
|
|
26
33
|
onOpen?: () => void;
|
|
27
34
|
value?: string;
|
|
28
35
|
onChange?: (value: string) => void;
|
|
@@ -36,5 +43,8 @@ export interface SearchProps {
|
|
|
36
43
|
labels: SearchLabels;
|
|
37
44
|
suggestionTypeIcons?: Partial<Record<NavSuggestionRecord["type"], string>>;
|
|
38
45
|
suggestionTypeBadges?: Partial<Record<NavSuggestionRecord["type"], string>>;
|
|
46
|
+
resourceTypes?: SearchResourceTypeOption[];
|
|
47
|
+
defaultResourceType?: SearchResourceType;
|
|
48
|
+
storageKey?: string;
|
|
39
49
|
}
|
|
40
|
-
export declare function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, placeholder, deferred, debounceMs, onClear, className, router, quickLinks, labels, suggestionTypeIcons, suggestionTypeBadges, }: SearchProps): import("react/jsx-runtime").JSX.Element | null;
|
|
50
|
+
export declare function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, placeholder, deferred, debounceMs, onClear, className, router, quickLinks, labels, suggestionTypeIcons, suggestionTypeBadges, resourceTypes, defaultResourceType, storageKey, }: SearchProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { Button, Input, Li, Row, Span, Text, Ul } from "../../../ui";
|
|
5
5
|
import { useNavSuggestions } from "../hooks/useNavSuggestions";
|
|
6
6
|
const DEFAULT_TYPE_ICONS = {
|
|
@@ -15,17 +15,31 @@ const DEFAULT_TYPE_BADGES = {
|
|
|
15
15
|
blog: "bg-fuchsia-100 text-fuchsia-600 dark:bg-fuchsia-900/40 dark:text-fuchsia-300",
|
|
16
16
|
event: "bg-amber-100 text-amber-600 dark:bg-amber-900/40 dark:text-amber-300",
|
|
17
17
|
};
|
|
18
|
-
export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, placeholder, deferred = true, debounceMs = 300, onClear, className, router, quickLinks = [], labels, suggestionTypeIcons, suggestionTypeBadges, }) {
|
|
18
|
+
export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, placeholder, deferred = true, debounceMs = 300, onClear, className, router, quickLinks = [], labels, suggestionTypeIcons, suggestionTypeBadges, resourceTypes, defaultResourceType = "products", storageKey = "letitrip_search_type", }) {
|
|
19
19
|
const isInlineMode = value !== undefined;
|
|
20
20
|
const [query, setQuery] = useState(isInlineMode ? value : "");
|
|
21
21
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
22
22
|
const [isInlineOpen, setIsInlineOpen] = useState(false);
|
|
23
|
+
const [selectedType, setSelectedType] = useState(defaultResourceType);
|
|
23
24
|
const inputRef = useRef(null);
|
|
24
25
|
const debounceRef = useRef(null);
|
|
25
26
|
const inlineBlurRef = useRef(null);
|
|
26
|
-
const { suggestions, isLoading: suggestionsLoading } = useNavSuggestions(query);
|
|
27
|
+
const { suggestions, isLoading: suggestionsLoading } = useNavSuggestions(query, selectedType);
|
|
27
28
|
const typeIcons = { ...DEFAULT_TYPE_ICONS, ...suggestionTypeIcons };
|
|
28
29
|
const typeBadges = { ...DEFAULT_TYPE_BADGES, ...suggestionTypeBadges };
|
|
30
|
+
// Restore persisted type from localStorage after mount
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (!resourceTypes?.length)
|
|
33
|
+
return;
|
|
34
|
+
const stored = localStorage.getItem(storageKey);
|
|
35
|
+
if (stored && resourceTypes.some((t) => t.value === stored)) {
|
|
36
|
+
setSelectedType(stored);
|
|
37
|
+
}
|
|
38
|
+
}, [storageKey, resourceTypes]);
|
|
39
|
+
const handleTypeChange = useCallback((type) => {
|
|
40
|
+
setSelectedType(type);
|
|
41
|
+
localStorage.setItem(storageKey, type);
|
|
42
|
+
}, [storageKey]);
|
|
29
43
|
useEffect(() => {
|
|
30
44
|
if (isInlineMode || !onOpen)
|
|
31
45
|
return;
|
|
@@ -71,7 +85,12 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
|
|
|
71
85
|
}
|
|
72
86
|
};
|
|
73
87
|
const handleDeferredSubmit = () => {
|
|
74
|
-
|
|
88
|
+
if (onSearch) {
|
|
89
|
+
onSearch(query, selectedType);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
onChange?.(query);
|
|
93
|
+
}
|
|
75
94
|
};
|
|
76
95
|
const handleClear = () => {
|
|
77
96
|
setQuery("");
|
|
@@ -86,7 +105,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
|
|
|
86
105
|
};
|
|
87
106
|
const handleOverlaySearch = () => {
|
|
88
107
|
if (query.trim() && onSearch)
|
|
89
|
-
onSearch(query);
|
|
108
|
+
onSearch(query, selectedType);
|
|
90
109
|
};
|
|
91
110
|
if (isInlineMode) {
|
|
92
111
|
const inlineQuery = query.toLowerCase();
|
|
@@ -164,7 +183,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
|
|
|
164
183
|
if (inlineBlurRef.current)
|
|
165
184
|
clearTimeout(inlineBlurRef.current);
|
|
166
185
|
inlineBlurRef.current = setTimeout(() => setIsInlineOpen(false), 120);
|
|
167
|
-
}, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-0.5 rounded-full text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }),
|
|
186
|
+
}, placeholder: placeholder ?? labels.placeholder, className: "w-full rounded-lg border border-zinc-300 bg-white pl-9 text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }), query && (_jsx(Button, { type: "button", variant: "ghost", onClick: handleClear, className: "absolute right-3 p-0.5 rounded-full text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 transition-colors", "aria-label": labels.clearAriaLabel, children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }))] }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), deferred && (_jsx(Button, { type: "button", variant: "primary", onClick: handleDeferredSubmit, "aria-label": labels.ariaLabel, className: "flex-shrink-0 px-3 py-2 rounded-lg", children: _jsx("svg", { className: "w-4 h-4", "aria-hidden": "true", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }) })), isInlineOpen && (filteredQuickLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 mt-2 rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900", style: { zIndex: "var(--appkit-z-dropdown)" }, onMouseDown: (event) => event.preventDefault(), children: [filteredQuickLinks.length > 0 && (_jsx(Ul, { children: filteredQuickLinks.map((link, index) => {
|
|
168
187
|
const Icon = link.icon;
|
|
169
188
|
const isActive = activeIndex === index;
|
|
170
189
|
return (_jsx(Li, { children: _jsxs(Button, { type: "button", variant: "ghost", onClick: () => {
|
|
@@ -246,7 +265,7 @@ export function Search({ isOpen, onClose, onSearch, onOpen, value, onChange, pla
|
|
|
246
265
|
};
|
|
247
266
|
if (!isOpen)
|
|
248
267
|
return null;
|
|
249
|
-
return (_jsx("div", { className: "border-b border-zinc-200 bg-white shadow-md dark:border-slate-800 dark:bg-slate-950 animate-[fadeIn_150ms_ease-out]", "data-section": "search-div-433", children: _jsxs("div", { className: "container mx-auto px-4 py-3 md:py-4 relative", "data-section": "search-div-434", children: [_jsxs(Row, { gap: "sm", className: "md:gap-3", children: [_jsx("div", { className: "flex-1 relative", "data-section": "search-div-435", children: _jsx(Input, { ref: inputRef, bare: true, type: "search", placeholder: placeholder ?? labels.placeholder, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: handleOverlayKeyDown, className: "w-full rounded-lg border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }) }), _jsxs(Button, { onClick: handleOverlaySearch, variant: "primary", size: "md", className: "hidden sm:flex gap-2", children: [_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), labels.title] }), _jsx(Button, { variant: "ghost", onClick: () => onClose?.(), className: "p-2.5 md:p-3 rounded-xl transition-colors text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-slate-800 dark:hover:text-zinc-200 flex-shrink-0", "aria-label": labels.closeAriaLabel, children: _jsx("svg", { className: "w-6 h-6 md:w-7 md:h-7", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), (filteredSiteLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 px-4 pt-2 pb-4 space-y-2 z-50", "data-section": "search-div-436", children: [filteredSiteLinks.length > 0 && !suggestionsLoading && (_jsxs("div", { className: "rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900", "data-section": "search-div-437", children: [_jsx("div", { className: "px-4 py-2 border-b border-zinc-200 dark:border-slate-700", "data-section": "search-div-438", children: _jsx(Text, { variant: "secondary", size: "xs", className: "uppercase tracking-wider font-semibold", children: labels.quickLinks }) }), _jsx(Ul, { children: filteredSiteLinks.map((link) => {
|
|
268
|
+
return (_jsx("div", { className: "border-b border-zinc-200 bg-white shadow-md dark:border-slate-800 dark:bg-slate-950 animate-[fadeIn_150ms_ease-out]", "data-section": "search-div-433", children: _jsxs("div", { className: "container mx-auto px-4 py-3 md:py-4 relative", "data-section": "search-div-434", children: [_jsxs(Row, { gap: "sm", className: "md:gap-3", children: [_jsx("div", { className: "flex-1 relative", "data-section": "search-div-435", children: _jsx(Input, { ref: inputRef, bare: true, type: "search", placeholder: placeholder ?? labels.placeholder, value: query, onChange: (event) => setQuery(event.target.value), onKeyDown: handleOverlayKeyDown, className: "w-full rounded-lg border border-zinc-300 bg-white text-zinc-900 placeholder:text-zinc-400 focus:border-primary focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-white dark:placeholder:text-slate-500" }) }), resourceTypes && resourceTypes.length > 0 && (_jsx("select", { value: selectedType, onChange: (e) => handleTypeChange(e.target.value), "aria-label": labels.resourceTypeLabel ?? "Search in", className: "flex-shrink-0 rounded-lg border border-zinc-300 bg-white px-2 py-2 text-sm text-zinc-700 focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-300 cursor-pointer", children: resourceTypes.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })), _jsxs(Button, { onClick: handleOverlaySearch, variant: "primary", size: "md", className: "hidden sm:flex gap-2", children: [_jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }), labels.title] }), _jsx(Button, { variant: "ghost", onClick: () => onClose?.(), className: "p-2.5 md:p-3 rounded-xl transition-colors text-zinc-500 hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-slate-800 dark:hover:text-zinc-200 flex-shrink-0", "aria-label": labels.closeAriaLabel, children: _jsx("svg", { className: "w-6 h-6 md:w-7 md:h-7", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), (filteredSiteLinks.length > 0 || query) && (_jsxs("div", { className: "absolute top-full left-0 right-0 px-4 pt-2 pb-4 space-y-2 z-50", "data-section": "search-div-436", children: [filteredSiteLinks.length > 0 && !suggestionsLoading && (_jsxs("div", { className: "rounded-xl overflow-hidden border border-zinc-200 bg-white shadow-lg dark:border-slate-700 dark:bg-slate-900", "data-section": "search-div-437", children: [_jsx("div", { className: "px-4 py-2 border-b border-zinc-200 dark:border-slate-700", "data-section": "search-div-438", children: _jsx(Text, { variant: "secondary", size: "xs", className: "uppercase tracking-wider font-semibold", children: labels.quickLinks }) }), _jsx(Ul, { children: filteredSiteLinks.map((link) => {
|
|
250
269
|
const Icon = link.icon;
|
|
251
270
|
const itemIndex = quickLinkItems.findIndex((item) => item.link.href === link.href);
|
|
252
271
|
const isActive = activeIndex === itemIndex;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Search } from "./Search";
|
|
2
|
-
export type { SearchLabels, SearchProps, SearchQuickLink, SearchRouterAdapter, } from "./Search";
|
|
2
|
+
export type { SearchLabels, SearchProps, SearchQuickLink, SearchRouterAdapter, SearchResourceType, SearchResourceTypeOption, } from "./Search";
|
|
3
3
|
export { SearchFiltersRow } from "./SearchFiltersRow";
|
|
4
4
|
export type {} from "./SearchFiltersRow";
|
|
5
5
|
export { SearchResultsSection } from "./SearchResultsSection";
|
|
@@ -5,7 +5,7 @@ export interface NavSuggestionRecord {
|
|
|
5
5
|
subtitle?: string;
|
|
6
6
|
url: string;
|
|
7
7
|
}
|
|
8
|
-
export declare function useNavSuggestions(query: string, debounceMs?: number): {
|
|
8
|
+
export declare function useNavSuggestions(query: string, selectedType?: string, debounceMs?: number): {
|
|
9
9
|
suggestions: NavSuggestionRecord[];
|
|
10
10
|
isLoading: boolean;
|
|
11
11
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
|
-
export function useNavSuggestions(query, debounceMs = 250) {
|
|
3
|
+
export function useNavSuggestions(query, selectedType, debounceMs = 250) {
|
|
4
4
|
const [suggestions, setSuggestions] = useState([]);
|
|
5
5
|
const [isLoading, setIsLoading] = useState(false);
|
|
6
6
|
const timerRef = useRef(null);
|
|
@@ -27,6 +27,6 @@ export function useNavSuggestions(query, debounceMs = 250) {
|
|
|
27
27
|
if (timerRef.current)
|
|
28
28
|
clearTimeout(timerRef.current);
|
|
29
29
|
};
|
|
30
|
-
}, [query, debounceMs]);
|
|
30
|
+
}, [query, selectedType, debounceMs]);
|
|
31
31
|
return { suggestions, isLoading };
|
|
32
32
|
}
|
|
@@ -25,23 +25,23 @@ export declare const searchProductItemSchema: z.ZodObject<{
|
|
|
25
25
|
title: string;
|
|
26
26
|
slug: string;
|
|
27
27
|
status?: string | undefined;
|
|
28
|
+
price?: number | undefined;
|
|
28
29
|
currency?: string | undefined;
|
|
29
30
|
featured?: boolean | undefined;
|
|
30
|
-
price?: number | undefined;
|
|
31
|
-
isAuction?: boolean | undefined;
|
|
32
|
-
mainImage?: string | undefined;
|
|
33
31
|
isPromoted?: boolean | undefined;
|
|
32
|
+
mainImage?: string | undefined;
|
|
33
|
+
isAuction?: boolean | undefined;
|
|
34
34
|
}, {
|
|
35
35
|
id: string;
|
|
36
36
|
title: string;
|
|
37
37
|
slug: string;
|
|
38
38
|
status?: string | undefined;
|
|
39
|
+
price?: number | undefined;
|
|
39
40
|
currency?: string | undefined;
|
|
40
41
|
featured?: boolean | undefined;
|
|
41
|
-
price?: number | undefined;
|
|
42
|
-
isAuction?: boolean | undefined;
|
|
43
|
-
mainImage?: string | undefined;
|
|
44
42
|
isPromoted?: boolean | undefined;
|
|
43
|
+
mainImage?: string | undefined;
|
|
44
|
+
isAuction?: boolean | undefined;
|
|
45
45
|
}>;
|
|
46
46
|
/**
|
|
47
47
|
* Form/query schema for a search request.
|
|
@@ -63,8 +63,8 @@ export declare const searchQuerySchema: z.ZodObject<{
|
|
|
63
63
|
}, {
|
|
64
64
|
q: string;
|
|
65
65
|
sort?: string | undefined;
|
|
66
|
-
page?: number | undefined;
|
|
67
66
|
category?: string | undefined;
|
|
67
|
+
page?: number | undefined;
|
|
68
68
|
minPrice?: number | undefined;
|
|
69
69
|
maxPrice?: number | undefined;
|
|
70
70
|
}>;
|
|
@@ -10,6 +10,7 @@ import { productRepository } from "../../products/repository/products.repository
|
|
|
10
10
|
import { ProductStatusValues } from "../../products/schemas";
|
|
11
11
|
import { notificationRepository } from "../../admin/repository/notification.repository";
|
|
12
12
|
import { userRepository } from "../../auth/repository/user.repository";
|
|
13
|
+
import { storeRepository } from "../../stores/repository/store.repository";
|
|
13
14
|
import { cartRepository } from "../../cart/repository/cart.repository";
|
|
14
15
|
import { maskOfferForSeller } from "../../../security";
|
|
15
16
|
import { ERROR_MESSAGES, AuthorizationError, ValidationError, NotFoundError, } from "../../../errors";
|
|
@@ -35,6 +36,8 @@ export async function makeOffer(userId, userEmail, input) {
|
|
|
35
36
|
throw new ValidationError(ERROR_MESSAGES.OFFER.ACTIVE_OFFER_EXISTS);
|
|
36
37
|
const profile = await userRepository.findById(userId);
|
|
37
38
|
const buyerDisplayName = profile?.displayName ?? "Buyer";
|
|
39
|
+
if (!product.storeId)
|
|
40
|
+
throw new ValidationError("Product is not associated with a store.");
|
|
38
41
|
const offer = await offerRepository.create({
|
|
39
42
|
productId,
|
|
40
43
|
productTitle: product.title,
|
|
@@ -43,22 +46,25 @@ export async function makeOffer(userId, userEmail, input) {
|
|
|
43
46
|
buyerUid: userId,
|
|
44
47
|
buyerName: buyerDisplayName,
|
|
45
48
|
buyerEmail: profile?.email ?? userEmail ?? "",
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
storeId: product.storeId,
|
|
50
|
+
storeName: product.storeName ?? "",
|
|
48
51
|
offerAmount,
|
|
49
52
|
listedPrice: product.price,
|
|
50
53
|
currency: product.currency,
|
|
51
54
|
buyerNote,
|
|
52
55
|
});
|
|
53
|
-
await
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
const sellerStore = product.storeId ? await storeRepository.findById(product.storeId) : null;
|
|
57
|
+
if (sellerStore?.ownerId) {
|
|
58
|
+
await notificationRepository.create({
|
|
59
|
+
userId: sellerStore.ownerId,
|
|
60
|
+
type: "offer_received",
|
|
61
|
+
priority: "normal",
|
|
62
|
+
title: "New offer received",
|
|
63
|
+
message: `${buyerDisplayName === "Buyer" ? "A buyer" : buyerDisplayName} offered ₹${offerAmount} on "${product.title}"`,
|
|
64
|
+
relatedId: offer.id,
|
|
65
|
+
relatedType: "offer",
|
|
66
|
+
});
|
|
67
|
+
}
|
|
62
68
|
serverLogger.info("makeOffer", {
|
|
63
69
|
offerId: offer.id,
|
|
64
70
|
buyerUid: userId,
|
|
@@ -73,7 +79,8 @@ export async function respondToOffer(userId, input) {
|
|
|
73
79
|
const offer = await offerRepository.findById(offerId);
|
|
74
80
|
if (!offer)
|
|
75
81
|
throw new NotFoundError("Offer not found.");
|
|
76
|
-
|
|
82
|
+
const offerStore = offer.storeId ? await storeRepository.findById(offer.storeId) : null;
|
|
83
|
+
if (!offerStore || offerStore.ownerId !== userId)
|
|
77
84
|
throw new AuthorizationError("Not authorised to respond to this offer.");
|
|
78
85
|
if (offer.status !== OfferStatusValues.PENDING)
|
|
79
86
|
throw new ValidationError(`Offer is already ${offer.status}. No further action is possible.`);
|
|
@@ -99,7 +106,7 @@ export async function respondToOffer(userId, input) {
|
|
|
99
106
|
? `Your offer of ₹${offer.offerAmount} on "${offer.productTitle}" was accepted! Complete checkout now.`
|
|
100
107
|
: action === "decline"
|
|
101
108
|
? `Your offer on "${offer.productTitle}" was declined.`
|
|
102
|
-
: `${offer.
|
|
109
|
+
: `${offer.storeName} countered with ₹${counterAmount} on "${offer.productTitle}".`;
|
|
103
110
|
await notificationRepository.create({
|
|
104
111
|
userId: offer.buyerUid,
|
|
105
112
|
type: "offer_responded",
|
|
@@ -132,15 +139,17 @@ export async function acceptCounterOffer(userId, offerId) {
|
|
|
132
139
|
if (new Date() > offer.expiresAt)
|
|
133
140
|
throw new ValidationError(ERROR_MESSAGES.OFFER.EXPIRED);
|
|
134
141
|
const updated = await offerRepository.acceptCounter(offerId);
|
|
135
|
-
await
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
const counterStore = offer.storeId ? await storeRepository.findById(offer.storeId) : null;
|
|
143
|
+
if (counterStore?.ownerId)
|
|
144
|
+
await notificationRepository.create({
|
|
145
|
+
userId: counterStore.ownerId,
|
|
146
|
+
type: "offer_counter_accepted",
|
|
147
|
+
priority: "high",
|
|
148
|
+
title: "Counter offer accepted",
|
|
149
|
+
message: `Buyer accepted your counter of ₹${offer.counterAmount} on "${offer.productTitle}". They can now checkout.`,
|
|
150
|
+
relatedId: offerId,
|
|
151
|
+
relatedType: "offer",
|
|
152
|
+
});
|
|
144
153
|
return updated;
|
|
145
154
|
}
|
|
146
155
|
// --- Buyer: Counter back --------------------------------------------------
|
|
@@ -155,6 +164,8 @@ export async function counterOfferByBuyer(userId, userEmail, input) {
|
|
|
155
164
|
throw new ValidationError(ERROR_MESSAGES.OFFER.NOT_COUNTERED);
|
|
156
165
|
if (new Date() > offer.expiresAt)
|
|
157
166
|
throw new ValidationError(ERROR_MESSAGES.OFFER.EXPIRED);
|
|
167
|
+
if (!offer.counterAmount)
|
|
168
|
+
throw new ValidationError("No counter amount found on this offer.");
|
|
158
169
|
const sellerCounter = offer.counterAmount;
|
|
159
170
|
const minAllowed = Math.floor(sellerCounter * 0.8);
|
|
160
171
|
const maxAllowed = Math.ceil(sellerCounter * 1.2);
|
|
@@ -177,22 +188,24 @@ export async function counterOfferByBuyer(userId, userEmail, input) {
|
|
|
177
188
|
buyerUid: userId,
|
|
178
189
|
buyerName: offer.buyerName,
|
|
179
190
|
buyerEmail: offer.buyerEmail,
|
|
180
|
-
|
|
181
|
-
|
|
191
|
+
storeId: offer.storeId,
|
|
192
|
+
storeName: offer.storeName,
|
|
182
193
|
offerAmount: counterAmount,
|
|
183
194
|
listedPrice: offer.listedPrice,
|
|
184
195
|
currency: offer.currency,
|
|
185
196
|
buyerNote,
|
|
186
197
|
});
|
|
187
|
-
await
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
198
|
+
const buyerCounterStore = offer.storeId ? await storeRepository.findById(offer.storeId) : null;
|
|
199
|
+
if (buyerCounterStore?.ownerId)
|
|
200
|
+
await notificationRepository.create({
|
|
201
|
+
userId: buyerCounterStore.ownerId,
|
|
202
|
+
type: "offer_received",
|
|
203
|
+
priority: "normal",
|
|
204
|
+
title: "Buyer counter offer",
|
|
205
|
+
message: `${offer.buyerName} countered with ₹${counterAmount} on "${offer.productTitle}".`,
|
|
206
|
+
relatedId: newOffer.id,
|
|
207
|
+
relatedType: "offer",
|
|
208
|
+
});
|
|
196
209
|
serverLogger.info("counterOfferByBuyer", {
|
|
197
210
|
previousOfferId: offerId,
|
|
198
211
|
newOfferId: newOffer.id,
|
|
@@ -222,7 +235,10 @@ export async function listBuyerOffers(userId) {
|
|
|
222
235
|
return result.items;
|
|
223
236
|
}
|
|
224
237
|
export async function listSellerOffers(userId) {
|
|
225
|
-
const
|
|
238
|
+
const store = await storeRepository.findByOwnerId(userId);
|
|
239
|
+
if (!store)
|
|
240
|
+
return [];
|
|
241
|
+
const result = await offerRepository.findByStore(store.id);
|
|
226
242
|
return result.items.map(maskOfferForSeller);
|
|
227
243
|
}
|
|
228
244
|
// --- Buyer: Checkout accepted offer ----------------------------------------
|
|
@@ -255,8 +271,8 @@ export async function checkoutOffer(userId, offerId) {
|
|
|
255
271
|
price: offer.lockedPrice,
|
|
256
272
|
currency: offer.currency,
|
|
257
273
|
quantity: 1,
|
|
258
|
-
|
|
259
|
-
|
|
274
|
+
storeId: offer.storeId,
|
|
275
|
+
storeName: offer.storeName,
|
|
260
276
|
isAuction: false,
|
|
261
277
|
isPreOrder: false,
|
|
262
278
|
isOffer: true,
|