@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
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Physical labels — the ones that get stuck to things.
|
|
5
|
+
*
|
|
6
|
+
* 🛑 EVERYTHING HERE IS SIZED IN MILLIMETRES, because the output is a physical
|
|
7
|
+
* object. `PrintCenterView` sized its labels `w-[200px]` and emitted no `@page`
|
|
8
|
+
* rule at all, so a thermal printer received the browser's default A4 with a
|
|
9
|
+
* 200-pixel card in the corner of it. Nothing errored; the operator found out
|
|
10
|
+
* by holding a mostly-blank 50 x 25 mm label.
|
|
11
|
+
*
|
|
12
|
+
* ── THE TWO UNIT CONVERSIONS THAT MATTER ────────────────────────────────────
|
|
13
|
+
*
|
|
14
|
+
* 1. CSS defines 96 px per inch, EXACTLY, regardless of screen DPI. At print
|
|
15
|
+
* time the browser maps that to physical length, so a CSS px is 25.4/96 =
|
|
16
|
+
* 0.2646 mm of paper. That is the only bridge between a layout and a ruler.
|
|
17
|
+
*
|
|
18
|
+
* 2. `JsBarcode`'s `width` option is PIXELS PER MODULE, not millimetres. The
|
|
19
|
+
* previous code passed `width: 2`, i.e. a 0.53 mm module — twice the density
|
|
20
|
+
* needed, which is why those barcodes were enormous. `moduleWidthPx()`
|
|
21
|
+
* converts a target mm module into that option so the intent is stated once.
|
|
22
|
+
*
|
|
23
|
+
* 🛑 AND THE WHOLE CHAIN IS DEFEATED BY THE PRINT DIALOG. "Fit to page" or any
|
|
24
|
+
* scale other than 100% rescales the symbol, taking the module width with it —
|
|
25
|
+
* silently, and the label still looks correct. Every printable view here says
|
|
26
|
+
* so on screen, because it is the one failure no code can prevent.
|
|
27
|
+
*
|
|
28
|
+
* ── WHY THIS FILE USES `style={{}}` FOR DIMENSIONS ──────────────────────────
|
|
29
|
+
*
|
|
30
|
+
* Normally a variant or a token; here the numbers come from the PROFILE at
|
|
31
|
+
* runtime, so `w-[${profile.widthMm}mm]` is a class Tailwind's build-time
|
|
32
|
+
* scanner never sees and therefore never generates — it would silently emit
|
|
33
|
+
* nothing and every label would collapse to its content size. These are the
|
|
34
|
+
* "dynamic values impossible with classes" case the inline-style rule exists
|
|
35
|
+
* to permit, and none of them is a COLOUR: every `style` here is a length or a
|
|
36
|
+
* position. Colour, surface and type still go through the primitives.
|
|
37
|
+
*/
|
|
38
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
39
|
+
import JsBarcode from "jsbarcode";
|
|
40
|
+
import { Div, Row, Stack, Text } from "../../../ui/index.js";
|
|
41
|
+
import { normalizeError } from "../../../errors/normalize.js";
|
|
42
|
+
import { MM_PER_INCH, SAFE_MODULE_MM, labelFitsProfile, sheetPositionMm, } from "../../../_internal/shared/features/print/label-profiles.js";
|
|
43
|
+
/** CSS px per inch is 96 by definition — not a screen measurement. */
|
|
44
|
+
const CSS_PX_PER_INCH = 96;
|
|
45
|
+
/** Millimetres of paper to CSS pixels. The only unit bridge in this file. */
|
|
46
|
+
export function mmToCssPx(mm) {
|
|
47
|
+
return (mm / MM_PER_INCH) * CSS_PX_PER_INCH;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A target module width in mm, as JsBarcode's `width` option.
|
|
51
|
+
*
|
|
52
|
+
* Not rounded to an integer: JsBarcode accepts a fractional module width and
|
|
53
|
+
* rounding to 1 px would quantise every density to 0.265 mm steps — which on a
|
|
54
|
+
* 50 x 25 mm label is the difference between fitting and not.
|
|
55
|
+
*/
|
|
56
|
+
export function moduleWidthPx(moduleMm = SAFE_MODULE_MM) {
|
|
57
|
+
return mmToCssPx(moduleMm);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Renders a CODE128 symbol at a known physical density.
|
|
61
|
+
*
|
|
62
|
+
* 🛑 THE QUIET ZONE IS COMPUTED, NOT GUESSED. CODE128 requires 10 modules of
|
|
63
|
+
* clear space each side, and JsBarcode's `margin` is in pixels — so it must
|
|
64
|
+
* scale with the module. The previous code passed a FIXED `margin: 8` beside
|
|
65
|
+
* `width: 2`, which is 4 modules: under half the spec minimum. A short quiet
|
|
66
|
+
* zone does not look wrong and does not fail to render; it just makes some
|
|
67
|
+
* scanners refuse some reads, which is indistinguishable from a worn label.
|
|
68
|
+
*/
|
|
69
|
+
function Barcode({ value, moduleMm = SAFE_MODULE_MM, heightMm, showValue = true, }) {
|
|
70
|
+
const ref = useRef(null);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!ref.current || !value)
|
|
73
|
+
return;
|
|
74
|
+
const px = moduleWidthPx(moduleMm);
|
|
75
|
+
try {
|
|
76
|
+
JsBarcode(ref.current, value, {
|
|
77
|
+
format: "CODE128",
|
|
78
|
+
width: px,
|
|
79
|
+
height: mmToCssPx(heightMm),
|
|
80
|
+
displayValue: showValue,
|
|
81
|
+
// ~2 mm of type: readable by a human squinting, and small enough that
|
|
82
|
+
// it does not steal height from the bars on a 25 mm label.
|
|
83
|
+
fontSize: mmToCssPx(2),
|
|
84
|
+
textMargin: mmToCssPx(0.4),
|
|
85
|
+
margin: 10 * px,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (_err) {
|
|
89
|
+
/*
|
|
90
|
+
* JsBarcode throws on a value CODE128 cannot encode. The `<svg>` is left
|
|
91
|
+
* empty and the label still prints its text, which is the right
|
|
92
|
+
* degradation: a label with a title and no barcode is filable by hand,
|
|
93
|
+
* and the only real fix is correcting the code on the record.
|
|
94
|
+
*/
|
|
95
|
+
void normalizeError(_err);
|
|
96
|
+
}
|
|
97
|
+
}, [value, moduleMm, heightMm, showValue]);
|
|
98
|
+
return _jsx("svg", { ref: ref, "aria-label": `Barcode ${value}` });
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The single `@page` owner for a printable view.
|
|
102
|
+
*
|
|
103
|
+
* 🛑 EXACTLY ONE OF THESE PER VIEW. `@page` is document-global and cannot be
|
|
104
|
+
* scoped — two of them does not give two geometries, the later one in document
|
|
105
|
+
* order silently wins and the label prints at the wrong size with nothing in
|
|
106
|
+
* the markup looking wrong. `audit-label-profiles` R3 enforces that only
|
|
107
|
+
* `label-profiles.ts` may author the rule at all.
|
|
108
|
+
*/
|
|
109
|
+
export function LabelPageStyle({ css }) {
|
|
110
|
+
return _jsx("style", { children: css });
|
|
111
|
+
}
|
|
112
|
+
/** One label's box, in mm, with the profile's padding inside it. */
|
|
113
|
+
function LabelBox({ profile, children, }) {
|
|
114
|
+
return (_jsx(Div, { className: "appkit-label", style: {
|
|
115
|
+
width: `${profile.widthMm}mm`,
|
|
116
|
+
height: `${profile.heightMm}mm`,
|
|
117
|
+
padding: `${profile.paddingMm}mm`,
|
|
118
|
+
boxSizing: "border-box",
|
|
119
|
+
overflow: "hidden",
|
|
120
|
+
display: "flex",
|
|
121
|
+
flexDirection: "column",
|
|
122
|
+
alignItems: "center",
|
|
123
|
+
justifyContent: "center",
|
|
124
|
+
textAlign: "center",
|
|
125
|
+
}, children: children }));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A product label: symbol, name, price, and WHERE IT LIVES.
|
|
129
|
+
*
|
|
130
|
+
* 🛑 THE BOX CODE IS THE ADDITION THAT MAKES THE LABEL USEFUL FOR PUTTING
|
|
131
|
+
* THINGS AWAY. Without it a picker holding the item has to scan it and look at
|
|
132
|
+
* a screen to learn which shelf it came off; with it the label answers the
|
|
133
|
+
* question the person holding it is actually asking. It replaces the free-text
|
|
134
|
+
* `physicalLocation` that used to print here — that field was three
|
|
135
|
+
* inconsistent inputs with no registry behind it, so two people wrote "shelf
|
|
136
|
+
* 3", "Shelf-3" and "AC60 3" for one place and no list could group them.
|
|
137
|
+
*/
|
|
138
|
+
export function ProductLabel({ profile, product, }) {
|
|
139
|
+
const code = product.barcodeId ?? product.sku ?? null;
|
|
140
|
+
/*
|
|
141
|
+
* The fit is checked PER LABEL, against the code this label actually
|
|
142
|
+
* carries — not once for the profile. Codes vary in length (a seller-authored
|
|
143
|
+
* SKU is variable width by design), so one product can fit stock that the
|
|
144
|
+
* next cannot.
|
|
145
|
+
*/
|
|
146
|
+
const fit = useMemo(() => (code ? labelFitsProfile(profile, code.length) : null), [profile, code]);
|
|
147
|
+
/*
|
|
148
|
+
* 🛑 REFUSES, NEVER SCALES. A symbol squeezed to fit looks perfect and does
|
|
149
|
+
* not scan — the proportions stay right while the module width drops below
|
|
150
|
+
* what a scanner resolves, so the failure surfaces weeks later as "the
|
|
151
|
+
* scanner is broken" with every label already stuck to something. A visible
|
|
152
|
+
* refusal is read in the second it happens, by the person who can still pick
|
|
153
|
+
* different stock.
|
|
154
|
+
*/
|
|
155
|
+
const refuse = fit !== null && !fit.fits;
|
|
156
|
+
return (_jsxs(LabelBox, { profile: profile, children: [code && !refuse ? (_jsx(Barcode, { value: code,
|
|
157
|
+
// A third of the label's height, which leaves room for the name and
|
|
158
|
+
// price without the bars becoming too short to scan at an angle.
|
|
159
|
+
heightMm: Math.max(6, profile.heightMm * 0.42) })) : code ? (_jsxs(Text, { size: "xs", color: "error", children: ["Code too long for ", profile.widthMm, "\u00D7", profile.heightMm, " mm"] })) : (_jsx(Text, { size: "xs", color: "muted", children: "No barcode" })), _jsx(Text, { size: "xs", weight: "medium", truncate: 1, children: product.name }), _jsxs(Row, { gap: "xs", justify: "center", wrap: true, children: [product.price != null && (_jsxs(Text, { size: "xs", color: "muted", children: ["\u20B9", product.price.toLocaleString("en-IN")] })), product.boxCode && (_jsx(Text, { size: "xs", weight: "semibold", children: product.boxCode }))] })] }));
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A box label: the code, large, plus what it held WHEN PRINTED.
|
|
163
|
+
*
|
|
164
|
+
* 🛑 THE PRINT DATE IS NOT DECORATION — it is what makes the counts honest. A
|
|
165
|
+
* label is a frozen snapshot stuck to a moving object: the moment something is
|
|
166
|
+
* picked, the printed count is wrong. Printing "8 items" with no date invites
|
|
167
|
+
* the operator to trust it; printing "8 items as of 21 Oct" says plainly that
|
|
168
|
+
* it is a note from the past and the screen is authoritative.
|
|
169
|
+
*
|
|
170
|
+
* 🛑 The barcode encodes `BOX-{code}`, with the prefix, because the receive
|
|
171
|
+
* station discriminates on it: a `BOX-` scan arms a box and a `LIR-` scan adds
|
|
172
|
+
* an item, and that decision has to be makeable without a lookup. The stored
|
|
173
|
+
* `code` is the bare `AC60-03`.
|
|
174
|
+
*/
|
|
175
|
+
export function BoxLabel({ profile, box, }) {
|
|
176
|
+
const value = `BOX-${box.code.toUpperCase()}`;
|
|
177
|
+
const fit = labelFitsProfile(profile, value.length);
|
|
178
|
+
return (_jsxs(LabelBox, { profile: profile, children: [fit.fits ? (_jsx(Barcode, { value: value, heightMm: Math.max(8, profile.heightMm * 0.4) })) : (_jsxs(Text, { size: "xs", color: "error", children: [value, " too long for this stock"] })), _jsx(Text, { size: "lg", weight: "bold", numeric: true, children: box.code }), _jsx(Text, { size: "xs", color: "muted", children: [box.boxType, box.location].filter(Boolean).join(" · ") }), box.totalUnits != null ? (_jsxs(Text, { size: "xs", color: "muted", children: [box.distinctProducts ?? 0, " product", box.distinctProducts === 1 ? "" : "s", " \u00B7 ", box.totalUnits, " unit", box.totalUnits === 1 ? "" : "s", box.countedAt
|
|
179
|
+
? ` as of ${new Date(box.countedAt).toLocaleDateString("en-IN", {
|
|
180
|
+
day: "numeric",
|
|
181
|
+
month: "short",
|
|
182
|
+
})}`
|
|
183
|
+
: ""] })) : (
|
|
184
|
+
/*
|
|
185
|
+
* "Not yet counted" rather than "0 products". The rollup is written by
|
|
186
|
+
* a scheduled job, so a box registered this morning has no counts —
|
|
187
|
+
* and a printed `0` about a full box is worse than no number at all.
|
|
188
|
+
*/
|
|
189
|
+
_jsx(Text, { size: "xs", color: "muted", children: "Not yet counted" }))] }));
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Lays labels out on an A4 die-cut sheet, at the stock's real pitch.
|
|
193
|
+
*
|
|
194
|
+
* 🛑 ABSOLUTE POSITIONING FROM THE PITCH, not a flex grid. A grid distributes
|
|
195
|
+
* whatever space it is given; a die-cut sheet has fixed holes, and the only
|
|
196
|
+
* thing that lands ink inside them is placing each label at
|
|
197
|
+
* `margin + n x pitch`. One millimetre of accumulated flex rounding is
|
|
198
|
+
* invisible on label one and off the die-cut by label thirteen.
|
|
199
|
+
*/
|
|
200
|
+
export function LabelSheet({ profile, children, }) {
|
|
201
|
+
const sheet = profile.sheet;
|
|
202
|
+
if (!sheet) {
|
|
203
|
+
// Thermal: the page IS the label, so each child is its own page and the
|
|
204
|
+
// `@page` rule plus `break-after` handles it. No positioning to do.
|
|
205
|
+
return _jsx(_Fragment, { children: children });
|
|
206
|
+
}
|
|
207
|
+
const perPage = sheet.columns * sheet.rows;
|
|
208
|
+
const pages = [];
|
|
209
|
+
for (let i = 0; i < children.length; i += perPage) {
|
|
210
|
+
pages.push(children.slice(i, i + perPage));
|
|
211
|
+
}
|
|
212
|
+
return (_jsx(_Fragment, { children: pages.map((page, pageIndex) => (_jsx(Div, { className: "appkit-label-sheet", style: {
|
|
213
|
+
position: "relative",
|
|
214
|
+
width: `${profile.page.widthMm}mm`,
|
|
215
|
+
height: `${profile.page.heightMm}mm`,
|
|
216
|
+
// A sheet past the first must start on a new page; the first must
|
|
217
|
+
// NOT, or every print begins with a blank sheet.
|
|
218
|
+
breakBefore: pageIndex === 0 ? "auto" : "page",
|
|
219
|
+
}, children: page.map((child, i) => {
|
|
220
|
+
const pos = sheetPositionMm(sheet, i);
|
|
221
|
+
if (!pos)
|
|
222
|
+
return null;
|
|
223
|
+
return (_jsx(Div, { style: {
|
|
224
|
+
position: "absolute",
|
|
225
|
+
left: `${pos.leftMm}mm`,
|
|
226
|
+
top: `${pos.topMm}mm`,
|
|
227
|
+
}, children: child }, i));
|
|
228
|
+
}) }, pageIndex))) }));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* An A4 sheet listing what is in a box — the thing that goes INSIDE it, or on
|
|
232
|
+
* the shelf beside it.
|
|
233
|
+
*
|
|
234
|
+
* 🛑 A4, not a label, and that is the point of having it at all. A 50 x 25 mm
|
|
235
|
+
* label cannot list eight products, so the box label carries only a total; the
|
|
236
|
+
* contents have to live somewhere a person can read them without a screen, and
|
|
237
|
+
* that is a sheet of paper. It is explicitly a snapshot, dated in the header
|
|
238
|
+
* for the same reason the box label's counts are.
|
|
239
|
+
*/
|
|
240
|
+
export function BoxContentsSheet({ boxCode, boxType, location, rows, printedAt, }) {
|
|
241
|
+
const totalUnits = rows.reduce((n, r) => n + r.quantity, 0);
|
|
242
|
+
return (_jsx(Div, { className: "appkit-label-sheet", style: {
|
|
243
|
+
width: "210mm",
|
|
244
|
+
minHeight: "297mm",
|
|
245
|
+
padding: "12mm",
|
|
246
|
+
boxSizing: "border-box",
|
|
247
|
+
}, children: _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { justify: "between", align: "center", children: [_jsx(Text, { size: "2xl", weight: "bold", numeric: true, children: boxCode }), _jsx(Text, { size: "sm", color: "muted", children: [boxType, location].filter(Boolean).join(" · ") })] }), _jsxs(Text, { size: "sm", color: "muted", children: [rows.length, " product", rows.length === 1 ? "" : "s", " \u00B7 ", totalUnits, " ", "unit", totalUnits === 1 ? "" : "s", " \u00B7 printed", " ", new Date(printedAt).toLocaleString("en-IN")] }), _jsx(Text, { size: "xs", color: "muted", children: "A snapshot. The dashboard is authoritative \u2014 anything picked since this was printed is still listed here." }), _jsx(Div, { style: { marginTop: "6mm" }, children: rows.length === 0 ? (_jsx(Text, { color: "muted", children: "This box is empty." })) : (_jsx(Stack, { gap: "none", children: rows.map((r, i) => (_jsxs(Row, { justify: "between", align: "center", padding: "y-2xs", border: "bottom", children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", children: r.productTitle }), (r.productSku || r.slot) && (_jsx(Text, { size: "xs", color: "muted", numeric: true, children: [r.productSku, r.slot].filter(Boolean).join(" · ") }))] }), _jsxs(Text, { size: "sm", weight: "semibold", numeric: true, children: ["\u00D7", r.quantity] })] }, `${r.productTitle}-${i}`))) })) })] }) }));
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The on-screen warning that no code can replace.
|
|
251
|
+
*
|
|
252
|
+
* Every density calculation in this file assumes the browser prints at 100%.
|
|
253
|
+
* "Fit to page" rescales the symbol and takes the module width with it, and
|
|
254
|
+
* the result still looks like a correct label.
|
|
255
|
+
*/
|
|
256
|
+
export function PrintScaleWarning() {
|
|
257
|
+
return (_jsx(Text, { size: "sm", color: "warning", className: "no-print", children: "Print at 100% / \u201CActual size\u201D. Any scaling \u2014 including \u201CFit to page\u201D \u2014 narrows the barcode below what scanners read, and the label will still look correct." }));
|
|
258
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Print-layout classes for physical labels and printable documents.
|
|
3
|
+
*
|
|
4
|
+
* 🛑 THESE LIVE IN A STATIC STYLESHEET, NOT ONLY IN `labelPageCss`'s STRING.
|
|
5
|
+
*
|
|
6
|
+
* `labelPageCss()` and `documentPageCss()` emit an `@page` rule plus these
|
|
7
|
+
* same `break-*` declarations into a runtime `<style>`. That is necessary for
|
|
8
|
+
* `@page` — its `size` is computed from the chosen profile, so it cannot be
|
|
9
|
+
* static — but it meant `.appkit-label` and `.appkit-label-sheet` existed
|
|
10
|
+
* ONLY inside a template literal.
|
|
11
|
+
*
|
|
12
|
+
* Consequence: `audit-dead-css-classes` reported them as classes generating no
|
|
13
|
+
* CSS rule, correctly, because nothing it can read defines them. A class whose
|
|
14
|
+
* only definition is a string concatenation is invisible to every tool — the
|
|
15
|
+
* audit, an editor's go-to-definition, and anyone grepping the stylesheets.
|
|
16
|
+
* Declaring them here makes them real; the runtime string still carries its
|
|
17
|
+
* own copy because a print view may be opened in a context where the bundled
|
|
18
|
+
* stylesheet has not loaded, and a duplicated `break-inside: avoid` is
|
|
19
|
+
* harmless where a missing one splits a label across two pages.
|
|
20
|
+
*
|
|
21
|
+
* @tag domain:print
|
|
22
|
+
* @tag layer:feature
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
@media print {
|
|
26
|
+
/*
|
|
27
|
+
* A label must never be split across a page boundary. On thermal stock a
|
|
28
|
+
* page IS a label, so a split would print the top half on one label and the
|
|
29
|
+
* bottom half on the next — and the operator discovers it after both have
|
|
30
|
+
* been peeled and stuck to something.
|
|
31
|
+
*/
|
|
32
|
+
.appkit-label {
|
|
33
|
+
break-inside: avoid;
|
|
34
|
+
page-break-inside: avoid;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* A sheet is one A4 page of die-cut labels, or one contents sheet. Same
|
|
39
|
+
* rule, different unit — splitting it would offset every label after the
|
|
40
|
+
* break from its die-cut hole.
|
|
41
|
+
*/
|
|
42
|
+
.appkit-label-sheet {
|
|
43
|
+
break-inside: avoid;
|
|
44
|
+
page-break-inside: avoid;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { LabelPageStyle, LabelSheet, ProductLabel, BoxLabel, BoxContentsSheet, PrintScaleWarning, mmToCssPx, moduleWidthPx, } from "./components/labels";
|
|
2
|
+
export type { ProductLabelData, BoxLabelData, BoxContentsRow, } from "./components/labels";
|
|
3
|
+
export { LabelProfilePicker } from "./components/LabelProfilePicker";
|
|
4
|
+
export type { LabelProfilePickerProps } from "./components/LabelProfilePicker";
|
|
5
|
+
export { BoxLabelPrintView } from "./components/BoxLabelPrintView";
|
|
6
|
+
export type { BoxLabelPrintViewProps, PrintableBox, } from "./components/BoxLabelPrintView";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The print feature's surface — physical labels and printable documents.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is a Client Component or a pure isomorphic helper, so unlike
|
|
5
|
+
* `features/inventory` there is no `firebase-admin` reachability hazard. It is
|
|
6
|
+
* still not re-exported from `appkit/src/index.ts`: nothing in the consumer
|
|
7
|
+
* imports it through a barrel, and adding a re-export for convenience is what
|
|
8
|
+
* Root Cause #18 is about.
|
|
9
|
+
*
|
|
10
|
+
* @tag domain:print
|
|
11
|
+
* @tag layer:feature
|
|
12
|
+
* @tag access:client
|
|
13
|
+
*/
|
|
14
|
+
export { LabelPageStyle, LabelSheet, ProductLabel, BoxLabel, BoxContentsSheet, PrintScaleWarning, mmToCssPx, moduleWidthPx, } from "./components/labels.js";
|
|
15
|
+
export { LabelProfilePicker } from "./components/LabelProfilePicker.js";
|
|
16
|
+
export { BoxLabelPrintView } from "./components/BoxLabelPrintView.js";
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Div, GatedPrice, Row, Span } from "../../../ui/index.js";
|
|
3
3
|
import { MediaImage } from "../../media/MediaImage.js";
|
|
4
|
+
import { statusLabel } from "../../../ui/columns/cell-renderers.js";
|
|
4
5
|
import { formatCurrency as defaultFormatCurrency } from "../../../utils/number.formatter.js";
|
|
5
6
|
const __O = {
|
|
6
7
|
hidden: "overflow-hidden",
|
|
7
8
|
};
|
|
8
9
|
const STATUS_STYLES = {
|
|
9
10
|
published: "bg-success-surface text-success dark:bg-success-surface dark:text-success",
|
|
10
|
-
draft: "bg-[var(--appkit-color-
|
|
11
|
+
draft: "bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
11
12
|
out_of_stock: "bg-warning-surface text-warning dark:bg-warning-surface dark:text-warning",
|
|
12
13
|
discontinued: "bg-error-surface text-error dark:bg-error-surface dark:text-error",
|
|
13
14
|
sold: "bg-primary/10 dark:bg-primary/20 text-primary",
|
|
@@ -54,8 +55,8 @@ export function getProductTableColumns({ labels, onEdit, onDelete, currencyCode,
|
|
|
54
55
|
return (_jsx(Span, { className: [
|
|
55
56
|
"rounded px-[var(--appkit-space-2)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-medium",
|
|
56
57
|
STATUS_STYLES[status] ??
|
|
57
|
-
"bg-[var(--appkit-color-
|
|
58
|
-
].join(" "), children: status
|
|
58
|
+
"bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
59
|
+
].join(" "), children: statusLabel(status) }));
|
|
59
60
|
},
|
|
60
61
|
},
|
|
61
62
|
{
|
|
@@ -76,7 +77,7 @@ export function getProductTableColumns({ labels, onEdit, onDelete, currencyCode,
|
|
|
76
77
|
"rounded px-[var(--appkit-space-2)] py-[var(--appkit-space-1)] text-[length:var(--appkit-text-xs)] font-medium",
|
|
77
78
|
featured
|
|
78
79
|
? CLS_LOW_STOCK
|
|
79
|
-
: "bg-[var(--appkit-color-
|
|
80
|
+
: "bg-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)]",
|
|
80
81
|
].join(" "), children: featured ? labels.yes : labels.no }));
|
|
81
82
|
},
|
|
82
83
|
},
|
|
@@ -50,7 +50,7 @@ export function MarketplaceBundleCard({ bundle, className = "", variant = "grid"
|
|
|
50
50
|
}
|
|
51
51
|
router.push(String(detailHref));
|
|
52
52
|
}, [detailHref, onNavigate, router]);
|
|
53
|
-
const card = (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: showCollage ? (_jsx(Div, { layout: "grid", className: `h-full w-full gap-[0.125rem] bg-[var(--appkit-color-
|
|
53
|
+
const card = (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: showCollage ? (_jsx(Div, { layout: "grid", className: `h-full w-full gap-[0.125rem] bg-[var(--appkit-color-bg)] ${collageTiles.length === 2 ? "grid-cols-2 grid-rows-1" : "grid-cols-2 grid-rows-2"}`, children: collageTiles.map((tile, i) => (_jsxs(Div, { className: "relative overflow-hidden bg-[var(--appkit-color-bg)]", children: [_jsx(MediaImage, { src: tile.imageURL, alt: tile.title ?? `${bundle.name} item ${i + 1}`, size: "card" }), i === collageTiles.length - 1 && overflow > 0 && (_jsxs(Row, { textWeight: "semibold", textSize: "sm", surface: "overlay-md", className: "absolute inset-0 text-white", align: "center", justify: "center", children: ["+", overflow] }))] }, `${tile.productId}-${i}`))) })) : cover ? (_jsx(Div, { className: "absolute inset-0 bg-[var(--appkit-color-bg)]", children: _jsx(MediaImage, { src: cover, alt: bundle.name, size: "card" }) })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-bg)]", align: "center", justify: "center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: "No image" }) })) }), discount && (_jsx(PricesOnly, { children: _jsx(Span, { size: "xs", weight: "bold", className: "absolute left-2 top-2 bg-success-solid text-success-on-solid", rounded: "full", padding: "pill-xs", children: BUNDLE_COPY.detail.discountBadge(discount.percent) }) })), _jsxs(Stack, { className: "absolute right-2 top-2", align: "end", gap: "xs", children: [_jsx(Span, { size: "xs", weight: "medium", className: CLS_BUNDLE_PILL, children: mergedLabels.bundleBadge }), _jsx(Span, { layout: "inline-flex", color: "inverse", className: `${stock === "out_of_stock" ? "bg-neutral-500 " : CLS_STOCK_OK}`, rounded: "full", padding: "pill-xs", size: "xs", weight: "medium", children: stock === "out_of_stock" ? mergedLabels.outOfStockBadge : mergedLabels.inStockBadge })] }), stock === "out_of_stock" && (_jsx(Row, { surface: "overlay-xs", className: "absolute inset-0", align: "center", justify: "center", children: _jsx(Span, { color: "inverse", size: "xs", weight: "bold", className: "bg-neutral-900/80 tracking-wider", rounded: "default", padding: "pill-md", transform: "uppercase", children: mergedLabels.outOfStockBadge }) })), onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (event) => {
|
|
54
54
|
event.stopPropagation();
|
|
55
55
|
onSelect(bundle.id, !isSelected);
|
|
56
56
|
}, className: selectable || isSelected
|
|
@@ -77,5 +77,5 @@ export function MarketplaceBundleCard({ bundle, className = "", variant = "grid"
|
|
|
77
77
|
* Sibling of the card, never a child — see the prop's docstring. `z-20`
|
|
78
78
|
* clears this card's own overlays, which all sit at `z-10`.
|
|
79
79
|
*/
|
|
80
|
-
return (_jsxs(Div, { className: "
|
|
80
|
+
return (_jsxs(Div, { className: "flex h-full flex-col", children: [card, _jsx(Div, { className: "flex justify-end px-[var(--appkit-space-3)] pb-[var(--appkit-space-3)]", children: ownerActions })] }));
|
|
81
81
|
}
|
|
@@ -11,7 +11,7 @@ const CLS_PRIZE_PILL = "inline-flex items-center rounded-full bg-fuchsia-600 px-
|
|
|
11
11
|
import { BaseListingCard, Button, Div, GatedPrice, Row, Span, Stack, Text, TextLink } from "../../../ui/index.js";
|
|
12
12
|
import { MediaImage } from "../../media/MediaImage.js";
|
|
13
13
|
import { CardStoreLine } from "./CardStoreLine.js";
|
|
14
|
-
import {
|
|
14
|
+
import { RecordOwnerQuickActions } from "../../admin/components/RecordOwnerQuickActions.js";
|
|
15
15
|
const DEFAULT_LABELS = {
|
|
16
16
|
prizeDrawBadge: "Prize draw",
|
|
17
17
|
pendingBadge: "Reveal pending",
|
|
@@ -91,11 +91,11 @@ export function MarketplacePrizeDrawCard({ product, className = "", variant = "g
|
|
|
91
91
|
}
|
|
92
92
|
router.push(String(detailHref));
|
|
93
93
|
}, [detailHref, onNavigate, router]);
|
|
94
|
-
const card = (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: thumbItems.length > 0 ? (_jsx(Div, { layout: "grid", className: "grid-cols-2 grid-rows-2 gap-[0.125rem] h-full w-full bg-[var(--appkit-color-
|
|
94
|
+
const card = (_jsxs(BaseListingCard, { isSelected: isSelected, variant: variant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [_jsxs(BaseListingCard.Hero, { aspect: "square", variant: variant, children: [_jsx(TextLink, { href: String(detailHref), className: "absolute inset-0 block", children: thumbItems.length > 0 ? (_jsx(Div, { layout: "grid", className: "grid-cols-2 grid-rows-2 gap-[0.125rem] h-full w-full bg-[var(--appkit-color-bg)]", children: Array.from({ length: 4 }).map((_, i) => {
|
|
95
95
|
const it = thumbItems[i];
|
|
96
96
|
const img = it?.images?.[0];
|
|
97
|
-
return (_jsx(Div, { className: "relative overflow-hidden bg-[var(--appkit-color-
|
|
98
|
-
}) })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-
|
|
97
|
+
return (_jsx(Div, { className: "relative overflow-hidden bg-[var(--appkit-color-bg)]", children: img ? (_jsx(MediaImage, { src: img, alt: it?.title ?? `Prize ${i + 1}`, size: "card" })) : null }, `thumb-${i}`));
|
|
98
|
+
}) })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-bg)]", align: "center", justify: "center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: "No prizes" }) })) }), _jsxs(Stack, { className: "absolute right-2 top-2", align: "end", gap: "xs", children: [_jsx(Span, { size: "xs", weight: "medium", className: CLS_PRIZE_PILL, children: mergedLabels.prizeDrawBadge }), _jsx(Span, { layout: "inline-flex", size: "xs", weight: "medium", className: `${statusVariant(status)}`, rounded: "full", padding: "pill-xs", children: statusLabel(status, mergedLabels) })] }), status === "closed" ? (_jsx(Row, { surface: "overlay-xs", className: "absolute inset-0", align: "center", justify: "center", children: _jsx(Span, { color: "inverse", size: "xs", weight: "bold", className: "bg-neutral-900/80 tracking-wider", rounded: "default", padding: "pill-md", transform: "uppercase", children: mergedLabels.closedBadge }) })) : null, onSelect && (_jsx(BaseListingCard.Checkbox, { selected: isSelected, onSelect: (event) => {
|
|
99
99
|
event.stopPropagation();
|
|
100
100
|
onSelect(product.id, !isSelected);
|
|
101
101
|
}, className: selectable || isSelected
|
|
@@ -111,7 +111,7 @@ export function MarketplacePrizeDrawCard({ product, className = "", variant = "g
|
|
|
111
111
|
const ownerActions = renderOwnerActions
|
|
112
112
|
? renderOwnerActions()
|
|
113
113
|
: product.id
|
|
114
|
-
? (_jsx(
|
|
114
|
+
? (_jsx(RecordOwnerQuickActions, { resource: "PRODUCT", recordId: String(product.id), storeId: product.storeId ? String(product.storeId) : undefined, recordLabel: product.title, placement: "card" }))
|
|
115
115
|
: null;
|
|
116
116
|
if (!ownerActions)
|
|
117
117
|
return card;
|
|
@@ -119,5 +119,5 @@ export function MarketplacePrizeDrawCard({ product, className = "", variant = "g
|
|
|
119
119
|
* Sibling of the card, never a child — see the prop's docstring. `z-20`
|
|
120
120
|
* clears this card's own overlays, which all sit at `z-10`.
|
|
121
121
|
*/
|
|
122
|
-
return (_jsxs(Div, { className: "
|
|
122
|
+
return (_jsxs(Div, { className: "flex h-full flex-col", children: [card, _jsx(Div, { className: "flex justify-end px-[var(--appkit-space-3)] pb-[var(--appkit-space-3)]", children: ownerActions })] }));
|
|
123
123
|
}
|
|
@@ -75,7 +75,7 @@ export function PrizeDrawCollage({ items, highlightItemNumber, onItemClick, wonL
|
|
|
75
75
|
isHighlight
|
|
76
76
|
? "ring-2 ring-offset-2 ring-[var(--appkit-color-primary)] scale-[1.02]"
|
|
77
77
|
: "hover:scale-[1.01]",
|
|
78
|
-
].join(" "), "aria-label": `View ${it.title || `prize #${it.itemNumber}`} in lightbox`, children: [_jsxs(Div, { className: "relative aspect-square w-full", children: [cover ? (_jsx(MediaImage, { src: cover, alt: it.title || `Prize #${it.itemNumber}`, size: "thumbnail" })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-
|
|
78
|
+
].join(" "), "aria-label": `View ${it.title || `prize #${it.itemNumber}`} in lightbox`, children: [_jsxs(Div, { className: "relative aspect-square w-full", children: [cover ? (_jsx(MediaImage, { src: cover, alt: it.title || `Prize #${it.itemNumber}`, size: "thumbnail" })) : (_jsx(Row, { className: "absolute inset-0 bg-[var(--appkit-color-bg)]", align: "center", justify: "center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "xs", children: "No image" }) })), _jsxs(Div, { textWeight: "semibold", textSize: "xs", surface: "overlay-xl", padding: "chip-2xs", className: "absolute left-2 top-2 text-white", rounded: "default", children: ["#", it.itemNumber] }), it.isWon && !hideWonState ? (_jsxs(_Fragment, { children: [_jsx(Scrim, { direction: "diagonal", intensity: "medium", multiply: true, className: "absolute inset-0" }), _jsx(Row, { className: "absolute inset-0", align: "center", justify: "center", children: _jsx(Text, { className: CLS_WON_STAMP, children: wonLabel }) })] })) : null] }), _jsxs(Div, { padding: "xs", children: [_jsx(Text, { className: "line-clamp-2", size: "sm", weight: "medium", children: it.title || `Prize #${it.itemNumber}` }), it.estimatedValue != null ? (
|
|
79
79
|
// The prize's estimated value is a money amount like any
|
|
80
80
|
// other — hidden rather than prompted, because the entry
|
|
81
81
|
// price beside it already carries the sign-in gate.
|
|
@@ -95,7 +95,7 @@ export function PrizeDrawItemsEditor({ items, onChange, onUploadImage, onUploadV
|
|
|
95
95
|
}), disabled: locked, placeholder: "2999" }) })] }), _jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "sm", weight: "medium", children: ["Images (", (it.images ?? []).length, "/", MAX_IMAGES_PER_ITEM, ")"] }), _jsx(Row, { gap: "sm", wrap: true, children: Array.from({ length: MAX_IMAGES_PER_ITEM }).map((_, slot) => {
|
|
96
96
|
const existing = (it.images ?? [])[slot];
|
|
97
97
|
return (_jsxs(Div, { className: "w-40", children: [_jsx(ImageUpload, { currentImage: existing, label: existing ? "Replace" : `Image ${slot + 1}`, onUpload: (file) => onUploadImage(file, it.itemNumber), onChange: (url) => setImage(index, slot, url) }), existing && !locked ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => removeImage(index, slot), children: "Remove" })) : null] }, slot));
|
|
98
|
-
}) })] }), onUploadVideo ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", children: "Video (optional)" }), _jsx(Input, { bare: true, type: "file", accept: "video/*", disabled: locked, onChange: (e) => handleVideoFileChange(e, index, it.itemNumber) }), it.video?.url ? (_jsxs(Text, { className: "text-[var(--appkit-color-text-muted)] truncate", size: "xs", children: ["Current: ", it.video.url] })) : null] })) : null] })] }, `prize-item-${it.itemNumber}-${index}`));
|
|
98
|
+
}) })] }), onUploadVideo ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Text, { size: "sm", weight: "medium", children: "Video (optional)" }), _jsx(Input, { bare: true, "aria-label": `Video for item ${it.itemNumber} (optional)`, type: "file", accept: "video/*", disabled: locked, onChange: (e) => handleVideoFileChange(e, index, it.itemNumber) }), it.video?.url ? (_jsxs(Text, { className: "text-[var(--appkit-color-text-muted)] truncate", size: "xs", children: ["Current: ", it.video.url] })) : null] })) : null] })] }, `prize-item-${it.itemNumber}-${index}`));
|
|
99
99
|
}) }), items.length < MIN_ITEMS ? (_jsxs(Div, { textSize: "sm", className: "border border-error/40", color: "error", surface: "danger-surface", padding: "inlineSm", rounded: "default", children: ["At least ", MIN_ITEMS, " prizes are required."] })) : null] }));
|
|
100
100
|
}
|
|
101
101
|
export default PrizeDrawItemsEditor;
|
|
@@ -24,8 +24,8 @@ export function PrizeRevealModal({ open, onClose, items, initialPrizeWon, reveal
|
|
|
24
24
|
const winnerImg = winner?.images?.[0];
|
|
25
25
|
return (_jsx(Modal, { isOpen: open, onClose: onClose, title: "Prize Reveal", size: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsx(PrizeDrawCollage, { items: items, hideWonState: true }), !winner ? (
|
|
26
26
|
// audit-content-alignment-ok: informational reveal-status panel, not marketing content
|
|
27
|
-
_jsxs(Div, { className: `bg-[var(--appkit-color-
|
|
27
|
+
_jsxs(Div, { className: `bg-[var(--appkit-color-bg)] ${__P.p4} text-center`, rounded: "default", children: [_jsx(Text, { size: "lg", weight: "semibold", children: "Reveal pending" }), _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", size: "sm", children: PENDING_COPY[revealMode] })] })) : (
|
|
28
28
|
// audit-content-alignment-ok: theatrical reveal-modal centerpiece, not marketing content
|
|
29
|
-
_jsxs(Div, { className: `border-2 border-[var(--appkit-color-primary)] bg-[var(--appkit-color-surface)] ${__P.p4} text-center`, rounded: "lg", children: [_jsx(Text, { className: "tracking-wider text-[var(--appkit-color-text-muted)]", size: "xs", transform: "uppercase", children: "You won" }), _jsxs(Heading, { level: 2, className: "my-2", children: ["#", winner.itemNumber, " \u2014 ", winner.title] }), winnerImg ? (_jsx(Div, { className: "relative mx-auto h-64 w-64 max-w-full", rounded: "md", overflow: "hidden", children: _jsx(MediaImage, { src: winnerImg, alt: winner.title, size: "hero", objectFit: "contain" }) })) : null, winner.estimatedValue != null ? (_jsx(PricesOnly, { children: _jsxs(Text, { className: "mt-2 text-[var(--appkit-color-text-muted)]", size: "sm", children: ["Estimated value: \u20B9", winner.estimatedValue.toLocaleString("en-IN")] }) })) : null] })), _jsxs(Div, { textSize: "xs", className: "border border-[var(--appkit-color-border)] bg-[var(--appkit-color-
|
|
29
|
+
_jsxs(Div, { className: `border-2 border-[var(--appkit-color-primary)] bg-[var(--appkit-color-surface)] ${__P.p4} text-center`, rounded: "lg", children: [_jsx(Text, { className: "tracking-wider text-[var(--appkit-color-text-muted)]", size: "xs", transform: "uppercase", children: "You won" }), _jsxs(Heading, { level: 2, className: "my-2", children: ["#", winner.itemNumber, " \u2014 ", winner.title] }), winnerImg ? (_jsx(Div, { className: "relative mx-auto h-64 w-64 max-w-full", rounded: "md", overflow: "hidden", children: _jsx(MediaImage, { src: winnerImg, alt: winner.title, size: "hero", objectFit: "contain" }) })) : null, winner.estimatedValue != null ? (_jsx(PricesOnly, { children: _jsxs(Text, { className: "mt-2 text-[var(--appkit-color-text-muted)]", size: "sm", children: ["Estimated value: \u20B9", winner.estimatedValue.toLocaleString("en-IN")] }) })) : null] })), _jsxs(Div, { textSize: "xs", className: "border border-[var(--appkit-color-border)] bg-[var(--appkit-color-bg)] text-[var(--appkit-color-text-muted)]", padding: "inlineSm", rounded: "default", children: [_jsx(Span, { weight: "bold", children: "Fairness guarantee:" }), " ", "Winners are picked by ", _jsx("code", { children: "crypto.randomInt" }), " running on LetItRip's server the moment your prize is assigned. Neither the store nor LetItRip staff can influence the outcome.", " ", rngSourceUrl ? (_jsx(Anchor, { href: rngSourceUrl, tone: "none", underline: "always", children: "View RNG source code \u2192" })) : null] })] }) }));
|
|
30
30
|
}
|
|
31
31
|
export default PrizeRevealModal;
|
|
@@ -31,7 +31,7 @@ import { ctaAnchorProps } from "../../layout/cta-anchor.js";
|
|
|
31
31
|
import { ContextualTrail } from "../../categories/components/ContextualTrail.js";
|
|
32
32
|
import { productCrumbs, withTrailHead } from "../../categories/utils/breadcrumb-chain.js";
|
|
33
33
|
import { getDefaultCurrency } from "../../../core/baseline-resolver.js";
|
|
34
|
-
import {
|
|
34
|
+
import { RecordOwnerQuickActions } from "../../admin/components/RecordOwnerQuickActions.js";
|
|
35
35
|
import { PurchaseReviewAffordance } from "../../reviews/components/PurchaseReviewAffordance.js";
|
|
36
36
|
import { Button, Container, Div, Heading, Main, PriceDisplay, RichText, Row, Section, Span, Stack, Text, Ul, Ol, Li, SpecTable, Icon, } from "../../../ui/index.js";
|
|
37
37
|
import { normalizeRichTextHtml } from "../../../utils/string.formatter.js";
|
|
@@ -348,11 +348,25 @@ export async function ProductDetailPageView({ slug, initialProduct, renderOfferA
|
|
|
348
348
|
const { relatedItems, relatedByBrand, relatedByTags, relatedByStore } = related;
|
|
349
349
|
return (_jsxs(Main, { children: [_jsx(HistoryTracker, { productId: product.id, productType: "product", snapshot: {
|
|
350
350
|
title: product.title,
|
|
351
|
-
|
|
351
|
+
/*
|
|
352
|
+
* 🛑 `images` is `ProductImage[]`, not `string[]` — reading
|
|
353
|
+
* `product.images?.[0]` here wrote an OBJECT into the history
|
|
354
|
+
* snapshot, which `resolveMediaUrl` then refuses on every later
|
|
355
|
+
* render of `/user/history` ("expected a string, received
|
|
356
|
+
* [object Object]") and shows a placeholder for. The three sibling
|
|
357
|
+
* detail views (classified, digital-code, live) already use the
|
|
358
|
+
* derived `images` array for exactly this reason; this one was
|
|
359
|
+
* missed by the `string[]` -> `ProductImage[]` migration.
|
|
360
|
+
*
|
|
361
|
+
* `mainImage` stays first because it is the authored cover and is
|
|
362
|
+
* not part of the gallery array, so `images[0]` is a different
|
|
363
|
+
* picture whenever both exist.
|
|
364
|
+
*/
|
|
365
|
+
thumb: typeof product.mainImage === "string" ? product.mainImage : images[0],
|
|
352
366
|
price: product.price,
|
|
353
367
|
storeId: product.storeId,
|
|
354
368
|
storeName: product.storeName,
|
|
355
|
-
} }), _jsxs(Container, { size: "xl", padding: "y-lg", children: [_jsx(ProductDetailView, { renderBreadcrumb: () => (_jsxs(Row, { className: "mb-4", align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsx(ContextualTrail, { trails: trails, alternates: { ids: categoryIds, names: categoryIdNames } }), _jsx(ShareButton, { title: title || undefined })] })), renderGallery: () => (_jsx(ProductGalleryClient, { images: images, video: productVideo, productName: title || undefined })), renderInfo: () => (_jsxs(Stack, { gap: "md", children: [_jsx(
|
|
369
|
+
} }), _jsxs(Container, { size: "xl", padding: "y-lg", children: [_jsx(ProductDetailView, { renderBreadcrumb: () => (_jsxs(Row, { className: "mb-4", align: "center", justify: "between", gap: "sm", wrap: true, children: [_jsx(ContextualTrail, { trails: trails, alternates: { ids: categoryIds, names: categoryIdNames } }), _jsx(ShareButton, { title: title || undefined })] })), renderGallery: () => (_jsx(ProductGalleryClient, { images: images, video: productVideo, productName: title || undefined })), renderInfo: () => (_jsxs(Stack, { gap: "md", children: [_jsx(RecordOwnerQuickActions, { resource: "PRODUCT", recordId: String(product.id), recordLabel: title || String(product.slug ?? product.id), storeId: product.storeId ? String(product.storeId) : undefined }), _jsxs(Div, { children: [condition && (_jsx(Span, { size: "xs", weight: "medium", className: "mb-2 inline-block", padding: "pill-sm", rounded: "full", surface: "subtle", color: "muted", transform: "capitalize", children: condition === "new"
|
|
356
370
|
? "Brand New"
|
|
357
371
|
: condition === "like_new"
|
|
358
372
|
? "Like New"
|
|
@@ -360,7 +374,7 @@ export async function ProductDetailPageView({ slug, initialProduct, renderOfferA
|
|
|
360
374
|
? "Refurbished"
|
|
361
375
|
: condition === "used"
|
|
362
376
|
? "Used"
|
|
363
|
-
: condition })), _jsx(Heading, { level: 1, className: "leading-snug", smSize: "2xl", color: "primary", size: "xl", weight: "bold", children: title || "Untitled Product" })] }), avgRating !== null ? (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(StarRating, { value: avgRating }), _jsxs(Span, { size: "sm", color: "muted", children: [avgRating.toFixed(1), reviewCount ? ` (${reviewCount} reviews)` : ""] }), showViews && (_jsxs(Span, { size: "sm", color: "muted", children: ["\u00B7 ", views7d.toLocaleString(), " viewed this week"] })), _jsxs(Span, { size: "xs", weight: "medium", surface: inStock ? "success-surface" : "danger-surface", className: `ml-auto ${inStock ? "text-success" : "text-error"}`, padding: "pill-sm", rounded: "full", children: [madeToOrder
|
|
377
|
+
: condition })), _jsx(Heading, { level: 1, className: "leading-snug", smSize: "2xl", color: "primary", size: "xl", weight: "bold", children: title || "Untitled Product" })] }), avgRating !== null && (reviewCount ?? 0) > 0 ? (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(StarRating, { value: avgRating }), _jsxs(Span, { size: "sm", color: "muted", children: [avgRating.toFixed(1), reviewCount ? ` (${reviewCount} reviews)` : ""] }), showViews && (_jsxs(Span, { size: "sm", color: "muted", children: ["\u00B7 ", views7d.toLocaleString(), " viewed this week"] })), _jsxs(Span, { size: "xs", weight: "medium", surface: inStock ? "success-surface" : "danger-surface", className: `ml-auto ${inStock ? "text-success" : "text-error"}`, padding: "pill-sm", rounded: "full", children: [madeToOrder
|
|
364
378
|
? "✓ Made to order"
|
|
365
379
|
: inStock
|
|
366
380
|
? "✓ In Stock"
|