@mohasinac/appkit 4.59.0 โ 4.60.1
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/.build-stamp.json +3 -3
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +62 -5
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +2 -2
- package/dist/_internal/server/features/brands/actions.js +78 -4
- package/dist/_internal/server/features/checkout/actions.d.ts +36 -13
- package/dist/_internal/server/features/checkout/actions.js +668 -183
- package/dist/_internal/server/features/checkout/supplier-identity.js +18 -1
- package/dist/_internal/server/features/gateway-events/index.d.ts +10 -0
- package/dist/_internal/server/features/gateway-events/index.js +10 -0
- package/dist/_internal/server/features/gateway-events/ingest.d.ts +127 -0
- package/dist/_internal/server/features/gateway-events/ingest.js +188 -0
- package/dist/_internal/server/features/gateway-events/redact.d.ts +66 -0
- package/dist/_internal/server/features/gateway-events/redact.js +151 -0
- package/dist/_internal/server/features/grievance/actions.d.ts +63 -0
- package/dist/_internal/server/features/grievance/actions.js +173 -0
- package/dist/_internal/server/features/grievance/index.d.ts +8 -0
- package/dist/_internal/server/features/grievance/index.js +8 -0
- package/dist/_internal/server/features/grouped/data.js +28 -3
- package/dist/_internal/server/features/lottery/actions.js +99 -4
- package/dist/_internal/server/features/order-completion/actions.d.ts +92 -0
- package/dist/_internal/server/features/order-completion/actions.js +336 -0
- package/dist/_internal/server/features/order-completion/index.d.ts +7 -0
- package/dist/_internal/server/features/order-completion/index.js +7 -0
- package/dist/_internal/server/features/orders/actions.d.ts +13 -0
- package/dist/_internal/server/features/orders/actions.js +56 -2
- package/dist/_internal/server/features/orders/adapters.d.ts +20 -2
- package/dist/_internal/server/features/orders/adapters.js +44 -0
- package/dist/_internal/server/features/orders/cancellation-refund.d.ts +116 -0
- package/dist/_internal/server/features/orders/cancellation-refund.js +466 -0
- package/dist/_internal/server/features/orders/index.d.ts +2 -1
- package/dist/_internal/server/features/orders/index.js +1 -1
- package/dist/_internal/server/features/orders/service.d.ts +60 -0
- package/dist/_internal/server/features/orders/service.js +74 -0
- package/dist/_internal/server/features/payment-cases/disputes.d.ts +76 -0
- package/dist/_internal/server/features/payment-cases/disputes.js +241 -0
- package/dist/_internal/server/features/payment-cases/index.d.ts +9 -0
- package/dist/_internal/server/features/payment-cases/index.js +9 -0
- package/dist/_internal/server/features/payouts/actions.d.ts +28 -3
- package/dist/_internal/server/features/payouts/actions.js +84 -10
- package/dist/_internal/server/features/points/adjust.d.ts +61 -0
- package/dist/_internal/server/features/points/adjust.js +121 -0
- package/dist/_internal/server/features/points/award.d.ts +65 -0
- package/dist/_internal/server/features/points/award.js +145 -0
- package/dist/_internal/server/features/price-index/market.d.ts +33 -0
- package/dist/_internal/server/features/price-index/market.js +54 -1
- package/dist/_internal/server/features/products/data.js +40 -22
- package/dist/_internal/server/features/protection-claims/actions.d.ts +72 -0
- package/dist/_internal/server/features/protection-claims/actions.js +228 -0
- package/dist/_internal/server/features/protection-claims/index.d.ts +8 -0
- package/dist/_internal/server/features/protection-claims/index.js +8 -0
- package/dist/_internal/server/features/refunds/actions.d.ts +20 -0
- package/dist/_internal/server/features/refunds/actions.js +259 -17
- package/dist/_internal/server/features/refunds/capacity.d.ts +29 -0
- package/dist/_internal/server/features/refunds/capacity.js +37 -0
- package/dist/_internal/server/features/reviews/actions.js +3 -2
- package/dist/_internal/server/features/search/index-build/sources.js +20 -1
- package/dist/_internal/server/features/shipping/reconcile.d.ts +10 -1
- package/dist/_internal/server/features/shipping/reconcile.js +34 -3
- package/dist/_internal/server/features/shipping/reimbursement.d.ts +117 -0
- package/dist/_internal/server/features/shipping/reimbursement.js +223 -0
- package/dist/_internal/server/features/stores/tabs.d.ts +19 -4
- package/dist/_internal/server/features/stores/tabs.js +24 -4
- package/dist/_internal/server/functions/https.d.ts +31 -1
- package/dist/_internal/server/functions/https.js +52 -1
- package/dist/_internal/server/functions/scheduled.d.ts +72 -1
- package/dist/_internal/server/functions/scheduled.js +124 -1
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +62 -16
- package/dist/_internal/server/jobs/core/boxRollupReconcile.d.ts +46 -0
- package/dist/_internal/server/jobs/core/boxRollupReconcile.js +142 -0
- package/dist/_internal/server/jobs/core/dailyDataCleanup.js +149 -1
- package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +14 -0
- package/dist/_internal/server/jobs/core/dailyStatusDigest.js +79 -1
- package/dist/_internal/server/jobs/core/index.d.ts +2 -0
- package/dist/_internal/server/jobs/core/index.js +2 -0
- package/dist/_internal/server/jobs/core/marketPriceRollup.d.ts +64 -0
- package/dist/_internal/server/jobs/core/marketPriceRollup.js +153 -0
- package/dist/_internal/server/jobs/core/obligationSweep.d.ts +36 -0
- package/dist/_internal/server/jobs/core/obligationSweep.js +503 -0
- package/dist/_internal/server/jobs/core/paymentReconcile.d.ts +79 -0
- package/dist/_internal/server/jobs/core/paymentReconcile.js +614 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +34 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +35 -4
- package/dist/_internal/server/jobs/handlers/boxRollupReconcile.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/boxRollupReconcile.js +15 -0
- package/dist/_internal/server/jobs/handlers/countersReconcileNow.d.ts +65 -0
- package/dist/_internal/server/jobs/handlers/countersReconcileNow.js +89 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +5 -0
- package/dist/_internal/server/jobs/handlers/index.js +5 -0
- package/dist/_internal/server/jobs/handlers/marketPriceRollup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/marketPriceRollup.js +2 -0
- package/dist/_internal/server/jobs/handlers/obligationSweep.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/obligationSweep.js +15 -0
- package/dist/_internal/server/jobs/handlers/onShipmentAllocationSync.js +30 -1
- package/dist/_internal/server/jobs/handlers/paymentReconcile.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/paymentReconcile.js +6 -0
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +71 -0
- package/dist/_internal/shared/checkout/coupon-discount.d.ts +73 -0
- package/dist/_internal/shared/checkout/coupon-discount.js +103 -0
- package/dist/_internal/shared/checkout/lanes.d.ts +42 -0
- package/dist/_internal/shared/checkout/lanes.js +46 -0
- package/dist/_internal/shared/checkout/order-math.d.ts +149 -1
- package/dist/_internal/shared/checkout/order-math.js +251 -3
- package/dist/_internal/shared/checkout/refundable-base.d.ts +116 -0
- package/dist/_internal/shared/checkout/refundable-base.js +122 -0
- package/dist/_internal/shared/features/auctions/config.d.ts +14 -1
- package/dist/_internal/shared/features/auctions/config.js +30 -1
- package/dist/_internal/shared/features/brands/schema.d.ts +42 -0
- package/dist/_internal/shared/features/brands/schema.js +18 -0
- package/dist/_internal/shared/features/orders/refund-copy.d.ts +22 -0
- package/dist/_internal/shared/features/orders/refund-copy.js +34 -0
- package/dist/_internal/shared/features/print/label-profiles.d.ts +198 -0
- package/dist/_internal/shared/features/print/label-profiles.js +350 -0
- package/dist/_internal/shared/features/products/to-product-item.js +33 -5
- package/dist/_internal/shared/fees/calculator.d.ts +31 -2
- package/dist/_internal/shared/fees/calculator.js +103 -5
- package/dist/_internal/shared/fees/india-states.d.ts +195 -0
- package/dist/_internal/shared/fees/india-states.js +190 -0
- package/dist/_internal/shared/fees/payout-hold.d.ts +80 -0
- package/dist/_internal/shared/fees/payout-hold.js +74 -0
- package/dist/_internal/shared/obligations/deadlines.d.ts +94 -0
- package/dist/_internal/shared/obligations/deadlines.js +155 -0
- package/dist/_internal/shared/shipping/quote.d.ts +96 -0
- package/dist/_internal/shared/shipping/quote.js +67 -0
- package/dist/_internal/shared/time/business-days.d.ts +91 -0
- package/dist/_internal/shared/time/business-days.js +185 -0
- package/dist/cli/index.js +0 -2
- package/dist/client.d.ts +10 -4
- package/dist/client.js +29 -3
- package/dist/configs/tailwind.d.ts +0 -12
- package/dist/configs/tailwind.js +28 -15
- package/dist/constants/api-endpoints.d.ts +51 -9
- package/dist/constants/api-endpoints.js +23 -7
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.js +1 -1
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/payment.d.ts +131 -0
- package/dist/features/about/components/AboutView.js +1 -1
- package/dist/features/about/components/DeveloperView.js +5 -2
- package/dist/features/about/components/FAQPageView.js +2 -1
- package/dist/features/about/components/FeesView.js +2 -1
- package/dist/features/about/components/HelpPageView.js +2 -1
- package/dist/features/about/components/HowAuctionsWorkView.js +2 -1
- package/dist/features/about/components/HowCheckoutWorksView.js +2 -1
- package/dist/features/about/components/HowEmiWorksView.js +2 -1
- package/dist/features/about/components/HowOffersWorkView.js +2 -1
- package/dist/features/about/components/HowOrdersWorkView.js +2 -1
- package/dist/features/about/components/HowPayoutsWorkView.js +2 -1
- package/dist/features/about/components/HowPreOrdersWorkView.js +2 -1
- package/dist/features/about/components/HowReviewsWorkView.js +2 -1
- package/dist/features/about/components/PolicyPageView.js +2 -1
- package/dist/features/about/components/ProseHero.d.ts +73 -0
- package/dist/features/about/components/ProseHero.js +18 -0
- package/dist/features/about/components/SecurityPrivacyView.js +2 -1
- package/dist/features/about/components/ShippingPolicyView.js +2 -1
- package/dist/features/about/components/TrackOrderView.js +2 -1
- package/dist/features/about/components/UnauthorizedView.js +1 -1
- package/dist/features/about/index.d.ts +2 -0
- package/dist/features/about/index.js +5 -0
- package/dist/features/account/actions/address-actions.d.ts +26 -2
- package/dist/features/account/actions/address-actions.js +25 -1
- package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
- package/dist/features/account/components/NotificationPreferencesPanel.js +1 -1
- package/dist/features/account/components/UserOrdersView.js +17 -0
- package/dist/features/account/components/UserSidebar.js +1 -1
- package/dist/features/account/hooks/useNotifications.js +29 -0
- package/dist/features/admin/actions/admin-coupon-actions.js +36 -0
- package/dist/features/admin/components/AdminBeysView.js +2 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +2 -2
- package/dist/features/admin/components/AdminBrandEditorView.js +32 -2
- package/dist/features/admin/components/AdminBundleEditorView.js +1 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
- package/dist/features/admin/components/AdminCategoriesView.js +1 -1
- package/dist/features/admin/components/AdminCategoryEditorView.js +73 -17
- package/dist/features/admin/components/AdminContactEditorView.js +1 -1
- package/dist/features/admin/components/AdminCouponEditorView.js +26 -1
- package/dist/features/admin/components/AdminFaqEditorView.js +1 -1
- package/dist/features/admin/components/AdminFaqsView.js +2 -2
- package/dist/features/admin/components/AdminGatewayEventsView.d.ts +54 -0
- package/dist/features/admin/components/AdminGatewayEventsView.js +209 -0
- package/dist/features/admin/components/AdminGuideHubView.js +1 -1
- package/dist/features/admin/components/AdminMoneyCasesView.d.ts +60 -0
- package/dist/features/admin/components/AdminMoneyCasesView.js +287 -0
- package/dist/features/admin/components/AdminPartsView.js +2 -2
- package/dist/features/admin/components/AdminProductsView.js +75 -4
- package/dist/features/admin/components/AdminSidebar.js +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +65 -7
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -0
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +1 -1
- package/dist/features/admin/components/AdminSupportTicketsView.js +2 -2
- package/dist/features/admin/components/AdminTesterChecklistView.js +2 -2
- package/dist/features/admin/components/AdminUsersView.js +72 -1
- package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
- package/dist/features/admin/components/AdminViewCards.js +4 -4
- package/dist/features/admin/components/DataListingView.d.ts +28 -0
- package/dist/features/admin/components/DataListingView.js +175 -14
- package/dist/features/admin/components/DataTable.d.ts +12 -1
- package/dist/features/admin/components/DataTable.js +3 -3
- package/dist/features/admin/components/OwnerQuickActions.d.ts +1 -1
- package/dist/features/admin/components/OwnerQuickActions.js +60 -2
- package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +1 -1
- package/dist/features/admin/components/RecordOwnerQuickActions.js +61 -14
- package/dist/features/admin/components/analytics/AdminStatCard.d.ts +35 -1
- package/dist/features/admin/components/analytics/AdminStatCard.js +77 -2
- package/dist/features/admin/components/index.d.ts +4 -0
- package/dist/features/admin/components/index.js +6 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +156 -0
- package/dist/features/admin/constants/filter-tabs.js +106 -0
- package/dist/features/admin/repository/site-settings.repository.d.ts +22 -0
- package/dist/features/admin/repository/site-settings.repository.js +82 -1
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +21 -0
- package/dist/features/admin/schemas/admin-editor-forms.js +44 -0
- package/dist/features/admin/schemas/firestore.js +5 -1
- package/dist/features/admin/schemas/site-settings-form.js +30 -1
- package/dist/features/auctions/actions/bid-actions.js +13 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +2 -2
- package/dist/features/auctions/components/AuctionDetailPageView.js +3 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -0
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +5 -3
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +8 -1
- package/dist/features/auctions/components/PlaceBidFormClient.js +2 -2
- package/dist/features/audit-log/schemas/firestore.d.ts +28 -0
- package/dist/features/audit-log/schemas/firestore.js +14 -0
- package/dist/features/auth/permissions/constants.d.ts +17 -1
- package/dist/features/auth/permissions/constants.js +18 -0
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +1 -1
- package/dist/features/categories/api/[id]/description-template/route.js +107 -1
- package/dist/features/categories/components/BrandDetailPageView.js +2 -2
- package/dist/features/categories/components/BreadcrumbTrail.js +7 -1
- package/dist/features/categories/components/BundleDetailView.js +1 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +2 -2
- package/dist/features/categories/components/CategoryForm.js +12 -1
- package/dist/features/categories/components/CategoryTemplatePicker.js +38 -5
- package/dist/features/categories/repository/market-price-index.repository.d.ts +123 -0
- package/dist/features/categories/repository/market-price-index.repository.js +105 -0
- package/dist/features/categories/repository/price-observation.repository.d.ts +166 -0
- package/dist/features/categories/repository/price-observation.repository.js +132 -0
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/events/components/EventStatusBadge.js +1 -1
- package/dist/features/faq/components/FAQAccordion.js +2 -1
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +4 -4
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/filters/FilterFacetSection.js +1 -1
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/gateway-events/repository/gateway-events.repository.d.ts +117 -0
- package/dist/features/gateway-events/repository/gateway-events.repository.js +274 -0
- package/dist/features/gateway-events/schemas/firestore.d.ts +217 -0
- package/dist/features/gateway-events/schemas/firestore.js +125 -0
- package/dist/features/gateway-events/schemas/index.d.ts +81 -0
- package/dist/features/gateway-events/schemas/index.js +79 -0
- package/dist/features/grouped/components/GroupedListingDetailView.js +1 -1
- package/dist/features/homepage/components/AnnouncementBar.js +37 -1
- package/dist/features/homepage/components/AnnouncementBar.style.css +30 -0
- package/dist/features/homepage/components/BrandsSection.js +1 -1
- package/dist/features/homepage/components/CTABannerSection.js +1 -1
- package/dist/features/homepage/components/FeaturedBundlesSection.js +14 -24
- package/dist/features/homepage/components/HeroCarousel.js +2 -2
- package/dist/features/homepage/components/SocialPostCard.js +1 -1
- package/dist/features/inventory/components/AdminMoveLedgerView.d.ts +7 -0
- package/dist/features/inventory/components/AdminMoveLedgerView.js +157 -0
- package/dist/features/inventory/components/AdminStorageBoxesView.d.ts +11 -0
- package/dist/features/inventory/components/AdminStorageBoxesView.js +168 -0
- package/dist/features/inventory/components/ReceiveStationView.d.ts +39 -0
- package/dist/features/inventory/components/ReceiveStationView.js +413 -0
- package/dist/features/inventory/components/operator-message.d.ts +29 -0
- package/dist/features/inventory/components/operator-message.js +41 -0
- package/dist/features/inventory/index.d.ts +13 -0
- package/dist/features/inventory/index.js +28 -0
- package/dist/features/inventory/repository/inventory-movements.repository.d.ts +97 -0
- package/dist/features/inventory/repository/inventory-movements.repository.js +186 -0
- package/dist/features/inventory/repository/inventory-placements.repository.d.ts +179 -0
- package/dist/features/inventory/repository/inventory-placements.repository.js +345 -0
- package/dist/features/inventory/repository/storage-boxes.repository.d.ts +83 -0
- package/dist/features/inventory/repository/storage-boxes.repository.js +127 -0
- package/dist/features/inventory/schemas/firestore.d.ts +197 -0
- package/dist/features/inventory/schemas/firestore.js +159 -0
- package/dist/features/layout/AppLayoutShell.d.ts +12 -1
- package/dist/features/layout/AppLayoutShell.js +25 -12
- package/dist/features/layout/AutoBreadcrumbs.js +162 -3
- package/dist/features/layout/AutoBreadcrumbs.style.css +45 -0
- package/dist/features/layout/BottomNavbar.d.ts +1 -1
- package/dist/features/layout/BottomNavbar.js +2 -2
- package/dist/features/media/MediaAvatar.js +1 -1
- package/dist/features/media/MediaImage.d.ts +24 -4
- package/dist/features/media/MediaImage.js +44 -4
- package/dist/features/media/MediaLightbox.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/upload/MediaUploadField.js +91 -3
- package/dist/features/obligations/constants/policies.d.ts +92 -0
- package/dist/features/obligations/constants/policies.js +378 -0
- package/dist/features/obligations/repository/obligations.repository.d.ts +68 -0
- package/dist/features/obligations/repository/obligations.repository.js +158 -0
- package/dist/features/obligations/schemas/firestore.d.ts +160 -0
- package/dist/features/obligations/schemas/firestore.js +87 -0
- package/dist/features/orders/actions/order-actions.d.ts +43 -4
- package/dist/features/orders/actions/order-actions.js +60 -3
- package/dist/features/orders/actions/refund-actions.js +70 -10
- package/dist/features/orders/components/OrderCompletionPanel.d.ts +27 -0
- package/dist/features/orders/components/OrderCompletionPanel.js +192 -0
- package/dist/features/orders/components/OrdersList.js +2 -2
- package/dist/features/orders/components/RefundHistoryTable.js +3 -1
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +6 -0
- package/dist/features/orders/constants/transitions.d.ts +59 -0
- package/dist/features/orders/constants/transitions.js +104 -0
- package/dist/features/orders/repository/orders.repository.d.ts +109 -6
- package/dist/features/orders/repository/orders.repository.js +464 -21
- package/dist/features/orders/schemas/firestore.d.ts +270 -0
- package/dist/features/orders/schemas/firestore.js +24 -0
- package/dist/features/orders/schemas/index.d.ts +61 -0
- package/dist/features/orders/schemas/index.js +22 -0
- package/dist/features/orders/types/index.d.ts +79 -0
- package/dist/features/parts/components/PartsIndexPageView.js +8 -1
- package/dist/features/payment-cases/repository/payment-cases.repository.d.ts +170 -0
- package/dist/features/payment-cases/repository/payment-cases.repository.js +342 -0
- package/dist/features/payment-cases/schemas/firestore.d.ts +229 -0
- package/dist/features/payment-cases/schemas/firestore.js +105 -0
- package/dist/features/payment-cases/schemas/resolve-form.d.ts +97 -0
- package/dist/features/payment-cases/schemas/resolve-form.js +114 -0
- package/dist/features/payments/repository/payout.repository.d.ts +0 -1
- package/dist/features/payments/repository/payout.repository.js +0 -1
- package/dist/features/points/repository/points.repository.d.ts +122 -0
- package/dist/features/points/repository/points.repository.js +304 -1
- package/dist/features/points/schemas/adjust-form.d.ts +58 -0
- package/dist/features/points/schemas/adjust-form.js +63 -0
- package/dist/features/points/schemas/firestore.d.ts +108 -1
- package/dist/features/points/schemas/firestore.js +84 -0
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -3
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +23 -4
- package/dist/features/price-index/components/PriceIndexToolView.js +71 -6
- package/dist/features/price-index/market-stats.d.ts +82 -0
- package/dist/features/price-index/market-stats.js +230 -0
- package/dist/features/print/components/BoxLabelPrintView.d.ts +25 -0
- package/dist/features/print/components/BoxLabelPrintView.js +66 -0
- package/dist/features/print/components/LabelProfilePicker.d.ts +13 -0
- package/dist/features/print/components/LabelProfilePicker.js +38 -0
- package/dist/features/print/components/labels.d.ts +117 -0
- package/dist/features/print/components/labels.js +258 -0
- package/dist/features/print/components/labels.style.css +46 -0
- package/dist/features/print/index.d.ts +6 -0
- package/dist/features/print/index.js +16 -0
- package/dist/features/products/columns/productTableColumns.js +5 -4
- package/dist/features/products/components/MarketplaceBundleCard.js +2 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +6 -6
- package/dist/features/products/components/PrizeDrawCollage.js +1 -1
- package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
- package/dist/features/products/components/PrizeRevealModal.js +2 -2
- package/dist/features/products/components/ProductDetailPageView.js +18 -4
- package/dist/features/products/components/ProductForm.js +34 -23
- package/dist/features/products/components/ProductGrid.js +86 -62
- package/dist/features/products/constants/card-badges.d.ts +97 -0
- package/dist/features/products/constants/card-badges.js +100 -0
- package/dist/features/products/repository/products.repository.js +34 -1
- package/dist/features/products/schemas/firestore.d.ts +46 -3
- package/dist/features/products/schemas/firestore.js +21 -0
- package/dist/features/promotions/components/PromotionsView.js +1 -1
- package/dist/features/promotions/repository/claimed-coupons.repository.d.ts +32 -0
- package/dist/features/promotions/repository/claimed-coupons.repository.js +58 -0
- package/dist/features/promotions/schemas/firestore.js +30 -3
- package/dist/features/promotions/schemas/index.d.ts +6 -6
- package/dist/features/protection-claims/repository/protection-claims.repository.d.ts +54 -0
- package/dist/features/protection-claims/repository/protection-claims.repository.js +174 -0
- package/dist/features/protection-claims/schemas/firestore.d.ts +168 -0
- package/dist/features/protection-claims/schemas/firestore.js +130 -0
- package/dist/features/reviews/actions/review-actions.js +3 -2
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/reviews/schemas/firestore.d.ts +20 -1
- package/dist/features/scams/constants/scam-types.d.ts +2 -0
- package/dist/features/scams/constants/scam-types.js +18 -0
- package/dist/features/scams/schemas/report-form.d.ts +3 -3
- package/dist/features/scams/schemas/report-form.js +26 -1
- package/dist/features/search/components/Search.js +9 -9
- package/dist/features/search/components/SearchResultsClient.js +18 -3
- package/dist/features/search/components/SearchResultsPageView.d.ts +1 -6
- package/dist/features/search/components/SearchResultsPageView.js +2 -2
- package/dist/features/seller/actions/offer-actions.js +16 -1
- package/dist/features/seller/actions/seller-actions.js +14 -3
- package/dist/features/seller/components/CategoryInlineSelect.js +75 -11
- package/dist/features/seller/components/PrintCenterView.d.ts +5 -0
- package/dist/features/seller/components/PrintCenterView.js +41 -30
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutRequestView.js +16 -5
- package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.d.ts +16 -0
- package/dist/features/seller/components/SellerProductShell.js +123 -13
- package/dist/features/seller/components/SellerReviewsView.js +4 -2
- package/dist/features/seller/components/SellerSidebar.js +1 -1
- package/dist/features/seller/schemas/coupon-form.d.ts +26 -0
- package/dist/features/seller/schemas/coupon-form.js +27 -0
- package/dist/features/seller/schemas/product-form.d.ts +3 -0
- package/dist/features/seller/schemas/product-form.js +5 -0
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +14 -0
- package/dist/features/shell/SectionForm.d.ts +19 -0
- package/dist/features/shell/SectionForm.js +133 -9
- package/dist/features/shell/SectionForm.style.css +54 -0
- package/dist/features/shipments/components/AdminShipmentsView.js +16 -1
- package/dist/features/shipments/repository/shipment-items.repository.d.ts +9 -0
- package/dist/features/shipments/repository/shipment-items.repository.js +14 -0
- package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
- package/dist/features/sticker-trace/components/StickerCommitPanel.js +1 -1
- package/dist/features/store-extensions/schemas/report-review-form.d.ts +8 -8
- package/dist/features/stores/components/StoreGuideHubView.js +1 -1
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/support/schemas/firestore.d.ts +73 -2
- package/dist/features/support/schemas/firestore.js +59 -0
- package/dist/index.d.ts +16 -24
- package/dist/index.js +38 -47
- package/dist/next/ErrorBoundary.js +1 -1
- package/dist/next/routing/route-map.d.ts +24 -0
- package/dist/next/routing/route-map.js +40 -0
- package/dist/providers/payment-manual/index.d.ts +15 -1
- package/dist/providers/payment-manual/index.js +37 -0
- package/dist/providers/payment-phonepe/index.d.ts +14 -1
- package/dist/providers/payment-phonepe/index.js +36 -0
- package/dist/providers/payment-razorpay/index.d.ts +44 -1
- package/dist/providers/payment-razorpay/index.js +99 -0
- package/dist/providers/shipping-shiprocket/index.d.ts +18 -0
- package/dist/providers/shipping-shiprocket/index.js +18 -0
- package/dist/schemas/registry.d.ts +44 -11
- package/dist/server-entry.d.ts +2 -0
- package/dist/server-entry.js +27 -0
- package/dist/server.d.ts +43 -0
- package/dist/server.js +98 -0
- package/dist/styles.css +418 -149
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +15 -12
- package/dist/tokens/themes/default-light.js +14 -11
- package/dist/tokens/tokens.css +106 -23
- package/dist/ui/DataTable.style.css +4 -4
- package/dist/ui/columns/cell-renderers.d.ts +20 -0
- package/dist/ui/columns/cell-renderers.js +26 -1
- package/dist/ui/columns/index.d.ts +1 -1
- package/dist/ui/columns/index.js +4 -1
- package/dist/ui/components/Badge.style.css +1 -1
- package/dist/ui/components/Breadcrumb.js +19 -1
- package/dist/ui/components/BulkActionBar.style.css +4 -4
- package/dist/ui/components/Button.style.css +1 -1
- package/dist/ui/components/Checkbox.style.css +1 -1
- package/dist/ui/components/FallbackShell.js +1 -1
- package/dist/ui/components/Form.d.ts +14 -1
- package/dist/ui/components/Form.js +2 -2
- package/dist/ui/components/FormField.js +18 -4
- package/dist/ui/components/FormField.style.css +43 -3
- package/dist/ui/components/GatedPrice.style.css +1 -1
- package/dist/ui/components/IconButton.style.css +1 -1
- package/dist/ui/components/Input.js +22 -1
- package/dist/ui/components/Input.style.css +38 -22
- package/dist/ui/components/ListingFilterDrawer.js +1 -1
- package/dist/ui/components/ListingToolbar.js +1 -1
- package/dist/ui/components/PaginatedSelect.js +0 -0
- package/dist/ui/components/Radio.style.css +1 -1
- package/dist/ui/components/Repeater.d.ts +53 -0
- package/dist/ui/components/Repeater.js +7 -0
- package/dist/ui/components/RichTextEditor.d.ts +20 -1
- package/dist/ui/components/RichTextEditor.js +23 -2
- package/dist/ui/components/Select.style.css +7 -21
- package/dist/ui/components/Semantic.js +27 -3
- package/dist/ui/components/TagInput.style.css +4 -9
- package/dist/ui/components/Textarea.style.css +4 -18
- package/dist/ui/components/Toggle.style.css +1 -1
- package/dist/ui/components/Typography.d.ts +3 -3
- package/dist/ui/components/Typography.js +15 -15
- package/dist/ui/components/ViewToggle.style.css +4 -4
- package/dist/ui/forms/AddAnotherToggle.d.ts +16 -0
- package/dist/ui/forms/AddAnotherToggle.js +56 -0
- package/dist/ui/forms/ColorPickerField.js +15 -2
- package/dist/ui/forms/FieldCheckbox.js +15 -2
- package/dist/ui/forms/FieldInput.d.ts +22 -1
- package/dist/ui/forms/FieldInput.js +19 -5
- package/dist/ui/forms/FieldLabel.d.ts +35 -0
- package/dist/ui/forms/FieldLabel.js +70 -0
- package/dist/ui/forms/FieldSelect.d.ts +4 -1
- package/dist/ui/forms/FieldSelect.js +27 -5
- package/dist/ui/forms/FieldTextarea.d.ts +4 -1
- package/dist/ui/forms/FieldTextarea.js +22 -5
- package/dist/ui/forms/FormShell.d.ts +17 -1
- package/dist/ui/forms/FormShell.js +36 -2
- package/dist/ui/forms/FormShell.style.css +41 -33
- package/dist/ui/forms/index.d.ts +5 -1
- package/dist/ui/forms/index.js +2 -0
- package/dist/ui/icons/icon-registry.d.ts +1 -0
- package/dist/ui/icons/icon-registry.js +17 -1
- package/dist/utils/id-generators.d.ts +80 -0
- package/dist/utils/id-generators.js +93 -0
- package/dist/utils/search-txt-builders.d.ts +12 -0
- package/dist/utils/search-txt-builders.js +17 -0
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +106 -5
- package/dist/features/loyalty/api/admin/loyalty/grant/route.d.ts +0 -12
- package/dist/features/loyalty/api/admin/loyalty/grant/route.js +0 -38
- package/dist/features/loyalty/api/balance/route.d.ts +0 -12
- package/dist/features/loyalty/api/balance/route.js +0 -41
- package/dist/features/loyalty/api/earn/route.d.ts +0 -12
- package/dist/features/loyalty/api/earn/route.js +0 -38
- package/dist/features/loyalty/api/history/route.d.ts +0 -12
- package/dist/features/loyalty/api/history/route.js +0 -58
- package/dist/features/loyalty/api/redeem/route.d.ts +0 -12
- package/dist/features/loyalty/api/redeem/route.js +0 -38
- package/dist/features/loyalty/columns/index.d.ts +0 -17
- package/dist/features/loyalty/columns/index.js +0 -40
- package/dist/features/loyalty/components/CoinsDisplay.d.ts +0 -12
- package/dist/features/loyalty/components/CoinsDisplay.js +0 -10
- package/dist/features/loyalty/components/index.d.ts +0 -1
- package/dist/features/loyalty/components/index.js +0 -1
- package/dist/features/loyalty/hooks/useLoyaltyBalance.d.ts +0 -4
- package/dist/features/loyalty/hooks/useLoyaltyBalance.js +0 -25
- package/dist/features/loyalty/index.d.ts +0 -6
- package/dist/features/loyalty/index.js +0 -6
- package/dist/features/loyalty/manifest.d.ts +0 -2
- package/dist/features/loyalty/manifest.js +0 -16
- package/dist/features/loyalty/messages/en.json +0 -19
- package/dist/features/loyalty/repository/loyalty.repository.d.ts +0 -8
- package/dist/features/loyalty/repository/loyalty.repository.js +0 -22
- package/dist/features/loyalty/schemas/index.d.ts +0 -85
- package/dist/features/loyalty/schemas/index.js +0 -40
- package/dist/features/loyalty/server.d.ts +0 -6
- package/dist/features/loyalty/server.js +0 -6
- package/dist/features/loyalty/types/index.d.ts +0 -31
- package/dist/features/loyalty/types/index.js +0 -1
- package/dist/features/loyalty/types/loyalty-config.d.ts +0 -7
- package/dist/features/loyalty/types/loyalty-config.js +0 -1
- package/dist/features/loyalty/types/loyalty-math.d.ts +0 -9
- package/dist/features/loyalty/types/loyalty-math.js +0 -27
- package/dist/features/products/components/ProductOwnerQuickActions.d.ts +0 -11
- package/dist/features/products/components/ProductOwnerQuickActions.js +0 -120
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* WHY: The price tool showed a MEDIAN of a competitor crawl, taken once, at
|
|
3
|
+
* GENERATION level โ so Dragoon MS and Strata Dragoon MS reported the
|
|
4
|
+
* same โน3,999 (they are different beys), Dragoon G reported nothing at
|
|
5
|
+
* all (Engine Gear was never crawled), and a figure measured in October
|
|
6
|
+
* would still read as current a year later. The owner's ask was precise:
|
|
7
|
+
* the headline should be the price most sightings actually cluster on,
|
|
8
|
+
* the low and high should describe the LAST SIX MONTHS, and anything
|
|
9
|
+
* older should be used only when there is nothing recent.
|
|
10
|
+
* WHAT: The pure statistics behind that โ mode over price buckets, a recency
|
|
11
|
+
* window with an explicit historic fallback, and the provenance flags a
|
|
12
|
+
* renderer needs to avoid overclaiming.
|
|
13
|
+
*
|
|
14
|
+
* EXPORTS:
|
|
15
|
+
* RECENT_WINDOW_DAYS โ the six-month window, as days
|
|
16
|
+
* MIN_BAND_OBSERVATIONS โ below this there is no band at all
|
|
17
|
+
* MIN_MODE_OBSERVATIONS โ below this there is no mode, only a median
|
|
18
|
+
* PriceObservationSample โ the minimum a sighting must carry
|
|
19
|
+
* MarketStats โ one computed band
|
|
20
|
+
* priceBucketWidth โ the bucket a price falls in, by magnitude
|
|
21
|
+
* computeMarketStats โ samples -> a band, or null
|
|
22
|
+
*
|
|
23
|
+
* ## ๐ Why MODE, and why it is bucketed
|
|
24
|
+
*
|
|
25
|
+
* A median answers "what is the middle of this list" and a mode answers "what
|
|
26
|
+
* do people actually charge", and for a collectible those differ. Six sightings
|
|
27
|
+
* at โน6,500 and three clearance ones at โน3,000 have a median of โน6,500 only by
|
|
28
|
+
* luck of the ordering; add two more cheap ones and the median drops to โน3,000
|
|
29
|
+
* while the going rate has not moved at all. The mode does not do that.
|
|
30
|
+
*
|
|
31
|
+
* ๐ But an EXACT-VALUE mode is a trap on this data. Retail listings cluster on
|
|
32
|
+
* round price points (โน999, โน1,399, โน2,999) where exact mode works perfectly โ
|
|
33
|
+
* and private resale does not (โน6,400, โน6,500, โน6,600 are one market and three
|
|
34
|
+
* distinct values). An exact mode would report "no mode" for precisely the
|
|
35
|
+
* second-hand market this tool exists to describe. So values are bucketed by
|
|
36
|
+
* magnitude first.
|
|
37
|
+
*
|
|
38
|
+
* ๐ The reported figure is the MEDIAN OF THE WINNING BUCKET, never the bucket
|
|
39
|
+
* edge. A bucket boundary is an artefact of our arithmetic; quoting โน6,500 when
|
|
40
|
+
* the bucket is 6,250โ6,750 and the sightings were 6,400/6,500/6,600 reports a
|
|
41
|
+
* price somebody actually asked. Quoting the edge would invent one.
|
|
42
|
+
*
|
|
43
|
+
* ## ๐ Recency is a MEASUREMENT, not a label
|
|
44
|
+
*
|
|
45
|
+
* `basedOnRecent` is false whenever the six-month window could not carry the
|
|
46
|
+
* band on its own, and the renderer must say "all time" in that case. Printing
|
|
47
|
+
* "last 6 months" over figures drawn from a three-year-old crawl is the exact
|
|
48
|
+
* dishonesty this module was written to remove โ and it is invisible, because a
|
|
49
|
+
* stale number looks identical to a current one.
|
|
50
|
+
*
|
|
51
|
+
* ## ๐ Why this is in `features/`, not `_internal/shared/`
|
|
52
|
+
*
|
|
53
|
+
* It needs THREE consumers โ the scheduled rollup, the `price-observations`
|
|
54
|
+
* CLI, and anything that later wants to restate a band โ and `_internal/` is
|
|
55
|
+
* not reachable from a standalone script through the package's export map. A
|
|
56
|
+
* CLI that could not import it would have to re-derive "the mode, bucketed,
|
|
57
|
+
* with a six-month window", which is Root Cause #75's exact shape: a rule
|
|
58
|
+
* reachable only by copy-paste gets copied, and the copy never learns about the
|
|
59
|
+
* branch added later. `lookup-target.ts` sits here for the same reason โ pure,
|
|
60
|
+
* shared, no React, no Firestore.
|
|
61
|
+
*
|
|
62
|
+
* @tag domain:price-index
|
|
63
|
+
* @tag layer:feature
|
|
64
|
+
* @tag pattern:pure-function
|
|
65
|
+
* @tag access:isomorphic
|
|
66
|
+
* @tag consumers:marketPriceRollup,price-observations CLI,PriceIndexToolView
|
|
67
|
+
* @tag sideEffects:none
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* Six months, the window the owner specified for "recent".
|
|
71
|
+
*
|
|
72
|
+
* 182 rather than 180: it is half of 365, so a year's data splits into exactly
|
|
73
|
+
* two windows and "the last six months" cannot quietly mean a different span
|
|
74
|
+
* depending on which months they were.
|
|
75
|
+
*/
|
|
76
|
+
export const RECENT_WINDOW_DAYS = 182;
|
|
77
|
+
/**
|
|
78
|
+
* Below this, NO band is published for a leaf.
|
|
79
|
+
*
|
|
80
|
+
* Three, matching `PRICE_INDEX_MIN_CONFIDENT_SAMPLES` on the sold half โ the
|
|
81
|
+
* two halves of this page must not disagree about what counts as evidence, and
|
|
82
|
+
* the sold half's reasoning ("a median of two sales is a coin flip presented as
|
|
83
|
+
* data") is about sample size, not about which side of the page it is on.
|
|
84
|
+
*/
|
|
85
|
+
export const MIN_BAND_OBSERVATIONS = 3;
|
|
86
|
+
/**
|
|
87
|
+
* Below this, the band publishes a MEDIAN and no mode.
|
|
88
|
+
*
|
|
89
|
+
* A "most common price" derived from a bucket containing one sighting is not a
|
|
90
|
+
* most-common anything โ it is that one sighting, relabelled. Two is the
|
|
91
|
+
* smallest number for which the word means what it says.
|
|
92
|
+
*/
|
|
93
|
+
export const MIN_MODE_OBSERVATIONS = 2;
|
|
94
|
+
/**
|
|
95
|
+
* Bucket width by magnitude.
|
|
96
|
+
*
|
|
97
|
+
* Proportional rather than fixed, because a โน50 bucket is three separate
|
|
98
|
+
* buckets across โน99โโน249 part pricing and a rounding error on a โน9,999 grail.
|
|
99
|
+
* The widths are ~2โ5% of the value throughout, so "the same price" means the
|
|
100
|
+
* same thing at every price point.
|
|
101
|
+
*/
|
|
102
|
+
export function priceBucketWidth(amount) {
|
|
103
|
+
if (amount < 500)
|
|
104
|
+
return 25;
|
|
105
|
+
if (amount < 1000)
|
|
106
|
+
return 50;
|
|
107
|
+
if (amount < 5000)
|
|
108
|
+
return 100;
|
|
109
|
+
if (amount < 20000)
|
|
110
|
+
return 250;
|
|
111
|
+
return 1000;
|
|
112
|
+
}
|
|
113
|
+
/** The inclusive-lower bucket key a price falls in. */
|
|
114
|
+
function bucketOf(amount) {
|
|
115
|
+
const width = priceBucketWidth(amount);
|
|
116
|
+
return Math.floor(amount / width) * width;
|
|
117
|
+
}
|
|
118
|
+
function medianOf(sorted) {
|
|
119
|
+
const n = sorted.length;
|
|
120
|
+
if (n === 0)
|
|
121
|
+
return 0;
|
|
122
|
+
const mid = n >> 1;
|
|
123
|
+
// Even n averages the two middles, which can land between two real prices.
|
|
124
|
+
// That is correct for a median and is why it is never the headline figure.
|
|
125
|
+
return n % 2 === 1 ? sorted[mid] : ((sorted[mid - 1] + sorted[mid]) / 2);
|
|
126
|
+
}
|
|
127
|
+
/** Whole rupees. Every price in this system is a decimal rupee amount. */
|
|
128
|
+
function round(n) {
|
|
129
|
+
return Math.round(n);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The band for one leaf, or `null` when there is not enough to say anything.
|
|
133
|
+
*
|
|
134
|
+
* ๐ `null`, never a zeroed band. A band of โน0 renders as a real figure meaning
|
|
135
|
+
* "this sells for nothing", which is strictly worse than silence โ the same
|
|
136
|
+
* rule `CategoryPriceGuidance.sold` is held to ("absent until there are some โ
|
|
137
|
+
* never zeroed").
|
|
138
|
+
*
|
|
139
|
+
* The recency decision happens ONCE here and is reported in `basedOnRecent`, so
|
|
140
|
+
* the job, the CLI and the renderer cannot each arrive at a different answer
|
|
141
|
+
* about which window a figure came from.
|
|
142
|
+
*/
|
|
143
|
+
export function computeMarketStats(samples, now = new Date()) {
|
|
144
|
+
const usable = samples.filter((s) => Number.isFinite(s.amount) && s.amount > 0 && s.seenAt instanceof Date && !Number.isNaN(s.seenAt.getTime()));
|
|
145
|
+
if (usable.length < MIN_BAND_OBSERVATIONS)
|
|
146
|
+
return null;
|
|
147
|
+
const cutoff = now.getTime() - RECENT_WINDOW_DAYS * 86400000;
|
|
148
|
+
const recent = usable.filter((s) => s.seenAt.getTime() >= cutoff);
|
|
149
|
+
/*
|
|
150
|
+
* ๐ The whole fallback, in one decision. The six-month window is used when
|
|
151
|
+
* it can carry a band ALONE; otherwise the full history is, and the caller is
|
|
152
|
+
* told. A blend of the two would be neither โ and would be undetectable,
|
|
153
|
+
* since the result is a number either way.
|
|
154
|
+
*/
|
|
155
|
+
const basedOnRecent = recent.length >= MIN_BAND_OBSERVATIONS;
|
|
156
|
+
const set = basedOnRecent ? recent : usable;
|
|
157
|
+
const amounts = set.map((s) => s.amount).sort((a, b) => a - b);
|
|
158
|
+
const lastSeenAt = set.reduce((max, s) => (s.seenAt.getTime() > max.getTime() ? s.seenAt : max), set[0].seenAt);
|
|
159
|
+
/*
|
|
160
|
+
* Buckets, with their members kept โ the reported mode is the median of the
|
|
161
|
+
* winning bucket's real prices, so the members cannot be discarded for a
|
|
162
|
+
* count alone.
|
|
163
|
+
*/
|
|
164
|
+
const buckets = new Map();
|
|
165
|
+
for (const amount of amounts) {
|
|
166
|
+
const key = bucketOf(amount);
|
|
167
|
+
const existing = buckets.get(key);
|
|
168
|
+
if (existing)
|
|
169
|
+
existing.push(amount);
|
|
170
|
+
else
|
|
171
|
+
buckets.set(key, [amount]);
|
|
172
|
+
}
|
|
173
|
+
let bestMembers;
|
|
174
|
+
for (const members of buckets.values()) {
|
|
175
|
+
if (members.length < MIN_MODE_OBSERVATIONS)
|
|
176
|
+
continue;
|
|
177
|
+
if (!bestMembers || members.length > bestMembers.length) {
|
|
178
|
+
bestMembers = members;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
/*
|
|
182
|
+
* ๐ A tie breaks toward the DEARER bucket, deliberately. The two failure
|
|
183
|
+
* directions are not symmetric: a seller shown too low a figure leaves
|
|
184
|
+
* money on the table on a sale that still happens, while a buyer shown too
|
|
185
|
+
* low a figure arrives at the listing expecting a price that does not
|
|
186
|
+
* exist. Breaking toward the cheaper bucket optimises for the second.
|
|
187
|
+
*/
|
|
188
|
+
if (members.length === bestMembers.length && members[0] > bestMembers[0]) {
|
|
189
|
+
bestMembers = members;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const median = round(medianOf(amounts));
|
|
193
|
+
return {
|
|
194
|
+
...(bestMembers
|
|
195
|
+
? {
|
|
196
|
+
// The median of the winning bucket's members โ a price somebody
|
|
197
|
+
// actually asked, not the arithmetic edge of our own bucket.
|
|
198
|
+
mode: round(medianOf(bestMembers)),
|
|
199
|
+
modeCount: bestMembers.length,
|
|
200
|
+
}
|
|
201
|
+
: {}),
|
|
202
|
+
median,
|
|
203
|
+
low: round(amounts[0]),
|
|
204
|
+
high: round(amounts[amounts.length - 1]),
|
|
205
|
+
sampleSize: set.length,
|
|
206
|
+
basedOnRecent,
|
|
207
|
+
windowDays: basedOnRecent ? RECENT_WINDOW_DAYS : spanDays(set),
|
|
208
|
+
lastSeenAt,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The real span of a sample set, for the historic-fallback case.
|
|
213
|
+
*
|
|
214
|
+
* Reported rather than left as `RECENT_WINDOW_DAYS`, because "all time" has to
|
|
215
|
+
* mean a measurable number of days for the renderer to say anything honest
|
|
216
|
+
* about it โ "over the 14 months we have data for" is a statement; "all time"
|
|
217
|
+
* alone is not.
|
|
218
|
+
*/
|
|
219
|
+
function spanDays(set) {
|
|
220
|
+
let min = set[0].seenAt.getTime();
|
|
221
|
+
let max = min;
|
|
222
|
+
for (const s of set) {
|
|
223
|
+
const t = s.seenAt.getTime();
|
|
224
|
+
if (t < min)
|
|
225
|
+
min = t;
|
|
226
|
+
if (t > max)
|
|
227
|
+
max = t;
|
|
228
|
+
}
|
|
229
|
+
return Math.max(1, Math.round((max - min) / 86400000));
|
|
230
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type BoxContentsRow } from "./labels";
|
|
2
|
+
export interface PrintableBox {
|
|
3
|
+
id: string;
|
|
4
|
+
code: string;
|
|
5
|
+
boxType: string;
|
|
6
|
+
location?: string | null;
|
|
7
|
+
distinctProducts?: number | null;
|
|
8
|
+
totalUnits?: number | null;
|
|
9
|
+
countedAt?: string | null;
|
|
10
|
+
/** Present only when the caller loaded placements for this box. */
|
|
11
|
+
contents?: BoxContentsRow[];
|
|
12
|
+
}
|
|
13
|
+
export interface BoxLabelPrintViewProps {
|
|
14
|
+
boxes: PrintableBox[];
|
|
15
|
+
/**
|
|
16
|
+
* ๐ Passed in rather than read from `Date.now()` here. A render-time clock
|
|
17
|
+
* makes the printed date differ between the server render and the client
|
|
18
|
+
* hydration, which React reports as a hydration mismatch โ and more
|
|
19
|
+
* practically it means the date on the paper is "whenever this component
|
|
20
|
+
* last rendered", which is not a fact about anything.
|
|
21
|
+
*/
|
|
22
|
+
printedAt: string;
|
|
23
|
+
boxesFailed?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function BoxLabelPrintView({ boxes, printedAt, boxesFailed, }: BoxLabelPrintViewProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Prints box labels and box contents sheets.
|
|
5
|
+
*
|
|
6
|
+
* Two outputs with deliberately different shapes, because they answer
|
|
7
|
+
* different questions at different distances:
|
|
8
|
+
*
|
|
9
|
+
* LABEL stuck to the box. `BOX-AC60-03` as a scannable symbol, the code
|
|
10
|
+
* large enough to read across a room, and a total with a date.
|
|
11
|
+
* CONTENTS A4, goes inside the box or on the shelf beside it. Lists every
|
|
12
|
+
* product. A 50 x 25 mm label cannot hold eight product names, so
|
|
13
|
+
* the label carries a total and this carries the detail.
|
|
14
|
+
*
|
|
15
|
+
* ๐ BOTH ARE DATED SNAPSHOTS, AND BOTH SAY SO. A printed count is wrong the
|
|
16
|
+
* moment something is picked. Printing "8 items" bare invites the operator to
|
|
17
|
+
* trust it over the screen; printing "8 items as of 21 Oct" says what it is.
|
|
18
|
+
*/
|
|
19
|
+
import { useMemo, useState } from "react";
|
|
20
|
+
import { Alert, Button, Div, Heading, Row, Stack, Text, } from "../../../ui/index.js";
|
|
21
|
+
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox.js";
|
|
22
|
+
import { BoxContentsSheet, BoxLabel, LabelPageStyle, LabelSheet, PrintScaleWarning, } from "./labels.js";
|
|
23
|
+
import { LabelProfilePicker } from "./LabelProfilePicker.js";
|
|
24
|
+
import { LABEL_PROFILES, documentPageCss, labelPageCss, } from "../../../_internal/shared/features/print/label-profiles.js";
|
|
25
|
+
export function BoxLabelPrintView({ boxes, printedAt, boxesFailed = false, }) {
|
|
26
|
+
const [mode, setMode] = useState("labels");
|
|
27
|
+
/*
|
|
28
|
+
* 100 x 50 mm by default, not the 50 x 25 used for products. A box label is
|
|
29
|
+
* read from across a room and carries a code, a type, a location and a
|
|
30
|
+
* count โ four lines plus a symbol does not fit on a product label, and the
|
|
31
|
+
* fit check would (correctly) refuse the barcode on 38 mm stock.
|
|
32
|
+
*/
|
|
33
|
+
const [profileId, setProfileId] = useState("thermal-100x50");
|
|
34
|
+
const profile = LABEL_PROFILES[profileId];
|
|
35
|
+
const [selected, setSelected] = useState(new Set());
|
|
36
|
+
const chosen = useMemo(() => boxes.filter((b) => selected.has(b.id)), [boxes, selected]);
|
|
37
|
+
const toggle = (id) => setSelected((prev) => {
|
|
38
|
+
const next = new Set(prev);
|
|
39
|
+
if (next.has(id))
|
|
40
|
+
next.delete(id);
|
|
41
|
+
else
|
|
42
|
+
next.add(id);
|
|
43
|
+
return next;
|
|
44
|
+
});
|
|
45
|
+
/*
|
|
46
|
+
* `BOX-` + the code. The longest one in the selection drives the fit report,
|
|
47
|
+
* so the warning is about the worst label in the batch rather than the first.
|
|
48
|
+
*/
|
|
49
|
+
const longestCodeLength = useMemo(() => chosen.reduce((n, b) => Math.max(n, b.code.length + 4), 0), [chosen]);
|
|
50
|
+
return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsx(LabelPageStyle, { css: mode === "labels" ? labelPageCss(profile) : documentPageCss() }), _jsxs(Stack, { className: "no-print", gap: "sm", children: [_jsx(Heading, { level: 1, size: "2xl", children: "Print box labels" }), boxesFailed && (_jsx(Alert, { variant: "warning", children: "Could not load the box list. It is unknown, not empty \u2014 reload before printing, or you will print a subset without knowing it." })), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { variant: mode === "labels" ? "primary" : "secondary", size: "sm", onClick: () => setMode("labels"), children: "Box labels" }), _jsx(Button, { variant: mode === "contents" ? "primary" : "secondary", size: "sm", onClick: () => setMode("contents"), children: "Contents sheets (A4)" })] }), mode === "labels" && (_jsxs(_Fragment, { children: [_jsx(LabelProfilePicker, { value: profileId, onChange: setProfileId, longestCodeLength: longestCodeLength }), _jsx(PrintScaleWarning, {})] })), boxes.length === 0 ? (_jsx(Text, { color: "muted", children: "No boxes registered yet. A box exists here because someone labelled a real one, so an empty list on a fresh install is correct." })) : (_jsx(Stack, { gap: "xs", children: boxes.map((b) => (_jsx(FieldCheckbox, { name: `box-${b.id}`, label: `${b.code}${b.location ? ` โ ${b.location}` : ""}`, checked: selected.has(b.id), onChange: () => toggle(b.id) }, b.id))) })), _jsxs(Row, { gap: "sm", align: "center", wrap: true, children: [_jsxs(Button, { disabled: chosen.length === 0, onClick: () => window.print(), children: ["Print ", chosen.length > 0 ? `${chosen.length} selected` : "selected"] }), boxes.length > 0 && (_jsx(Button, { variant: "ghost", onClick: () => setSelected(selected.size === boxes.length
|
|
51
|
+
? new Set()
|
|
52
|
+
: new Set(boxes.map((b) => b.id))), children: selected.size === boxes.length ? "Clear all" : "Select all" }))] }), mode === "contents" && chosen.some((b) => !b.contents) && (
|
|
53
|
+
/*
|
|
54
|
+
* ๐ Says WHICH sheets will be blank rather than printing a blank
|
|
55
|
+
* one. A contents sheet for a box whose placements were never loaded
|
|
56
|
+
* prints "This box is empty" โ about a box that may hold eight
|
|
57
|
+
* things. That is the worst claim this feature can make, and it is
|
|
58
|
+
* indistinguishable from a genuinely empty box on paper.
|
|
59
|
+
*/
|
|
60
|
+
_jsxs(Alert, { variant: "warning", children: ["Contents were not loaded for", " ", chosen
|
|
61
|
+
.filter((b) => !b.contents)
|
|
62
|
+
.map((b) => b.code)
|
|
63
|
+
.join(", "), ". Those sheets would print as empty, which is not the same as the box being empty \u2014 open each box's page to load its contents first."] }))] }), mode === "labels" ? (_jsx(LabelSheet, { profile: profile, children: chosen.map((b) => (_jsx(BoxLabel, { profile: profile, box: b }, b.id))) })) : (_jsx(Div, { children: chosen
|
|
64
|
+
.filter((b) => b.contents)
|
|
65
|
+
.map((b) => (_jsx(BoxContentsSheet, { boxCode: b.code, boxType: b.boxType, location: b.location, rows: b.contents ?? [], printedAt: printedAt }, b.id))) }))] }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type LabelProfileId } from "../../../_internal/shared/features/print/label-profiles";
|
|
2
|
+
export interface LabelProfilePickerProps {
|
|
3
|
+
value: LabelProfileId;
|
|
4
|
+
onChange: (id: LabelProfileId) => void;
|
|
5
|
+
/**
|
|
6
|
+
* The LONGEST code in the job. Checking the longest is the only check worth
|
|
7
|
+
* making: a report based on the average or the first row says "fits" about a
|
|
8
|
+
* batch in which some labels do not.
|
|
9
|
+
*/
|
|
10
|
+
longestCodeLength?: number;
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function LabelProfilePicker({ value, onChange, longestCodeLength, label, }: LabelProfilePickerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Picks the label stock, and says what that choice costs.
|
|
5
|
+
*
|
|
6
|
+
* ๐ THE FIT REPORT IS SHOWN BESIDE THE PICKER, NOT AFTER PRINTING. The whole
|
|
7
|
+
* reason `labelFitsProfile` reports rather than scales is that a squeezed
|
|
8
|
+
* barcode looks perfect and does not scan, surfacing weeks later as "the
|
|
9
|
+
* scanner is broken" with every label already stuck to something. That
|
|
10
|
+
* guarantee is worth nothing if the report arrives after the stock is in the
|
|
11
|
+
* printer โ so the picker tells the operator, in the moment they choose, what
|
|
12
|
+
* the longest code they are about to print will do on it.
|
|
13
|
+
*
|
|
14
|
+
* ๐ `FieldSelect` WITH SIX OPTIONS, AGAINST RULE #9's ">5 USES
|
|
15
|
+
* PaginatedSelect" LINE โ flagged rather than done quietly.
|
|
16
|
+
*
|
|
17
|
+
* That rule's own stated reason is that a long list cannot be scanned, and its
|
|
18
|
+
* mechanism is an async searchable drawer. This list is six physical stocks,
|
|
19
|
+
* closed and bounded by what the warehouse buys, with no server behind it; a
|
|
20
|
+
* search box over six static strings and a "Load more" is more chrome than
|
|
21
|
+
* choice. No audit enforces the threshold, so this is a judgement call and not
|
|
22
|
+
* a build failure โ one line to reverse if the call is wrong.
|
|
23
|
+
*/
|
|
24
|
+
import { Alert, Row, Stack, Text } from "../../../ui/index.js";
|
|
25
|
+
import { FieldSelect } from "../../../ui/forms/index.js";
|
|
26
|
+
import { LABEL_PROFILES, LABEL_PROFILE_IDS, MIN_SCANNABLE_MODULE_MM, labelFitsProfile, } from "../../../_internal/shared/features/print/label-profiles.js";
|
|
27
|
+
export function LabelProfilePicker({ value, onChange, longestCodeLength, label = "Label stock", }) {
|
|
28
|
+
const profile = LABEL_PROFILES[value];
|
|
29
|
+
const fit = longestCodeLength && longestCodeLength > 0
|
|
30
|
+
? labelFitsProfile(profile, longestCodeLength)
|
|
31
|
+
: null;
|
|
32
|
+
return (_jsxs(Stack, { gap: "xs", className: "no-print", children: [_jsxs(Row, { gap: "sm", align: "end", wrap: true, children: [_jsx(FieldSelect, { name: "labelProfile", label: label, value: value, onChange: (v) => onChange(v), options: LABEL_PROFILE_IDS.map((id) => ({
|
|
33
|
+
value: id,
|
|
34
|
+
label: LABEL_PROFILES[id].label,
|
|
35
|
+
})) }), _jsxs(Text, { size: "sm", color: "muted", children: [profile.widthMm, " \u00D7 ", profile.heightMm, " mm", profile.sheet
|
|
36
|
+
? ` ยท ${profile.sheet.columns * profile.sheet.rows} per A4 sheet`
|
|
37
|
+
: " ยท one per page (roll)"] })] }), fit && !fit.fits && fit.impliedModuleMm < MIN_SCANNABLE_MODULE_MM && (_jsx(Alert, { variant: "error", children: fit.reason })), fit && !fit.fits && fit.impliedModuleMm >= MIN_SCANNABLE_MODULE_MM && (_jsx(Alert, { variant: "warning", children: fit.reason })), fit && fit.fits && (_jsx(Text, { size: "xs", color: "success", children: fit.reason }))] }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type LabelProfile } from "../../../_internal/shared/features/print/label-profiles";
|
|
2
|
+
/** Millimetres of paper to CSS pixels. The only unit bridge in this file. */
|
|
3
|
+
export declare function mmToCssPx(mm: number): number;
|
|
4
|
+
/**
|
|
5
|
+
* A target module width in mm, as JsBarcode's `width` option.
|
|
6
|
+
*
|
|
7
|
+
* Not rounded to an integer: JsBarcode accepts a fractional module width and
|
|
8
|
+
* rounding to 1 px would quantise every density to 0.265 mm steps โ which on a
|
|
9
|
+
* 50 x 25 mm label is the difference between fitting and not.
|
|
10
|
+
*/
|
|
11
|
+
export declare function moduleWidthPx(moduleMm?: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* The single `@page` owner for a printable view.
|
|
14
|
+
*
|
|
15
|
+
* ๐ EXACTLY ONE OF THESE PER VIEW. `@page` is document-global and cannot be
|
|
16
|
+
* scoped โ two of them does not give two geometries, the later one in document
|
|
17
|
+
* order silently wins and the label prints at the wrong size with nothing in
|
|
18
|
+
* the markup looking wrong. `audit-label-profiles` R3 enforces that only
|
|
19
|
+
* `label-profiles.ts` may author the rule at all.
|
|
20
|
+
*/
|
|
21
|
+
export declare function LabelPageStyle({ css }: {
|
|
22
|
+
css: string;
|
|
23
|
+
}): import("react").JSX.Element;
|
|
24
|
+
export interface ProductLabelData {
|
|
25
|
+
barcodeId?: string | null;
|
|
26
|
+
sku?: string | null;
|
|
27
|
+
name: string;
|
|
28
|
+
price?: number | null;
|
|
29
|
+
/** ๐ Which box it lives in โ see the component note. */
|
|
30
|
+
boxCode?: string | null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A product label: symbol, name, price, and WHERE IT LIVES.
|
|
34
|
+
*
|
|
35
|
+
* ๐ THE BOX CODE IS THE ADDITION THAT MAKES THE LABEL USEFUL FOR PUTTING
|
|
36
|
+
* THINGS AWAY. Without it a picker holding the item has to scan it and look at
|
|
37
|
+
* a screen to learn which shelf it came off; with it the label answers the
|
|
38
|
+
* question the person holding it is actually asking. It replaces the free-text
|
|
39
|
+
* `physicalLocation` that used to print here โ that field was three
|
|
40
|
+
* inconsistent inputs with no registry behind it, so two people wrote "shelf
|
|
41
|
+
* 3", "Shelf-3" and "AC60 3" for one place and no list could group them.
|
|
42
|
+
*/
|
|
43
|
+
export declare function ProductLabel({ profile, product, }: {
|
|
44
|
+
profile: LabelProfile;
|
|
45
|
+
product: ProductLabelData;
|
|
46
|
+
}): import("react").JSX.Element;
|
|
47
|
+
export interface BoxLabelData {
|
|
48
|
+
code: string;
|
|
49
|
+
boxType: string;
|
|
50
|
+
location?: string | null;
|
|
51
|
+
distinctProducts?: number | null;
|
|
52
|
+
totalUnits?: number | null;
|
|
53
|
+
/** When the rollup was computed โ see the staleness note. */
|
|
54
|
+
countedAt?: string | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A box label: the code, large, plus what it held WHEN PRINTED.
|
|
58
|
+
*
|
|
59
|
+
* ๐ THE PRINT DATE IS NOT DECORATION โ it is what makes the counts honest. A
|
|
60
|
+
* label is a frozen snapshot stuck to a moving object: the moment something is
|
|
61
|
+
* picked, the printed count is wrong. Printing "8 items" with no date invites
|
|
62
|
+
* the operator to trust it; printing "8 items as of 21 Oct" says plainly that
|
|
63
|
+
* it is a note from the past and the screen is authoritative.
|
|
64
|
+
*
|
|
65
|
+
* ๐ The barcode encodes `BOX-{code}`, with the prefix, because the receive
|
|
66
|
+
* station discriminates on it: a `BOX-` scan arms a box and a `LIR-` scan adds
|
|
67
|
+
* an item, and that decision has to be makeable without a lookup. The stored
|
|
68
|
+
* `code` is the bare `AC60-03`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function BoxLabel({ profile, box, }: {
|
|
71
|
+
profile: LabelProfile;
|
|
72
|
+
box: BoxLabelData;
|
|
73
|
+
}): import("react").JSX.Element;
|
|
74
|
+
/**
|
|
75
|
+
* Lays labels out on an A4 die-cut sheet, at the stock's real pitch.
|
|
76
|
+
*
|
|
77
|
+
* ๐ ABSOLUTE POSITIONING FROM THE PITCH, not a flex grid. A grid distributes
|
|
78
|
+
* whatever space it is given; a die-cut sheet has fixed holes, and the only
|
|
79
|
+
* thing that lands ink inside them is placing each label at
|
|
80
|
+
* `margin + n x pitch`. One millimetre of accumulated flex rounding is
|
|
81
|
+
* invisible on label one and off the die-cut by label thirteen.
|
|
82
|
+
*/
|
|
83
|
+
export declare function LabelSheet({ profile, children, }: {
|
|
84
|
+
profile: LabelProfile;
|
|
85
|
+
children: React.ReactNode[];
|
|
86
|
+
}): import("react").JSX.Element;
|
|
87
|
+
export interface BoxContentsRow {
|
|
88
|
+
productTitle: string;
|
|
89
|
+
productSku?: string | null;
|
|
90
|
+
quantity: number;
|
|
91
|
+
slot?: string | null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* An A4 sheet listing what is in a box โ the thing that goes INSIDE it, or on
|
|
95
|
+
* the shelf beside it.
|
|
96
|
+
*
|
|
97
|
+
* ๐ A4, not a label, and that is the point of having it at all. A 50 x 25 mm
|
|
98
|
+
* label cannot list eight products, so the box label carries only a total; the
|
|
99
|
+
* contents have to live somewhere a person can read them without a screen, and
|
|
100
|
+
* that is a sheet of paper. It is explicitly a snapshot, dated in the header
|
|
101
|
+
* for the same reason the box label's counts are.
|
|
102
|
+
*/
|
|
103
|
+
export declare function BoxContentsSheet({ boxCode, boxType, location, rows, printedAt, }: {
|
|
104
|
+
boxCode: string;
|
|
105
|
+
boxType: string;
|
|
106
|
+
location?: string | null;
|
|
107
|
+
rows: BoxContentsRow[];
|
|
108
|
+
printedAt: string;
|
|
109
|
+
}): import("react").JSX.Element;
|
|
110
|
+
/**
|
|
111
|
+
* The on-screen warning that no code can replace.
|
|
112
|
+
*
|
|
113
|
+
* Every density calculation in this file assumes the browser prints at 100%.
|
|
114
|
+
* "Fit to page" rescales the symbol and takes the module width with it, and
|
|
115
|
+
* the result still looks like a correct label.
|
|
116
|
+
*/
|
|
117
|
+
export declare function PrintScaleWarning(): import("react").JSX.Element;
|