@mohasinac/appkit 3.4.7 → 3.5.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/_internal/client/features/classified/ClassifiedDetailView.js +1 -1
- package/dist/_internal/client/features/digital-code/CodeRevealPanel.js +1 -1
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +1 -1
- package/dist/_internal/client/features/filters/filter-load-options.js +10 -9
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +11 -4
- package/dist/_internal/client/features/live/LiveItemDetailView.js +2 -2
- package/dist/_internal/client/features/maintenance/views/AnalysisRunnerView.js +10 -3
- package/dist/_internal/client/features/maintenance/views/ServerErrorsListView.js +2 -2
- package/dist/_internal/client/scaffolds/DashboardScaffold.js +3 -1
- package/dist/_internal/server/features/checkout/actions.d.ts +16 -0
- package/dist/_internal/server/features/checkout/actions.js +149 -35
- package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +31 -0
- package/dist/_internal/server/features/checkout/bundle-expansion.js +41 -0
- package/dist/_internal/server/features/lottery/actions.js +14 -4
- package/dist/_internal/server/features/maintenance/analyze.js +4 -2
- package/dist/_internal/server/features/orders/actions.js +9 -0
- package/dist/_internal/server/features/orders/adapters.js +19 -0
- package/dist/_internal/server/features/seo/robots.js +1 -1
- package/dist/_internal/server/functions/firestore.d.ts +47 -1
- package/dist/_internal/server/functions/firestore.js +56 -1
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +9 -1
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.d.ts +10 -0
- package/dist/_internal/server/jobs/core/catalogueImageStalenessReminder.js +49 -0
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +32 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.d.ts +26 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +179 -0
- package/dist/_internal/server/jobs/core/index.d.ts +4 -1
- package/dist/_internal/server/jobs/core/index.js +4 -1
- package/dist/_internal/server/jobs/core/jobRunners.d.ts +28 -0
- package/dist/_internal/server/jobs/core/jobRunners.js +37 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.d.ts +15 -0
- package/dist/_internal/server/jobs/core/onCatalogueSubmittedForApproval.js +38 -0
- package/dist/_internal/server/jobs/core/onJobCreated.d.ts +22 -0
- package/dist/_internal/server/jobs/core/onJobCreated.js +59 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.d.ts +6 -1
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +5 -2
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/catalogueImageStalenessReminder.js +2 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +6 -0
- package/dist/_internal/server/jobs/handlers/index.js +8 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.d.ts +12 -0
- package/dist/_internal/server/jobs/handlers/onCatalogueSubmittedForApproval.js +20 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.d.ts +3 -0
- package/dist/_internal/server/jobs/handlers/onJobCreated.js +9 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.d.ts +25 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +71 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.d.ts +14 -0
- package/dist/_internal/server/jobs/handlers/onShipmentDeleted.js +23 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.d.ts +17 -0
- package/dist/_internal/server/jobs/handlers/onShipmentItemWrite.js +26 -0
- package/dist/_internal/server/jobs/handlers/weeklyPayoutEligibility.js +3 -1
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +136 -0
- package/dist/_internal/shared/features/blog/schema.d.ts +8 -8
- package/dist/_internal/shared/features/brands/schema.d.ts +4 -4
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +8 -8
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/_internal/shared/features/products/schema.d.ts +8 -8
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +4 -4
- package/dist/client/api/useFeatureFlags.d.ts +22 -0
- package/dist/client/api/useFeatureFlags.js +27 -0
- package/dist/client/observability/reportClientError.js +3 -2
- package/dist/client.d.ts +4 -2
- package/dist/client.js +2 -1
- package/dist/configs/next.js +1 -0
- package/dist/constants/api-endpoints.d.ts +279 -3
- package/dist/constants/api-endpoints.js +130 -2
- package/dist/core/hooks/useSyncManager.js +5 -4
- package/dist/errors/conflict-error.d.ts +4 -0
- package/dist/errors/conflict-error.js +6 -0
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/features/about/components/FeesView.js +2 -2
- package/dist/features/about/components/HelpPageView.js +2 -2
- package/dist/features/about/components/HowAuctionsWorkView.js +2 -2
- package/dist/features/about/components/HowCheckoutWorksView.js +2 -2
- package/dist/features/about/components/HowEmiWorksView.js +2 -2
- package/dist/features/about/components/HowOffersWorkView.js +3 -3
- package/dist/features/about/components/HowOrdersWorkView.js +3 -3
- package/dist/features/about/components/HowPayoutsWorkView.js +2 -2
- package/dist/features/about/components/HowPreOrdersWorkView.js +2 -2
- package/dist/features/about/components/HowReviewsWorkView.js +2 -2
- package/dist/features/about/components/PublicProfileView.d.ts +8 -1
- package/dist/features/about/components/PublicProfileView.js +11 -9
- package/dist/features/about/components/SecurityPrivacyView.js +2 -2
- package/dist/features/about/components/UnauthorizedView.js +2 -2
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/NotificationBell.js +5 -5
- package/dist/features/account/components/NotificationPreferencesPanel.js +5 -2
- package/dist/features/account/components/UserOffersPanel.js +5 -4
- package/dist/features/account/components/UserSidebar.js +2 -2
- package/dist/features/account/components/UserSupportView.js +3 -3
- package/dist/features/account/schemas/index.d.ts +12 -12
- package/dist/features/addresses/schemas/index.d.ts +6 -6
- package/dist/features/admin/components/AdminAdEditorView.js +3 -3
- package/dist/features/admin/components/AdminAddressEditorView.js +3 -3
- package/dist/features/admin/components/AdminAdsView.js +3 -3
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBlogView.js +12 -15
- package/dist/features/admin/components/AdminBrandEditorView.js +1 -1
- package/dist/features/admin/components/AdminBrandsView.js +12 -13
- package/dist/features/admin/components/AdminBundleEditorView.js +5 -4
- package/dist/features/admin/components/AdminBundlesView.js +32 -23
- package/dist/features/admin/components/AdminCarouselEditorView.js +5 -5
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCatalogGuideView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +12 -13
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminContactEditorView.js +2 -2
- package/dist/features/admin/components/AdminCouponEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +7 -2
- package/dist/features/admin/components/AdminCouponsView.js +32 -27
- package/dist/features/admin/components/AdminEmployeeEditorView.js +3 -3
- package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +20 -20
- package/dist/features/admin/components/AdminFeatureEditorView.js +5 -5
- package/dist/features/admin/components/AdminFeaturesView.js +9 -10
- package/dist/features/admin/components/AdminFilterBar.js +1 -1
- package/dist/features/admin/components/AdminFulfillmentView.js +4 -4
- package/dist/features/admin/components/AdminGuideHubView.js +2 -2
- package/dist/features/admin/components/AdminMediaView.js +3 -2
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +3 -3
- package/dist/features/admin/components/AdminOrdersView.js +21 -30
- package/dist/features/admin/components/AdminPageHeader.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +8 -8
- package/dist/features/admin/components/AdminPrizeDrawsView.js +8 -9
- package/dist/features/admin/components/AdminProductEditorView.d.ts +9 -1
- package/dist/features/admin/components/AdminProductEditorView.js +7 -4
- package/dist/features/admin/components/AdminProductsView.js +30 -41
- package/dist/features/admin/components/AdminReviewsView.js +14 -17
- package/dist/features/admin/components/AdminScammerEditorView.js +5 -5
- package/dist/features/admin/components/AdminSectionsView.js +3 -3
- package/dist/features/admin/components/AdminSessionsView.js +8 -10
- package/dist/features/admin/components/AdminSidebar.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +10 -3
- package/dist/features/admin/components/AdminStoreEditorView.js +4 -5
- package/dist/features/admin/components/AdminStoresView.js +18 -13
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamView.js +9 -5
- package/dist/features/admin/components/AdminUsersView.js +19 -15
- package/dist/features/admin/components/AdminViewCards.js +5 -5
- package/dist/features/admin/components/DashboardStats.js +1 -1
- package/dist/features/admin/components/DataListingView.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/DrawerFormFooter.js +1 -1
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +2 -2
- package/dist/features/admin/components/analytics/AdminStatCard.js +1 -1
- package/dist/features/admin/hooks/useAdminListing.d.ts +3 -2
- package/dist/features/admin/hooks/useAdminListing.js +8 -2
- package/dist/features/admin/permission-map.js +2 -0
- package/dist/features/admin/schemas/firestore.d.ts +7 -0
- package/dist/features/admin/schemas/firestore.js +4 -0
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +7 -7
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auctions/components/MarketplaceAuctionGrid.js +4 -4
- package/dist/features/auctions/components/PlaceBidFormClient.js +1 -1
- package/dist/features/auctions/schemas/index.d.ts +16 -16
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +2 -0
- package/dist/features/auth/schemas/index.d.ts +6 -6
- package/dist/features/before-after/schemas/index.d.ts +3 -3
- package/dist/features/blog/actions/blog-actions.d.ts +32 -32
- package/dist/features/blog/components/BlogFeaturedCard.js +2 -2
- package/dist/features/blog/components/BlogIndexListing.js +2 -2
- package/dist/features/blog/components/BlogListView.js +4 -4
- package/dist/features/blog/components/BlogPostView.js +4 -4
- package/dist/features/blog/schemas/index.d.ts +77 -77
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/catalogue/actions/approve-catalogue-listing.d.ts +12 -0
- package/dist/features/catalogue/actions/approve-catalogue-listing.js +50 -0
- package/dist/features/catalogue/actions/list-from-catalogue.d.ts +17 -0
- package/dist/features/catalogue/actions/list-from-catalogue.js +50 -0
- package/dist/features/catalogue/actions/submit-for-approval.d.ts +8 -0
- package/dist/features/catalogue/actions/submit-for-approval.js +30 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.d.ts +2 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +53 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.d.ts +7 -0
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +79 -0
- package/dist/features/catalogue/components/PublicCatalogueView.d.ts +5 -0
- package/dist/features/catalogue/components/PublicCatalogueView.js +22 -0
- package/dist/features/catalogue/components/UserCatalogueView.d.ts +12 -0
- package/dist/features/catalogue/components/UserCatalogueView.js +51 -0
- package/dist/features/catalogue/index.d.ts +12 -0
- package/dist/features/catalogue/index.js +9 -0
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +39 -0
- package/dist/features/catalogue/repository/catalogue.repository.js +68 -0
- package/dist/features/catalogue/schemas/firestore.d.ts +47 -0
- package/dist/features/catalogue/schemas/firestore.js +22 -0
- package/dist/features/catalogue/schemas/index.d.ts +2 -0
- package/dist/features/catalogue/schemas/index.js +2 -0
- package/dist/features/catalogue/schemas/validation.d.ts +71 -0
- package/dist/features/catalogue/schemas/validation.js +25 -0
- package/dist/features/catalogue/utils/freshness.d.ts +10 -0
- package/dist/features/catalogue/utils/freshness.js +15 -0
- package/dist/features/catalogue/utils/product-from-item.d.ts +15 -0
- package/dist/features/catalogue/utils/product-from-item.js +34 -0
- package/dist/features/categories/components/BrandDetailPageView.js +1 -1
- package/dist/features/categories/components/BrandDetailTabs.js +2 -2
- package/dist/features/categories/components/BundleCollage.js +2 -2
- package/dist/features/categories/components/BundleItemsPicker.js +3 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +8 -6
- package/dist/features/categories/components/CategoryBundlesListing.js +10 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +2 -2
- package/dist/features/categories/components/CategoryGrid.js +3 -3
- package/dist/features/categories/components/CategoryProductsListing.js +1 -1
- package/dist/features/categories/components/CategorySortSelect.js +1 -1
- package/dist/features/categories/components/CategoryStoresListing.js +1 -1
- package/dist/features/categories/components/CategoryTableColumns.js +1 -1
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/hooks/useCategories.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +32 -32
- package/dist/features/classified/components/ClassifiedFilters.js +2 -2
- package/dist/features/classified/components/ClassifiedIndexListing.js +9 -3
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/consultation/components/ConsultationForm.js +1 -1
- package/dist/features/consultation/schemas/index.d.ts +10 -10
- package/dist/features/contact/components/ContactForm.js +4 -4
- package/dist/features/contact/components/ContactInfoSidebar.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +2 -1
- package/dist/features/copilot/components/AdminCopilotView.js +5 -4
- package/dist/features/corporate/schemas/index.d.ts +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +3 -3
- package/dist/features/events/components/AdminEventEditorView.js +4 -4
- package/dist/features/events/components/AdminEventEntriesView.js +2 -2
- package/dist/features/events/components/AdminEventsView.js +8 -8
- package/dist/features/events/components/EventBanner.js +1 -1
- package/dist/features/events/components/EventCard.js +3 -3
- package/dist/features/events/components/EventLeaderboard.js +1 -1
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventPollWidget.js +6 -5
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +5 -5
- package/dist/features/events/components/EventRafflesSection.js +1 -1
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/events/components/EventsIndexListing.js +4 -2
- package/dist/features/events/components/EventsListView.js +2 -2
- package/dist/features/events/components/SpinWheelView.js +11 -5
- package/dist/features/events/schemas/index.d.ts +100 -100
- package/dist/features/faq/actions/faq-actions.d.ts +6 -6
- package/dist/features/faq/components/ContactCTA.js +3 -3
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +3 -3
- package/dist/features/faq/schemas/index.d.ts +12 -12
- package/dist/features/filters/AsyncFacetSection.js +4 -4
- package/dist/features/filters/FilterFacetSection.js +8 -8
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +2 -8
- package/dist/features/forms/Input.js +2 -1
- package/dist/features/forms/Radio.js +3 -3
- package/dist/features/forms/Select.d.ts +1 -1
- package/dist/features/forms/Select.js +3 -2
- package/dist/features/forms/Slider.js +5 -11
- package/dist/features/forms/Textarea.js +2 -1
- package/dist/features/grouped/schemas/index.d.ts +6 -6
- package/dist/features/homepage/actions/homepage-section-actions.d.ts +4 -4
- package/dist/features/homepage/components/AdvertisementBanner.js +4 -4
- package/dist/features/homepage/components/AnnouncementBar.js +3 -3
- package/dist/features/homepage/components/BeforeAfterCard.js +1 -1
- package/dist/features/homepage/components/BrandsSection.js +9 -9
- package/dist/features/homepage/components/CTABannerSection.js +1 -1
- package/dist/features/homepage/components/CharacterHotspot.js +4 -4
- package/dist/features/homepage/components/CharacterHotspotForm.js +15 -13
- package/dist/features/homepage/components/CollectionCardsSection.js +1 -1
- package/dist/features/homepage/components/CustomCardsSection.js +6 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +2 -2
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedBundlesSection.js +3 -3
- package/dist/features/homepage/components/FeaturedResultsSection.js +2 -2
- package/dist/features/homepage/components/GoogleReviewsSection.js +6 -6
- package/dist/features/homepage/components/HeroBanner.js +1 -1
- package/dist/features/homepage/components/HeroCarousel.js +5 -4
- package/dist/features/homepage/components/HeroSection.js +1 -7
- package/dist/features/homepage/components/HomepageSkeleton.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +2 -2
- package/dist/features/homepage/components/NewsletterBanner.js +2 -2
- package/dist/features/homepage/components/NewsletterSection.js +1 -1
- package/dist/features/homepage/components/PromoGrid.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +6 -6
- package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
- package/dist/features/homepage/components/ShopByCategorySection.js +10 -10
- package/dist/features/homepage/components/SiteFeaturesSection.js +2 -2
- package/dist/features/homepage/components/SocialFeedSection.js +5 -5
- package/dist/features/homepage/components/SocialPostCard.js +1 -1
- package/dist/features/homepage/components/StatsCounterSection.js +1 -1
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/TrustBadges.js +1 -1
- package/dist/features/homepage/components/TrustFeaturesSection.js +2 -2
- package/dist/features/homepage/components/TrustIndicatorsSection.js +2 -2
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/hooks/useActiveAd.js +2 -1
- package/dist/features/homepage/schemas/firestore.d.ts +10 -0
- package/dist/features/homepage/schemas/index.d.ts +116 -116
- package/dist/features/jobs/actions/enqueue-job.d.ts +24 -0
- package/dist/features/jobs/actions/enqueue-job.js +44 -0
- package/dist/features/jobs/repository/jobs.repository.d.ts +21 -0
- package/dist/features/jobs/repository/jobs.repository.js +48 -0
- package/dist/features/jobs/schemas/firestore.d.ts +54 -0
- package/dist/features/jobs/schemas/firestore.js +24 -0
- package/dist/features/layout/AppLayoutShell.js +17 -11
- package/dist/features/layout/AutoBreadcrumbs.js +1 -1
- package/dist/features/layout/BackToTop.js +2 -2
- package/dist/features/layout/BottomActions.js +7 -7
- package/dist/features/layout/BottomNavItem.js +2 -2
- package/dist/features/layout/BottomNavLayout.js +13 -4
- package/dist/features/layout/BottomNavbar.d.ts +9 -1
- package/dist/features/layout/BottomNavbar.js +12 -5
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/Breadcrumbs.js +1 -1
- package/dist/features/layout/FooterLayout.js +2 -2
- package/dist/features/layout/NavItem.js +3 -3
- package/dist/features/layout/NavbarLayout.js +6 -6
- package/dist/features/layout/SidebarLayout.d.ts +3 -0
- package/dist/features/layout/SidebarLayout.js +3 -3
- package/dist/features/layout/TitleBarLayout.js +4 -4
- package/dist/features/live/components/LiveItemFilters.js +2 -2
- package/dist/features/live/components/LiveItemsIndexListing.js +3 -3
- package/dist/features/lottery/types/index.d.ts +3 -1
- package/dist/features/lottery/types/index.js +16 -3
- package/dist/features/loyalty/components/CoinsDisplay.js +2 -2
- package/dist/features/media/MediaImage.d.ts +6 -1
- package/dist/features/media/MediaImage.js +10 -4
- package/dist/features/media/MediaLightbox.js +1 -1
- package/dist/features/media/MediaPickerModal.js +4 -3
- package/dist/features/media/MediaVideo.js +1 -1
- package/dist/features/media/modals/ImageCropModal.js +1 -1
- package/dist/features/media/modals/ImageEditor.js +1 -1
- package/dist/features/media/repository/media-assets.repository.d.ts +9 -0
- package/dist/features/media/types/index.d.ts +4 -4
- package/dist/features/media/upload/MediaUploadField.js +3 -3
- package/dist/features/media/upload/MediaUploadList.js +1 -1
- package/dist/features/messages/hooks/useConversation.js +4 -3
- package/dist/features/messages/hooks/useConversations.js +2 -1
- package/dist/features/messages/schemas/index.d.ts +6 -6
- package/dist/features/orders/components/MarketplaceOrderCard.js +1 -1
- package/dist/features/orders/components/OrderPaymentSummary.d.ts +16 -0
- package/dist/features/orders/components/OrderPaymentSummary.js +32 -0
- package/dist/features/orders/components/OrderSiblingPayments.js +1 -1
- package/dist/features/orders/components/OrdersList.d.ts +7 -2
- package/dist/features/orders/components/OrdersList.js +5 -5
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/components/RefundRequestView.js +1 -1
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/repository/orders.repository.d.ts +8 -0
- package/dist/features/orders/repository/orders.repository.js +24 -0
- package/dist/features/orders/schemas/firestore.d.ts +59 -0
- package/dist/features/orders/schemas/firestore.js +5 -0
- package/dist/features/orders/schemas/index.d.ts +91 -40
- package/dist/features/orders/schemas/index.js +10 -0
- package/dist/features/orders/types/index.d.ts +15 -0
- package/dist/features/payments/schemas/index.d.ts +12 -12
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +5 -5
- package/dist/features/pre-orders/components/PreOrderActionsClient.js +1 -1
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +7 -7
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +3 -3
- package/dist/features/pre-orders/schemas/index.d.ts +12 -12
- package/dist/features/products/columns/productTableColumns.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +3 -3
- package/dist/features/products/components/CompareOverlay.js +15 -10
- package/dist/features/products/components/CustomFieldsEditor.js +2 -2
- package/dist/features/products/components/CustomSectionsEditor.js +3 -3
- package/dist/features/products/components/FeatureBadge.js +2 -2
- package/dist/features/products/components/GroupSettingsPanel.js +5 -4
- package/dist/features/products/components/MakeOfferButton.js +4 -4
- package/dist/features/products/components/MarketplaceBundleCard.js +3 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +1 -1
- package/dist/features/products/components/PrizeDrawCollage.js +6 -6
- package/dist/features/products/components/PrizeDrawDetailPageView.js +5 -5
- package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +4 -4
- package/dist/features/products/components/PrizeDrawsIndexListing.js +11 -4
- package/dist/features/products/components/PrizeDrawsSection.js +1 -1
- package/dist/features/products/components/PrizeRevealModal.js +9 -4
- package/dist/features/products/components/ProductDetailActions.js +2 -1
- package/dist/features/products/components/ProductDetailPageView.js +16 -16
- package/dist/features/products/components/ProductFeaturesSelector.js +5 -5
- package/dist/features/products/components/ProductForm.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +5 -3
- package/dist/features/products/components/ProductGrid.js +11 -11
- package/dist/features/products/components/ProductTabs.js +2 -2
- package/dist/features/products/components/ProductTabsShell.js +2 -1
- package/dist/features/products/components/ProductsIndexListing.js +6 -1
- package/dist/features/products/components/ShareButton.js +2 -1
- package/dist/features/products/components/ShowGroupSection.js +9 -5
- package/dist/features/products/components/SublistingCarouselSection.js +8 -4
- package/dist/features/products/constants/action-defs.d.ts +10 -2
- package/dist/features/products/constants/action-defs.js +20 -2
- package/dist/features/products/schemas/firestore.d.ts +5 -0
- package/dist/features/products/schemas/index.d.ts +40 -40
- package/dist/features/products/schemas/product-features.validators.d.ts +14 -14
- package/dist/features/promotions/components/CouponCard.js +13 -7
- package/dist/features/promotions/components/CouponsIndexListing.js +4 -6
- package/dist/features/promotions/components/PromotionsView.js +2 -2
- package/dist/features/promotions/schemas/index.d.ts +26 -26
- package/dist/features/reviews/components/ReviewDetailPageView.js +1 -1
- package/dist/features/reviews/components/ReviewDetailShell.js +11 -11
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewsList.js +2 -2
- package/dist/features/reviews/schemas/index.d.ts +22 -22
- package/dist/features/scams/components/ScamAwarenessModal.js +2 -2
- package/dist/features/scams/components/ScamProfileView.js +3 -3
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/schemas/index.d.ts +20 -20
- package/dist/features/search/components/Search.js +9 -9
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/components/SearchResultsSection.js +3 -3
- package/dist/features/search/components/SearchView.js +1 -1
- package/dist/features/search/hooks/useNavSuggestions.js +2 -1
- package/dist/features/search/hooks/useSearch.js +2 -2
- package/dist/features/search/schemas/index.d.ts +3 -3
- package/dist/features/seller/components/BrandInlineSelect.js +2 -2
- package/dist/features/seller/components/CategoryInlineSelect.js +2 -2
- package/dist/features/seller/components/QuickProductForm.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +4 -4
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +3 -3
- package/dist/features/seller/components/SellerAnalyticsView.js +2 -2
- package/dist/features/seller/components/SellerArtView.js +11 -11
- package/dist/features/seller/components/SellerAuctionsView.js +11 -11
- package/dist/features/seller/components/SellerBidsView.js +3 -3
- package/dist/features/seller/components/SellerBundlesView.js +12 -12
- package/dist/features/seller/components/SellerClassifiedView.js +11 -11
- package/dist/features/seller/components/SellerCouponEditorView.js +2 -2
- package/dist/features/seller/components/SellerDigitalCodesView.js +11 -11
- package/dist/features/seller/components/SellerFeaturesView.js +4 -4
- package/dist/features/seller/components/SellerLiveView.js +11 -11
- package/dist/features/seller/components/SellerOffersPanel.js +3 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerPayoutMethodsView.js +1 -1
- package/dist/features/seller/components/SellerPayoutRequestView.js +6 -5
- package/dist/features/seller/components/SellerPayoutSettingsView.js +5 -4
- package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +20 -6
- package/dist/features/seller/components/SellerProductsCards.js +3 -3
- package/dist/features/seller/components/SellerProductsView.js +4 -4
- package/dist/features/seller/components/SellerReviewsView.js +7 -6
- package/dist/features/seller/components/SellerShippingView.js +2 -1
- package/dist/features/seller/components/SellerSidebar.js +5 -5
- package/dist/features/seller/components/SellerStickersView.js +11 -11
- package/dist/features/seller/components/SellerTemplatesView.js +1 -1
- package/dist/features/seller/schemas/index.d.ts +20 -20
- package/dist/features/server-errors/schemas/index.d.ts +6 -6
- package/dist/features/shell/CommandPalette.d.ts +27 -0
- package/dist/features/shell/CommandPalette.js +92 -0
- package/dist/features/shell/FormShell.js +4 -3
- package/dist/features/shell/QuickFormDrawer.js +3 -2
- package/dist/features/shell/StepForm.js +2 -2
- package/dist/features/shell/index.d.ts +2 -0
- package/dist/features/shell/index.js +1 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.d.ts +7 -0
- package/dist/features/shipments/components/AdminShipmentEditorView.js +123 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.d.ts +6 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +96 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.d.ts +9 -0
- package/dist/features/shipments/components/AdminShipmentProjectionsView.js +44 -0
- package/dist/features/shipments/components/AdminShipmentsView.d.ts +8 -0
- package/dist/features/shipments/components/AdminShipmentsView.js +82 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.d.ts +15 -0
- package/dist/features/shipments/components/ShipmentItemLinkModal.js +37 -0
- package/dist/features/shipments/hooks/useShipments.d.ts +69 -0
- package/dist/features/shipments/hooks/useShipments.js +96 -0
- package/dist/features/shipments/index.d.ts +10 -0
- package/dist/features/shipments/index.js +7 -0
- package/dist/features/shipments/manifest.d.ts +2 -0
- package/dist/features/shipments/manifest.js +26 -0
- package/dist/features/shipments/repository/shipment-items.repository.d.ts +56 -0
- package/dist/features/shipments/repository/shipment-items.repository.js +78 -0
- package/dist/features/shipments/repository/shipment-lots.repository.d.ts +48 -0
- package/dist/features/shipments/repository/shipment-lots.repository.js +55 -0
- package/dist/features/shipments/repository/shipments.repository.d.ts +50 -0
- package/dist/features/shipments/repository/shipments.repository.js +77 -0
- package/dist/features/shipments/schemas/firestore.d.ts +150 -0
- package/dist/features/shipments/schemas/firestore.js +76 -0
- package/dist/features/shipments/schemas/index.d.ts +2 -0
- package/dist/features/shipments/schemas/index.js +2 -0
- package/dist/features/shipments/schemas/validation.d.ts +350 -0
- package/dist/features/shipments/schemas/validation.js +96 -0
- package/dist/features/shipments/utils/cost-allocation.d.ts +25 -0
- package/dist/features/shipments/utils/cost-allocation.js +83 -0
- package/dist/features/site-settings/components/ActionPermissionsManager.js +2 -2
- package/dist/features/stores/components/InteractiveStoreCard.js +2 -2
- package/dist/features/stores/components/StoreAboutView.js +1 -1
- package/dist/features/stores/components/StoreAuctionsListing.js +3 -3
- package/dist/features/stores/components/StoreAuctionsView.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
- package/dist/features/stores/components/StoreDetailLayoutView.js +1 -1
- package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
- package/dist/features/stores/components/StoreFinanceGuideView.js +2 -2
- package/dist/features/stores/components/StoreGuideHubView.js +2 -2
- package/dist/features/stores/components/StoreHeader.js +4 -4
- package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
- package/dist/features/stores/components/StoreNavTabs.js +2 -2
- package/dist/features/stores/components/StoreOrdersGuideView.js +1 -1
- package/dist/features/stores/components/StorePreOrdersListing.js +3 -3
- package/dist/features/stores/components/StoreProductsListing.js +1 -1
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoreReviewsView.js +1 -1
- package/dist/features/stores/components/StoreSettingsGuideView.js +1 -1
- package/dist/features/stores/components/StoresIndexListing.js +9 -3
- package/dist/features/stores/schemas/index.d.ts +10 -10
- package/dist/features/support/schemas/index.d.ts +22 -22
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +3 -3
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +1 -1
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -2
- package/dist/index.d.ts +44 -1
- package/dist/index.js +37 -1
- package/dist/next/routing/route-map.d.ts +18 -0
- package/dist/next/routing/route-map.js +9 -0
- package/dist/react/hooks/useVisualViewportInset.d.ts +1 -0
- package/dist/react/hooks/useVisualViewportInset.js +59 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/repositories/index.d.ts +5 -0
- package/dist/repositories/index.js +5 -0
- package/dist/schemas/registry.d.ts +398 -364
- package/dist/schemas/sieve.d.ts +2 -2
- package/dist/schemas/webhooks/google-oauth.d.ts +2 -2
- package/dist/schemas/webhooks/razorpay.d.ts +100 -100
- package/dist/seed/_helpers/media.js +1 -0
- package/dist/seed/actions/demo-seed-actions.d.ts +1 -1
- package/dist/seed/catalogue-seed-data.d.ts +2 -0
- package/dist/seed/catalogue-seed-data.js +112 -0
- package/dist/seed/grouped-listings-seed-data.d.ts +5 -0
- package/dist/seed/homepage-sections-seed-data.js +0 -1
- package/dist/seed/index.d.ts +2 -0
- package/dist/seed/index.js +2 -0
- package/dist/seed/manifest.js +6 -0
- package/dist/seed/products-preorders-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.d.ts +5 -0
- package/dist/seed/shipments-seed-data.js +185 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +5 -0
- package/dist/styles.css +75 -19
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +0 -2
- package/dist/tokens/index.js +0 -2
- package/dist/tokens/tokens.css +12 -2
- package/dist/ui/DataTable.js +4 -3
- package/dist/ui/components/Button.d.ts +4 -1
- package/dist/ui/components/Button.js +11 -5
- package/dist/ui/components/Checkbox.d.ts +9 -1
- package/dist/ui/components/Checkbox.js +5 -2
- package/dist/ui/components/ClaimCouponButton.js +2 -1
- package/dist/ui/components/ConfirmDeleteModal.style.css +1 -1
- package/dist/ui/components/Drawer.style.css +13 -1
- package/dist/ui/components/Dropdown.style.css +2 -2
- package/dist/ui/components/FilterDrawer.d.ts +4 -1
- package/dist/ui/components/FilterDrawer.js +8 -2
- package/dist/ui/components/Form.d.ts +1 -1
- package/dist/ui/components/Form.js +2 -2
- package/dist/ui/components/FormActionBar.style.css +6 -1
- package/dist/ui/components/IconButton.d.ts +6 -1
- package/dist/ui/components/IconButton.js +5 -2
- package/dist/ui/components/IconButton.style.css +11 -0
- package/dist/ui/components/ImageGallery.style.css +2 -0
- package/dist/ui/components/ImageLightbox.style.css +1 -0
- package/dist/ui/components/ListingFilterDrawer.d.ts +4 -1
- package/dist/ui/components/ListingFilterDrawer.js +4 -3
- package/dist/ui/components/ListingLayout.style.css +2 -2
- package/dist/ui/components/Modal.style.css +1 -1
- package/dist/ui/components/Pagination.d.ts +5 -1
- package/dist/ui/components/Pagination.js +4 -2
- package/dist/ui/components/RowActionMenu.js +1 -1
- package/dist/ui/components/RowActionMenu.style.css +1 -1
- package/dist/ui/components/Select.d.ts +6 -1
- package/dist/ui/components/Select.js +18 -13
- package/dist/ui/components/Select.style.css +1 -1
- package/dist/ui/components/Semantic.d.ts +13 -0
- package/dist/ui/components/Semantic.js +16 -3
- package/dist/ui/components/SideDrawer.style.css +16 -4
- package/dist/ui/components/SideModal.style.css +1 -1
- package/dist/ui/components/StickyToolbar.d.ts +3 -2
- package/dist/ui/components/StickyToolbar.js +1 -1
- package/dist/ui/components/Textarea.d.ts +5 -0
- package/dist/ui/components/Textarea.js +8 -4
- package/dist/ui/components/Toast.style.css +3 -0
- package/dist/ui/components/Typography.js +69 -8
- package/dist/ui/components/UnsavedChangesModal.style.css +1 -1
- package/dist/ui/components/surface-tokens.d.ts +121 -113
- package/dist/ui/components/surface-tokens.js +110 -104
- package/dist/ui/forms/FormShell.d.ts +8 -27
- package/dist/ui/forms/FormShell.js +1 -194
- package/dist/ui/forms/index.d.ts +2 -2
- package/dist/ui/forms/index.js +1 -1
- package/dist/ui/index.d.ts +8 -4
- package/dist/ui/index.js +4 -2
- package/dist/utils/id-generators.d.ts +27 -0
- package/dist/utils/id-generators.js +45 -0
- package/dist/utils/number.formatter.d.ts +7 -0
- package/dist/utils/number.formatter.js +9 -0
- package/dist/validation/schemas.d.ts +5 -5
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { sieveFilter, SIEVE_OP } from "@mohasinac/appkit";
|
|
4
|
+
import { sortBy } from "@mohasinac/appkit";
|
|
5
|
+
import React from "react";
|
|
6
|
+
import { FilterChipGroup, ListingLayout } from "../../../ui";
|
|
7
|
+
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
|
+
import { toRecordArray, toRelativeDate, toStringValue, } from "../../admin/hooks/useAdminListingData";
|
|
9
|
+
import { DataListingView } from "../../admin/components/DataListingView";
|
|
10
|
+
import { AdminShipmentEditorView } from "./AdminShipmentEditorView";
|
|
11
|
+
import { ADMIN_BULK_ACTIONS, ROW_ACTION_META } from "../../products/constants/action-defs";
|
|
12
|
+
import { formatPaise } from "../../../utils/number.formatter";
|
|
13
|
+
const STATUS_OPTIONS = [
|
|
14
|
+
{ id: "All", label: "All" },
|
|
15
|
+
{ id: "planning", label: "Planning" },
|
|
16
|
+
{ id: "ordered", label: "Ordered" },
|
|
17
|
+
{ id: "in_transit", label: "In Transit" },
|
|
18
|
+
{ id: "customs", label: "Customs" },
|
|
19
|
+
{ id: "received", label: "Received" },
|
|
20
|
+
{ id: "processing", label: "Processing" },
|
|
21
|
+
{ id: "completed", label: "Completed" },
|
|
22
|
+
{ id: "cancelled", label: "Cancelled" },
|
|
23
|
+
];
|
|
24
|
+
export function AdminShipmentsView({ children, ...props }) {
|
|
25
|
+
if (React.Children.count(children) > 0) {
|
|
26
|
+
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
27
|
+
}
|
|
28
|
+
const config = {
|
|
29
|
+
portal: "admin",
|
|
30
|
+
title: "Procurement Shipments",
|
|
31
|
+
searchPlaceholder: "Search by shipment number or supplier",
|
|
32
|
+
emptyLabel: "No shipments found",
|
|
33
|
+
filterKeys: ["status"],
|
|
34
|
+
defaultSort: sortBy("createdAt", "DESC"),
|
|
35
|
+
queryKey: ["admin", "shipments", "listing"],
|
|
36
|
+
endpoint: ADMIN_ENDPOINTS.SHIPMENTS,
|
|
37
|
+
sortOptions: [
|
|
38
|
+
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
39
|
+
{ value: sortBy("etaDate", "ASC"), label: "ETA soonest" },
|
|
40
|
+
{ value: sortBy("projectedProfitPaise", "DESC"), label: "Highest projected profit" },
|
|
41
|
+
{ value: "shipmentNumber", label: "Shipment # A–Z" },
|
|
42
|
+
],
|
|
43
|
+
mapRows: (response) => toRecordArray(response.shipments).map((item, index) => {
|
|
44
|
+
const totals = item.totals ?? {};
|
|
45
|
+
const totalsComputedAt = item.totalsComputedAt;
|
|
46
|
+
const updatedAt = item.updatedAt;
|
|
47
|
+
return {
|
|
48
|
+
id: toStringValue(item.id, `shipment-${index}`),
|
|
49
|
+
primary: toStringValue(item.shipmentNumber, "Untitled shipment"),
|
|
50
|
+
secondary: [toStringValue(item.supplierName, ""), toStringValue(item.status, "")]
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.join(" · "),
|
|
53
|
+
status: toStringValue(item.status, "planning"),
|
|
54
|
+
updatedAt: toRelativeDate(updatedAt),
|
|
55
|
+
totalCost: formatPaise(Number(totals.totalShipmentCostPaise ?? 0)),
|
|
56
|
+
projectedProfit: formatPaise(Number(totals.projectedProfitPaise ?? 0)),
|
|
57
|
+
recalculating: !totalsComputedAt || (!!updatedAt && String(updatedAt) > String(totalsComputedAt)),
|
|
58
|
+
};
|
|
59
|
+
}),
|
|
60
|
+
getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
|
|
61
|
+
buildFilters: (state) => {
|
|
62
|
+
const parts = [];
|
|
63
|
+
if (state.status && state.status !== "All")
|
|
64
|
+
parts.push(sieveFilter("status", SIEVE_OP.EQ, state.status));
|
|
65
|
+
return parts.join(",") || undefined;
|
|
66
|
+
},
|
|
67
|
+
primaryAction: {
|
|
68
|
+
label: "New Shipment",
|
|
69
|
+
onClick: ({ openCreatePanel }) => openCreatePanel(),
|
|
70
|
+
},
|
|
71
|
+
buildBulkActions: (selection) => ADMIN_BULK_ACTIONS.shipments.map((id) => ({
|
|
72
|
+
id,
|
|
73
|
+
label: ROW_ACTION_META[id].label,
|
|
74
|
+
destructive: ROW_ACTION_META[id].destructive,
|
|
75
|
+
onClick: () => selection.clearSelection(),
|
|
76
|
+
})),
|
|
77
|
+
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) })),
|
|
78
|
+
renderEditor: ({ editId, closePanel }) => (_jsx(AdminShipmentEditorView, { shipmentId: editId ?? undefined, onSaved: closePanel, embedded: true })),
|
|
79
|
+
resolveEditorTitle: ({ isCreate }) => (isCreate ? "New Shipment" : "Edit Shipment"),
|
|
80
|
+
};
|
|
81
|
+
return _jsx(DataListingView, { config: config });
|
|
82
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ShipmentItemLinkModalProps {
|
|
3
|
+
shipmentId: string;
|
|
4
|
+
lotId: string;
|
|
5
|
+
itemId: string;
|
|
6
|
+
itemTitle: string;
|
|
7
|
+
isOpen: boolean;
|
|
8
|
+
onClose: () => void;
|
|
9
|
+
onLinked: () => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* "Create pre-order link" (req #11) — manual, opt-in only, per main item.
|
|
13
|
+
* Shared between AdminShipmentLotItemsView and AdminShipmentProjectionsView.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ShipmentItemLinkModal({ shipmentId, lotId, itemId, itemTitle, isOpen, onClose, onLinked, }: ShipmentItemLinkModalProps): React.JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { useApiMutation } from "@mohasinac/appkit/client";
|
|
5
|
+
import { Button, FieldInput, Modal, Row, Stack, Text, Toggle } from "../../../ui";
|
|
6
|
+
import { apiClient } from "../../../http";
|
|
7
|
+
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
8
|
+
import { ProductInlineSelect } from "../../seller/components/ProductInlineSelect";
|
|
9
|
+
/**
|
|
10
|
+
* "Create pre-order link" (req #11) — manual, opt-in only, per main item.
|
|
11
|
+
* Shared between AdminShipmentLotItemsView and AdminShipmentProjectionsView.
|
|
12
|
+
*/
|
|
13
|
+
export function ShipmentItemLinkModal({ shipmentId, lotId, itemId, itemTitle, isOpen, onClose, onLinked, }) {
|
|
14
|
+
const [mode, setMode] = React.useState("create");
|
|
15
|
+
const [existingProductId, setExistingProductId] = React.useState(null);
|
|
16
|
+
const [categorySlugs, setCategorySlugs] = React.useState("");
|
|
17
|
+
const [brandSlug, setBrandSlug] = React.useState("");
|
|
18
|
+
const linkMutation = useApiMutation({
|
|
19
|
+
successMessage: "Item linked to product",
|
|
20
|
+
mutationFn: () => {
|
|
21
|
+
const body = mode === "link"
|
|
22
|
+
? { mode: "link", productId: existingProductId }
|
|
23
|
+
: {
|
|
24
|
+
mode: "create",
|
|
25
|
+
categorySlugs: categorySlugs.split(",").map((s) => s.trim()).filter(Boolean),
|
|
26
|
+
brandSlug: brandSlug.trim() || undefined,
|
|
27
|
+
};
|
|
28
|
+
return apiClient.post(ADMIN_ENDPOINTS.SHIPMENT_LOT_ITEM_LINK(shipmentId, lotId, itemId), body);
|
|
29
|
+
},
|
|
30
|
+
onSuccess: () => {
|
|
31
|
+
onLinked();
|
|
32
|
+
onClose();
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
const canSubmit = mode === "link" ? !!existingProductId : categorySlugs.trim().length > 0;
|
|
36
|
+
return (_jsx(Modal, { isOpen: isOpen, onClose: onClose, title: `Create pre-order link — ${itemTitle}`, size: "md", children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { variant: "secondary", children: "Links this item to a real product listing. This is a deliberate, one-time action \u2014 nothing links automatically." }), _jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Toggle, { checked: mode === "create", onChange: (checked) => setMode(checked ? "create" : "link"), size: "sm" }), _jsx(Text, { children: mode === "create" ? "Create a new pre-order product" : "Link to an existing product" })] }), mode === "link" ? (_jsx(ProductInlineSelect, { scope: "admin", value: existingProductId, onChange: setExistingProductId, placeholder: "Search products\u2026" })) : (_jsxs(Stack, { gap: "sm", children: [_jsx(FieldInput, { name: "categorySlugs", label: "Category slugs (comma-separated)", required: true, value: categorySlugs, onChange: setCategorySlugs, placeholder: "category-action-figures" }), _jsx(FieldInput, { name: "brandSlug", label: "Brand slug (optional)", value: brandSlug, onChange: setBrandSlug })] })), _jsx(Button, { isLoading: linkMutation.isPending, disabled: !canSubmit, onClick: () => linkMutation.mutate(), children: mode === "create" ? "Create & Link" : "Link" })] }) }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ShipmentDocument, ShipmentLot, ShipmentItem } from "../schemas/firestore";
|
|
2
|
+
interface ListMeta {
|
|
3
|
+
total: number;
|
|
4
|
+
page: number;
|
|
5
|
+
pageSize: number;
|
|
6
|
+
totalPages: number;
|
|
7
|
+
hasMore: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface ShipmentsListResponse {
|
|
10
|
+
shipments: ShipmentDocument[];
|
|
11
|
+
meta: ListMeta;
|
|
12
|
+
}
|
|
13
|
+
export interface UseShipmentsParams {
|
|
14
|
+
page?: number;
|
|
15
|
+
pageSize?: number;
|
|
16
|
+
sorts?: string;
|
|
17
|
+
filters?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function useShipments(params?: UseShipmentsParams): {
|
|
20
|
+
shipments: ShipmentDocument[];
|
|
21
|
+
meta: ListMeta | undefined;
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
error: string | null;
|
|
24
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<ShipmentsListResponse>, Error>>;
|
|
25
|
+
};
|
|
26
|
+
export declare function useShipment(shipmentId?: string): {
|
|
27
|
+
shipment: NoInfer<ShipmentDocument> | undefined;
|
|
28
|
+
lots: ShipmentLot[];
|
|
29
|
+
isLoading: boolean;
|
|
30
|
+
error: string | null;
|
|
31
|
+
refetchShipment: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<ShipmentDocument>, Error>>;
|
|
32
|
+
refetchLots: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<{
|
|
33
|
+
lots: ShipmentLot[];
|
|
34
|
+
}>, Error>>;
|
|
35
|
+
};
|
|
36
|
+
interface ShipmentItemsListResponse {
|
|
37
|
+
items: ShipmentItem[];
|
|
38
|
+
meta: ListMeta;
|
|
39
|
+
}
|
|
40
|
+
export interface UseShipmentItemsParams {
|
|
41
|
+
page?: number;
|
|
42
|
+
pageSize?: number;
|
|
43
|
+
sorts?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function useShipmentItems(shipmentId?: string, lotId?: string, params?: UseShipmentItemsParams): {
|
|
46
|
+
items: ShipmentItem[];
|
|
47
|
+
meta: ListMeta | undefined;
|
|
48
|
+
isLoading: boolean;
|
|
49
|
+
error: string | null;
|
|
50
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<ShipmentItemsListResponse>, Error>>;
|
|
51
|
+
};
|
|
52
|
+
interface ShipmentProjectionsResponse {
|
|
53
|
+
lots: ShipmentLot[];
|
|
54
|
+
meta: ListMeta;
|
|
55
|
+
}
|
|
56
|
+
export interface UseShipmentProjectionsParams {
|
|
57
|
+
page?: number;
|
|
58
|
+
pageSize?: number;
|
|
59
|
+
sorts?: string;
|
|
60
|
+
filters?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function useShipmentProjections(params?: UseShipmentProjectionsParams): {
|
|
63
|
+
lots: ShipmentLot[];
|
|
64
|
+
meta: ListMeta | undefined;
|
|
65
|
+
isLoading: boolean;
|
|
66
|
+
error: string | null;
|
|
67
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<NoInfer<ShipmentProjectionsResponse>, Error>>;
|
|
68
|
+
};
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { apiClient } from "../../../http";
|
|
4
|
+
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
5
|
+
export function useShipments(params = {}) {
|
|
6
|
+
const sp = new URLSearchParams();
|
|
7
|
+
if (params.page)
|
|
8
|
+
sp.set("page", String(params.page));
|
|
9
|
+
if (params.pageSize)
|
|
10
|
+
sp.set("pageSize", String(params.pageSize));
|
|
11
|
+
if (params.sorts)
|
|
12
|
+
sp.set("sorts", params.sorts);
|
|
13
|
+
if (params.filters)
|
|
14
|
+
sp.set("filters", params.filters);
|
|
15
|
+
const qs = sp.toString();
|
|
16
|
+
const { data, isLoading, error, refetch } = useQuery({
|
|
17
|
+
queryKey: ["admin", "shipments", qs],
|
|
18
|
+
queryFn: () => apiClient.get(`${ADMIN_ENDPOINTS.SHIPMENTS}${qs ? `?${qs}` : ""}`),
|
|
19
|
+
});
|
|
20
|
+
return {
|
|
21
|
+
shipments: data?.shipments ?? [],
|
|
22
|
+
meta: data?.meta,
|
|
23
|
+
isLoading,
|
|
24
|
+
error: error instanceof Error ? error.message : null,
|
|
25
|
+
refetch,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function useShipment(shipmentId) {
|
|
29
|
+
const shipmentQuery = useQuery({
|
|
30
|
+
queryKey: ["admin", "shipment", shipmentId],
|
|
31
|
+
queryFn: () => apiClient.get(ADMIN_ENDPOINTS.SHIPMENT_BY_ID(shipmentId)),
|
|
32
|
+
enabled: !!shipmentId,
|
|
33
|
+
});
|
|
34
|
+
const lotsQuery = useQuery({
|
|
35
|
+
queryKey: ["admin", "shipment", shipmentId, "lots"],
|
|
36
|
+
queryFn: () => apiClient.get(ADMIN_ENDPOINTS.SHIPMENT_LOTS(shipmentId)),
|
|
37
|
+
enabled: !!shipmentId,
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
shipment: shipmentQuery.data,
|
|
41
|
+
lots: lotsQuery.data?.lots ?? [],
|
|
42
|
+
isLoading: shipmentQuery.isLoading || lotsQuery.isLoading,
|
|
43
|
+
error: shipmentQuery.error instanceof Error
|
|
44
|
+
? shipmentQuery.error.message
|
|
45
|
+
: lotsQuery.error instanceof Error
|
|
46
|
+
? lotsQuery.error.message
|
|
47
|
+
: null,
|
|
48
|
+
refetchShipment: shipmentQuery.refetch,
|
|
49
|
+
refetchLots: lotsQuery.refetch,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function useShipmentItems(shipmentId, lotId, params = {}) {
|
|
53
|
+
const sp = new URLSearchParams();
|
|
54
|
+
if (params.page)
|
|
55
|
+
sp.set("page", String(params.page));
|
|
56
|
+
if (params.pageSize)
|
|
57
|
+
sp.set("pageSize", String(params.pageSize));
|
|
58
|
+
if (params.sorts)
|
|
59
|
+
sp.set("sorts", params.sorts);
|
|
60
|
+
const qs = sp.toString();
|
|
61
|
+
const { data, isLoading, error, refetch } = useQuery({
|
|
62
|
+
queryKey: ["admin", "shipment", shipmentId, "lot", lotId, "items", qs],
|
|
63
|
+
queryFn: () => apiClient.get(`${ADMIN_ENDPOINTS.SHIPMENT_LOT_ITEMS(shipmentId, lotId)}${qs ? `?${qs}` : ""}`),
|
|
64
|
+
enabled: !!shipmentId && !!lotId,
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
items: data?.items ?? [],
|
|
68
|
+
meta: data?.meta,
|
|
69
|
+
isLoading,
|
|
70
|
+
error: error instanceof Error ? error.message : null,
|
|
71
|
+
refetch,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function useShipmentProjections(params = {}) {
|
|
75
|
+
const sp = new URLSearchParams();
|
|
76
|
+
if (params.page)
|
|
77
|
+
sp.set("page", String(params.page));
|
|
78
|
+
if (params.pageSize)
|
|
79
|
+
sp.set("pageSize", String(params.pageSize));
|
|
80
|
+
if (params.sorts)
|
|
81
|
+
sp.set("sorts", params.sorts);
|
|
82
|
+
if (params.filters)
|
|
83
|
+
sp.set("filters", params.filters);
|
|
84
|
+
const qs = sp.toString();
|
|
85
|
+
const { data, isLoading, error, refetch } = useQuery({
|
|
86
|
+
queryKey: ["admin", "shipments", "projections", qs],
|
|
87
|
+
queryFn: () => apiClient.get(`${ADMIN_ENDPOINTS.SHIPMENTS_PROJECTIONS}${qs ? `?${qs}` : ""}`),
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
lots: data?.lots ?? [],
|
|
91
|
+
meta: data?.meta,
|
|
92
|
+
isLoading,
|
|
93
|
+
error: error instanceof Error ? error.message : null,
|
|
94
|
+
refetch,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./schemas";
|
|
2
|
+
export * from "./utils/cost-allocation";
|
|
3
|
+
export * from "./hooks/useShipments";
|
|
4
|
+
export { AdminShipmentsView } from "./components/AdminShipmentsView";
|
|
5
|
+
export type { AdminShipmentsViewProps } from "./components/AdminShipmentsView";
|
|
6
|
+
export { AdminShipmentEditorView } from "./components/AdminShipmentEditorView";
|
|
7
|
+
export type { AdminShipmentEditorViewProps } from "./components/AdminShipmentEditorView";
|
|
8
|
+
export { AdminShipmentLotItemsView } from "./components/AdminShipmentLotItemsView";
|
|
9
|
+
export type { AdminShipmentLotItemsViewProps } from "./components/AdminShipmentLotItemsView";
|
|
10
|
+
export { AdminShipmentProjectionsView } from "./components/AdminShipmentProjectionsView";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from "./schemas";
|
|
2
|
+
export * from "./utils/cost-allocation";
|
|
3
|
+
export * from "./hooks/useShipments";
|
|
4
|
+
export { AdminShipmentsView } from "./components/AdminShipmentsView";
|
|
5
|
+
export { AdminShipmentEditorView } from "./components/AdminShipmentEditorView";
|
|
6
|
+
export { AdminShipmentLotItemsView } from "./components/AdminShipmentLotItemsView";
|
|
7
|
+
export { AdminShipmentProjectionsView } from "./components/AdminShipmentProjectionsView";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const manifest = {
|
|
2
|
+
name: "shipments",
|
|
3
|
+
i18nNamespace: "shipments",
|
|
4
|
+
envKeys: [],
|
|
5
|
+
routes: [
|
|
6
|
+
{ segment: "[locale]/admin/shipments", exports: { default: "AdminShipmentsView" } },
|
|
7
|
+
{ segment: "[locale]/admin/shipments/new", exports: { default: "AdminShipmentEditorView" } },
|
|
8
|
+
{ segment: "[locale]/admin/shipments/[id]/edit", exports: { default: "AdminShipmentEditorView" } },
|
|
9
|
+
{
|
|
10
|
+
segment: "[locale]/admin/shipments/[id]/lots/[lotId]/items",
|
|
11
|
+
exports: { default: "AdminShipmentLotItemsView" },
|
|
12
|
+
},
|
|
13
|
+
{ segment: "[locale]/admin/shipments/projections", exports: { default: "AdminShipmentProjectionsView" } },
|
|
14
|
+
],
|
|
15
|
+
apiRoutes: [
|
|
16
|
+
{ segment: "api/admin/shipments", methods: ["GET", "POST"] },
|
|
17
|
+
{ segment: "api/admin/shipments/[id]", methods: ["GET", "PATCH", "DELETE"] },
|
|
18
|
+
{ segment: "api/admin/shipments/[id]/lots", methods: ["GET", "POST"] },
|
|
19
|
+
{ segment: "api/admin/shipments/[id]/lots/[lotId]", methods: ["GET", "PATCH", "DELETE"] },
|
|
20
|
+
{ segment: "api/admin/shipments/[id]/lots/[lotId]/items", methods: ["GET", "POST"] },
|
|
21
|
+
{ segment: "api/admin/shipments/[id]/lots/[lotId]/items/bulk", methods: ["POST"] },
|
|
22
|
+
{ segment: "api/admin/shipments/[id]/lots/[lotId]/items/[itemId]", methods: ["PATCH", "DELETE"] },
|
|
23
|
+
{ segment: "api/admin/shipments/[id]/lots/[lotId]/items/[itemId]/link", methods: ["POST"] },
|
|
24
|
+
{ segment: "api/admin/shipments/projections", methods: ["GET"] },
|
|
25
|
+
],
|
|
26
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipment Items Repository — one doc per individually-tracked "main" item,
|
|
3
|
+
* FK'd to a lot + shipment. Capped at MAX_ITEMS_PER_LOT (500) per lot —
|
|
4
|
+
* exactly Firestore's native batched-write limit, so bulkCreate() writes an
|
|
5
|
+
* entire import in a single WriteBatch with no chunking logic.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseRepository, type SieveModel, type FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
8
|
+
import { type ShipmentItem, type ShipmentItemCreateInput, type ShipmentItemUpdateInput } from "../schemas/firestore";
|
|
9
|
+
export declare class ShipmentItemsRepository extends BaseRepository<ShipmentItem> {
|
|
10
|
+
constructor();
|
|
11
|
+
listByLot(lotId: string, model?: SieveModel): Promise<FirebaseSieveResult<ShipmentItem>>;
|
|
12
|
+
countByLot(lotId: string): Promise<number>;
|
|
13
|
+
/** Cheap bounded existence check — any item in this lot still linked to a product? */
|
|
14
|
+
hasLinkedItemsInLot(lotId: string): Promise<boolean>;
|
|
15
|
+
createItem(shipmentId: string, lotId: string, input: ShipmentItemCreateInput): Promise<ShipmentItem>;
|
|
16
|
+
/**
|
|
17
|
+
* Writes an entire bulk-paste import in a single Firestore WriteBatch
|
|
18
|
+
* (≤500 ops — Firestore's own batch cap, matching MAX_ITEMS_PER_LOT
|
|
19
|
+
* exactly, so no chunking is ever needed).
|
|
20
|
+
*/
|
|
21
|
+
bulkCreate(shipmentId: string, lotId: string, rows: ShipmentItemCreateInput[]): Promise<number>;
|
|
22
|
+
updateItem(itemId: string, input: ShipmentItemUpdateInput): Promise<ShipmentItem>;
|
|
23
|
+
/** Clears a product link without touching the linked product itself. */
|
|
24
|
+
unlink(itemId: string): Promise<ShipmentItem>;
|
|
25
|
+
static readonly SIEVE_FIELDS: {
|
|
26
|
+
id: {
|
|
27
|
+
canFilter: boolean;
|
|
28
|
+
canSort: boolean;
|
|
29
|
+
};
|
|
30
|
+
shipmentId: {
|
|
31
|
+
canFilter: boolean;
|
|
32
|
+
canSort: boolean;
|
|
33
|
+
};
|
|
34
|
+
lotId: {
|
|
35
|
+
canFilter: boolean;
|
|
36
|
+
canSort: boolean;
|
|
37
|
+
};
|
|
38
|
+
title: {
|
|
39
|
+
canFilter: boolean;
|
|
40
|
+
canSort: boolean;
|
|
41
|
+
};
|
|
42
|
+
price: {
|
|
43
|
+
canFilter: boolean;
|
|
44
|
+
canSort: boolean;
|
|
45
|
+
};
|
|
46
|
+
linkedProductId: {
|
|
47
|
+
canFilter: boolean;
|
|
48
|
+
canSort: boolean;
|
|
49
|
+
};
|
|
50
|
+
createdAt: {
|
|
51
|
+
canFilter: boolean;
|
|
52
|
+
canSort: boolean;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export declare const shipmentItemsRepository: ShipmentItemsRepository;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipment Items Repository — one doc per individually-tracked "main" item,
|
|
3
|
+
* FK'd to a lot + shipment. Capped at MAX_ITEMS_PER_LOT (500) per lot —
|
|
4
|
+
* exactly Firestore's native batched-write limit, so bulkCreate() writes an
|
|
5
|
+
* entire import in a single WriteBatch with no chunking logic.
|
|
6
|
+
*/
|
|
7
|
+
import { BaseRepository, } from "../../../providers/db-firebase";
|
|
8
|
+
import { SHIPMENT_ITEM_COLLECTION, SHIPMENT_ITEM_FIELDS, MAX_ITEMS_PER_LOT, } from "../schemas/firestore";
|
|
9
|
+
import { ValidationError } from "../../../errors";
|
|
10
|
+
import { sieveAnd, sieveFilter, SIEVE_OP } from "../../../utils/sieve-builder";
|
|
11
|
+
export class ShipmentItemsRepository extends BaseRepository {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(SHIPMENT_ITEM_COLLECTION);
|
|
14
|
+
}
|
|
15
|
+
async listByLot(lotId, model) {
|
|
16
|
+
return this.sieveQuery({ ...(model ?? {}), filters: sieveAnd(sieveFilter("lotId", SIEVE_OP.EQ, lotId), model?.filters) }, ShipmentItemsRepository.SIEVE_FIELDS, { defaultPageSize: 50, maxPageSize: 100 });
|
|
17
|
+
}
|
|
18
|
+
async countByLot(lotId) {
|
|
19
|
+
const snap = await this.getCollection().where(SHIPMENT_ITEM_FIELDS.LOT_ID, "==", lotId).count().get();
|
|
20
|
+
return snap.data().count;
|
|
21
|
+
}
|
|
22
|
+
/** Cheap bounded existence check — any item in this lot still linked to a product? */
|
|
23
|
+
async hasLinkedItemsInLot(lotId) {
|
|
24
|
+
const snap = await this.getCollection()
|
|
25
|
+
.where(SHIPMENT_ITEM_FIELDS.LOT_ID, "==", lotId)
|
|
26
|
+
.where(SHIPMENT_ITEM_FIELDS.LINKED_PRODUCT_ID, "!=", null)
|
|
27
|
+
.limit(1)
|
|
28
|
+
.get();
|
|
29
|
+
return !snap.empty;
|
|
30
|
+
}
|
|
31
|
+
async createItem(shipmentId, lotId, input) {
|
|
32
|
+
const existing = await this.countByLot(lotId);
|
|
33
|
+
if (existing >= MAX_ITEMS_PER_LOT) {
|
|
34
|
+
throw new ValidationError(`Lot already has the maximum of ${MAX_ITEMS_PER_LOT} tracked items`);
|
|
35
|
+
}
|
|
36
|
+
return this.create({ ...input, shipmentId, lotId });
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Writes an entire bulk-paste import in a single Firestore WriteBatch
|
|
40
|
+
* (≤500 ops — Firestore's own batch cap, matching MAX_ITEMS_PER_LOT
|
|
41
|
+
* exactly, so no chunking is ever needed).
|
|
42
|
+
*/
|
|
43
|
+
async bulkCreate(shipmentId, lotId, rows) {
|
|
44
|
+
const existing = await this.countByLot(lotId);
|
|
45
|
+
if (existing + rows.length > MAX_ITEMS_PER_LOT) {
|
|
46
|
+
throw new ValidationError(`This import would exceed the ${MAX_ITEMS_PER_LOT}-item cap for this lot (${existing} already tracked, ${rows.length} in this import)`);
|
|
47
|
+
}
|
|
48
|
+
const batch = this.db.batch();
|
|
49
|
+
rows.forEach((row) => {
|
|
50
|
+
this.createInBatch(batch, { ...row, shipmentId, lotId });
|
|
51
|
+
});
|
|
52
|
+
await batch.commit();
|
|
53
|
+
return rows.length;
|
|
54
|
+
}
|
|
55
|
+
async updateItem(itemId, input) {
|
|
56
|
+
return this.update(itemId, input);
|
|
57
|
+
}
|
|
58
|
+
/** Clears a product link without touching the linked product itself. */
|
|
59
|
+
async unlink(itemId) {
|
|
60
|
+
// `null`, not `undefined` — prepareForFirestore() strips undefined
|
|
61
|
+
// values before every write, which would leave the fields untouched.
|
|
62
|
+
return this.update(itemId, {
|
|
63
|
+
linkedProductId: null,
|
|
64
|
+
linkedProductSlug: null,
|
|
65
|
+
linkedProductListingType: null,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
ShipmentItemsRepository.SIEVE_FIELDS = {
|
|
70
|
+
id: { canFilter: true, canSort: false },
|
|
71
|
+
shipmentId: { canFilter: true, canSort: false },
|
|
72
|
+
lotId: { canFilter: true, canSort: false },
|
|
73
|
+
title: { canFilter: true, canSort: true },
|
|
74
|
+
price: { canFilter: true, canSort: true },
|
|
75
|
+
linkedProductId: { canFilter: true, canSort: false },
|
|
76
|
+
createdAt: { canFilter: true, canSort: true },
|
|
77
|
+
};
|
|
78
|
+
export const shipmentItemsRepository = new ShipmentItemsRepository();
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipment Lots Repository — one doc per lot, FK'd to a shipment.
|
|
3
|
+
*/
|
|
4
|
+
import { BaseRepository, type SieveModel, type FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
5
|
+
import { type ShipmentLot, type ShipmentLotCreateInput, type ShipmentLotUpdateInput } from "../schemas/firestore";
|
|
6
|
+
export declare class ShipmentLotsRepository extends BaseRepository<ShipmentLot> {
|
|
7
|
+
constructor();
|
|
8
|
+
listByShipment(shipmentId: string): Promise<ShipmentLot[]>;
|
|
9
|
+
createLot(shipmentId: string, shipmentStatus: ShipmentLot["shipmentStatus"], input: ShipmentLotCreateInput): Promise<ShipmentLot>;
|
|
10
|
+
updateLot(lotId: string, input: ShipmentLotUpdateInput): Promise<ShipmentLot>;
|
|
11
|
+
/**
|
|
12
|
+
* Real, paginated, persisted Projections list — one row per lot across
|
|
13
|
+
* every non-cancelled shipment, sorted by whichever computed field the
|
|
14
|
+
* admin picks. Reads the persisted rollup fields only; never recomputes.
|
|
15
|
+
*/
|
|
16
|
+
listForProjections(model: SieveModel): Promise<FirebaseSieveResult<ShipmentLot>>;
|
|
17
|
+
static readonly SIEVE_FIELDS: {
|
|
18
|
+
id: {
|
|
19
|
+
canFilter: boolean;
|
|
20
|
+
canSort: boolean;
|
|
21
|
+
};
|
|
22
|
+
shipmentId: {
|
|
23
|
+
canFilter: boolean;
|
|
24
|
+
canSort: boolean;
|
|
25
|
+
};
|
|
26
|
+
shipmentStatus: {
|
|
27
|
+
canFilter: boolean;
|
|
28
|
+
canSort: boolean;
|
|
29
|
+
};
|
|
30
|
+
lotName: {
|
|
31
|
+
canFilter: boolean;
|
|
32
|
+
canSort: boolean;
|
|
33
|
+
};
|
|
34
|
+
projectedProfitPaise: {
|
|
35
|
+
canFilter: boolean;
|
|
36
|
+
canSort: boolean;
|
|
37
|
+
};
|
|
38
|
+
projectedRevenuePaise: {
|
|
39
|
+
canFilter: boolean;
|
|
40
|
+
canSort: boolean;
|
|
41
|
+
};
|
|
42
|
+
createdAt: {
|
|
43
|
+
canFilter: boolean;
|
|
44
|
+
canSort: boolean;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export declare const shipmentLotsRepository: ShipmentLotsRepository;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shipment Lots Repository — one doc per lot, FK'd to a shipment.
|
|
3
|
+
*/
|
|
4
|
+
import { BaseRepository, } from "../../../providers/db-firebase";
|
|
5
|
+
import { SHIPMENT_LOT_COLLECTION, SHIPMENT_LOT_FIELDS, } from "../schemas/firestore";
|
|
6
|
+
export class ShipmentLotsRepository extends BaseRepository {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(SHIPMENT_LOT_COLLECTION);
|
|
9
|
+
}
|
|
10
|
+
async listByShipment(shipmentId) {
|
|
11
|
+
const snapshot = await this.getCollection()
|
|
12
|
+
.where(SHIPMENT_LOT_FIELDS.SHIPMENT_ID, "==", shipmentId)
|
|
13
|
+
.orderBy(SHIPMENT_LOT_FIELDS.CREATED_AT, "asc")
|
|
14
|
+
.get();
|
|
15
|
+
return snapshot.docs.map((doc) => this.mapDoc(doc));
|
|
16
|
+
}
|
|
17
|
+
async createLot(shipmentId, shipmentStatus, input) {
|
|
18
|
+
return this.create({
|
|
19
|
+
...input,
|
|
20
|
+
shipmentId,
|
|
21
|
+
shipmentStatus,
|
|
22
|
+
itemCount: 0,
|
|
23
|
+
mainItemsProjectedRevenuePaise: 0,
|
|
24
|
+
customsAllocatedPaise: 0,
|
|
25
|
+
shippingAllocatedPaise: 0,
|
|
26
|
+
totalLandedCostPaise: input.purchaseCostPaise,
|
|
27
|
+
projectedRevenuePaise: input.remainderEstimatedValuePaise ?? 0,
|
|
28
|
+
projectedProfitPaise: (input.remainderEstimatedValuePaise ?? 0) - input.purchaseCostPaise,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async updateLot(lotId, input) {
|
|
32
|
+
return this.update(lotId, input);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Real, paginated, persisted Projections list — one row per lot across
|
|
36
|
+
* every non-cancelled shipment, sorted by whichever computed field the
|
|
37
|
+
* admin picks. Reads the persisted rollup fields only; never recomputes.
|
|
38
|
+
*/
|
|
39
|
+
async listForProjections(model) {
|
|
40
|
+
return this.sieveQuery(model, ShipmentLotsRepository.SIEVE_FIELDS, {
|
|
41
|
+
defaultPageSize: 25,
|
|
42
|
+
maxPageSize: 100,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
ShipmentLotsRepository.SIEVE_FIELDS = {
|
|
47
|
+
id: { canFilter: true, canSort: false },
|
|
48
|
+
shipmentId: { canFilter: true, canSort: false },
|
|
49
|
+
shipmentStatus: { canFilter: true, canSort: false },
|
|
50
|
+
lotName: { canFilter: true, canSort: true },
|
|
51
|
+
projectedProfitPaise: { canFilter: true, canSort: true },
|
|
52
|
+
projectedRevenuePaise: { canFilter: true, canSort: true },
|
|
53
|
+
createdAt: { canFilter: true, canSort: true },
|
|
54
|
+
};
|
|
55
|
+
export const shipmentLotsRepository = new ShipmentLotsRepository();
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procurement Shipments Repository — header document only.
|
|
3
|
+
* Lots/items live in ShipmentLotsRepository / ShipmentItemsRepository.
|
|
4
|
+
*/
|
|
5
|
+
import { BaseRepository, type SieveModel, type FirebaseSieveResult } from "../../../providers/db-firebase";
|
|
6
|
+
import { type ShipmentDocument, type ShipmentCreateInput, type ShipmentUpdateInput } from "../schemas/firestore";
|
|
7
|
+
export declare class ShipmentsRepository extends BaseRepository<ShipmentDocument> {
|
|
8
|
+
constructor();
|
|
9
|
+
findByShipmentNumber(shipmentNumber: string): Promise<ShipmentDocument | null>;
|
|
10
|
+
private assertShipmentNumberAvailable;
|
|
11
|
+
create(input: ShipmentCreateInput): Promise<ShipmentDocument>;
|
|
12
|
+
update(shipmentId: string, input: ShipmentUpdateInput): Promise<ShipmentDocument>;
|
|
13
|
+
/** Cheap bounded existence check — any item under this shipment still linked to a product? */
|
|
14
|
+
private hasLinkedItems;
|
|
15
|
+
/**
|
|
16
|
+
* Blocks deletion if any item is still linked to a product — unlink first.
|
|
17
|
+
* Cascade-deleting the shipment's lots/items themselves is handled by the
|
|
18
|
+
* onShipmentDeleted Firestore trigger (Function #3), not here — this keeps
|
|
19
|
+
* the route fast regardless of how many items the shipment had.
|
|
20
|
+
*/
|
|
21
|
+
delete(shipmentId: string): Promise<void>;
|
|
22
|
+
static readonly SIEVE_FIELDS: {
|
|
23
|
+
id: {
|
|
24
|
+
canFilter: boolean;
|
|
25
|
+
canSort: boolean;
|
|
26
|
+
};
|
|
27
|
+
shipmentNumber: {
|
|
28
|
+
canFilter: boolean;
|
|
29
|
+
canSort: boolean;
|
|
30
|
+
};
|
|
31
|
+
supplierName: {
|
|
32
|
+
canFilter: boolean;
|
|
33
|
+
canSort: boolean;
|
|
34
|
+
};
|
|
35
|
+
status: {
|
|
36
|
+
canFilter: boolean;
|
|
37
|
+
canSort: boolean;
|
|
38
|
+
};
|
|
39
|
+
etaDate: {
|
|
40
|
+
canFilter: boolean;
|
|
41
|
+
canSort: boolean;
|
|
42
|
+
};
|
|
43
|
+
createdAt: {
|
|
44
|
+
canFilter: boolean;
|
|
45
|
+
canSort: boolean;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
list(model: SieveModel): Promise<FirebaseSieveResult<ShipmentDocument>>;
|
|
49
|
+
}
|
|
50
|
+
export declare const shipmentsRepository: ShipmentsRepository;
|