@mohasinac/appkit 4.62.0 → 4.63.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 +8 -29
- package/dist/_internal/client/features/layout/filterNavItems.d.ts +28 -0
- package/dist/_internal/client/features/layout/filterNavItems.js +35 -0
- package/dist/_internal/server/features/ads/booking.d.ts +118 -0
- package/dist/_internal/server/features/ads/booking.js +326 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +129 -9
- package/dist/_internal/server/features/checkout/actions.js +850 -79
- package/dist/_internal/server/features/checkout/expand-order-items.d.ts +1 -2
- package/dist/_internal/server/features/checkout/expand-order-items.js +32 -0
- package/dist/_internal/server/features/checkout/freeze-parts.d.ts +50 -0
- package/dist/_internal/server/features/checkout/freeze-parts.js +94 -0
- package/dist/_internal/server/features/checkout/value-otp-gate.d.ts +55 -0
- package/dist/_internal/server/features/checkout/value-otp-gate.js +60 -0
- package/dist/_internal/server/features/dashboard/attention.d.ts +128 -0
- package/dist/_internal/server/features/dashboard/attention.js +183 -0
- package/dist/_internal/server/features/dashboard/data.d.ts +47 -0
- package/dist/_internal/server/features/dashboard/data.js +82 -0
- package/dist/_internal/server/features/inventory/reservations.d.ts +99 -0
- package/dist/_internal/server/features/inventory/reservations.js +273 -0
- package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
- package/dist/_internal/server/features/invoicing/allocate.js +162 -0
- package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
- package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
- package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
- package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
- package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
- package/dist/_internal/server/features/invoicing/issue.js +202 -0
- package/dist/_internal/server/features/offers/destinations.d.ts +40 -0
- package/dist/_internal/server/features/offers/destinations.js +65 -0
- package/dist/_internal/server/features/orders/actions.d.ts +8 -1
- package/dist/_internal/server/features/orders/actions.js +81 -8
- package/dist/_internal/server/features/orders/adapters.js +54 -0
- package/dist/_internal/server/features/orders/amend-delivery.d.ts +56 -0
- package/dist/_internal/server/features/orders/amend-delivery.js +124 -0
- package/dist/_internal/server/features/orders/balance.d.ts +89 -0
- package/dist/_internal/server/features/orders/balance.js +256 -0
- package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
- package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
- package/dist/_internal/server/features/points/award.js +46 -4
- package/dist/_internal/server/features/pricing/actions.d.ts +58 -0
- package/dist/_internal/server/features/pricing/actions.js +144 -0
- package/dist/_internal/server/features/refunds/actions.js +26 -0
- package/dist/_internal/server/features/shipping/book-split.d.ts +86 -0
- package/dist/_internal/server/features/shipping/book-split.js +130 -0
- package/dist/_internal/server/features/shipping/book.d.ts +61 -0
- package/dist/_internal/server/features/shipping/book.js +176 -0
- package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
- package/dist/_internal/server/features/shipping/courier-block.js +264 -0
- package/dist/_internal/server/features/site-settings/adapters.d.ts +2 -2
- package/dist/_internal/server/features/site-settings/adapters.js +29 -0
- package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
- package/dist/_internal/server/features/stores/adapters.js +65 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +95 -2
- package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +11 -2
- package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
- package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
- package/dist/_internal/server/jobs/core/index.d.ts +2 -1
- package/dist/_internal/server/jobs/core/index.js +2 -1
- package/dist/_internal/server/jobs/core/jobRunners.js +45 -0
- package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
- package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
- package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +65 -0
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
- package/dist/_internal/server/jobs/core/reservationExpiry.d.ts +17 -0
- package/dist/_internal/server/jobs/core/reservationExpiry.js +40 -0
- package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
- package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
- package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +25 -2
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +1 -0
- package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
- package/dist/_internal/server/jobs/handlers/reservationExpiry.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/reservationExpiry.js +2 -0
- package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +296 -0
- package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
- package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
- package/dist/_internal/shared/checkout/order-math.d.ts +174 -0
- package/dist/_internal/shared/checkout/order-math.js +159 -0
- package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
- package/dist/_internal/shared/checkout/refundable-base.js +13 -1
- package/dist/_internal/shared/checkout/rules/index.d.ts +1 -1
- package/dist/_internal/shared/checkout/rules/index.js +1 -1
- package/dist/_internal/shared/checkout/rules/payment-gate.d.ts +18 -0
- package/dist/_internal/shared/checkout/rules/payment-gate.js +25 -0
- package/dist/_internal/shared/checkout/split.d.ts +75 -0
- package/dist/_internal/shared/checkout/split.js +120 -0
- package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
- package/dist/_internal/shared/content/disclaimers.js +217 -0
- package/dist/_internal/shared/content/published-values.d.ts +93 -0
- package/dist/_internal/shared/content/published-values.js +206 -0
- package/dist/_internal/shared/features/admin/integrations.d.ts +139 -0
- package/dist/_internal/shared/features/admin/integrations.js +263 -0
- package/dist/_internal/shared/features/dashboard/hub-sections.d.ts +72 -0
- package/dist/_internal/shared/features/dashboard/hub-sections.js +75 -0
- package/dist/_internal/shared/features/emi/choice.d.ts +98 -0
- package/dist/_internal/shared/features/emi/choice.js +69 -0
- package/dist/_internal/shared/features/emi/group.d.ts +84 -0
- package/dist/_internal/shared/features/emi/group.js +126 -0
- package/dist/_internal/shared/features/ledger/posting.d.ts +107 -0
- package/dist/_internal/shared/features/ledger/posting.js +165 -0
- package/dist/_internal/shared/features/ledger/reports.d.ts +76 -0
- package/dist/_internal/shared/features/ledger/reports.js +127 -0
- package/dist/_internal/shared/features/ledger/rules.d.ts +170 -0
- package/dist/_internal/shared/features/ledger/rules.js +221 -0
- package/dist/_internal/shared/features/offers/coordination.d.ts +122 -0
- package/dist/_internal/shared/features/offers/coordination.js +80 -0
- package/dist/_internal/shared/features/orders/delivery-snapshot.d.ts +114 -0
- package/dist/_internal/shared/features/orders/delivery-snapshot.js +116 -0
- package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
- package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
- package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
- package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
- package/dist/_internal/shared/features/payouts/pay-period.d.ts +91 -0
- package/dist/_internal/shared/features/payouts/pay-period.js +104 -0
- package/dist/_internal/shared/features/points/accepts.d.ts +29 -0
- package/dist/_internal/shared/features/points/accepts.js +49 -0
- package/dist/_internal/shared/features/pricing/rate-registry.d.ts +150 -0
- package/dist/_internal/shared/features/pricing/rate-registry.js +246 -0
- package/dist/_internal/shared/features/shipping/parcel.d.ts +123 -0
- package/dist/_internal/shared/features/shipping/parcel.js +139 -0
- package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
- package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
- package/dist/_internal/shared/features/site-settings/fees.d.ts +16 -8
- package/dist/_internal/shared/features/site-settings/fees.js +12 -8
- package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
- package/dist/_internal/shared/fees/calculator.d.ts +33 -1
- package/dist/_internal/shared/fees/calculator.js +32 -2
- package/dist/_internal/shared/fees/explain.d.ts +81 -0
- package/dist/_internal/shared/fees/explain.js +101 -0
- package/dist/_internal/shared/history/index.d.ts +1 -1
- package/dist/_internal/shared/history/index.js +1 -1
- package/dist/_internal/shared/history/types.d.ts +7 -1
- package/dist/_internal/shared/history/types.js +25 -0
- package/dist/client.d.ts +21 -0
- package/dist/client.js +43 -0
- package/dist/constants/api-endpoints.d.ts +114 -0
- package/dist/constants/api-endpoints.js +55 -0
- package/dist/constants/field-names.d.ts +42 -0
- package/dist/constants/field-names.js +52 -0
- package/dist/contracts/index.d.ts +1 -1
- package/dist/contracts/shipping.d.ts +45 -0
- package/dist/contracts/shipping.js +15 -0
- package/dist/features/about/components/AboutView.js +1 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
- package/dist/features/account/components/UserOrdersView.js +47 -35
- package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
- package/dist/features/admin/components/AdminIntegrationsView.d.ts +55 -0
- package/dist/features/admin/components/AdminIntegrationsView.js +74 -0
- package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
- package/dist/features/admin/components/AdminInvoicingView.js +65 -0
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +33 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +81 -3
- package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
- package/dist/features/admin/components/AdminOrdersView.js +86 -5
- package/dist/features/admin/components/OwnerQuickActions.js +24 -2
- package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
- package/dist/features/admin/constants/filter-tabs.js +6 -0
- package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
- package/dist/features/admin/hooks/useAdminListingData.js +16 -0
- package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
- package/dist/features/admin/schemas/firestore.d.ts +62 -0
- package/dist/features/admin/schemas/firestore.js +5 -0
- package/dist/features/ads/schemas/booking-write.d.ts +120 -0
- package/dist/features/ads/schemas/booking-write.js +75 -0
- package/dist/features/ads/schemas/creative-form.d.ts +18 -0
- package/dist/features/ads/schemas/creative-form.js +51 -0
- package/dist/features/ads/schemas/firestore.d.ts +140 -0
- package/dist/features/ads/schemas/firestore.js +109 -0
- package/dist/features/auctions/repository/bid.repository.js +3 -1
- package/dist/features/audit-log/schemas/firestore.d.ts +140 -0
- package/dist/features/audit-log/schemas/firestore.js +89 -0
- package/dist/features/auth/actions/profile-actions.d.ts +69 -1
- package/dist/features/auth/actions/profile-actions.js +62 -1
- package/dist/features/auth/permissions/constants.js +13 -0
- package/dist/features/auth/schemas/firestore.d.ts +16 -2
- package/dist/features/auth/schemas/firestore.js +2 -1
- package/dist/features/blog/actions/blog-actions.d.ts +6 -0
- package/dist/features/blog/actions/blog-actions.js +17 -2
- package/dist/features/blog/api/route.js +4 -1
- package/dist/features/blog/columns/index.js +5 -0
- package/dist/features/blog/components/BlogIndexPageView.js +2 -1
- package/dist/features/blog/repository/blog.repository.d.ts +4 -0
- package/dist/features/blog/repository/blog.repository.js +5 -0
- package/dist/features/blog/schemas/blog-form.d.ts +3 -0
- package/dist/features/blog/schemas/blog-form.js +1 -0
- package/dist/features/blog/schemas/firestore.d.ts +38 -1
- package/dist/features/blog/schemas/firestore.js +23 -0
- package/dist/features/blog/schemas/index.d.ts +6 -0
- package/dist/features/blog/schemas/index.js +2 -0
- package/dist/features/blog/types/index.d.ts +2 -0
- package/dist/features/cart/components/CartPriceBreakdown.d.ts +25 -1
- package/dist/features/cart/components/CartPriceBreakdown.js +29 -6
- package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
- package/dist/features/cart/components/PointsTenderPicker.js +15 -0
- package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
- package/dist/features/cart/components/index.d.ts +2 -0
- package/dist/features/cart/components/index.js +1 -0
- package/dist/features/cart/repository/cart.repository.d.ts +33 -0
- package/dist/features/cart/repository/cart.repository.js +47 -0
- package/dist/features/cart/schemas/firestore.d.ts +116 -0
- package/dist/features/contact/email.d.ts +27 -10
- package/dist/features/contact/email.js +20 -3
- package/dist/features/dashboard/components/DashboardHubView.d.ts +83 -0
- package/dist/features/dashboard/components/DashboardHubView.js +56 -0
- package/dist/features/dashboard/components/DashboardSectionsClient.d.ts +23 -0
- package/dist/features/dashboard/components/DashboardSectionsClient.js +66 -0
- package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.d.ts +55 -0
- package/dist/features/dispute-reasons/components/AdminDisputeReasonsView.js +175 -0
- package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +62 -0
- package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +108 -0
- package/dist/features/dispute-reasons/schemas/firestore.d.ts +62 -0
- package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
- package/dist/features/events/components/EventSaleBanner.js +1 -1
- package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
- package/dist/features/faq/components/FAQAccordion.js +29 -4
- package/dist/features/faq/components/FAQPageContent.js +2 -2
- package/dist/features/gateway-events/schemas/index.d.ts +2 -2
- package/dist/features/homepage/schemas/index.d.ts +8 -8
- package/dist/features/inventory/schemas/stock-reservation.d.ts +114 -0
- package/dist/features/inventory/schemas/stock-reservation.js +103 -0
- package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
- package/dist/features/invoicing/schemas/firestore.js +45 -0
- package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
- package/dist/features/invoicing/utils/financial-year.js +53 -0
- package/dist/features/jobs/actions/enqueue-job.js +18 -1
- package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
- package/dist/features/jobs/repository/jobs.repository.js +84 -1
- package/dist/features/jobs/schemas/firestore.d.ts +80 -0
- package/dist/features/jobs/schemas/firestore.js +37 -0
- package/dist/features/layout/AppLayoutShell.d.ts +9 -1
- package/dist/features/layout/AppLayoutShell.js +12 -4
- package/dist/features/layout/BottomActions.js +2 -1
- package/dist/features/layout/BottomNavbar.d.ts +10 -2
- package/dist/features/layout/SideActionDock.js +52 -2
- package/dist/features/layout/TitleBarLayout.js +13 -4
- package/dist/features/layout/TitleBarLayout.style.css +59 -0
- package/dist/features/layout/useCtaReveal.d.ts +16 -1
- package/dist/features/layout/useCtaReveal.js +17 -26
- package/dist/features/ledger/repository/journal.repository.d.ts +110 -0
- package/dist/features/ledger/repository/journal.repository.js +312 -0
- package/dist/features/ledger/schemas/expenses.d.ts +87 -0
- package/dist/features/ledger/schemas/expenses.js +27 -0
- package/dist/features/ledger/schemas/firestore.d.ts +183 -0
- package/dist/features/ledger/schemas/firestore.js +69 -0
- package/dist/features/lottery/schemas/zod.d.ts +6 -6
- package/dist/features/media/MediaImage.js +22 -1
- package/dist/features/media/upload/ImageUpload.js +1 -1
- package/dist/features/obligations/constants/policies.js +24 -1
- package/dist/features/orders/components/BalancePaymentPanel.d.ts +12 -0
- package/dist/features/orders/components/BalancePaymentPanel.js +94 -0
- package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
- package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
- package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
- package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
- package/dist/features/orders/components/RaiseDisputeForm.js +119 -0
- package/dist/features/orders/components/RefundRequestView.js +19 -1
- package/dist/features/orders/components/index.d.ts +4 -0
- package/dist/features/orders/components/index.js +2 -0
- package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
- package/dist/features/orders/constants/order-lane-tabs.js +88 -0
- package/dist/features/orders/repository/orders.repository.d.ts +85 -1
- package/dist/features/orders/repository/orders.repository.js +205 -6
- package/dist/features/orders/schemas/balance.d.ts +40 -0
- package/dist/features/orders/schemas/balance.js +47 -0
- package/dist/features/orders/schemas/firestore.d.ts +398 -1
- package/dist/features/orders/schemas/firestore.js +43 -0
- package/dist/features/orders/schemas/index.d.ts +56 -8
- package/dist/features/orders/schemas/index.js +12 -0
- package/dist/features/orders/types/index.d.ts +47 -0
- package/dist/features/orders/utils/courier-block.d.ts +25 -0
- package/dist/features/orders/utils/courier-block.js +23 -0
- package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
- package/dist/features/payment-cases/schemas/firestore.js +1 -0
- package/dist/features/payments/repository/payout.repository.js +3 -2
- package/dist/features/payments/schemas/firestore.d.ts +92 -1
- package/dist/features/payments/schemas/firestore.js +23 -0
- package/dist/features/pricing/components/AdminPricingView.d.ts +13 -0
- package/dist/features/pricing/components/AdminPricingView.js +157 -0
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
- package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
- package/dist/features/products/components/ProductDetailPageView.js +2 -2
- package/dist/features/products/schemas/firestore.d.ts +26 -1
- package/dist/features/products/schemas/firestore.js +2 -0
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
- package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
- package/dist/features/promotions/actions/coupon-stacking.js +21 -2
- package/dist/features/promotions/components/CouponCard.js +13 -0
- package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
- package/dist/features/promotions/constants/coupon-help.js +9 -1
- package/dist/features/promotions/schemas/firestore.d.ts +24 -0
- package/dist/features/promotions/schemas/firestore.js +4 -0
- package/dist/features/promotions/types/index.d.ts +19 -1
- package/dist/features/reviews/repository/reviews.repository.d.ts +14 -0
- package/dist/features/reviews/repository/reviews.repository.js +16 -0
- package/dist/features/scams/components/ScamProfileView.js +2 -2
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/scams/repository/scammer.repository.js +2 -1
- package/dist/features/scams/schemas/firestore.d.ts +2 -1
- package/dist/features/scams/schemas/firestore.js +2 -1
- package/dist/features/search/action-index/tab-entries.js +1 -1
- package/dist/features/seller/actions/offer-actions.js +56 -0
- package/dist/features/seller/actions/seller-actions.d.ts +1 -1
- package/dist/features/seller/actions/seller-actions.js +37 -3
- package/dist/features/seller/components/DispatchForm.d.ts +11 -0
- package/dist/features/seller/components/DispatchForm.js +190 -0
- package/dist/features/seller/components/SellerOrdersView.js +221 -27
- package/dist/features/seller/components/index.d.ts +1 -0
- package/dist/features/seller/components/index.js +1 -0
- package/dist/features/seller/hooks/useSellerListingData.js +25 -0
- package/dist/features/seller/repository/offer.repository.js +4 -3
- package/dist/features/seller/schemas/firestore.d.ts +23 -2
- package/dist/features/seller/schemas/firestore.js +3 -2
- package/dist/features/seller/schemas/index.d.ts +4 -4
- package/dist/features/seller/schemas/order-forms.d.ts +61 -4
- package/dist/features/seller/schemas/order-forms.js +41 -8
- package/dist/features/shipments/schemas/firestore.d.ts +25 -0
- package/dist/features/shipments/schemas/validation.d.ts +4 -4
- package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +82 -0
- package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +145 -0
- package/dist/features/shipping-boxes/schemas/firestore.d.ts +80 -0
- package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
- package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
- package/dist/features/stores/repository/store.repository.d.ts +18 -0
- package/dist/features/stores/repository/store.repository.js +27 -1
- package/dist/features/stores/schemas/firestore.d.ts +112 -0
- package/dist/features/stores/schemas/firestore.js +20 -0
- package/dist/features/stores/schemas/index.d.ts +6 -6
- package/dist/features/stores/types/index.d.ts +19 -0
- package/dist/features/support/repository/support.repository.js +72 -6
- package/dist/features/support/schemas/firestore.d.ts +17 -0
- package/dist/features/support/schemas/index.d.ts +8 -8
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +33 -1
- package/dist/next/routing/route-map.d.ts +112 -0
- package/dist/next/routing/route-map.js +63 -0
- package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
- package/dist/providers/shipping-shiprocket/index.js +84 -1
- package/dist/react/contexts/SessionContext.d.ts +17 -1
- package/dist/schemas/registry.d.ts +69 -34
- package/dist/schemas/sieve.d.ts +2 -2
- package/dist/security/pii-schemas.d.ts +1 -1
- package/dist/security/pii-schemas.js +45 -0
- package/dist/server-entry.d.ts +2 -2
- package/dist/server-entry.js +8 -1
- package/dist/server.d.ts +36 -1
- package/dist/server.js +183 -1
- package/dist/styles.css +412 -80
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +1 -0
- package/dist/tokens/themes/default-light.js +1 -0
- package/dist/tokens/themes/required.d.ts +1 -1
- package/dist/tokens/themes/required.js +1 -0
- package/dist/tokens/tokens.css +15 -0
- package/dist/ui/components/Button.d.ts +10 -1
- package/dist/ui/components/Button.js +25 -3
- package/dist/ui/components/Chart.d.ts +63 -0
- package/dist/ui/components/Chart.js +169 -0
- package/dist/ui/components/Chart.style.css +214 -0
- package/dist/ui/components/Disclaimer.d.ts +19 -0
- package/dist/ui/components/Disclaimer.js +83 -0
- package/dist/ui/components/OverflowRow.js +54 -2
- package/dist/ui/components/OverflowRow.style.css +38 -0
- package/dist/ui/components/RichTextEditor.js +99 -8
- package/dist/ui/components/chart-spec.d.ts +68 -0
- package/dist/ui/components/chart-spec.js +140 -0
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/components/surface-tokens.d.ts +1 -1
- package/dist/ui/components/surface-tokens.js +9 -0
- package/dist/ui/components/tabs-overflow.js +64 -11
- package/dist/ui/components/toolbar-collapse.d.ts +13 -0
- package/dist/ui/components/toolbar-collapse.js +10 -1
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.js +9 -0
- package/dist/ui/rich-text/RichText.d.ts +10 -1
- package/dist/ui/rich-text/RichText.js +33 -2
- package/dist/ui/rich-text/RichText.style.css +83 -79
- package/dist/ui/rich-text/RichTextRenderer.d.ts +30 -1
- package/dist/ui/rich-text/RichTextRenderer.js +34 -2
- package/dist/ui/rich-text/chart-blocks.d.ts +62 -0
- package/dist/ui/rich-text/chart-blocks.js +87 -0
- package/package.json +1 -1
- package/scripts/seed-cli.mjs +1834 -1822
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { Badge, Button, Row, Stack, Text } from "../../../ui/index.js";
|
|
5
|
+
import { RecordDetailModal } from "../../../ui/components/RecordDetailModal.js";
|
|
6
|
+
import { useToast } from "../../../ui/components/Toast.js";
|
|
7
|
+
import { FieldInput } from "../../../ui/forms/FieldInput.js";
|
|
8
|
+
import { FieldSelect } from "../../../ui/forms/FieldSelect.js";
|
|
9
|
+
import { normalizeError } from "../../../errors/normalize.js";
|
|
10
|
+
import { DataListingView } from "../../admin/components/DataListingView.js";
|
|
11
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry.js";
|
|
12
|
+
import { DISPUTE_KIND, } from "../../../_internal/shared/features/orders/dispute-reasons.js";
|
|
13
|
+
import { DISPUTE_REASON_LABEL_MAX, } from "../schemas/firestore.js";
|
|
14
|
+
/**
|
|
15
|
+
* What each kind MEANS, in one place.
|
|
16
|
+
*
|
|
17
|
+
* 🛑 A `Record<DisputeKind, string>`, so a third kind is a compile error here
|
|
18
|
+
* rather than a picker option rendering a bare token. The kind is the only
|
|
19
|
+
* field on a reason with a consequence — it decides which gate a dispute
|
|
20
|
+
* raised under it inherits — so it is the one that must never read as jargon.
|
|
21
|
+
*/
|
|
22
|
+
const KIND_MEANING = {
|
|
23
|
+
item: "Item problem — it arrived wrong or damaged",
|
|
24
|
+
not_reached: "Never arrived — the parcel did not reach the buyer",
|
|
25
|
+
};
|
|
26
|
+
/*
|
|
27
|
+
* Chips over `isActive`, as ordinary Sieve clauses. `listAll` applies no
|
|
28
|
+
* `isActive` filter of its own precisely so these work without the repository
|
|
29
|
+
* growing a method per chip.
|
|
30
|
+
*
|
|
31
|
+
* 🛑 "All" carries NO filter rather than `isActive==true|false`. A pipe-joined
|
|
32
|
+
* OR over a boolean would be two equalities merged for no reason, and — worse —
|
|
33
|
+
* it would exclude any row written before the field existed, which is the `!=`
|
|
34
|
+
* trap one step removed.
|
|
35
|
+
*/
|
|
36
|
+
const SCOPE_CHIPS = [
|
|
37
|
+
{ id: "active", label: "Active", filter: "isActive==true" },
|
|
38
|
+
{ id: "retired", label: "Retired", filter: "isActive==false" },
|
|
39
|
+
{ id: "all", label: "All", filter: undefined },
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* The two fields, exported so the triage drawer's inline create and this page
|
|
43
|
+
* cannot drift on the label bound or the kind vocabulary.
|
|
44
|
+
*/
|
|
45
|
+
export function DisputeReasonFields({ label, kind, onLabel, onKind, }) {
|
|
46
|
+
return (_jsxs(Stack, { gap: "md", children: [_jsx(FieldInput, { name: "label", label: "Reason wording", required: true, value: label, onChange: onLabel, maxLength: DISPUTE_REASON_LABEL_MAX, placeholder: "The courier left it at the wrong flat" }), _jsx(FieldSelect, { name: "kind", label: "Kind", required: true, value: kind, onChange: (v) => onKind(v),
|
|
47
|
+
/*
|
|
48
|
+
* Two options, so `<FieldSelect>` is correct — `PaginatedSelect` is for
|
|
49
|
+
* >5 (Rule #9), and a searchable dropdown over two values is worse than
|
|
50
|
+
* a native select. Derived from the shipped union so a third kind
|
|
51
|
+
* cannot exist in the gate and be missing here.
|
|
52
|
+
*/
|
|
53
|
+
options: DISPUTE_KIND.map((k) => ({ value: k, label: KIND_MEANING[k] })) })] }));
|
|
54
|
+
}
|
|
55
|
+
/** Create form. Shares `DisputeReasonFields` and the endpoint with the drawer. */
|
|
56
|
+
function CreateReasonForm({ onSubmit, }) {
|
|
57
|
+
const [label, setLabel] = useState("");
|
|
58
|
+
const [kind, setKind] = useState(DISPUTE_KIND[0]);
|
|
59
|
+
const [busy, setBusy] = useState(false);
|
|
60
|
+
const { showToast } = useToast();
|
|
61
|
+
return (_jsxs(Stack, { gap: "md", children: [_jsx(Text, { size: "sm", color: "muted", children: "Short wording, as a buyer would read it. The detail goes in their own free-text field \u2014 this is a picker option, not the explanation." }), _jsx(DisputeReasonFields, { label: label, kind: kind, onLabel: setLabel, onKind: setKind }), _jsx(Button, { action: ACTIONS.ADMIN["add-dispute-reason"], isLoading: busy, disabled: busy || label.trim().length < 3, onClick: async () => {
|
|
62
|
+
setBusy(true);
|
|
63
|
+
try {
|
|
64
|
+
await onSubmit({ label: label.trim(), kind });
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
void normalizeError(err);
|
|
68
|
+
showToast("Couldn't add that reason.", "error");
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
setBusy(false);
|
|
72
|
+
}
|
|
73
|
+
} })] }));
|
|
74
|
+
}
|
|
75
|
+
export function AdminDisputeReasonsView({ endpoint, onSetActive, onCreate, }) {
|
|
76
|
+
const { showToast } = useToast();
|
|
77
|
+
const [open, setOpen] = useState(null);
|
|
78
|
+
const [pending, setPending] = useState(null);
|
|
79
|
+
const setActive = useCallback(async (row, isActive) => {
|
|
80
|
+
setPending(row.id);
|
|
81
|
+
try {
|
|
82
|
+
await onSetActive(row.id, isActive);
|
|
83
|
+
showToast(isActive ? `"${row.label}" is back in the picker.` : `"${row.label}" retired.`, "success");
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
void normalizeError(err);
|
|
87
|
+
/*
|
|
88
|
+
* No optimistic flip anywhere here, so a failure needs no rollback —
|
|
89
|
+
* the row still shows what the server last told us. Only a successful
|
|
90
|
+
* write and the refetch behind it move the list.
|
|
91
|
+
*/
|
|
92
|
+
showToast("Couldn't save that. Nothing was changed.", "error");
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
setPending(null);
|
|
96
|
+
}
|
|
97
|
+
}, [onSetActive, showToast]);
|
|
98
|
+
const rowControls = useCallback((row) => (_jsxs(Row, { align: "center", gap: "sm", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: () => setOpen(row), children: "View" }), _jsx(Button, { action: row.isActive
|
|
99
|
+
? ACTIONS.ADMIN["retire-dispute-reason"]
|
|
100
|
+
: ACTIONS.ADMIN["reactivate-dispute-reason"], size: "sm", isLoading: pending === row.id, disabled: pending !== null, onClick: () => setActive(row, !row.isActive) })] })), [pending, setActive]);
|
|
101
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: {
|
|
102
|
+
portal: "admin",
|
|
103
|
+
title: "Dispute reasons",
|
|
104
|
+
subtitle: "What buyers can pick when reporting a problem. A reason's kind decides which gate it inherits — the wording is yours.",
|
|
105
|
+
endpoint: endpoint,
|
|
106
|
+
queryKey: ["admin", "dispute-reasons"],
|
|
107
|
+
defaultSort: "label",
|
|
108
|
+
/*
|
|
109
|
+
* 🛑 REQUIRED on `ListingViewConfig`, and the default must be one of
|
|
110
|
+
* these or the dropdown opens with nothing selected (Root Cause #63).
|
|
111
|
+
* Eleven rows, so the only orders worth offering are the buyer-facing
|
|
112
|
+
* wording and which kind a reason belongs to.
|
|
113
|
+
*/
|
|
114
|
+
sortOptions: [
|
|
115
|
+
{ value: "label", label: "Wording (A–Z)" },
|
|
116
|
+
{ value: "-label", label: "Wording (Z–A)" },
|
|
117
|
+
{ value: "kind", label: "Kind" },
|
|
118
|
+
],
|
|
119
|
+
filterKeys: ["scope"],
|
|
120
|
+
filterDefaults: { scope: "active" },
|
|
121
|
+
buildFilters: (state) => SCOPE_CHIPS.find((c) => c.id === (state.scope ?? "active"))?.filter,
|
|
122
|
+
mapRows: (res) => (res.items ?? []).map((r) => ({
|
|
123
|
+
id: r.id,
|
|
124
|
+
label: r.label,
|
|
125
|
+
kind: r.kind,
|
|
126
|
+
isActive: r.isActive,
|
|
127
|
+
createdByName: r.createdByName,
|
|
128
|
+
})),
|
|
129
|
+
getTotal: (res, rows) => res.total ?? rows.length,
|
|
130
|
+
/*
|
|
131
|
+
* 🛑 No `searchPlaceholder` and no `search` — the endpoint does not read
|
|
132
|
+
* `q`, and declaring either is what makes the box exist. ~39 views here
|
|
133
|
+
* render a box whose endpoint ignores the term: it accepts typing, the
|
|
134
|
+
* request carries it, and the results do not change, with no error
|
|
135
|
+
* anywhere. Eleven rows with scope chips need no search.
|
|
136
|
+
*/
|
|
137
|
+
emptyLabel: "No reasons in this scope.",
|
|
138
|
+
primaryAction: {
|
|
139
|
+
label: ACTIONS.ADMIN["add-dispute-reason"].label,
|
|
140
|
+
onClick: ({ openCreatePanel }) => openCreatePanel(),
|
|
141
|
+
},
|
|
142
|
+
renderEditor: ({ closePanel }) => (_jsx(CreateReasonForm, { onSubmit: async (input) => {
|
|
143
|
+
await onCreate(input);
|
|
144
|
+
closePanel();
|
|
145
|
+
} })),
|
|
146
|
+
resolveEditorTitle: () => "Add a dispute reason",
|
|
147
|
+
onRowClick: (row) => setOpen(row),
|
|
148
|
+
renderRowActions: rowControls,
|
|
149
|
+
renderCards: (rows) => (_jsx(Stack, { gap: "sm", children: rows.map((row) => (_jsxs(Row, { surface: "card", padding: "md", rounded: "lg", border: "default", align: "center", justify: "between", gap: "md", className: "min-w-0", children: [_jsxs(Stack, { gap: "xs", className: "min-w-0", children: [_jsxs(Row, { align: "center", gap: "sm", className: "min-w-0", children: [_jsx(Text, { weight: "semibold", color: "primary", className: "min-w-0", children: row.label }), _jsx(Badge, { variant: row.isActive ? "success" : "inactive", children: row.isActive ? "Active" : "Retired" })] }), _jsx(Text, { size: "xs", color: "muted", children: KIND_MEANING[row.kind] }), _jsxs(Text, { size: "xs", color: "faint", children: ["Added by ", row.createdByName] })] }), rowControls(row)] }, row.id))) })),
|
|
150
|
+
} }), open && (_jsx(RecordDetailModal, { isOpen: true, onClose: () => setOpen(null), title: open.label, badges: [
|
|
151
|
+
{
|
|
152
|
+
label: open.isActive ? "Active" : "Retired",
|
|
153
|
+
variant: open.isActive ? "success" : "secondary",
|
|
154
|
+
},
|
|
155
|
+
], fields: [
|
|
156
|
+
{ label: "Buyer-facing wording", value: open.label },
|
|
157
|
+
{ label: "Kind", value: `${open.kind} — ${KIND_MEANING[open.kind]}` },
|
|
158
|
+
{
|
|
159
|
+
label: "State",
|
|
160
|
+
value: open.isActive
|
|
161
|
+
? "Active — buyers see it on the dispute form"
|
|
162
|
+
: "Retired — hidden from the form",
|
|
163
|
+
},
|
|
164
|
+
{ label: "Added by", value: open.createdByName },
|
|
165
|
+
], metadata: {
|
|
166
|
+
id: open.id,
|
|
167
|
+
/*
|
|
168
|
+
* Stated on the record itself, because it is the fact an agent is
|
|
169
|
+
* most likely to be unsure about at the moment they are deciding
|
|
170
|
+
* whether to retire: the order snapshots the LABEL, so retiring
|
|
171
|
+
* cannot rewrite what a past dispute said.
|
|
172
|
+
*/
|
|
173
|
+
retiringIsNeverADelete: "Disputes already raised under this reason keep their wording — the order snapshots the label rather than pointing at this row.",
|
|
174
|
+
} }))] }));
|
|
175
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { FirebaseSieveFields, FirebaseSieveResult, SieveModel } from "../../../providers/db-firebase";
|
|
2
|
+
import { BaseRepository } from "../../../providers/db-firebase";
|
|
3
|
+
import type { DisputeKind } from "../../../_internal/shared/features/orders/dispute-reasons";
|
|
4
|
+
import { type DisputeReasonDocument } from "../schemas/firestore";
|
|
5
|
+
export declare class DisputeReasonsRepository extends BaseRepository<DisputeReasonDocument> {
|
|
6
|
+
static readonly SIEVE_FIELDS: FirebaseSieveFields;
|
|
7
|
+
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* The picker's list, scoped to one kind.
|
|
10
|
+
*
|
|
11
|
+
* 🛑 Scoped by KIND, not merged. A buyer reporting a damaged item must not be
|
|
12
|
+
* offered "it never arrived" — that reason belongs to the other gate, and
|
|
13
|
+
* picking it would produce a dispute the gate then refuses, which reads to
|
|
14
|
+
* the buyer as the form being broken rather than as the wrong choice.
|
|
15
|
+
*/
|
|
16
|
+
listActiveByKind(kind: DisputeKind, model: SieveModel): Promise<FirebaseSieveResult<DisputeReasonDocument>>;
|
|
17
|
+
/**
|
|
18
|
+
* Add a reason. Staff only — enforced at the route, not here.
|
|
19
|
+
*
|
|
20
|
+
* 🛑 Keyed `dreason-<slug>`, so two agents cannot add the same wording twice.
|
|
21
|
+
* A colliding create returns the EXISTING row rather than overwriting it:
|
|
22
|
+
* that row has an author and may already be named on live disputes, and the
|
|
23
|
+
* second agent's intent ("there should be a reason for this") is satisfied by
|
|
24
|
+
* what exists. Same rule as the shipping-box presets.
|
|
25
|
+
*/
|
|
26
|
+
createReason(input: {
|
|
27
|
+
label: string;
|
|
28
|
+
kind: DisputeKind;
|
|
29
|
+
createdByUid: string;
|
|
30
|
+
createdByName: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
reason: DisputeReasonDocument;
|
|
33
|
+
created: boolean;
|
|
34
|
+
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Every row, retired included — the staff management list.
|
|
37
|
+
*
|
|
38
|
+
* 🛑 Deliberately NOT `listActiveByKind` with the `isActive` clause dropped.
|
|
39
|
+
* That method also pins `kind`, and a management view must span both kinds:
|
|
40
|
+
* a reason retired for the wrong gate is exactly the row staff need to find.
|
|
41
|
+
*
|
|
42
|
+
* No `isActive` filter is applied here at all, so the caller's own Sieve
|
|
43
|
+
* filters decide — which is what lets the view offer Active / Retired / All
|
|
44
|
+
* chips without this method growing a parameter per chip.
|
|
45
|
+
*/
|
|
46
|
+
listAll(model: SieveModel): Promise<FirebaseSieveResult<DisputeReasonDocument>>;
|
|
47
|
+
/** Soft-retire. See the schema for why this is never a delete. */
|
|
48
|
+
retire(id: string): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Put a retired reason back in the picker.
|
|
51
|
+
*
|
|
52
|
+
* `createReason` already reactivates on a colliding re-add, which covers the
|
|
53
|
+
* agent who types the wording again. This covers the different case the
|
|
54
|
+
* management view creates: a row you can SEE and want back, where re-typing
|
|
55
|
+
* its exact label to resurrect it would be a trick rather than a control.
|
|
56
|
+
*
|
|
57
|
+
* The original `createdByName` is kept — they wrote the wording, and a
|
|
58
|
+
* reactivation is not authorship.
|
|
59
|
+
*/
|
|
60
|
+
reactivate(id: string): Promise<void>;
|
|
61
|
+
}
|
|
62
|
+
export declare const disputeReasonsRepository: DisputeReasonsRepository;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { BaseRepository } from "../../../providers/db-firebase/index.js";
|
|
2
|
+
import { slugify } from "../../../utils/string.formatter.js";
|
|
3
|
+
import { DISPUTE_REASON_COLLECTION, DISPUTE_REASON_FIELDS, DISPUTE_REASON_LABEL_MAX, } from "../schemas/firestore.js";
|
|
4
|
+
export class DisputeReasonsRepository extends BaseRepository {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(DISPUTE_REASON_COLLECTION);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The picker's list, scoped to one kind.
|
|
10
|
+
*
|
|
11
|
+
* 🛑 Scoped by KIND, not merged. A buyer reporting a damaged item must not be
|
|
12
|
+
* offered "it never arrived" — that reason belongs to the other gate, and
|
|
13
|
+
* picking it would produce a dispute the gate then refuses, which reads to
|
|
14
|
+
* the buyer as the form being broken rather than as the wrong choice.
|
|
15
|
+
*/
|
|
16
|
+
async listActiveByKind(kind, model) {
|
|
17
|
+
const baseQuery = this.getCollection()
|
|
18
|
+
.where(DISPUTE_REASON_FIELDS.IS_ACTIVE, "==", true)
|
|
19
|
+
.where(DISPUTE_REASON_FIELDS.KIND, "==", kind);
|
|
20
|
+
return this.sieveQuery(model, DisputeReasonsRepository.SIEVE_FIELDS, { baseQuery, defaultPageSize: 20, maxPageSize: 50 });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add a reason. Staff only — enforced at the route, not here.
|
|
24
|
+
*
|
|
25
|
+
* 🛑 Keyed `dreason-<slug>`, so two agents cannot add the same wording twice.
|
|
26
|
+
* A colliding create returns the EXISTING row rather than overwriting it:
|
|
27
|
+
* that row has an author and may already be named on live disputes, and the
|
|
28
|
+
* second agent's intent ("there should be a reason for this") is satisfied by
|
|
29
|
+
* what exists. Same rule as the shipping-box presets.
|
|
30
|
+
*/
|
|
31
|
+
async createReason(input) {
|
|
32
|
+
const label = input.label.trim().slice(0, DISPUTE_REASON_LABEL_MAX);
|
|
33
|
+
const id = `dreason-${slugify(label)}`;
|
|
34
|
+
const existing = await this.findById(id);
|
|
35
|
+
/*
|
|
36
|
+
* A retired row that someone re-adds is REACTIVATED rather than duplicated
|
|
37
|
+
* — otherwise the slug collides forever and the agent can never get their
|
|
38
|
+
* reason back. Reactivating keeps the original author, which is correct:
|
|
39
|
+
* they wrote the wording.
|
|
40
|
+
*/
|
|
41
|
+
if (existing) {
|
|
42
|
+
if (!existing.isActive) {
|
|
43
|
+
await this.update(id, { isActive: true, updatedAt: new Date() });
|
|
44
|
+
return { reason: { ...existing, isActive: true }, created: false };
|
|
45
|
+
}
|
|
46
|
+
return { reason: existing, created: false };
|
|
47
|
+
}
|
|
48
|
+
const now = new Date();
|
|
49
|
+
const reason = {
|
|
50
|
+
id,
|
|
51
|
+
label,
|
|
52
|
+
kind: input.kind,
|
|
53
|
+
isActive: true,
|
|
54
|
+
createdByUid: input.createdByUid,
|
|
55
|
+
createdByName: input.createdByName,
|
|
56
|
+
createdAt: now,
|
|
57
|
+
updatedAt: now,
|
|
58
|
+
};
|
|
59
|
+
await this.createWithId(id, reason);
|
|
60
|
+
return { reason, created: true };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Every row, retired included — the staff management list.
|
|
64
|
+
*
|
|
65
|
+
* 🛑 Deliberately NOT `listActiveByKind` with the `isActive` clause dropped.
|
|
66
|
+
* That method also pins `kind`, and a management view must span both kinds:
|
|
67
|
+
* a reason retired for the wrong gate is exactly the row staff need to find.
|
|
68
|
+
*
|
|
69
|
+
* No `isActive` filter is applied here at all, so the caller's own Sieve
|
|
70
|
+
* filters decide — which is what lets the view offer Active / Retired / All
|
|
71
|
+
* chips without this method growing a parameter per chip.
|
|
72
|
+
*/
|
|
73
|
+
async listAll(model) {
|
|
74
|
+
return this.sieveQuery(model, DisputeReasonsRepository.SIEVE_FIELDS, { baseQuery: this.getCollection(), defaultPageSize: 20, maxPageSize: 50 });
|
|
75
|
+
}
|
|
76
|
+
/** Soft-retire. See the schema for why this is never a delete. */
|
|
77
|
+
async retire(id) {
|
|
78
|
+
await this.update(id, { isActive: false, updatedAt: new Date() });
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Put a retired reason back in the picker.
|
|
82
|
+
*
|
|
83
|
+
* `createReason` already reactivates on a colliding re-add, which covers the
|
|
84
|
+
* agent who types the wording again. This covers the different case the
|
|
85
|
+
* management view creates: a row you can SEE and want back, where re-typing
|
|
86
|
+
* its exact label to resurrect it would be a trick rather than a control.
|
|
87
|
+
*
|
|
88
|
+
* The original `createdByName` is kept — they wrote the wording, and a
|
|
89
|
+
* reactivation is not authorship.
|
|
90
|
+
*/
|
|
91
|
+
async reactivate(id) {
|
|
92
|
+
await this.update(id, { isActive: true, updatedAt: new Date() });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
DisputeReasonsRepository.SIEVE_FIELDS = {
|
|
96
|
+
/*
|
|
97
|
+
* 🛑 `label` must be here because `PaginatedSelect` SEARCHES it. An
|
|
98
|
+
* unallowlisted searched field does not raise — `sieve.ts` sets
|
|
99
|
+
* `throwExceptions: false`, so `findField` returns undefined, the clause is
|
|
100
|
+
* silently dropped, and the picker returns the WHOLE list while looking
|
|
101
|
+
* exactly like it filtered (Root Cause #62).
|
|
102
|
+
*/
|
|
103
|
+
label: { canFilter: true, canSort: true },
|
|
104
|
+
kind: { canFilter: true, canSort: false },
|
|
105
|
+
isActive: { canFilter: true, canSort: false },
|
|
106
|
+
createdByUid: { canFilter: true, canSort: false },
|
|
107
|
+
};
|
|
108
|
+
export const disputeReasonsRepository = new DisputeReasonsRepository();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `disputeReasons` — the staff-curated list a buyer picks from when raising a
|
|
3
|
+
* dispute.
|
|
4
|
+
*
|
|
5
|
+
* ## What this is NOT
|
|
6
|
+
*
|
|
7
|
+
* 🛑 It is not policy. Every row carries a `kind`, and the GATE lives on the
|
|
8
|
+
* kind — see `_internal/shared/features/orders/dispute-reasons.ts`. A row can
|
|
9
|
+
* never introduce a new kind of claim, because a gate cannot branch on a
|
|
10
|
+
* user-created string.
|
|
11
|
+
*
|
|
12
|
+
* So this list is for TRIAGE and ANALYTICS: "what are buyers actually
|
|
13
|
+
* reporting", answered without reading free text. Staff (admin + employees)
|
|
14
|
+
* add rows as real gaps appear; buyers select only.
|
|
15
|
+
*
|
|
16
|
+
* ## Why staff-creatable rather than a closed enum
|
|
17
|
+
*
|
|
18
|
+
* Its sibling `RETURN_REASON` *is* a closed enum, and deliberately so: each
|
|
19
|
+
* member there decides whether a final sale can refuse the return, which is a
|
|
20
|
+
* money consequence that must be reviewed in code. Nothing here decides money.
|
|
21
|
+
* A support agent who keeps seeing "the courier left it at the wrong flat"
|
|
22
|
+
* should be able to add it without a release.
|
|
23
|
+
*/
|
|
24
|
+
import type { DisputeKind } from "../../../_internal/shared/features/orders/dispute-reasons";
|
|
25
|
+
import type { BaseDocument } from "../../../_internal/shared/types/base-document";
|
|
26
|
+
export declare const DISPUTE_REASON_COLLECTION = "disputeReasons";
|
|
27
|
+
/** `id` is `dreason-<slug of label>`, so the same reason cannot be added twice. */
|
|
28
|
+
export interface DisputeReasonDocument extends BaseDocument {
|
|
29
|
+
/** Buyer-facing. Shown verbatim in the picker. */
|
|
30
|
+
label: string;
|
|
31
|
+
/** Which gate this reason is subject to. Never free-form. */
|
|
32
|
+
kind: DisputeKind;
|
|
33
|
+
/**
|
|
34
|
+
* 🛑 Soft-retire, never delete.
|
|
35
|
+
*
|
|
36
|
+
* A past dispute names this reason. Deleting the row would orphan that
|
|
37
|
+
* record and take the author with it — and the order snapshots the LABEL
|
|
38
|
+
* precisely so history survives either way, but a deleted row still loses
|
|
39
|
+
* "who added this, and when" for anyone auditing the list itself.
|
|
40
|
+
*/
|
|
41
|
+
isActive: boolean;
|
|
42
|
+
/** Display name, so a seller or agent can see whose wording this is. */
|
|
43
|
+
createdByName: string;
|
|
44
|
+
/** The uid, for moderation. Never rendered. */
|
|
45
|
+
createdByUid: string;
|
|
46
|
+
}
|
|
47
|
+
export declare const DISPUTE_REASON_FIELDS: {
|
|
48
|
+
readonly ID: "id";
|
|
49
|
+
readonly LABEL: "label";
|
|
50
|
+
readonly KIND: "kind";
|
|
51
|
+
readonly IS_ACTIVE: "isActive";
|
|
52
|
+
readonly CREATED_BY_UID: "createdByUid";
|
|
53
|
+
readonly CREATED_AT: "createdAt";
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Bounds on a label.
|
|
57
|
+
*
|
|
58
|
+
* Short on purpose: this is a picker option, not the buyer's explanation. The
|
|
59
|
+
* detail goes in the free-text field on the dispute itself, which is where a
|
|
60
|
+
* buyer should describe what actually happened.
|
|
61
|
+
*/
|
|
62
|
+
export declare const DISPUTE_REASON_LABEL_MAX = 80;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `disputeReasons` — the staff-curated list a buyer picks from when raising a
|
|
3
|
+
* dispute.
|
|
4
|
+
*
|
|
5
|
+
* ## What this is NOT
|
|
6
|
+
*
|
|
7
|
+
* 🛑 It is not policy. Every row carries a `kind`, and the GATE lives on the
|
|
8
|
+
* kind — see `_internal/shared/features/orders/dispute-reasons.ts`. A row can
|
|
9
|
+
* never introduce a new kind of claim, because a gate cannot branch on a
|
|
10
|
+
* user-created string.
|
|
11
|
+
*
|
|
12
|
+
* So this list is for TRIAGE and ANALYTICS: "what are buyers actually
|
|
13
|
+
* reporting", answered without reading free text. Staff (admin + employees)
|
|
14
|
+
* add rows as real gaps appear; buyers select only.
|
|
15
|
+
*
|
|
16
|
+
* ## Why staff-creatable rather than a closed enum
|
|
17
|
+
*
|
|
18
|
+
* Its sibling `RETURN_REASON` *is* a closed enum, and deliberately so: each
|
|
19
|
+
* member there decides whether a final sale can refuse the return, which is a
|
|
20
|
+
* money consequence that must be reviewed in code. Nothing here decides money.
|
|
21
|
+
* A support agent who keeps seeing "the courier left it at the wrong flat"
|
|
22
|
+
* should be able to add it without a release.
|
|
23
|
+
*/
|
|
24
|
+
export const DISPUTE_REASON_COLLECTION = "disputeReasons";
|
|
25
|
+
export const DISPUTE_REASON_FIELDS = {
|
|
26
|
+
ID: "id",
|
|
27
|
+
LABEL: "label",
|
|
28
|
+
KIND: "kind",
|
|
29
|
+
IS_ACTIVE: "isActive",
|
|
30
|
+
CREATED_BY_UID: "createdByUid",
|
|
31
|
+
CREATED_AT: "createdAt",
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Bounds on a label.
|
|
35
|
+
*
|
|
36
|
+
* Short on purpose: this is a picker option, not the buyer's explanation. The
|
|
37
|
+
* detail goes in the free-text field on the dispute itself, which is where a
|
|
38
|
+
* buyer should describe what actually happened.
|
|
39
|
+
*/
|
|
40
|
+
export const DISPUTE_REASON_LABEL_MAX = 80;
|
|
@@ -16,5 +16,5 @@ export function EventSaleBanner({ discountPercent, couponCode, title, subtitle,
|
|
|
16
16
|
const href = filterParam
|
|
17
17
|
? `${ROUTES.PUBLIC.PRODUCTS}?${encodeURIComponent(filterParam.key)}=${encodeURIComponent(filterParam.value)}`
|
|
18
18
|
: `${ROUTES.PUBLIC.PRODUCTS}?onSale=true`;
|
|
19
|
-
return (_jsx(Section, { color: "inverse", tone: "accent-banner", className: `${__P.p6}`, rounded: "2xl", shadow: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { level: 2, weight: "bold", size: "3xl", children: headline }), subtitle ? _jsx(Text, { color: "inverse-muted", size: "base", children: subtitle }) : null] }), couponCode ? (_jsxs(Div, { layout: "inline-flex", gap: "3", align: "center", className: "backdrop-blur", surface: "default", paddingY: "y-xs", paddingX: "x-md", rounded: "lg", children: [_jsx(Span, { size: "xs", className: "tracking-wide opacity-80", transform: "uppercase", children: "Code" }), _jsx(Span, { size: "lg", weight: "bold", className: "font-mono", children: couponCode })] })) : null, _jsx(Div, { children: _jsx(Link, { href: href, children: _jsx(Button, { variant: "secondary", children: "Shop the sale" }) }) })] }) }));
|
|
19
|
+
return (_jsx(Section, { color: "inverse", tone: "accent-banner", className: `${__P.p6}`, rounded: "2xl", shadow: "lg", children: _jsxs(Stack, { gap: "md", children: [_jsxs(Stack, { gap: "xs", children: [_jsx(Heading, { color: "inverse", variant: "none", level: 2, weight: "bold", size: "3xl", children: headline }), subtitle ? _jsx(Text, { color: "inverse-muted", size: "base", children: subtitle }) : null] }), couponCode ? (_jsxs(Div, { layout: "inline-flex", gap: "3", align: "center", className: "backdrop-blur", surface: "default", paddingY: "y-xs", paddingX: "x-md", rounded: "lg", children: [_jsx(Span, { size: "xs", className: "tracking-wide opacity-80", transform: "uppercase", children: "Code" }), _jsx(Span, { size: "lg", weight: "bold", className: "font-mono", children: couponCode })] })) : null, _jsx(Div, { children: _jsx(Link, { href: href, children: _jsx(Button, { variant: "secondary", children: "Shop the sale" }) }) })] }) }));
|
|
20
20
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { FAQ, FAQCategory } from "../types";
|
|
3
|
+
import { type PublishedValues } from "../../../_internal/shared/content/published-values";
|
|
3
4
|
export interface FAQAccordionProps {
|
|
4
5
|
faqs: FAQ[];
|
|
5
6
|
className?: string;
|
|
@@ -8,8 +9,19 @@ export interface FAQAccordionProps {
|
|
|
8
9
|
labels?: {
|
|
9
10
|
noResults?: string;
|
|
10
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Phase 9 — resolved published values, for `{{token}}` substitution in
|
|
14
|
+
* answers. Build them with `resolvePublishedValues(settings?.commissions)`
|
|
15
|
+
* at the page level and pass them down.
|
|
16
|
+
*
|
|
17
|
+
* 🛑 Passed in rather than read here. This component renders on the server
|
|
18
|
+
* and in the client, and a settings read inside a presentational component
|
|
19
|
+
* would both make it unusable in half the places it is needed and fire one
|
|
20
|
+
* read per accordion on a page that has several.
|
|
21
|
+
*/
|
|
22
|
+
publishedValues?: PublishedValues;
|
|
11
23
|
}
|
|
12
|
-
export declare function FAQAccordion({ faqs, className, renderExpandedFooter, labels, }: FAQAccordionProps): React.JSX.Element;
|
|
24
|
+
export declare function FAQAccordion({ faqs, className, renderExpandedFooter, labels, publishedValues, }: FAQAccordionProps): React.JSX.Element;
|
|
13
25
|
interface FAQCategoryTabsProps {
|
|
14
26
|
categories: FAQCategory[];
|
|
15
27
|
active?: FAQCategory | null;
|
|
@@ -2,16 +2,41 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, Div, RichText, Row, Span, Tabs, TabsList, TabsTrigger, Text } from "../../../ui/index.js";
|
|
5
|
+
/* Phase 9 — `publishedCopyKey`'s first reader. See the 🛑 at the render site. */
|
|
6
|
+
import { resolvePublishedCopy, resolvePublishedValues, } from "../../../_internal/shared/content/published-values.js";
|
|
5
7
|
import { RecordOwnerQuickActions } from "../../admin/components/RecordOwnerQuickActions.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Code-derived values, resolved once at module scope.
|
|
10
|
+
*
|
|
11
|
+
* ## 🛑 Why a DEFAULT rather than a required prop
|
|
12
|
+
*
|
|
13
|
+
* `resolvePublishedValues()` with no settings argument is PURE over code
|
|
14
|
+
* constants — the obligation policies, `LANE_CHECKOUT_WINDOW_MS`,
|
|
15
|
+
* `POINTS_EARN_PERCENT`. It reads no Firestore and touches no settings, so
|
|
16
|
+
* calling it here costs one object at import and cannot leak anything.
|
|
17
|
+
*
|
|
18
|
+
* That matters because there are FOUR mount sites (the FAQ page, the
|
|
19
|
+
* searchable list, the category highlights section, and this file's own
|
|
20
|
+
* loop). Requiring the prop would mean threading it through four callers and
|
|
21
|
+
* their callers — and the one that got missed would render `{{…}}` to a
|
|
22
|
+
* visitor. A default that always resolves the code-derived numbers, with an
|
|
23
|
+
* override for the settings-driven money ones, gets every surface right
|
|
24
|
+
* immediately.
|
|
25
|
+
*
|
|
26
|
+
* A caller WITH settings in hand should still pass them: without them the
|
|
27
|
+
* money values fall back to the schema defaults, which is correct but is not
|
|
28
|
+
* the admin's current configuration.
|
|
29
|
+
*/
|
|
30
|
+
const CODE_DERIVED_VALUES = resolvePublishedValues();
|
|
31
|
+
function FAQAccordionItem({ faq, isOpen, onToggle, renderExpandedFooter, publishedValues = CODE_DERIVED_VALUES, }) {
|
|
32
|
+
return (_jsxs(Div, { className: "border-b border-neutral-200 last:border-0", children: [_jsxs(Button, { variant: "ghost", onClick: onToggle, "aria-expanded": isOpen, justify: "between", className: "w-full gap-[1rem] py-[1rem] text-left text-[0.875rem] font-[500] text-[var(--appkit-color-text)] dark:text-[var(--appkit-color-text)] transition hover:text-primary", children: [_jsx(Span, { children: faq.question }), _jsx(Span, { className: `flex-shrink-0 transition-transform ${isOpen ? "rotate-180" : ""}`, children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] }), isOpen && (_jsxs(Div, { textSize: "sm", className: "text-[var(--appkit-color-text-muted)]", padding: "b-md", children: [faq.tags && faq.tags.length > 0 && (_jsx(Row, { wrap: true, gap: "sm", className: "mb-3", children: faq.tags.map((tag) => (_jsx(Span, { className: "bg-[var(--appkit-color-surface)] py-[0.25rem] text-[var(--appkit-color-text-muted)]", rounded: "md", padding: "x-xs", size: "xs", children: tag }, tag))) })), faq.answer.format === "html" ? (_jsx(RichText, { html: resolvePublishedCopy(faq.answer.text, publishedValues), className: "prose-sm" })) : (_jsx(Text, { className: "whitespace-pre-line", children: resolvePublishedCopy(faq.answer.text, publishedValues) })), _jsx(Row, { justify: "end", className: "mt-3", children: _jsx(RecordOwnerQuickActions, { resource: "FAQ", recordId: faq.id, placement: "detail", recordLabel: faq.question }) }), renderExpandedFooter?.(faq)] }))] }));
|
|
8
33
|
}
|
|
9
|
-
export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, }) {
|
|
34
|
+
export function FAQAccordion({ faqs, className = "", renderExpandedFooter, labels, publishedValues, }) {
|
|
10
35
|
const [openId, setOpenId] = useState(null);
|
|
11
36
|
if (faqs.length === 0 && labels?.noResults) {
|
|
12
37
|
return (_jsx(Div, { surface: "card", padding: "xl", className: "text-center", children: _jsx(Text, { className: "text-[var(--appkit-color-text-muted)]", children: labels.noResults }) }));
|
|
13
38
|
}
|
|
14
|
-
return (_jsx(Div, { surface: "card", className: `divide-y divide-neutral-100 divide-[var(--appkit-color-border)] ${className}`, padding: "x-md", children: faqs.map((faq) => (_jsx(FAQAccordionItem, { faq: faq, isOpen: openId === faq.id, onToggle: () => setOpenId(openId === faq.id ? null : faq.id), renderExpandedFooter: renderExpandedFooter }, faq.id))) }));
|
|
39
|
+
return (_jsx(Div, { surface: "card", className: `divide-y divide-neutral-100 divide-[var(--appkit-color-border)] ${className}`, padding: "x-md", children: faqs.map((faq) => (_jsx(FAQAccordionItem, { faq: faq, isOpen: openId === faq.id, onToggle: () => setOpenId(openId === faq.id ? null : faq.id), renderExpandedFooter: renderExpandedFooter, publishedValues: publishedValues }, faq.id))) }));
|
|
15
40
|
}
|
|
16
41
|
const ALL_TAB_VALUE = "__all__";
|
|
17
42
|
export function FAQCategoryTabs({ categories, active, onSelect, labels = {}, }) {
|
|
@@ -45,12 +45,12 @@ export function FAQPageContent({ initialCategory = "all", categories, routeHelpe
|
|
|
45
45
|
total,
|
|
46
46
|
categoryCounts,
|
|
47
47
|
onSelect: handleCategorySelect,
|
|
48
|
-
}) }), _jsxs(Div, { layout: "grid", gap: "8", className: "
|
|
48
|
+
}) }), _jsxs(Div, { layout: "grid", gap: "8", className: "lg:grid-cols-12", children: [_jsx(Div, { className: "hidden lg:col-span-4 lg:block xl:col-span-3", children: _jsx(FAQCategorySidebar, { selectedCategory: selectedCategory, onCategorySelect: handleCategorySelect, categoryCounts: categoryCounts, categories: categories, allFaqsHref: routeHelpers.allFaqsHref, categoryHref: routeHelpers.faqCategoryHref, contactHref: routeHelpers.contactHref, labels: {
|
|
49
49
|
title: labels.categoriesTitle,
|
|
50
50
|
allFaqs: labels.allFaqs,
|
|
51
51
|
stillHaveQuestions: labels.stillHaveQuestions,
|
|
52
52
|
contactSupport: labels.contactSupport,
|
|
53
|
-
} }) }), _jsxs(Div, { className: "
|
|
53
|
+
} }) }), _jsxs(Div, { className: "lg:col-span-8 xl:col-span-9", children: [_jsx(SlottedListingView, { portal: "public", inlineToolbar: true, className: "space-y-6", renderHeader: () => {
|
|
54
54
|
/*
|
|
55
55
|
* The fuller answer, next to the short ones.
|
|
56
56
|
*
|
|
@@ -44,13 +44,13 @@ export declare const gatewayEventFirestoreSchema: z.ZodObject<{
|
|
|
44
44
|
terminal?: boolean | undefined;
|
|
45
45
|
amount?: number | undefined;
|
|
46
46
|
seedPurpose?: string | undefined;
|
|
47
|
+
payload?: Record<string, unknown> | undefined;
|
|
47
48
|
orderIds?: string[] | undefined;
|
|
48
49
|
processedAt?: Date | undefined;
|
|
49
50
|
gatewayPaymentId?: string | undefined;
|
|
50
51
|
gatewayOrderId?: string | undefined;
|
|
51
52
|
providerEventId?: string | undefined;
|
|
52
53
|
lastError?: string | undefined;
|
|
53
|
-
payload?: Record<string, unknown> | undefined;
|
|
54
54
|
payloadTruncated?: boolean | undefined;
|
|
55
55
|
}, {
|
|
56
56
|
status: "received" | "failed" | "processed" | "processing" | "conflict" | "ignored";
|
|
@@ -69,13 +69,13 @@ export declare const gatewayEventFirestoreSchema: z.ZodObject<{
|
|
|
69
69
|
terminal?: boolean | undefined;
|
|
70
70
|
amount?: number | undefined;
|
|
71
71
|
seedPurpose?: string | undefined;
|
|
72
|
+
payload?: Record<string, unknown> | undefined;
|
|
72
73
|
orderIds?: string[] | undefined;
|
|
73
74
|
processedAt?: Date | undefined;
|
|
74
75
|
gatewayPaymentId?: string | undefined;
|
|
75
76
|
gatewayOrderId?: string | undefined;
|
|
76
77
|
providerEventId?: string | undefined;
|
|
77
78
|
lastError?: string | undefined;
|
|
78
|
-
payload?: Record<string, unknown> | undefined;
|
|
79
79
|
payloadTruncated?: boolean | undefined;
|
|
80
80
|
}>;
|
|
81
81
|
export type GatewayEventFromSchema = z.infer<typeof gatewayEventFirestoreSchema>;
|
|
@@ -867,16 +867,16 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
867
867
|
opacity?: number | undefined;
|
|
868
868
|
subtitle?: string | undefined;
|
|
869
869
|
} | undefined;
|
|
870
|
+
settings?: {
|
|
871
|
+
height?: "medium" | "viewport" | "tall" | undefined;
|
|
872
|
+
autoplayDelayMs?: number | undefined;
|
|
873
|
+
} | undefined;
|
|
870
874
|
analytics?: {
|
|
871
875
|
views: number;
|
|
872
876
|
lastViewed?: string | Date | z.objectOutputType<{
|
|
873
877
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
874
878
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
875
879
|
} | undefined;
|
|
876
|
-
settings?: {
|
|
877
|
-
height?: "medium" | "viewport" | "tall" | undefined;
|
|
878
|
-
autoplayDelayMs?: number | undefined;
|
|
879
|
-
} | undefined;
|
|
880
880
|
carouselId?: string | null | undefined;
|
|
881
881
|
}, {
|
|
882
882
|
id: string;
|
|
@@ -976,16 +976,16 @@ export declare const carouselSlideFirestoreSchema: z.ZodObject<{
|
|
|
976
976
|
opacity?: number | undefined;
|
|
977
977
|
subtitle?: string | undefined;
|
|
978
978
|
} | undefined;
|
|
979
|
+
settings?: {
|
|
980
|
+
height?: "medium" | "viewport" | "tall" | undefined;
|
|
981
|
+
autoplayDelayMs?: number | undefined;
|
|
982
|
+
} | undefined;
|
|
979
983
|
analytics?: {
|
|
980
984
|
views: number;
|
|
981
985
|
lastViewed?: string | Date | z.objectInputType<{
|
|
982
986
|
toDate: z.ZodFunction<z.ZodTuple<[], z.ZodUnknown>, z.ZodDate>;
|
|
983
987
|
}, z.ZodTypeAny, "passthrough"> | undefined;
|
|
984
988
|
} | undefined;
|
|
985
|
-
settings?: {
|
|
986
|
-
height?: "medium" | "viewport" | "tall" | undefined;
|
|
987
|
-
autoplayDelayMs?: number | undefined;
|
|
988
|
-
} | undefined;
|
|
989
989
|
carouselId?: string | null | undefined;
|
|
990
990
|
}>;
|
|
991
991
|
export type HomepageSectionFromSchema = z.infer<typeof homepageSectionFirestoreSchema>;
|