@mohasinac/appkit 4.59.0 → 4.60.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/.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.js +26 -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 +9 -4
- package/dist/client.js +26 -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 +42 -0
- package/dist/server.js +93 -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
|
@@ -38,10 +38,5 @@ export interface SearchResultsPageViewProps {
|
|
|
38
38
|
* invites a `?? []` that silently renders an empty rail.
|
|
39
39
|
*/
|
|
40
40
|
renderAboveGroups?: () => React.ReactNode;
|
|
41
|
-
/**
|
|
42
|
-
* A short line under the heading — "results as of 10:51". Optional because
|
|
43
|
-
* the server tier has no build time to report.
|
|
44
|
-
*/
|
|
45
|
-
footnote?: string;
|
|
46
41
|
}
|
|
47
|
-
export declare function SearchResultsPageView({ result, renderSearchInput, renderAboveGroups,
|
|
42
|
+
export declare function SearchResultsPageView({ result, renderSearchInput, renderAboveGroups, }: SearchResultsPageViewProps): React.JSX.Element;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ROUTES } from "../../../next/routing/route-map.js";
|
|
3
3
|
import { Section, Container, Stack, Row, Div, Heading, Text, Span, TextLink } from "../../../ui/index.js";
|
|
4
|
-
export function SearchResultsPageView({ result, renderSearchInput, renderAboveGroups,
|
|
4
|
+
export function SearchResultsPageView({ result, renderSearchInput, renderAboveGroups, }) {
|
|
5
5
|
const { q, terms, groups, totalHits } = result;
|
|
6
6
|
const hasQuery = q.trim().length > 0;
|
|
7
7
|
/*
|
|
@@ -18,5 +18,5 @@ export function SearchResultsPageView({ result, renderSearchInput, renderAboveGr
|
|
|
18
18
|
const normalisedAway = hasQuery && terms.length === 0;
|
|
19
19
|
return (_jsx(Section, { padding: "page", children: _jsx(Container, { children: _jsxs(Stack, { gap: "loose", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 1, children: hasQuery ? `Search: ${q}` : "Search" }), hasQuery && !normalisedAway && (_jsx(Text, { color: "muted", size: "sm", children: totalHits === 0
|
|
20
20
|
? "Nothing matched."
|
|
21
|
-
: `${totalHits}${groups.some((g) => g.truncated) ? "+" : ""} result${totalHits === 1 ? "" : "s"} across ${groups.length} section${groups.length === 1 ? "" : "s"}.` }))] }),
|
|
21
|
+
: `${totalHits}${groups.some((g) => g.truncated) ? "+" : ""} result${totalHits === 1 ? "" : "s"} across ${groups.length} section${groups.length === 1 ? "" : "s"}.` }))] }), renderSearchInput?.(), renderAboveGroups?.(), !hasQuery && (_jsx(Text, { color: "muted", children: "Search listings, categories, brands, stores, articles and help pages at once." })), normalisedAway && (_jsx(Text, { color: "muted", children: "That search had no searchable words in it. Try a product, part or category name." })), groups.map((group) => (_jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { justify: "between", align: "center", wrap: true, gap: "sm", children: [_jsxs(Heading, { level: 2, size: "lg", children: [group.label, group.truncated && (_jsxs(Span, { size: "sm", color: "muted", children: [" ", "(", group.hits.length, "+)"] }))] }), _jsxs(TextLink, { href: group.moreHref, children: ["See all ", group.label.toLowerCase(), " \u2192"] })] }), _jsx(Stack, { gap: "xs", children: group.hits.map((hit) => (_jsx(Div, { surface: "card", rounded: "md", overflow: "hidden", children: _jsxs(TextLink, { href: hit.href, variant: "inherit", layout: "flex-col", gap: "xs", paddingX: "sm", paddingY: "sm", className: "w-full hover:bg-surface-hover", children: [_jsx(Text, { size: "sm", weight: "medium", children: hit.title }), hit.detail && (_jsx(Text, { size: "xs", color: "muted", children: hit.detail }))] }) }, `${group.key}-${hit.id}`))) })] }, group.key))), hasQuery && !normalisedAway && totalHits === 0 && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { color: "muted", children: ["No listings, categories, brands, stores, articles or help pages matched \u201C", q, "\u201D."] }), _jsx(TextLink, { href: ROUTES.PUBLIC.PRODUCTS, children: "Browse all listings \u2192" })] }))] }) }) }));
|
|
22
22
|
}
|
|
@@ -336,7 +336,22 @@ export async function counterOfferByBuyer(userId, userEmail, input) {
|
|
|
336
336
|
type: "offer_received",
|
|
337
337
|
priority: "normal",
|
|
338
338
|
title: "Buyer counter offer",
|
|
339
|
-
|
|
339
|
+
/*
|
|
340
|
+
* 🛑 `offerPlain.buyerName`, NOT `offer.buyerName`.
|
|
341
|
+
*
|
|
342
|
+
* `buyerName` is in `OFFER_PII_FIELDS`, so the raw document holds
|
|
343
|
+
* `enc:v1:…` — and `sendNotification` BAKES this string into the
|
|
344
|
+
* notification document at write time. Reading the encrypted field here
|
|
345
|
+
* stamped ciphertext permanently into a seller's inbox on every buyer
|
|
346
|
+
* counter-offer, unfixable after the fact because the message is frozen
|
|
347
|
+
* at write.
|
|
348
|
+
*
|
|
349
|
+
* This is the same mechanism that previously put `enc:v1:…` into 383
|
|
350
|
+
* admin alerts (see `onOrderCreate`'s decrypt comment). The plaintext was
|
|
351
|
+
* already in scope 41 lines up — `offerPlain` at :431, used for the
|
|
352
|
+
* `createOffer` call at :439.
|
|
353
|
+
*/
|
|
354
|
+
message: `${offerPlain.buyerName} countered with ₹${counterAmount} on "${offer.productTitle}".`,
|
|
340
355
|
relatedId: newOffer.id,
|
|
341
356
|
relatedType: "offer",
|
|
342
357
|
});
|
|
@@ -28,7 +28,7 @@ import { couponsRepository } from "../../promotions/repository/coupons.repositor
|
|
|
28
28
|
import { generateStoreSlug } from "../../stores/schemas/firestore.js";
|
|
29
29
|
import { siteSettingsRepository } from "../../admin/repository/site-settings.repository.js";
|
|
30
30
|
import { computePayoutDeduction } from "../../../_internal/shared/fees/calculator.js";
|
|
31
|
-
import { ordersTaxableValue } from "../../../_internal/shared/checkout/order-math.js";
|
|
31
|
+
import { ordersTaxableValue, ordersShippingReimbursement, } from "../../../_internal/shared/checkout/order-math.js";
|
|
32
32
|
import { getDefaultCurrency } from "../../../core/baseline-resolver.js";
|
|
33
33
|
import { finalizeStagedMediaUrl, finalizeStagedMediaField, finalizeStagedMediaArray, } from "../../media/finalize.js";
|
|
34
34
|
import { StoreStatusValues } from "../../stores/schemas/firestore.js";
|
|
@@ -238,7 +238,18 @@ async function computeSellerEarnings(sellerId) {
|
|
|
238
238
|
*/
|
|
239
239
|
const grossAmount = ordersTaxableValue(eligibleOrders);
|
|
240
240
|
const siteSettings = await siteSettingsRepository.getSingleton();
|
|
241
|
-
|
|
241
|
+
/*
|
|
242
|
+
* D45 — postage the seller is owed back, added AFTER the fee bases by
|
|
243
|
+
* `computePayoutDeduction` so no commission or gateway percentage is charged
|
|
244
|
+
* on a cost being refunded. Shiprocket-booked parcels return 0 (we paid that
|
|
245
|
+
* courier), and the self-shipped branch pays only what an admin APPROVED.
|
|
246
|
+
*
|
|
247
|
+
* 🛑 Passed at ALL FOUR payout call sites or they disagree to the rupee, and
|
|
248
|
+
* a seller shown one figure and paid another is worse than either being wrong
|
|
249
|
+
* alone.
|
|
250
|
+
*/
|
|
251
|
+
const shippingReimbursement = ordersShippingReimbursement(eligibleOrders);
|
|
252
|
+
const deduction = computePayoutDeduction(grossAmount, siteSettings.commissions, shippingReimbursement);
|
|
242
253
|
return {
|
|
243
254
|
eligibleOrders,
|
|
244
255
|
grossAmount,
|
|
@@ -348,7 +359,7 @@ export async function bulkSellerOrder(userId, userRole, userDisplayName, userEma
|
|
|
348
359
|
* scheduled job pay differently for the same orders. */
|
|
349
360
|
const grossAmount = ordersTaxableValue(eligible);
|
|
350
361
|
const bulkSiteSettings = await siteSettingsRepository.getSingleton();
|
|
351
|
-
const bulkDeduction = computePayoutDeduction(grossAmount, bulkSiteSettings.commissions);
|
|
362
|
+
const bulkDeduction = computePayoutDeduction(grossAmount, bulkSiteSettings.commissions, ordersShippingReimbursement(eligible));
|
|
352
363
|
const payoutDoc = await payoutRepository.createPayout({
|
|
353
364
|
storeId: userId,
|
|
354
365
|
sellerName: userDisplayName,
|
|
@@ -59,24 +59,56 @@ async function loadAdminCategoryOptions(query, page, leavesOnly) {
|
|
|
59
59
|
const total = res.total ?? items.length;
|
|
60
60
|
return { items, hasMore: page * 20 < total, nextPage: page + 1 };
|
|
61
61
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const PUBLIC_CATEGORY_PAGE_SIZE = 20;
|
|
63
|
+
/**
|
|
64
|
+
* Seller: paginated + SERVER-side search via the public `/api/categories`.
|
|
65
|
+
*
|
|
66
|
+
* 🛑 THIS USED TO FETCH 200 ROWS AND FILTER THEM IN THE BROWSER, against a
|
|
67
|
+
* catalogue of **1,185 categories**. It also returned `hasMore: false`, so
|
|
68
|
+
* `PaginatedSelect` never asked for page 2 — meaning **985 categories were
|
|
69
|
+
* permanently unreachable by search**, and what the box searched was whatever
|
|
70
|
+
* arbitrary 200 the endpoint happened to return first. The query never left
|
|
71
|
+
* the browser.
|
|
72
|
+
*
|
|
73
|
+
* The server was always ready: `/api/categories` reads `q` (its own comment
|
|
74
|
+
* notes that pickers send only `page`/`pageSize`/`q`) and returns a `total`
|
|
75
|
+
* for a paged flat request. The admin loader above has done it this way all
|
|
76
|
+
* along — this is the same shape, pointed at the unauthenticated endpoint.
|
|
77
|
+
*
|
|
78
|
+
* 🛑 A failed response now THROWS instead of degrading to an empty list. The
|
|
79
|
+
* old `.catch(() => ({}))` plus `json.data ?? []` turned any non-OK response
|
|
80
|
+
* or shape change into "No results" — indistinguishable from a genuine empty
|
|
81
|
+
* search, and a strong suspect for the reported symptom where typing a single
|
|
82
|
+
* letter matched nothing. `PaginatedSelect` renders an error state with a
|
|
83
|
+
* retry; a silent empty list is the one outcome that teaches the user their
|
|
84
|
+
* category does not exist.
|
|
85
|
+
*/
|
|
86
|
+
async function loadPublicCategoryOptions(query, page, leavesOnly) {
|
|
65
87
|
const leafFilter = leafFilterFor(leavesOnly);
|
|
66
88
|
const params = new URLSearchParams({
|
|
89
|
+
q: query.trim(),
|
|
90
|
+
page: String(page),
|
|
91
|
+
pageSize: String(PUBLIC_CATEGORY_PAGE_SIZE),
|
|
67
92
|
flat: "true",
|
|
68
|
-
pageSize: "200",
|
|
69
93
|
...(leafFilter ? { filters: leafFilter } : {}),
|
|
70
94
|
});
|
|
71
|
-
const res = await fetch(CATEGORY_ENDPOINTS.FILTERED(params.toString()), {
|
|
72
|
-
|
|
73
|
-
|
|
95
|
+
const res = await fetch(CATEGORY_ENDPOINTS.FILTERED(params.toString()), {
|
|
96
|
+
credentials: "include",
|
|
97
|
+
});
|
|
98
|
+
if (!res.ok) {
|
|
99
|
+
throw new Error(`Category lookup failed (${res.status})`);
|
|
100
|
+
}
|
|
101
|
+
const json = await res.json();
|
|
102
|
+
const items = (json.data ?? []).map((c) => ({
|
|
74
103
|
value: String(c.id ?? ""),
|
|
75
104
|
label: String(c.name ?? ""),
|
|
76
105
|
}));
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
106
|
+
const total = json.total ?? items.length;
|
|
107
|
+
return {
|
|
108
|
+
items,
|
|
109
|
+
hasMore: page * PUBLIC_CATEGORY_PAGE_SIZE < total,
|
|
110
|
+
nextPage: page + 1,
|
|
111
|
+
};
|
|
80
112
|
}
|
|
81
113
|
export function CategoryInlineSelect({ value, onChange, placeholder = "Search categories…", disabled, allowCreate = true, extraValues, onExtraValuesChange, maxAssignments = MAX_CATEGORY_ASSIGNMENTS, leavesOnly, }) {
|
|
82
114
|
/*
|
|
@@ -86,6 +118,24 @@ export function CategoryInlineSelect({ value, onChange, placeholder = "Search ca
|
|
|
86
118
|
* functions precisely to avoid it — binding the scope here would reintroduce
|
|
87
119
|
* the loop if it were done inline.
|
|
88
120
|
*/
|
|
121
|
+
/*
|
|
122
|
+
* 🛑 SUSPECT COUPLING, left in place deliberately rather than changed on a
|
|
123
|
+
* guess. `allowCreate` decides WHICH ENDPOINT is queried — and it defaults
|
|
124
|
+
* to `true` with the docstring "sellers can create categories inline", so a
|
|
125
|
+
* seller's picker calls `/api/admin/categories`. If that endpoint refuses a
|
|
126
|
+
* non-admin, the picker's symptom is "No results", not an error.
|
|
127
|
+
*
|
|
128
|
+
* Permission to CREATE and permission to SEARCH are different questions, and
|
|
129
|
+
* conflating them is how a lookup silently empties for one role. The public
|
|
130
|
+
* endpoint now has server-side search and paging (below), so it could serve
|
|
131
|
+
* both — but admins may rely on the admin endpoint to see inactive or
|
|
132
|
+
* unpublished rows the public one filters out, and losing those from the
|
|
133
|
+
* picker would be a worse regression than the one being fixed.
|
|
134
|
+
*
|
|
135
|
+
* To settle it: open the network tab and type one character. A 403 means
|
|
136
|
+
* this coupling is the bug; rows returned while the box says "No results"
|
|
137
|
+
* means the response shape moved; `[]` returned means the `filters` clause.
|
|
138
|
+
*/
|
|
89
139
|
const base = allowCreate ? loadAdminCategoryOptions : loadPublicCategoryOptions;
|
|
90
140
|
const loadOptions = React.useCallback((query, page) => base(query, page, leavesOnly), [base, leavesOnly]);
|
|
91
141
|
const primary = (_jsx(PaginatedSelect, { value: value || null, onChange: (v) => onChange(v ?? ""), loadOptions: loadOptions, placeholder: placeholder, disabled: disabled, createLabel: "category", drawerTitle: "Create Category", renderCreateForm: allowCreate
|
|
@@ -98,5 +148,19 @@ export function CategoryInlineSelect({ value, onChange, placeholder = "Search ca
|
|
|
98
148
|
const remaining = Math.max(0, maxAssignments - 1 - extras.length);
|
|
99
149
|
return (_jsxs(Stack, { gap: "sm", children: [primary, _jsx(PaginatedSelect, { multiple: true, value: extras, onChange: (v) => onExtraValuesChange(Array.isArray(v) ? v : []), loadOptions: loadOptions, placeholder: remaining > 0
|
|
100
150
|
? `Also list under… (up to ${remaining} more)`
|
|
101
|
-
: "No more categories can be added", disabled: disabled || remaining <= 0
|
|
151
|
+
: "No more categories can be added", disabled: disabled || remaining <= 0,
|
|
152
|
+
/*
|
|
153
|
+
* 🛑 The create affordance belongs here too, and its absence was a
|
|
154
|
+
* one-line omission rather than a decision. The primary picker above
|
|
155
|
+
* passes all three of these; this one passed none, so a seller could
|
|
156
|
+
* create a category for their FIRST assignment and not for any other.
|
|
157
|
+
*
|
|
158
|
+
* Nothing about a secondary assignment makes creating one less valid
|
|
159
|
+
* — and the helper text directly below actively tells the seller to
|
|
160
|
+
* "add a category from a DIFFERENT tree", which is precisely when the
|
|
161
|
+
* one they want is least likely to exist yet.
|
|
162
|
+
*/
|
|
163
|
+
createLabel: "category", drawerTitle: "Create Category", renderCreateForm: allowCreate
|
|
164
|
+
? ({ onCreated, onCancel }) => (_jsx(CategoryQuickCreateForm, { onSaved: (id, name) => onCreated({ value: id, label: name }), onCancel: onCancel }))
|
|
165
|
+
: undefined }), _jsx(Text, { size: "xs", color: "muted", children: "Optional. Add a category from a DIFFERENT tree \u2014 a franchise, for example. Two categories from the same tree will be refused, because the broader one is already implied by the narrower." })] }));
|
|
102
166
|
}
|
|
@@ -17,6 +17,11 @@ interface PrintCenterProduct {
|
|
|
17
17
|
stockCount?: number;
|
|
18
18
|
physicalLocation?: PhysicalLocationParts;
|
|
19
19
|
barcodeId?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The storage box this product is placed in, from the placements registry.
|
|
22
|
+
* Preferred over `physicalLocation` on the label — see the render note.
|
|
23
|
+
*/
|
|
24
|
+
boxCode?: string | null;
|
|
20
25
|
}
|
|
21
26
|
interface PrintCenterOrder {
|
|
22
27
|
id: string;
|
|
@@ -1,37 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { useEffect, useRef, useState } from "react";
|
|
5
|
-
import JsBarcode from "jsbarcode";
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
6
4
|
import { Heading, Text } from "../../../ui/components/Typography.js";
|
|
7
5
|
import { Stack, Row } from "../../../ui/components/Layout.js";
|
|
8
6
|
import { Button } from "../../../ui/components/Button.js";
|
|
9
7
|
import { FieldCheckbox } from "../../../ui/forms/FieldCheckbox.js";
|
|
10
8
|
import { formatPhysicalLocation, } from "../../../utils/physical-location.js";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// recovery beyond fixing the barcodeId on the product itself.
|
|
27
|
-
}
|
|
28
|
-
catch (_err) {
|
|
29
|
-
void normalizeError(_err);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}, [product.barcodeId]);
|
|
33
|
-
return (_jsxs(Stack, { surface: "card", padding: "sm", rounded: "sm", gap: "xs", className: "break-inside-avoid text-center w-[200px]", children: [product.barcodeId ? (_jsx("svg", { ref: svgRef })) : (_jsx(Text, { size: "xs", color: "muted", children: "No barcode" })), _jsx(Text, { size: "xs", weight: "medium", truncate: 1, children: product.name }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u20B9", product.price.toLocaleString("en-IN")] }), formatPhysicalLocation(product.physicalLocation) && (_jsx(Text, { size: "xs", color: "muted", children: formatPhysicalLocation(product.physicalLocation) }))] }));
|
|
34
|
-
}
|
|
9
|
+
import { LabelPageStyle, LabelSheet, ProductLabel, PrintScaleWarning, } from "../../print/components/labels.js";
|
|
10
|
+
import { LabelProfilePicker } from "../../print/components/LabelProfilePicker.js";
|
|
11
|
+
import { LABEL_PROFILES, documentPageCss, labelPageCss, } from "../../../_internal/shared/features/print/label-profiles.js";
|
|
12
|
+
/*
|
|
13
|
+
* 🛑 THE LOCAL `ProductLabel` IS GONE. It was `w-[200px]`, rendered a barcode
|
|
14
|
+
* at `width: 2` (a 0.53 mm module — twice the density needed) with a fixed
|
|
15
|
+
* `margin: 8` quiet zone (4 modules against the 10 the symbology requires),
|
|
16
|
+
* and this view emitted no `@page` rule at all. So a thermal printer received
|
|
17
|
+
* the browser's default A4 with a 200-pixel card in the corner, and nothing
|
|
18
|
+
* errored.
|
|
19
|
+
*
|
|
20
|
+
* `features/print/components/labels.tsx` replaces it with mm geometry driven
|
|
21
|
+
* by the chosen profile. See that file's header for the two unit conversions,
|
|
22
|
+
* and `label-profiles.ts` for why the fit check refuses rather than scales.
|
|
23
|
+
*/
|
|
35
24
|
function PackingSlip({ order, brandName }) {
|
|
36
25
|
return (_jsxs(Stack, { surface: "card", padding: "md", rounded: "sm", className: "break-inside-avoid mb-4 max-w-[480px]", children: [_jsxs(Row, { justify: "between", className: "mb-2", children: [_jsx(Heading, { level: 5, children: brandName }), _jsxs(Text, { size: "xs", color: "muted", children: ["#", order.id] })] }), _jsx(Text, { size: "xs", color: "muted", children: new Date(order.createdAt).toLocaleDateString("en-IN") }), order.buyerDisplayName && _jsx(Text, { size: "sm", weight: "medium", children: order.buyerDisplayName }), order.buyerCity && _jsx(Text, { size: "xs", color: "muted", children: order.buyerCity }), formatPhysicalLocation(order.physicalLocation) && (_jsxs(Text, { size: "xs", color: "muted", children: ["Staging: ", formatPhysicalLocation(order.physicalLocation)] })), _jsx(Stack, { border: "top", padding: "t-xs", className: "mt-3", children: order.items.map((item, i) => (_jsxs(Row, { justify: "between", padding: "y-2xs", className: "border-b last:border-b-0", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "xs", weight: "medium", children: item.productName }), item.barcodeId && _jsx(Text, { size: "xs", color: "muted", children: item.barcodeId })] }), _jsxs(Stack, { className: "text-right", children: [_jsxs(Text, { size: "xs", children: ["\u00D7", item.quantity] }), _jsxs(Text, { size: "xs", color: "muted", children: ["\u20B9", item.price.toLocaleString("en-IN")] })] })] }, i))) })] }));
|
|
37
26
|
}
|
|
@@ -39,6 +28,16 @@ export function PrintCenterView({ store, brandName = "LetItRip", initialProducts
|
|
|
39
28
|
const [tab, setTab] = useState("labels");
|
|
40
29
|
const [selectedProducts, setSelectedProducts] = useState(new Set());
|
|
41
30
|
const [selectedOrders, setSelectedOrders] = useState(new Set());
|
|
31
|
+
const [profileId, setProfileId] = useState("thermal-50x25");
|
|
32
|
+
const profile = LABEL_PROFILES[profileId];
|
|
33
|
+
const chosenProducts = useMemo(() => initialProducts.filter((p) => selectedProducts.has(p.id)), [initialProducts, selectedProducts]);
|
|
34
|
+
/*
|
|
35
|
+
* The LONGEST code in the selection, so the fit warning is about the worst
|
|
36
|
+
* label in the batch. Checking the first or the average would report "fits"
|
|
37
|
+
* about a job in which some labels do not — and the operator only finds out
|
|
38
|
+
* which ones after printing.
|
|
39
|
+
*/
|
|
40
|
+
const longestCodeLength = useMemo(() => chosenProducts.reduce((n, p) => Math.max(n, (p.barcodeId ?? "").length), 0), [chosenProducts]);
|
|
42
41
|
const toggleProduct = (id) => setSelectedProducts((prev) => {
|
|
43
42
|
const next = new Set(prev);
|
|
44
43
|
if (next.has(id))
|
|
@@ -56,9 +55,21 @@ export function PrintCenterView({ store, brandName = "LetItRip", initialProducts
|
|
|
56
55
|
return next;
|
|
57
56
|
});
|
|
58
57
|
const printSelected = () => window.print();
|
|
59
|
-
return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsx(
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
return (_jsxs(Stack, { gap: "md", padding: "md", children: [_jsx(LabelPageStyle, { css: tab === "labels" ? labelPageCss(profile) : documentPageCss() }), _jsxs(Stack, { className: "no-print", children: [_jsxs(Heading, { level: 3, children: ["Print Center", store ? ` — ${store.storeName}` : ""] }), _jsxs(Row, { gap: "xs", className: "mt-3", children: [_jsx(Button, { onClick: () => setTab("labels"), variant: tab === "labels" ? "primary" : "secondary", size: "sm", children: "Product Labels" }), _jsx(Button, { onClick: () => setTab("slips"), variant: tab === "slips" ? "primary" : "secondary", size: "sm", children: "Packing Slips" })] })] }), tab === "labels" && (_jsxs(_Fragment, { children: [_jsxs(Stack, { className: "no-print", gap: "sm", children: [_jsx(LabelProfilePicker, { value: profileId, onChange: setProfileId, longestCodeLength: longestCodeLength }), _jsx(PrintScaleWarning, {}), _jsxs(Stack, { gap: "sm", children: [initialProducts.length === 0 ? (_jsx(Text, { color: "muted", children: "No products available." })) : (initialProducts.map((p) => (_jsx(FieldCheckbox, { name: `product-${p.id}`, label: p.name, checked: selectedProducts.has(p.id), onChange: () => toggleProduct(p.id) }, p.id)))), _jsxs(Button, { onClick: printSelected, disabled: selectedProducts.size === 0, children: ["Print Selected (", selectedProducts.size, ")"] })] })] }), _jsx(LabelSheet, { profile: profile, children: chosenProducts.map((p) => (_jsx(ProductLabel, { profile: profile, product: {
|
|
59
|
+
barcodeId: p.barcodeId,
|
|
60
|
+
name: p.name,
|
|
61
|
+
price: p.price,
|
|
62
|
+
/*
|
|
63
|
+
* 🛑 The BOX CODE, falling back to the legacy free-text
|
|
64
|
+
* location. `boxCode` comes from the placements registry, so
|
|
65
|
+
* it is one of a known set and groups correctly;
|
|
66
|
+
* `physicalLocation` was three uncontrolled inputs where
|
|
67
|
+
* "shelf 3", "Shelf-3" and "AC60 3" all meant one place and
|
|
68
|
+
* no list could group them. The fallback keeps old products
|
|
69
|
+
* printing something until that field is retired.
|
|
70
|
+
*/
|
|
71
|
+
boxCode: p.boxCode ?? formatPhysicalLocation(p.physicalLocation) ?? null,
|
|
72
|
+
} }, p.id))) })] })), tab === "slips" && (_jsxs(_Fragment, { children: [_jsx(Stack, { className: "no-print", children: _jsxs(Stack, { gap: "sm", children: [initialOrders.length === 0 ? (_jsx(Text, { color: "muted", children: "No orders available." })) : (initialOrders.map((o) => (_jsx(FieldCheckbox, { name: `order-${o.id}`, label: `#${o.id}${o.buyerDisplayName ? ` — ${o.buyerDisplayName}` : ""}`, checked: selectedOrders.has(o.id), onChange: () => toggleOrder(o.id) }, o.id)))), _jsxs(Button, { onClick: printSelected, disabled: selectedOrders.size === 0, children: ["Print Selected (", selectedOrders.size, ")"] })] }) }), _jsx(Stack, { gap: "sm", children: initialOrders
|
|
62
73
|
.filter((o) => selectedOrders.has(o.id))
|
|
63
74
|
.map((o) => (_jsx(PackingSlip, { order: o, brandName: brandName }, o.id))) })] }))] }));
|
|
64
75
|
}
|
|
@@ -249,7 +249,7 @@ export function SellerOrderDetailPanel({ orderId, apiBase, onClose, }) {
|
|
|
249
249
|
const addrLine = typeof rawAddr === "string" && rawAddr.trim()
|
|
250
250
|
? rawAddr.trim()
|
|
251
251
|
: [addr.addressLine1, addr.city, addr.state, addr.pincode].filter(Boolean).join(", ");
|
|
252
|
-
return (_jsxs(_Fragment, { children: [loading && (_jsx(Row, { align: "center", justify: "center", padding: "y-4xl", children: _jsx(Div, { className: "h-6 w-6 animate-spin border-2 border-[var(--appkit-color-primary)] border-t-transparent", rounded: "full" }) })), fetchError && (_jsx(Div, { textSize: "sm", className: "mx-4 mt-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "lg", children: fetchError })), order && !loading && (_jsxs(Stack, { gap: "none", children: [_jsxs(Stack, { className: `flex-1 ${__O.yAuto}`, gap: "5", padding: "md", children: [_jsxs(Row, { align: "center", justify: "between", children: [_jsx(Badge, { variant: STATUS_BADGE_VARIANT[order.status ?? ""] ?? "default", children: order.status ?? "Unknown" }), _jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text-
|
|
252
|
+
return (_jsxs(_Fragment, { children: [loading && (_jsx(Row, { align: "center", justify: "center", padding: "y-4xl", children: _jsx(Div, { className: "h-6 w-6 animate-spin border-2 border-[var(--appkit-color-primary)] border-t-transparent", rounded: "full" }) })), fetchError && (_jsx(Div, { textSize: "sm", className: "mx-4 mt-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "lg", children: fetchError })), order && !loading && (_jsxs(Stack, { gap: "none", children: [_jsxs(Stack, { className: `flex-1 ${__O.yAuto}`, gap: "5", padding: "md", children: [_jsxs(Row, { align: "center", justify: "between", children: [_jsx(Badge, { variant: STATUS_BADGE_VARIANT[order.status ?? ""] ?? "default", children: order.status ?? "Unknown" }), _jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text-muted)]", children: toRelativeDate(order.createdAt) })] }), (order.items ?? []).length > 0 && (_jsxs(Div, { children: [_jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text)] mb-2", weight: "semibold", children: "Items" }), _jsx(Div, { className: "divide-y divide-[var(--appkit-color-border)] divide-[var(--appkit-color-border)] border border-[var(--appkit-color-border)]", rounded: "lg", children: (order.items ?? []).map((item, i) => (_jsxs(Row, { paddingY: "y-xs-tall", padding: "x-sm", align: "center", justify: "between", gap: "3", children: [_jsxs(Row, { align: "center", gap: "sm", className: "min-w-0", children: [_jsx(Div, { className: "h-10 w-10 shrink-0", rounded: "md", overflow: "hidden", children: _jsx(MediaImage, { src: item.image, alt: item.title ?? "Order item", size: "thumbnail" }) }), _jsxs(Div, { className: "min-w-0", children: [_jsx(Text, { size: "sm", className: "truncate", weight: "medium", children: item.productTitle ?? item.title ?? item.productId ?? "Item" }), _jsxs(Text, { size: "xs", className: "text-[var(--appkit-color-text-muted)]", children: ["Qty: ", item.quantity ?? 1] })] })] }), _jsx(Text, { size: "sm", className: "shrink-0", weight: "medium", children: toCurrency(item.totalPrice ?? item.unitPrice ?? item.price ?? 0) })] }, i))) })] })), _jsx(OrderAddonBadges, { order: order, variant: "detail" }), order.giftWrapAddon && (_jsxs(Div, { className: "border border-[var(--appkit-color-primary-200)] dark:border-[var(--appkit-color-primary-800)]", surface: "subtle", padding: "inline", rounded: "lg", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "\uD83C\uDF81 Gift wrap requested" }), order.giftWrapMessage && (_jsxs(Text, { size: "sm", className: "mt-1 text-[var(--appkit-color-text-muted)]", children: ["\u201C", order.giftWrapMessage, "\u201D"] }))] })), _jsxs(Row, { surface: "muted", padding: "inline", align: "center", justify: "between", rounded: "lg", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Total" }), _jsx(Text, { size: "sm", className: "text-[var(--appkit-color-primary)]", weight: "bold", children: toCurrency(order.totalAmount ?? order.totalPrice ?? 0) })] }), addrLine && (_jsxs(Div, { children: [_jsx(Text, { size: "sm", className: "mb-1", weight: "semibold", children: "Shipping address" }), _jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text-muted)]", children: [String(addr.fullName ?? ""), addrLine].filter(Boolean).join(" · ") })] })), order.paymentMethod && (_jsxs(Div, { children: [_jsxs(Row, { align: "center", justify: "between", className: "mb-1", gap: "3", children: [_jsx(Text, { size: "sm", weight: "semibold", children: "Payment" }), isManualPaymentMethod(order.paymentMethod) && (_jsx(Badge, { variant: sellerPaymentBadge(order).variant, children: sellerPaymentBadge(order).label }))] }), _jsx(Text, { size: "sm", className: "text-[var(--appkit-color-text-muted)]", transform: "capitalize", children: order.paymentMethod }), isManualPaymentMethod(order.paymentMethod) && order.paymentTransactionId && (_jsxs(Text, { size: "xs", color: "muted", className: "mt-1", children: ["UTR: ", order.paymentTransactionId] }))] })), order.emiEnabled && (_jsxs(Div, { className: "border-t border-[var(--appkit-color-border)]", padding: "t-md", children: [_jsxs(Row, { align: "center", justify: "between", className: "mb-2", children: [_jsxs(Text, { size: "sm", weight: "semibold", children: ["EMI plan ", order.emiTenureMonths ? `· ${order.emiTenureMonths} months` : ""] }), _jsx(Badge, { variant: order.emiComplete ? "success" : "warning", children: order.emiComplete ? "Fully paid" : "In progress" })] }), _jsxs(Row, { align: "center", justify: "between", className: "mb-2", children: [_jsx(Text, { size: "xs", color: "muted", children: "Token collected" }), _jsx(Text, { size: "xs", weight: "medium", children: toCurrency(order.emiTokenAmount ?? 0) })] }), _jsxs(Row, { align: "center", justify: "between", className: "mb-3", children: [_jsx(Text, { size: "xs", color: "muted", children: "Remaining balance" }), _jsx(Text, { size: "xs", weight: "medium", children: toCurrency(order.emiRemainingBalance ?? 0) })] }), _jsx(Div, { className: "divide-y divide-[var(--appkit-color-border)] border border-[var(--appkit-color-border)]", rounded: "lg", children: (order.emiInstallments ?? []).map((inst) => (_jsxs(Row, { paddingY: "y-xs-tall", padding: "x-sm", align: "center", justify: "between", gap: "3", children: [_jsxs(Div, { className: "min-w-0", children: [_jsxs(Text, { size: "sm", weight: "medium", children: ["Installment ", inst.index, " \u00B7 ", toCurrency(inst.amount)] }), _jsx(Text, { size: "xs", color: "muted", children: inst.status === "paid" && inst.paidAt
|
|
253
253
|
? `Paid ${toRelativeDate(inst.paidAt)}`
|
|
254
254
|
: inst.dueDate
|
|
255
255
|
? `Due ${toRelativeDate(inst.dueDate)}`
|
|
@@ -4,13 +4,24 @@ import { normalizeError } from "../../../errors/normalize.js";
|
|
|
4
4
|
import { useEffect, useState } from "react";
|
|
5
5
|
import { Alert, Badge, Button, Div, Modal, Row, Stack, Text, Textarea } from "../../../ui/index.js";
|
|
6
6
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints.js";
|
|
7
|
+
import { formatCurrency } from "../../../utils/number.formatter.js";
|
|
7
8
|
const __P = {
|
|
8
9
|
p3: "p-[var(--appkit-space-3)]",
|
|
9
10
|
p4: "p-[var(--appkit-space-4)]",
|
|
10
11
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/*
|
|
13
|
+
* 🛑 A LOCAL `rupees()` HELPER WAS DELETED HERE in favour of the one formatter.
|
|
14
|
+
*
|
|
15
|
+
* It set `minimumFractionDigits: 2` and no MAXIMUM, so a value carrying more
|
|
16
|
+
* than two decimals printed every one of them — and payout amounts are
|
|
17
|
+
* commission arithmetic, which is exactly where they come from. A seller's
|
|
18
|
+
* available earnings could read "₹17,500.333".
|
|
19
|
+
*
|
|
20
|
+
* `formatCurrency` goes through `Intl.NumberFormat` with `style: "currency"`,
|
|
21
|
+
* which pins the fraction digits to the currency's own minor-unit count (2
|
|
22
|
+
* for INR) in both directions, and takes the symbol from the locale rather
|
|
23
|
+
* than hardcoding one.
|
|
24
|
+
*/
|
|
14
25
|
export function SellerPayoutRequestView({ payoutsApiBase = SELLER_ENDPOINTS.PAYOUTS, payoutSettingsApiBase = SELLER_ENDPOINTS.PAYOUT_SETTINGS, requestApiBase = SELLER_ENDPOINTS.PAYOUT_REQUEST, onRequested, }) {
|
|
15
26
|
const [summary, setSummary] = useState(null);
|
|
16
27
|
const [payoutDetails, setPayoutDetails] = useState(null);
|
|
@@ -64,7 +75,7 @@ export function SellerPayoutRequestView({ payoutsApiBase = SELLER_ENDPOINTS.PAYO
|
|
|
64
75
|
if (!summary)
|
|
65
76
|
return null;
|
|
66
77
|
const canRequest = !summary.hasPendingPayout && summary.availableEarnings > 0 && payoutDetails?.isConfigured;
|
|
67
|
-
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: `${__P.p4} border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]`, rounded: "lg", children: _jsxs(Row, { align: "center", justify: "between", gap: "3", wrap: true, children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Available for Payout" }), _jsx(Text, { className: "text-[var(--appkit-color-primary)]", size: "2xl", weight: "bold", children:
|
|
78
|
+
return (_jsxs(_Fragment, { children: [_jsx(Div, { className: `${__P.p4} border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]`, rounded: "lg", children: _jsxs(Row, { align: "center", justify: "between", gap: "3", wrap: true, children: [_jsxs(Div, { children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Available for Payout" }), _jsx(Text, { className: "text-[var(--appkit-color-primary)]", size: "2xl", weight: "bold", children: formatCurrency(summary.availableEarnings) }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)] mt-0.5", size: "xs", children: [summary.eligibleOrderCount, " eligible order", summary.eligibleOrderCount !== 1 ? "s" : ""] })] }), _jsxs(Row, { align: "center", gap: "sm", wrap: true, children: [summary.hasPendingPayout && _jsx(Badge, { variant: "warning", children: "Payout in progress" }), submitted && _jsx(Badge, { variant: "success", children: "Payout requested!" }), !payoutDetails?.isConfigured && (_jsx(Text, { className: "text-[var(--appkit-color-warning)]", size: "sm", children: "Set up payout details first" })), _jsx(Button, { variant: "primary", onClick: () => setModalOpen(true), disabled: !canRequest, children: "Request Payout" })] })] }) }), _jsx(Modal, { isOpen: modalOpen, onClose: () => { setModalOpen(false); setSubmitError(null); }, title: "Request Payout", children: _jsxs(Stack, { gap: "md", className: `${__P.p4}`, children: [_jsxs(Div, { className: `${__P.p3} bg-[var(--appkit-color-bg)]`, rounded: "default", children: [_jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Amount to be paid" }), _jsx(Text, { size: "xl", weight: "bold", children: formatCurrency(summary?.availableEarnings ?? 0) }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: ["Via ", payoutDetails?.method === "upi"
|
|
68
79
|
? `UPI — ${payoutDetails.upiId}`
|
|
69
|
-
: `Bank — ${payoutDetails?.bankAccount?.bankName ?? ""} ••••${payoutDetails?.bankAccount?.accountNumberMasked?.slice(-4) ?? "••••"}`] })] }), submitError && _jsx(Alert, { variant: "error", children: submitError }),
|
|
80
|
+
: `Bank — ${payoutDetails?.bankAccount?.bankName ?? ""} ••••${payoutDetails?.bankAccount?.accountNumberMasked?.slice(-4) ?? "••••"}`] })] }), submitError && _jsx(Alert, { variant: "error", children: submitError }), _jsx(Div, { children: _jsx(Textarea, { label: "Notes (optional)", rows: 3, value: notes, onChange: (e) => setNotes(e.target.value), maxLength: 500, placeholder: "Any notes for the payout request\u2026" }) }), _jsxs(Row, { justify: "end", gap: "sm", children: [_jsx(Button, { variant: "outline", onClick: () => setModalOpen(false), disabled: submitting, children: "Cancel" }), _jsx(Button, { variant: "primary", onClick: handleRequest, disabled: submitting, isLoading: submitting, children: "Confirm Request" })] })] }) })] }));
|
|
70
81
|
}
|
|
@@ -300,7 +300,7 @@ export function SellerPayoutSettingsView({ apiBase = SELLER_ENDPOINTS.PAYOUT_SET
|
|
|
300
300
|
id: "preferences",
|
|
301
301
|
label: "Preferences",
|
|
302
302
|
fields: ["autoPayout", "minimumThreshold", "emiEnabled", "pricesIncludeGst", "supportsShippingProtection", "supportsSaleProtection", "advancedListingTypesEnabled"],
|
|
303
|
-
render: ({ values, onChange }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, className: "mb-2", children: "Payout Preferences" }), _jsx(Toggle, { checked: values.autoPayout, onChange: (checked) => onChange({ autoPayout: checked }), label: "Enable auto-payout \u2014 automatically transfer earnings on schedule", disabled: busy }), _jsx(FormField, { name: "minimumThreshold", label: "Minimum Payout Threshold (\u20B9)", type: "number", value: values.minimumThreshold, onChange: (v) => onChange({ minimumThreshold: v }), placeholder: "e.g. 500", helpText: "Payouts are held until your balance exceeds this amount. Leave blank for no minimum.", disabled: busy }), _jsxs(Div, { className: `${__P.p3} bg-[var(--appkit-color-
|
|
303
|
+
render: ({ values, onChange }) => (_jsxs(Stack, { gap: "md", children: [_jsx(Heading, { level: 3, className: "mb-2", children: "Payout Preferences" }), _jsx(Toggle, { checked: values.autoPayout, onChange: (checked) => onChange({ autoPayout: checked }), label: "Enable auto-payout \u2014 automatically transfer earnings on schedule", disabled: busy }), _jsx(FormField, { name: "minimumThreshold", label: "Minimum Payout Threshold (\u20B9)", type: "number", value: values.minimumThreshold, onChange: (v) => onChange({ minimumThreshold: v }), placeholder: "e.g. 500", helpText: "Payouts are held until your balance exceeds this amount. Leave blank for no minimum.", disabled: busy }), _jsxs(Div, { className: `${__P.p3} bg-[var(--appkit-color-bg)] border border-[var(--appkit-color-border)]`, rounded: "lg", children: [_jsx(Text, { className: "mb-1", size: "sm", weight: "medium", children: "Payout Schedule" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Auto-payouts run every Monday for the previous week's settled orders. Manual payouts can be requested from the Payouts page at any time." })] }), _jsx(Toggle, { checked: values.emiEnabled, onChange: (checked) => onChange({ emiEnabled: checked }), label: "Offer EMI financing on eligible orders", disabled: busy }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Only shown to buyers when platform-wide EMI is also enabled and their cart subtotal from your store exceeds the site's minimum order value. Orders on an EMI plan hold your payout until every installment is paid, unless you mark the item \"ship before EMI completes\"." }), _jsx(Toggle, { checked: values.pricesIncludeGst, onChange: (checked) => onChange({ pricesIncludeGst: checked }), label: "The prices I enter already include GST", disabled: busy }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: ["Buyers always see a tax-inclusive price, so this only changes how your own entry is read. Leave it", " ", _jsx(Span, { weight: "semibold", children: "on" }), " and a \u20B9999 listing at 5% GST means the buyer pays \u20B9999 and you earn \u20B9951.43 \u2014 the \u20B947.57 is GST we collect and remit for you. Turn it", " ", _jsx(Span, { weight: "semibold", children: "off" }), " and \u20B9999 is treated as your ex-GST price: the listing is shown at \u20B91,048.95 and you earn \u20B9999."] }), _jsx(Heading, { level: 3, className: "mb-2 mt-4", children: "Buyer Protections" }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: ["Two separate covers a buyer can pay for at checkout. Supporting one earns a safety badge on your listings;", " ", _jsx(Span, { weight: "semibold", children: "declining shows buyers a risk notice instead" }), " \u2014 there is no neutral option, because a buyer who is told nothing cannot tell a seller who declined from one who was never asked."] }), _jsx(Toggle, { checked: values.supportsShippingProtection, onChange: (checked) => onChange({ supportsShippingProtection: checked }), label: "Offer shipment protection \u2014 loss or damage in transit", disabled: busy }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "The parcel never arrived or arrived damaged. We pursue the courier, not you, and the buyer is refunded from the funds we hold \u2014 so a genuine transit loss costs you the item, not an argument." }), _jsx(Toggle, { checked: values.supportsSaleProtection, onChange: (checked) => onChange({ supportsSaleProtection: checked }), label: "Offer sale protection \u2014 item not as described", disabled: busy }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: ["A no-questions-asked refund on the item itself. Be clear about what this means:", " ", _jsx(Span, { weight: "semibold", children: "a claim we inspect and find genuine is charged back to you" }), " ", "\u2014 that is the cover. A claim we find to be a change of mind is absorbed by us, which is what the buyer's fee pays for. Not offered on your final-sale listings, since \"no returns\" and \"no questions asked\" cannot both be true."] }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: "Changing this does not re-price listings you have already published. It applies to products you save from now on." }), _jsx(Toggle, { checked: values.advancedListingTypesEnabled, onChange: (checked) => onChange({ advancedListingTypesEnabled: checked }), label: "Enable advanced listing types", disabled: busy }), _jsxs(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: ["Adds pre-orders, prize draws, classifieds, digital codes, live items, art and stickers alongside the products, spares and auctions you can already list. Each carries its own obligation:", " ", _jsx(Span, { weight: "semibold", children: "a pre-order takes payment for stock you do not have yet, a prize draw is a regulated promotion, a classified happens off-platform with no escrow protection, a digital code must be delivered from a pool you keep stocked, and a live listing is an animal." }), " ", "Turning this off later does not unpublish listings you have already created \u2014 it only stops you making new ones."] })] })),
|
|
304
304
|
},
|
|
305
305
|
], [busy, current]);
|
|
306
306
|
const { openIds, setOpenIds, goToSection, fieldToSectionIndex, sectionMeta } = useSectionFormNav(sections, draft);
|
|
@@ -150,6 +150,22 @@ export interface SellerProductDraft {
|
|
|
150
150
|
liveCites?: boolean;
|
|
151
151
|
/** Barcode ID of the physical sticker on this item. Auto-generated on save if blank. */
|
|
152
152
|
barcodeId?: string;
|
|
153
|
+
/**
|
|
154
|
+
* The seller's OWN stock-keeping code — human-chosen, human-typed, and
|
|
155
|
+
* distinct from `barcodeId`, which is machine-generated.
|
|
156
|
+
*
|
|
157
|
+
* 🛑 This was RENDERED WITHOUT BEING DECLARED. The `sku` FormField read
|
|
158
|
+
* `values.sku` and wrote `onChange({ sku })` while the property existed on
|
|
159
|
+
* neither this interface nor `sellerProductSchema`, so both lines were hard
|
|
160
|
+
* type errors — invisible only because a syntax error elsewhere in appkit
|
|
161
|
+
* was stopping tsc before it got here.
|
|
162
|
+
*
|
|
163
|
+
* It did not fail silently at runtime, which is the part worth noting:
|
|
164
|
+
* `sellerProductSchema` is `.passthrough()`, so a typed value survived to
|
|
165
|
+
* Firestore untyped and unvalidated — exactly the trap this file's own
|
|
166
|
+
* `isLot` and `categoryIds` comments warn about, two hundred lines up.
|
|
167
|
+
*/
|
|
168
|
+
sku?: string;
|
|
153
169
|
printSize?: string;
|
|
154
170
|
printMaterial?: string;
|
|
155
171
|
printFinish?: string;
|