@mohasinac/appkit 4.9.5 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +6 -1
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +4 -1
- package/dist/_internal/client/features/lottery/LotteryPullForm.d.ts +1 -1
- package/dist/_internal/client/features/lottery/LotteryPullForm.js +2 -2
- package/dist/_internal/server/features/admin/daily-digest-actions.d.ts +18 -0
- package/dist/_internal/server/features/admin/daily-digest-actions.js +37 -0
- package/dist/_internal/server/features/auctions/actions.js +3 -2
- package/dist/_internal/server/features/auctions/service.d.ts +4 -3
- package/dist/_internal/server/features/auctions/service.js +6 -6
- package/dist/_internal/server/features/audit-log/actions.d.ts +25 -0
- package/dist/_internal/server/features/audit-log/actions.js +38 -0
- package/dist/_internal/server/features/brands/actions.js +0 -2
- package/dist/_internal/server/features/brands/og.d.ts +4 -1
- package/dist/_internal/server/features/brands/og.js +1 -1
- package/dist/_internal/server/features/bundles/data.d.ts +9 -0
- package/dist/_internal/server/features/bundles/data.js +14 -0
- package/dist/_internal/server/features/bundles/index.d.ts +1 -1
- package/dist/_internal/server/features/bundles/index.js +1 -1
- package/dist/_internal/server/features/catalogue/og.d.ts +20 -0
- package/dist/_internal/server/features/catalogue/og.js +27 -0
- package/dist/_internal/server/features/grouped/data.d.ts +16 -0
- package/dist/_internal/server/features/grouped/data.js +50 -1
- package/dist/_internal/server/features/grouped/index.d.ts +1 -1
- package/dist/_internal/server/features/grouped/index.js +1 -1
- package/dist/_internal/server/features/orders/actions.js +9 -0
- package/dist/_internal/server/features/orders/adapters.js +25 -0
- package/dist/_internal/server/features/products/data.d.ts +23 -0
- package/dist/_internal/server/features/products/data.js +159 -0
- package/dist/_internal/server/features/products/index.d.ts +1 -1
- package/dist/_internal/server/features/products/index.js +1 -1
- package/dist/_internal/server/functions/scheduled.d.ts +3 -1
- package/dist/_internal/server/functions/scheduled.js +17 -1
- package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +40 -0
- package/dist/_internal/server/jobs/core/dailyStatusDigest.js +164 -0
- package/dist/_internal/server/jobs/core/hardBanCascade.js +11 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
- package/dist/_internal/server/jobs/core/testerSandboxRefresh.d.ts +12 -0
- package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +85 -0
- package/dist/_internal/server/jobs/core/whatsappNotify.js +16 -0
- package/dist/_internal/server/jobs/handlers/dailyStatusDigest.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/dailyStatusDigest.js +4 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/index.js +3 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxRefresh.js +2 -0
- package/dist/_internal/server/notifications/channel-health.d.ts +27 -0
- package/dist/_internal/server/notifications/channel-health.js +101 -0
- package/dist/_internal/shared/features/auctions/config.d.ts +20 -0
- package/dist/_internal/shared/features/auctions/config.js +31 -1
- package/dist/_internal/shared/features/brands/schema.d.ts +0 -6
- package/dist/_internal/shared/features/brands/schema.js +0 -1
- package/dist/_internal/shared/features/categories/bundle-schemas.d.ts +7 -0
- package/dist/_internal/shared/features/categories/bundle-schemas.js +3 -0
- package/dist/_internal/shared/features/orders/schema.d.ts +8 -8
- package/dist/_internal/shared/listing-types/art/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/art/config.js +1 -1
- package/dist/_internal/shared/listing-types/classified/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/classified/config.js +1 -1
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/digital-code/config.js +1 -1
- package/dist/_internal/shared/listing-types/live/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/live/config.js +1 -1
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/prize-draw/config.js +1 -1
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +1 -1
- package/dist/_internal/shared/listing-types/stickers/config.js +1 -1
- package/dist/client.d.ts +21 -12
- package/dist/client.js +14 -7
- package/dist/constants/api-endpoints.d.ts +9 -9
- package/dist/constants/api-endpoints.js +3 -3
- package/dist/contracts/client-auth.d.ts +3 -7
- package/dist/contracts/email.d.ts +1 -0
- package/dist/features/account/components/AddressForm.js +24 -2
- package/dist/features/account/components/BecomeSellerView.d.ts +1 -2
- package/dist/features/account/components/BecomeSellerView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +1 -1
- package/dist/features/account/components/UserBidsView.d.ts +1 -0
- package/dist/features/account/components/UserBidsView.js +47 -0
- package/dist/features/account/components/UserOrdersView.d.ts +4 -11
- package/dist/features/account/components/UserOrdersView.js +54 -4
- package/dist/features/account/components/UserReturnsView.d.ts +4 -9
- package/dist/features/account/components/UserReturnsView.js +37 -3
- package/dist/features/account/components/index.d.ts +3 -2
- package/dist/features/account/components/index.js +1 -0
- package/dist/features/admin/actions/admin-actions.js +22 -0
- package/dist/features/admin/actions/admin-coupon-actions.js +10 -0
- package/dist/features/admin/actions/notification-actions.js +4 -3
- package/dist/features/admin/components/AdminAdsView.d.ts +2 -3
- package/dist/features/admin/components/AdminAdsView.js +86 -89
- package/dist/features/admin/components/AdminAllEventEntriesView.js +18 -3
- package/dist/features/admin/components/AdminAuditLogView.d.ts +11 -0
- package/dist/features/admin/components/AdminAuditLogView.js +95 -0
- package/dist/features/admin/components/AdminBlogEditorView.js +37 -3
- package/dist/features/admin/components/AdminBrandEditorView.js +10 -6
- package/dist/features/admin/components/AdminBundleEditorView.js +18 -2
- package/dist/features/admin/components/AdminCarouselEditorView.js +2 -2
- package/dist/features/admin/components/AdminCarouselGroupEditorView.js +2 -2
- package/dist/features/admin/components/AdminCartsView.js +34 -4
- package/dist/features/admin/components/AdminCategoryEditorView.js +5 -4
- package/dist/features/admin/components/AdminCouponEditorView.js +2 -2
- package/dist/features/admin/components/AdminFaqEditorView.js +2 -2
- package/dist/features/admin/components/AdminHistoryView.js +11 -1
- package/dist/features/admin/components/AdminNotificationsView.js +27 -1
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +10 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
- package/dist/features/admin/components/AdminOrdersView.js +92 -24
- package/dist/features/admin/components/AdminPayoutMarkPaidModal.d.ts +7 -0
- package/dist/features/admin/components/AdminPayoutMarkPaidModal.js +47 -0
- package/dist/features/admin/components/AdminPayoutsView.js +15 -31
- package/dist/features/admin/components/AdminProductEditorView.js +26 -3
- package/dist/features/admin/components/AdminSiteSettingsView.js +31 -4
- package/dist/features/admin/components/AdminStoreAddressesView.js +22 -2
- package/dist/features/admin/components/AdminStoresView.js +7 -0
- package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +2 -2
- package/dist/features/admin/components/AdminUserEditorView.d.ts +2 -2
- package/dist/features/admin/components/AdminUserEditorView.js +4 -2
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/AdminWishlistsView.js +14 -1
- package/dist/features/admin/components/DataListingView.d.ts +2 -2
- package/dist/features/admin/components/ViewAuditLogEntryModal.d.ts +19 -0
- package/dist/features/admin/components/ViewAuditLogEntryModal.js +22 -0
- package/dist/features/admin/components/ViewNotificationModal.d.ts +21 -0
- package/dist/features/admin/components/ViewNotificationModal.js +15 -0
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +4 -7
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +56 -36
- package/dist/features/admin/components/index.d.ts +8 -1
- package/dist/features/admin/components/index.js +4 -0
- package/dist/features/admin/constants/filter-tabs.d.ts +49 -0
- package/dist/features/admin/constants/filter-tabs.js +27 -0
- package/dist/features/admin/hooks/useAdminListing.d.ts +6 -0
- package/dist/features/admin/hooks/useAdminListing.js +3 -1
- package/dist/features/admin/hooks/useAdminListingData.d.ts +9 -1
- package/dist/features/admin/hooks/useAdminListingData.js +9 -2
- package/dist/features/admin/repository/site-settings.repository.d.ts +5 -0
- package/dist/features/admin/schemas/firestore.d.ts +21 -0
- package/dist/features/admin/schemas/firestore.js +6 -0
- package/dist/features/analytics/types.d.ts +1 -1
- package/dist/features/analytics/types.js +8 -0
- package/dist/features/auctions/actions/bid-actions.js +4 -1
- package/dist/features/auctions/components/AuctionBottomActions.d.ts +2 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +14 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +21 -9
- package/dist/features/auctions/components/LiveMinIncrement.d.ts +18 -0
- package/dist/features/auctions/components/LiveMinIncrement.js +17 -0
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +5 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +7 -3
- package/dist/features/auctions/schemas/index.d.ts +5 -0
- package/dist/features/audit-log/repository/audit-log.repository.d.ts +45 -0
- package/dist/features/audit-log/repository/audit-log.repository.js +30 -0
- package/dist/features/audit-log/schemas/firestore.d.ts +59 -0
- package/dist/features/audit-log/schemas/firestore.js +35 -0
- package/dist/features/auth/actions/index.d.ts +0 -1
- package/dist/features/auth/actions/index.js +0 -1
- package/dist/features/auth/hooks/useAuth.d.ts +8 -35
- package/dist/features/auth/hooks/useAuth.js +21 -37
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +2 -0
- package/dist/features/blog/schemas/index.d.ts +32 -0
- package/dist/features/catalogue/components/AdminCatalogueApprovalsView.js +31 -3
- package/dist/features/catalogue/components/CatalogueItemEditorView.js +2 -1
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.d.ts +11 -0
- package/dist/features/catalogue/components/PublicCatalogueItemDetailView.js +33 -0
- package/dist/features/catalogue/components/PublicCatalogueView.js +2 -1
- package/dist/features/catalogue/index.d.ts +2 -0
- package/dist/features/catalogue/index.js +1 -0
- package/dist/features/categories/components/BrandDetailPageView.js +14 -12
- package/dist/features/categories/components/BundleDetailView.d.ts +3 -1
- package/dist/features/categories/components/BundleDetailView.js +3 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +7 -3
- package/dist/features/categories/components/CategoryHighlightsAndFaqSection.d.ts +14 -0
- package/dist/features/categories/components/CategoryHighlightsAndFaqSection.js +22 -0
- package/dist/features/categories/components/CategoryProductsView.d.ts +1 -5
- package/dist/features/categories/components/CategoryProductsView.js +1 -1
- package/dist/features/categories/components/CategorySelectorCreate.js +16 -2
- package/dist/features/categories/schemas/firestore.d.ts +19 -2
- package/dist/features/categories/schemas/index.d.ts +24 -3
- package/dist/features/categories/schemas/index.js +3 -1
- package/dist/features/categories/types/index.d.ts +7 -0
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +17 -3
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +101 -22
- package/dist/features/classified/components/ClassifiedContactSellerPanel.d.ts +12 -0
- package/dist/features/classified/components/ClassifiedContactSellerPanel.js +49 -0
- package/dist/features/classified/components/ClassifiedDetailPageView.d.ts +7 -0
- package/dist/features/classified/components/ClassifiedDetailPageView.js +69 -0
- package/dist/features/contact/components/ContactForm.js +17 -4
- package/dist/features/contact/components/ContactPageView.js +8 -2
- package/dist/features/contact/email.d.ts +1 -0
- package/dist/features/contact/email.js +3 -0
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.d.ts +19 -0
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +79 -0
- package/dist/features/events/components/AdminEventEditorView.js +54 -2
- package/dist/features/events/components/AdminEventEntriesView.d.ts +2 -16
- package/dist/features/events/components/AdminEventEntriesView.js +56 -89
- package/dist/features/events/components/EventFormDrawer.js +5 -1
- package/dist/features/events/components/EventRaffleEntryForm.d.ts +1 -3
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/schemas/index.d.ts +22 -0
- package/dist/features/grouped/components/GroupedListingsCarousel.d.ts +13 -0
- package/dist/features/grouped/components/GroupedListingsCarousel.js +31 -0
- package/dist/features/grouped/repository/grouped-listings.repository.d.ts +12 -0
- package/dist/features/grouped/repository/grouped-listings.repository.js +34 -0
- package/dist/features/homepage/components/CharacterHotspotForm.js +202 -187
- package/dist/features/homepage/components/SectionCarousel.d.ts +1 -7
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/layout/BottomActions.js +4 -3
- package/dist/features/layout/BottomActionsContext.d.ts +10 -0
- package/dist/features/layout/BottomActionsContext.js +5 -1
- package/dist/features/layout/TitleBarLayout.d.ts +1 -1
- package/dist/features/layout/TitleBarLayout.js +3 -3
- package/dist/features/layout/hooks/useBottomActions.d.ts +2 -0
- package/dist/features/layout/hooks/useBottomActions.js +4 -1
- package/dist/features/live/components/LiveItemDetailPageView.d.ts +9 -0
- package/dist/features/live/components/LiveItemDetailPageView.js +74 -0
- package/dist/features/media/MediaImage.js +39 -3
- package/dist/features/media/MediaVideo.js +17 -1
- package/dist/features/media/types/index.d.ts +10 -0
- package/dist/features/media/types/index.js +1 -0
- package/dist/features/media/upload/MediaUploadField.d.ts +7 -1
- package/dist/features/media/upload/MediaUploadField.js +11 -7
- package/dist/features/media/upload/video-poster.d.ts +2 -0
- package/dist/features/media/upload/video-poster.js +16 -1
- package/dist/features/media/upload/video-poster.test.js +1 -1
- package/dist/features/orders/components/OrderStatusTimeline.d.ts +12 -0
- package/dist/features/orders/components/OrderStatusTimeline.js +55 -0
- package/dist/features/orders/components/index.d.ts +2 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/constants/payment-window.d.ts +25 -0
- package/dist/features/orders/constants/payment-window.js +25 -0
- package/dist/features/orders/repository/orders.repository.d.ts +32 -0
- package/dist/features/orders/repository/orders.repository.js +56 -0
- package/dist/features/orders/schemas/index.d.ts +24 -24
- package/dist/features/orders/types/index.d.ts +33 -0
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +9 -1
- package/dist/features/pre-orders/schemas/index.d.ts +5 -0
- package/dist/features/products/components/BidHistory.js +9 -1
- package/dist/features/products/components/GroupSettingsPanel.js +25 -3
- package/dist/features/products/components/PrizeDrawDetailPageView.js +11 -1
- package/dist/features/products/components/PrizeDrawEntryActions.d.ts +1 -4
- package/dist/features/products/components/PrizeDrawEntryActions.js +1 -1
- package/dist/features/products/components/ProductDetailActions.d.ts +1 -2
- package/dist/features/products/components/ProductDetailActions.js +1 -1
- package/dist/features/products/components/ProductDetailPageView.js +11 -116
- package/dist/features/products/components/ProductGrid.js +15 -1
- package/dist/features/products/components/RelatedItemsSection.d.ts +16 -0
- package/dist/features/products/components/RelatedItemsSection.js +17 -0
- package/dist/features/products/constants/action-defs.d.ts +1 -0
- package/dist/features/products/constants/action-defs.js +1 -0
- package/dist/features/products/schemas/index.d.ts +5 -0
- package/dist/features/promotions/components/CouponsIndexListing.d.ts +1 -3
- package/dist/features/promotions/components/CouponsIndexListing.js +1 -1
- package/dist/features/search/components/SearchView.d.ts +1 -3
- package/dist/features/search/components/SearchView.js +1 -1
- package/dist/features/seller/components/QuickProductForm.js +2 -1
- package/dist/features/seller/components/SellerBidsView.js +66 -107
- package/dist/features/seller/components/SellerGoogleReviewsView.js +17 -1
- package/dist/features/seller/components/SellerOrdersView.d.ts +15 -3
- package/dist/features/seller/components/SellerOrdersView.js +134 -163
- package/dist/features/seller/components/SellerPayoutMethodsView.js +60 -48
- package/dist/features/seller/components/SellerPayoutSettingsView.js +69 -4
- package/dist/features/seller/components/SellerPayoutsView.d.ts +12 -0
- package/dist/features/seller/components/SellerPayoutsView.js +25 -5
- package/dist/features/seller/components/SellerProductShell.d.ts +10 -3
- package/dist/features/seller/components/SellerProductShell.js +90 -37
- package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +2 -7
- package/dist/features/seller/components/SellerProductsFilterDrawer.js +4 -4
- package/dist/features/seller/components/SellerProductsView.d.ts +2 -4
- package/dist/features/seller/components/SellerProductsView.js +131 -189
- package/dist/features/seller/components/SellerReviewsView.js +95 -133
- package/dist/features/seller/components/SellerShippingConfigsView.js +47 -67
- package/dist/features/seller/components/SellerShippingView.js +41 -4
- package/dist/features/seller/components/SellerStoreCategoriesView.js +51 -59
- package/dist/features/seller/components/SellerStorefrontView.d.ts +6 -1
- package/dist/features/seller/components/SellerStorefrontView.js +42 -5
- package/dist/features/seller/components/index.d.ts +2 -2
- package/dist/features/seller/components/index.js +2 -2
- package/dist/features/shell/FormShell.d.ts +24 -4
- package/dist/features/shell/FormShell.js +12 -6
- package/dist/features/shell/QuickFormDrawer.js +67 -12
- package/dist/features/shell/StepForm.d.ts +30 -1
- package/dist/features/shell/StepForm.js +47 -4
- package/dist/features/shell/index.d.ts +1 -1
- package/dist/features/shell/index.js +1 -1
- package/dist/features/shipments/components/AdminShipmentEditorView.js +2 -2
- package/dist/features/shipments/schemas/validation.d.ts +14 -4
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +23 -2
- package/dist/features/tester/components/TesterChecklistStepRow.js +1 -1
- package/dist/features/tester/components/TesterHubView.js +3 -2
- package/dist/features/tester/seed-data/orders-tester-seed-data.js +9 -1
- package/dist/features/tester/seed-data/products-tester-seed-data.js +43 -32
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +487 -18
- package/dist/index.d.ts +17 -3
- package/dist/index.js +23 -5
- package/dist/next/routing/route-map.d.ts +13 -0
- package/dist/next/routing/route-map.js +12 -0
- package/dist/providers/email-resend/provider.js +1 -0
- package/dist/providers/firebase-client/auth.d.ts +1 -0
- package/dist/providers/firebase-client/auth.js +7 -1
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.js +1 -0
- package/dist/schemas/registry.d.ts +61 -25
- package/dist/security/pii-mask.js +1 -1
- package/dist/seed/bids-seed-data.js +48 -3
- package/dist/seed/categories-seed-data.js +69 -0
- package/dist/seed/grouped-listings-seed-data.js +167 -0
- package/dist/seed/payouts-seed-data.js +4 -4
- package/dist/seed/products-art-seed-data.js +188 -5
- package/dist/seed/products-auctions-seed-data.js +226 -6
- package/dist/seed/products-classifieds-seed-data.js +255 -8
- package/dist/seed/products-digital-codes-seed-data.js +258 -19
- package/dist/seed/products-live-items-seed-data.js +143 -10
- package/dist/seed/products-preorders-seed-data.js +213 -8
- package/dist/seed/products-prize-draws-seed-data.js +198 -0
- package/dist/seed/products-standard-seed-data.js +234 -4
- package/dist/seed/products-stickers-seed-data.js +178 -5
- package/dist/seed/site-settings-seed-data.js +23 -30
- package/dist/seed/store-extensions-seed-data.js +2 -2
- package/dist/server-entry.d.ts +6 -2
- package/dist/server-entry.js +24 -3
- package/dist/server.d.ts +10 -3
- package/dist/server.js +11 -4
- package/dist/styles.css +29 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Form.d.ts +11 -2
- package/dist/ui/components/Form.js +4 -3
- package/dist/ui/components/FormField.d.ts +3 -1
- package/dist/ui/components/FormField.js +22 -4
- package/dist/ui/components/ImageLightbox.js +37 -3
- package/dist/ui/components/ImageLightbox.style.css +28 -0
- package/dist/ui/components/ListingLayout.d.ts +1 -2
- package/dist/ui/components/ListingLayout.js +1 -1
- package/dist/ui/components/RecordDetailModal.d.ts +68 -0
- package/dist/ui/components/RecordDetailModal.js +8 -0
- package/dist/ui/components/SlottedListingView.js +9 -1
- package/dist/ui/forms/FormErrorSummary.d.ts +25 -0
- package/dist/ui/forms/FormErrorSummary.js +37 -0
- package/dist/ui/forms/FormShell.d.ts +37 -2
- package/dist/ui/forms/FormShell.js +37 -7
- package/dist/ui/forms/FormShell.style.css +17 -0
- package/dist/ui/forms/index.d.ts +2 -0
- package/dist/ui/forms/index.js +1 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +5 -0
- package/dist/utils/media-url.d.ts +12 -1
- package/dist/utils/media-url.js +59 -1
- package/dist/validation/schemas.d.ts +4 -4
- package/package.json +1 -1
- package/dist/_internal/client/features/classified/ClassifiedDetailView.d.ts +0 -9
- package/dist/_internal/client/features/classified/ClassifiedDetailView.js +0 -55
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.d.ts +0 -18
- package/dist/_internal/client/features/digital-code/DigitalCodeDetailView.js +0 -21
- package/dist/_internal/client/features/live/LiveItemDetailView.d.ts +0 -9
- package/dist/_internal/client/features/live/LiveItemDetailView.js +0 -25
- package/dist/_internal/server/jobs/core/prizeRevealClose.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealClose.js +0 -28
- package/dist/_internal/server/jobs/core/prizeRevealExpiry.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealExpiry.js +0 -61
- package/dist/_internal/server/jobs/core/prizeRevealOpen.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealOpen.js +0 -68
- package/dist/_internal/server/jobs/core/prizeRevealReminder.d.ts +0 -2
- package/dist/_internal/server/jobs/core/prizeRevealReminder.js +0 -49
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealClose.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealExpiry.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealOpen.js +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/prizeRevealReminder.js +0 -2
- package/dist/features/auth/consent-otp.d.ts +0 -57
- package/dist/features/auth/consent-otp.js +0 -127
- package/dist/features/cart/components/CheckoutOtpModal.d.ts +0 -15
- package/dist/features/cart/components/CheckoutOtpModal.js +0 -12
- package/dist/features/checkout/actions/checkout-actions.d.ts +0 -31
- package/dist/features/checkout/actions/checkout-actions.js +0 -124
- package/dist/features/classified/components/ClassifiedIndexListing.d.ts +0 -5
- package/dist/features/classified/components/ClassifiedIndexListing.js +0 -123
- package/dist/features/classified/components/ClassifiedListView.d.ts +0 -6
- package/dist/features/classified/components/ClassifiedListView.js +0 -44
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.d.ts +0 -5
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +0 -114
- package/dist/features/digital-codes/components/DigitalCodesListView.d.ts +0 -6
- package/dist/features/digital-codes/components/DigitalCodesListView.js +0 -38
- package/dist/features/live/components/LiveItemsIndexListing.d.ts +0 -5
- package/dist/features/live/components/LiveItemsIndexListing.js +0 -115
- package/dist/features/live/components/LiveItemsListView.d.ts +0 -6
- package/dist/features/live/components/LiveItemsListView.js +0 -44
- package/dist/features/seller/components/SellerTemplatesView.d.ts +0 -12
- package/dist/features/seller/components/SellerTemplatesView.js +0 -276
- package/dist/react/hooks/useVisibleItems.d.ts +0 -37
- package/dist/react/hooks/useVisibleItems.js +0 -59
- package/dist/ui/components/TabStrip.d.ts +0 -34
- package/dist/ui/components/TabStrip.js +0 -56
- package/dist/ui/components/TabStrip.style.css +0 -97
package/dist/ui/forms/index.js
CHANGED
package/dist/ui/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type { FieldCheckboxProps } from "./forms";
|
|
|
10
10
|
export { FieldCheckbox } from "./forms";
|
|
11
11
|
export type { FieldTextareaProps } from "./forms";
|
|
12
12
|
export { FieldTextarea } from "./forms";
|
|
13
|
+
export type { FormErrorSummaryProps } from "./forms";
|
|
14
|
+
export { FormErrorSummary } from "./forms";
|
|
13
15
|
export { buildColumns, createColumnBuilder, renderBoolean, renderCurrency, renderCurrencyCompact, renderCount, renderNullable, renderRating, getStatusTone, getResourceIcon, } from "./columns";
|
|
14
16
|
export type { BooleanRenderOpts, RatingMode, RatingRenderOpts, StatusTone, } from "./columns";
|
|
15
17
|
export type { SectionProps, SectionBackgroundConfig, ArticleProps, MainProps, AsideProps, NavProps, BlockHeaderProps, BlockFooterProps, UlProps, OlProps, LiProps, TableProps, TheadProps, TbodyProps, TrProps, ThProps, TdProps, CodeProps, PreProps, BlockquoteProps, FigureProps, FigcaptionProps, DlProps, DtProps, DdProps, } from "./components/Semantic";
|
|
@@ -229,3 +231,5 @@ export { Show, Hide } from "./components/Responsive";
|
|
|
229
231
|
export type { ShowProps, HideProps } from "./components/Responsive";
|
|
230
232
|
export { CollapsibleSection } from "./components/CollapsibleSection";
|
|
231
233
|
export type { CollapsibleSectionProps } from "./components/CollapsibleSection";
|
|
234
|
+
export { RecordDetailModal } from "./components/RecordDetailModal";
|
|
235
|
+
export type { RecordDetailModalProps, RecordDetailField, RecordDetailItem, RecordDetailBadge, } from "./components/RecordDetailModal";
|
package/dist/ui/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { FieldInput } from "./forms";
|
|
|
5
5
|
export { FieldSelect } from "./forms";
|
|
6
6
|
export { FieldCheckbox } from "./forms";
|
|
7
7
|
export { FieldTextarea } from "./forms";
|
|
8
|
+
export { FormErrorSummary } from "./forms";
|
|
8
9
|
// --- Column utilities ---------------------------------------------------------
|
|
9
10
|
export { buildColumns, createColumnBuilder, renderBoolean, renderCurrency, renderCurrencyCompact, renderCount, renderNullable, renderRating, getStatusTone, getResourceIcon, } from "./columns";
|
|
10
11
|
export { Section, sectionBackgroundStyle, Article, Main, Aside, Nav, BlockHeader, BlockFooter, Ul, Ol, Li, Table, Thead, Tbody, Tr, Th, Td, Code, Pre, Blockquote, Figure, Figcaption, Dl, Dt, Dd, } from "./components/Semantic";
|
|
@@ -120,3 +121,7 @@ export { Kbd } from "./components/Kbd";
|
|
|
120
121
|
export { StickyToolbar } from "./components/StickyToolbar";
|
|
121
122
|
export { Show, Hide } from "./components/Responsive";
|
|
122
123
|
export { CollapsibleSection } from "./components/CollapsibleSection";
|
|
124
|
+
// RecordDetailModal — shared "open one listing row and read it" surface.
|
|
125
|
+
// Backs the 2026-08-21 dead-end-listing sweep; see the component's own
|
|
126
|
+
// header comment and scripts/audit-listing-detail-affordance.mjs.
|
|
127
|
+
export { RecordDetailModal } from "./components/RecordDetailModal";
|
|
@@ -10,9 +10,20 @@ export declare const GCS_HOST = "storage.googleapis.com";
|
|
|
10
10
|
/**
|
|
11
11
|
* Normalise any image URL so it goes through the watermark proxy:
|
|
12
12
|
* - /media/<path> → return as-is (already proxied via Firebase Storage)
|
|
13
|
+
* - blob: / data: URI → return as-is (local-only, never fetchable server-side)
|
|
13
14
|
* - Firebase Storage URL → extract /o/ path → /media/<path>
|
|
15
|
+
* - GCS (storage.googleapis.com) URL → drop the bucket segment → /media/<path>
|
|
14
16
|
* - Any other absolute URL → /api/media/ext?url=<encoded> (ext watermark proxy)
|
|
15
|
-
* - Relative
|
|
17
|
+
* - Relative URI → return as-is
|
|
16
18
|
* - Falsy → undefined
|
|
17
19
|
*/
|
|
18
20
|
export declare function resolveMediaUrl(url: string | null | undefined): string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts the 11-char YouTube video ID from a watch/share/embed URL, or
|
|
23
|
+
* `null` when `url` isn't a recognized YouTube URL. A video field can be
|
|
24
|
+
* sourced via `MediaUploadField`'s "YouTube" tab (see `showYoutube` there),
|
|
25
|
+
* which stores a `youtube.com/watch?v=...` URL — that URL is never a raw
|
|
26
|
+
* playable media file, so every `<video src>` renderer (`MediaVideo`,
|
|
27
|
+
* `ImageLightbox`) must check this first and fall back to an iframe embed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getYouTubeVideoId(url: string | null | undefined): string | null;
|
package/dist/utils/media-url.js
CHANGED
|
@@ -13,9 +13,11 @@ const PROXY_PREFIX = "/media/";
|
|
|
13
13
|
/**
|
|
14
14
|
* Normalise any image URL so it goes through the watermark proxy:
|
|
15
15
|
* - /media/<path> → return as-is (already proxied via Firebase Storage)
|
|
16
|
+
* - blob: / data: URI → return as-is (local-only, never fetchable server-side)
|
|
16
17
|
* - Firebase Storage URL → extract /o/ path → /media/<path>
|
|
18
|
+
* - GCS (storage.googleapis.com) URL → drop the bucket segment → /media/<path>
|
|
17
19
|
* - Any other absolute URL → /api/media/ext?url=<encoded> (ext watermark proxy)
|
|
18
|
-
* - Relative
|
|
20
|
+
* - Relative URI → return as-is
|
|
19
21
|
* - Falsy → undefined
|
|
20
22
|
*/
|
|
21
23
|
export function resolveMediaUrl(url) {
|
|
@@ -23,6 +25,13 @@ export function resolveMediaUrl(url) {
|
|
|
23
25
|
return undefined;
|
|
24
26
|
if (url.startsWith(PROXY_PREFIX))
|
|
25
27
|
return url;
|
|
28
|
+
// A blob:/data: URI is only ever valid in the tab that created it (e.g. a
|
|
29
|
+
// freshly-selected file preview via URL.createObjectURL, or a FileReader
|
|
30
|
+
// data URL fed to a crop modal). Routing it through the external-URL
|
|
31
|
+
// watermark proxy would try to fetch it server-side and 400 — it must be
|
|
32
|
+
// rendered directly instead.
|
|
33
|
+
if (url.startsWith("blob:") || url.startsWith("data:"))
|
|
34
|
+
return url;
|
|
26
35
|
try {
|
|
27
36
|
const parsed = new URL(url);
|
|
28
37
|
if (parsed.hostname.endsWith(FIREBASE_STORAGE_HOST)) {
|
|
@@ -30,6 +39,16 @@ export function resolveMediaUrl(url) {
|
|
|
30
39
|
if (m)
|
|
31
40
|
return `${PROXY_PREFIX}${decodeURIComponent(m[1])}`;
|
|
32
41
|
}
|
|
42
|
+
if (parsed.hostname === GCS_HOST) {
|
|
43
|
+
// Path shape: /<bucket>/<object-path...> — drop the bucket segment,
|
|
44
|
+
// proxy the rest like a Firebase Storage URL (consistent watermarking
|
|
45
|
+
// + caching instead of falling through to the external-URL proxy).
|
|
46
|
+
const parts = parsed.pathname.replace(/^\//, "").split("/");
|
|
47
|
+
if (parts.length > 1) {
|
|
48
|
+
const objectPath = parts.slice(1).join("/");
|
|
49
|
+
return `${PROXY_PREFIX}${decodeURIComponent(objectPath)}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
33
52
|
return MEDIA_ENDPOINTS.EXT_URL(url);
|
|
34
53
|
}
|
|
35
54
|
catch (_err) {
|
|
@@ -37,3 +56,42 @@ export function resolveMediaUrl(url) {
|
|
|
37
56
|
return url;
|
|
38
57
|
}
|
|
39
58
|
}
|
|
59
|
+
const YOUTUBE_HOSTS = new Set([
|
|
60
|
+
"youtube.com",
|
|
61
|
+
"m.youtube.com",
|
|
62
|
+
"youtu.be",
|
|
63
|
+
"youtube-nocookie.com",
|
|
64
|
+
]);
|
|
65
|
+
/**
|
|
66
|
+
* Extracts the 11-char YouTube video ID from a watch/share/embed URL, or
|
|
67
|
+
* `null` when `url` isn't a recognized YouTube URL. A video field can be
|
|
68
|
+
* sourced via `MediaUploadField`'s "YouTube" tab (see `showYoutube` there),
|
|
69
|
+
* which stores a `youtube.com/watch?v=...` URL — that URL is never a raw
|
|
70
|
+
* playable media file, so every `<video src>` renderer (`MediaVideo`,
|
|
71
|
+
* `ImageLightbox`) must check this first and fall back to an iframe embed.
|
|
72
|
+
*/
|
|
73
|
+
export function getYouTubeVideoId(url) {
|
|
74
|
+
if (!url)
|
|
75
|
+
return null;
|
|
76
|
+
try {
|
|
77
|
+
const parsed = new URL(url);
|
|
78
|
+
const host = parsed.hostname.replace(/^www\./, "");
|
|
79
|
+
if (!YOUTUBE_HOSTS.has(host))
|
|
80
|
+
return null;
|
|
81
|
+
if (host === "youtu.be") {
|
|
82
|
+
const id = parsed.pathname.slice(1);
|
|
83
|
+
return /^[\w-]{11}$/.test(id) ? id : null;
|
|
84
|
+
}
|
|
85
|
+
const fromQuery = parsed.searchParams.get("v");
|
|
86
|
+
if (fromQuery && /^[\w-]{11}$/.test(fromQuery))
|
|
87
|
+
return fromQuery;
|
|
88
|
+
const embedMatch = parsed.pathname.match(/\/embed\/([\w-]{11})/);
|
|
89
|
+
if (embedMatch)
|
|
90
|
+
return embedMatch[1];
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
catch (_err) {
|
|
94
|
+
void normalizeError(_err);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -114,17 +114,17 @@ export declare const changePasswordSchema: z.ZodEffects<z.ZodObject<{
|
|
|
114
114
|
currentPassword: z.ZodString;
|
|
115
115
|
newPassword: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
116
116
|
}, "strip", z.ZodTypeAny, {
|
|
117
|
-
currentPassword: string;
|
|
118
117
|
newPassword: string;
|
|
119
|
-
}, {
|
|
120
118
|
currentPassword: string;
|
|
119
|
+
}, {
|
|
121
120
|
newPassword: string;
|
|
122
|
-
}>, {
|
|
123
121
|
currentPassword: string;
|
|
122
|
+
}>, {
|
|
124
123
|
newPassword: string;
|
|
125
|
-
}, {
|
|
126
124
|
currentPassword: string;
|
|
125
|
+
}, {
|
|
127
126
|
newPassword: string;
|
|
127
|
+
currentPassword: string;
|
|
128
128
|
}>;
|
|
129
129
|
export declare const cropDataSchema: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
130
130
|
sourceUrl: z.ZodEffects<z.ZodString, string, string>;
|
package/package.json
CHANGED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
|
-
import type { startClassifiedConversationAction } from "../../../server/features/classified/actions";
|
|
4
|
-
export interface ClassifiedDetailViewProps {
|
|
5
|
-
product: ProductDocument | null;
|
|
6
|
-
isLoading?: boolean;
|
|
7
|
-
onContactSeller: typeof startClassifiedConversationAction;
|
|
8
|
-
}
|
|
9
|
-
export declare function ClassifiedDetailView({ product, isLoading, onContactSeller, }: ClassifiedDetailViewProps): React.JSX.Element;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { normalizeError } from "../../../../errors/normalize";
|
|
4
|
-
import { useState } from "react";
|
|
5
|
-
import Link from "next/link";
|
|
6
|
-
import { Badge, Button, Container, Div, Heading, Row, Section, Stack, Text, } from "../../../../ui";
|
|
7
|
-
import { MediaImage } from "../../../../features/media/MediaImage";
|
|
8
|
-
import { ROUTES } from "../../../../next/routing/route-map";
|
|
9
|
-
import { formatCurrency } from "../../../../utils/number.formatter";
|
|
10
|
-
const __P = {
|
|
11
|
-
p4: "p-[var(--appkit-space-4)]",
|
|
12
|
-
};
|
|
13
|
-
const __O = {
|
|
14
|
-
hidden: "overflow-hidden",
|
|
15
|
-
};
|
|
16
|
-
export function ClassifiedDetailView({ product, isLoading = false, onContactSeller, }) {
|
|
17
|
-
const [pending, setPending] = useState(false);
|
|
18
|
-
const [conversation, setConversation] = useState(null);
|
|
19
|
-
const [error, setError] = useState(null);
|
|
20
|
-
if (isLoading || !product) {
|
|
21
|
-
return (_jsx(Container, { children: _jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { className: "text-muted-foreground", children: isLoading ? "Loading…" : "Classified listing not found." }) }) }));
|
|
22
|
-
}
|
|
23
|
-
const meta = product.classified;
|
|
24
|
-
const price = formatCurrency(product.price, product.currency ?? "INR");
|
|
25
|
-
const location = meta?.meetupArea
|
|
26
|
-
? [meta.meetupArea.locality, meta.meetupArea.city].filter(Boolean).join(", ")
|
|
27
|
-
: null;
|
|
28
|
-
async function handleContactSeller() {
|
|
29
|
-
setPending(true);
|
|
30
|
-
setError(null);
|
|
31
|
-
try {
|
|
32
|
-
const result = await onContactSeller({ productId: product.id });
|
|
33
|
-
// ActionResult envelope — unwrap or surface
|
|
34
|
-
if (result && typeof result === "object" && "ok" in result) {
|
|
35
|
-
if (result.ok) {
|
|
36
|
-
setConversation(result.data);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
setError(result.error);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
setConversation(result);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
void normalizeError(e);
|
|
48
|
-
setError(e instanceof Error ? e.message : "Something went wrong");
|
|
49
|
-
}
|
|
50
|
-
finally {
|
|
51
|
-
setPending(false);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return (_jsx(Container, { children: _jsx(Section, { padding: "y-xl", children: _jsxs(Stack, { gap: "lg", children: [product.images.length > 0 && (_jsx(Div, { className: `relative h-80 w-full ${__O.hidden} bg-muted`, rounded: "lg", children: _jsx(MediaImage, { src: product.mainImage || product.images[0], alt: product.title, size: "hero", objectFit: "contain" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", wrap: true, children: [_jsx(Badge, { variant: "secondary", children: "Classified" }), meta?.negotiable && _jsx(Badge, { variant: "secondary", children: "Negotiable" }), meta?.acceptsShipping && _jsx(Badge, { variant: "secondary", children: "Shipping available" })] }), _jsx(Heading, { level: 1, weight: "bold", size: "2xl", children: product.title }), _jsx(Text, { className: "text-primary", size: "2xl", weight: "semibold", children: price }), location && (_jsx(Text, { className: "text-muted-foreground", size: "sm", children: location })), _jsx(Text, { className: "text-muted-foreground", children: product.description })] }), conversation ? (_jsxs(Div, { className: `border border-border bg-muted/40 ${__P.p4}`, rounded: "lg", children: [_jsx(Text, { className: "mb-2", weight: "medium", children: "Conversation started!" }), _jsx(Link, { href: ROUTES.USER.MESSAGES, className: "text-primary underline underline-offset-2", children: "Go to your messages \u2192" })] })) : (_jsxs(Stack, { gap: "sm", children: [error && (_jsx(Text, { className: "text-destructive", size: "sm", children: error })), _jsx(Button, { type: "button", variant: "primary", size: "lg", isLoading: pending, disabled: pending, onClick: handleContactSeller, className: "w-full", children: "Contact Seller" })] }))] }) }) }));
|
|
55
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
|
-
import type { RevealedCode } from "./CodeRevealPanel";
|
|
4
|
-
export interface DigitalCodeDetailViewProps {
|
|
5
|
-
product: ProductDocument | null;
|
|
6
|
-
isLoading?: boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Set when the buyer has a confirmed order for this product and wants to
|
|
9
|
-
* reveal their code. The page shim wires this from the order context.
|
|
10
|
-
*/
|
|
11
|
-
orderId?: string;
|
|
12
|
-
/**
|
|
13
|
-
* Injected from the page so the panel never hard-codes the API path.
|
|
14
|
-
* Required when orderId is set.
|
|
15
|
-
*/
|
|
16
|
-
fetchCode?: (orderId: string) => Promise<RevealedCode>;
|
|
17
|
-
}
|
|
18
|
-
export declare function DigitalCodeDetailView({ product, isLoading, orderId, fetchCode, }: DigitalCodeDetailViewProps): React.JSX.Element;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Badge, Container, Div, Heading, Row, Section, Stack, Text, } from "../../../../ui";
|
|
4
|
-
import { MediaImage } from "../../../../features/media/MediaImage";
|
|
5
|
-
import { formatCurrency } from "../../../../utils/number.formatter";
|
|
6
|
-
import { CodeRevealPanel } from "./CodeRevealPanel";
|
|
7
|
-
const __P = {
|
|
8
|
-
p4: "p-[var(--appkit-space-4)]",
|
|
9
|
-
};
|
|
10
|
-
const __O = {
|
|
11
|
-
hidden: "overflow-hidden",
|
|
12
|
-
};
|
|
13
|
-
export function DigitalCodeDetailView({ product, isLoading = false, orderId, fetchCode, }) {
|
|
14
|
-
if (isLoading || !product) {
|
|
15
|
-
return (_jsx(Container, { children: _jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { className: "text-muted-foreground", children: isLoading ? "Loading…" : "Digital code listing not found." }) }) }));
|
|
16
|
-
}
|
|
17
|
-
const meta = product.digitalCode;
|
|
18
|
-
const price = formatCurrency(product.price, product.currency ?? "INR");
|
|
19
|
-
const codesLeft = meta?.codesAvailable ?? 0;
|
|
20
|
-
return (_jsx(Container, { children: _jsx(Section, { padding: "y-xl", children: _jsxs(Stack, { gap: "lg", children: [product.images.length > 0 && (_jsx(Div, { className: `relative h-80 w-full ${__O.hidden} bg-muted`, rounded: "lg", children: _jsx(MediaImage, { src: product.mainImage || product.images[0], alt: product.title, size: "hero", objectFit: "contain" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", wrap: true, children: [_jsx(Badge, { variant: "secondary", children: "Digital Code" }), codesLeft > 0 ? (_jsxs(Badge, { variant: "active", children: [codesLeft, " available"] })) : (_jsx(Badge, { variant: "danger", children: "Sold out" }))] }), _jsx(Heading, { level: 1, weight: "bold", size: "2xl", children: product.title }), _jsx(Text, { className: "text-primary", size: "2xl", weight: "semibold", children: price }), _jsx(Text, { className: "text-muted-foreground", children: product.description })] }), orderId && fetchCode ? (_jsx(CodeRevealPanel, { orderId: orderId, redemptionInstructions: meta?.redemptionInstructions, fetchCode: fetchCode })) : (_jsxs(Div, { className: `border border-border bg-muted/40 ${__P.p4}`, rounded: "lg", children: [_jsx(Text, { className: "text-muted-foreground", size: "sm", children: "After purchase, return to your order to reveal the code instantly." }), meta?.redemptionInstructions && (_jsx(Text, { className: "mt-2", size: "sm", children: meta.redemptionInstructions }))] }))] }) }) }));
|
|
21
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import type { ProductDocument } from "../../../../features/products/schemas/firestore";
|
|
3
|
-
export interface LiveItemDetailViewProps {
|
|
4
|
-
product: ProductDocument | null;
|
|
5
|
-
isLoading?: boolean;
|
|
6
|
-
/** Render-prop for the add-to-cart CTA — wired by the page shim. */
|
|
7
|
-
renderActions?: () => React.ReactNode;
|
|
8
|
-
}
|
|
9
|
-
export declare function LiveItemDetailView({ product, isLoading, renderActions, }: LiveItemDetailViewProps): React.JSX.Element;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Badge, Container, Div, Heading, Row, Section, Stack, Text, } from "../../../../ui";
|
|
4
|
-
import { MediaImage } from "../../../../features/media/MediaImage";
|
|
5
|
-
import { formatCurrency } from "../../../../utils/number.formatter";
|
|
6
|
-
const __P = {
|
|
7
|
-
p4: "p-[var(--appkit-space-4)]",
|
|
8
|
-
};
|
|
9
|
-
const __O = {
|
|
10
|
-
hidden: "overflow-hidden",
|
|
11
|
-
};
|
|
12
|
-
const CLS_WARN_BOX = "rounded-lg border border-warning bg-warning-surface p-[var(--appkit-space-4)] text-[length:var(--appkit-text-sm)]";
|
|
13
|
-
const CLS_WARN_TITLE = "font-medium text-warning";
|
|
14
|
-
const CLS_WARN_BODY = "mt-1 text-warning";
|
|
15
|
-
export function LiveItemDetailView({ product, isLoading = false, renderActions, }) {
|
|
16
|
-
if (isLoading || !product) {
|
|
17
|
-
return (_jsx(Container, { children: _jsx(Div, { className: "text-center", padding: "y-4xl", children: _jsx(Text, { className: "text-muted-foreground", children: isLoading ? "Loading…" : "Live listing not found." }) }) }));
|
|
18
|
-
}
|
|
19
|
-
const meta = product.liveItem;
|
|
20
|
-
const price = formatCurrency(product.price, product.currency ?? "INR");
|
|
21
|
-
const jurisdictions = meta?.jurisdictionAllowed ?? [];
|
|
22
|
-
const transport = meta?.transport;
|
|
23
|
-
return (_jsx(Container, { children: _jsx(Section, { padding: "y-xl", children: _jsxs(Stack, { gap: "lg", children: [product.images.length > 0 && (_jsx(Div, { className: `relative h-80 w-full ${__O.hidden} bg-muted`, rounded: "lg", children: _jsx(MediaImage, { src: product.mainImage || product.images[0], alt: product.title, size: "hero", objectFit: "contain" }) })), _jsxs(Stack, { gap: "sm", children: [_jsxs(Row, { gap: "sm", wrap: true, children: [_jsx(Badge, { variant: "secondary", children: "Live Item" }), meta?.vendorVerified && (_jsx(Badge, { variant: "active", children: "Verified Seller" })), meta?.cites && (_jsxs(Badge, { variant: "warning", children: ["CITES: ", meta.cites] }))] }), _jsx(Heading, { level: 1, weight: "bold", size: "2xl", children: product.title }), meta?.species && (_jsxs(Text, { className: "italic text-muted-foreground", size: "sm", children: [meta.species, meta.sex && meta.sex !== "n/a" && ` · ${meta.sex}`, meta.ageMonths !== undefined && ` · ${meta.ageMonths}mo`] })), _jsx(Text, { className: "text-primary", size: "2xl", weight: "semibold", children: price }), _jsx(Text, { className: "text-muted-foreground", children: product.description })] }), jurisdictions.length > 0 && (_jsxs(Div, { className: CLS_WARN_BOX, children: [_jsx(Text, { className: CLS_WARN_TITLE, children: "Delivery restrictions" }), _jsxs(Text, { className: CLS_WARN_BODY, children: ["This item can only be shipped to: ", jurisdictions.join(", ")] })] })), transport && (_jsxs(Div, { textSize: "sm", className: `border border-border bg-muted/40 ${__P.p4}`, rounded: "lg", children: [_jsx(Text, { weight: "medium", children: "Transport" }), _jsxs(Text, { className: "text-muted-foreground", children: ["Method: ", transport.method, transport.handlingFee !== undefined &&
|
|
24
|
-
` · Handling: ${formatCurrency(transport.handlingFee, "INR")}`, transport.insuranceIncluded && " · Insurance included"] })] })), meta?.careInfo && (_jsxs(Div, { textSize: "sm", className: `border border-border bg-muted/40 ${__P.p4}`, rounded: "lg", children: [_jsx(Text, { weight: "medium", children: "Care information" }), _jsx(Text, { className: "mt-1 text-muted-foreground", children: meta.careInfo })] })), renderActions?.()] }) }) }));
|
|
25
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { PRODUCT_FIELDS, COMMON_FIELDS } from "../../../../constants/field-names";
|
|
2
|
-
const PRODUCT_COLLECTION = "products";
|
|
3
|
-
const PRIZE_DRAW_LISTING_TYPE = "prize-draw";
|
|
4
|
-
export async function runPrizeRevealClose(ctx) {
|
|
5
|
-
if (ctx.env("FEATURE_PRIZE_DRAWS") !== "true") {
|
|
6
|
-
ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping prize reveal close");
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
ctx.logger.info("Prize reveal close sweep starting");
|
|
10
|
-
const snap = await ctx.db
|
|
11
|
-
.collection(PRODUCT_COLLECTION)
|
|
12
|
-
.where(PRODUCT_FIELDS.LISTING_TYPE, "==", PRIZE_DRAW_LISTING_TYPE)
|
|
13
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_STATUS, "==", PRODUCT_FIELDS.PRIZE_REVEAL_STATUS_VALUES.OPEN)
|
|
14
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_WINDOW_END, "<=", ctx.now)
|
|
15
|
-
.limit(100)
|
|
16
|
-
.get();
|
|
17
|
-
if (snap.empty) {
|
|
18
|
-
ctx.logger.info("No prize draws to close");
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const batch = ctx.db.batch();
|
|
22
|
-
snap.docs.forEach((doc) => batch.update(doc.ref, {
|
|
23
|
-
[PRODUCT_FIELDS.PRIZE_REVEAL_STATUS]: PRODUCT_FIELDS.PRIZE_REVEAL_STATUS_VALUES.CLOSED,
|
|
24
|
-
[COMMON_FIELDS.UPDATED_AT]: ctx.now,
|
|
25
|
-
}));
|
|
26
|
-
await batch.commit();
|
|
27
|
-
ctx.logger.info("Closed prize draws", { count: snap.size });
|
|
28
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { normalizeError } from "../../../../errors/normalize";
|
|
2
|
-
import { sendNotification } from "../../../../features/admin/actions/notification-actions";
|
|
3
|
-
import { ORDER_FIELDS, PRODUCT_FIELDS, COMMON_FIELDS } from "../../../../constants/field-names";
|
|
4
|
-
const ORDER_COLLECTION = "orders";
|
|
5
|
-
export async function runPrizeRevealExpiry(ctx) {
|
|
6
|
-
if (ctx.env("FEATURE_PRIZE_DRAWS") !== "true") {
|
|
7
|
-
ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping prize reveal expiry");
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
10
|
-
ctx.logger.info("Prize reveal expiry sweep starting");
|
|
11
|
-
const snap = await ctx.db
|
|
12
|
-
.collection(ORDER_COLLECTION)
|
|
13
|
-
.where(ORDER_FIELDS.PAYMENT_STATUS, "==", ORDER_FIELDS.PAYMENT_STATUS_VALUES.PAID)
|
|
14
|
-
.where(ORDER_FIELDS.STATUS, "in", [
|
|
15
|
-
ORDER_FIELDS.STATUS_VALUES.PENDING,
|
|
16
|
-
ORDER_FIELDS.STATUS_VALUES.CONFIRMED,
|
|
17
|
-
ORDER_FIELDS.STATUS_VALUES.PROCESSING,
|
|
18
|
-
])
|
|
19
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_DEADLINE, "<", ctx.now)
|
|
20
|
-
.limit(200)
|
|
21
|
-
.get();
|
|
22
|
-
if (snap.empty) {
|
|
23
|
-
ctx.logger.info("No prize-draw orders past deadline");
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
let refunded = 0;
|
|
27
|
-
for (const doc of snap.docs) {
|
|
28
|
-
const order = doc.data();
|
|
29
|
-
if (order.prizeWon)
|
|
30
|
-
continue;
|
|
31
|
-
if (!order.prizeDrawProductId)
|
|
32
|
-
continue;
|
|
33
|
-
await doc.ref.update({
|
|
34
|
-
[ORDER_FIELDS.STATUS]: ORDER_FIELDS.STATUS_VALUES.REFUNDED,
|
|
35
|
-
[ORDER_FIELDS.PAYMENT_STATUS]: ORDER_FIELDS.PAYMENT_STATUS_VALUES.REFUNDED,
|
|
36
|
-
isNonRefundable: false,
|
|
37
|
-
prizeRevealExpired: true,
|
|
38
|
-
[COMMON_FIELDS.UPDATED_AT]: ctx.now,
|
|
39
|
-
});
|
|
40
|
-
if (order.userId) {
|
|
41
|
-
try {
|
|
42
|
-
await sendNotification({
|
|
43
|
-
userId: order.userId,
|
|
44
|
-
type: "prize_reveal_expired",
|
|
45
|
-
priority: "high",
|
|
46
|
-
title: "Reveal deadline passed — refunded",
|
|
47
|
-
message: `Your entry for "${order.productTitle ?? "the draw"}" expired without a reveal. We've refunded the order.`,
|
|
48
|
-
relatedId: doc.id,
|
|
49
|
-
relatedType: "order",
|
|
50
|
-
actionUrl: `/user/orders/view/${doc.id}`,
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
catch (err) {
|
|
54
|
-
void normalizeError(err);
|
|
55
|
-
ctx.logger.warn("Reveal-expired notification failed", { err: err instanceof Error ? err.message : String(err) });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
refunded++;
|
|
59
|
-
}
|
|
60
|
-
ctx.logger.info("Prize reveal expiry sweep complete", { refunded });
|
|
61
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { normalizeError } from "../../../../errors/normalize";
|
|
2
|
-
import { sendNotification } from "../../../../features/admin/actions/notification-actions";
|
|
3
|
-
import { PRODUCT_FIELDS, ORDER_FIELDS, COMMON_FIELDS } from "../../../../constants/field-names";
|
|
4
|
-
const PRODUCT_COLLECTION = "products";
|
|
5
|
-
const ORDER_COLLECTION = "orders";
|
|
6
|
-
const PRIZE_DRAW_LISTING_TYPE = "prize-draw";
|
|
7
|
-
export async function runPrizeRevealOpen(ctx) {
|
|
8
|
-
if (ctx.env("FEATURE_PRIZE_DRAWS") !== "true") {
|
|
9
|
-
ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping prize reveal open");
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
ctx.logger.info("Prize reveal open sweep starting");
|
|
13
|
-
const snap = await ctx.db
|
|
14
|
-
.collection(PRODUCT_COLLECTION)
|
|
15
|
-
.where(PRODUCT_FIELDS.LISTING_TYPE, "==", PRIZE_DRAW_LISTING_TYPE)
|
|
16
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_STATUS, "==", PRODUCT_FIELDS.PRIZE_REVEAL_STATUS_VALUES.PENDING)
|
|
17
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_WINDOW_START, "<=", ctx.now)
|
|
18
|
-
.limit(100)
|
|
19
|
-
.get();
|
|
20
|
-
if (snap.empty) {
|
|
21
|
-
ctx.logger.info("No prize draws to open");
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
for (const doc of snap.docs) {
|
|
25
|
-
const product = doc.data();
|
|
26
|
-
await doc.ref.update({
|
|
27
|
-
[PRODUCT_FIELDS.PRIZE_REVEAL_STATUS]: PRODUCT_FIELDS.PRIZE_REVEAL_STATUS_VALUES.OPEN,
|
|
28
|
-
[COMMON_FIELDS.UPDATED_AT]: ctx.now,
|
|
29
|
-
});
|
|
30
|
-
const orders = await ctx.db
|
|
31
|
-
.collection(ORDER_COLLECTION)
|
|
32
|
-
.where("prizeDrawProductId", "==", doc.id)
|
|
33
|
-
.where(ORDER_FIELDS.PAYMENT_STATUS, "==", ORDER_FIELDS.PAYMENT_STATUS_VALUES.PAID)
|
|
34
|
-
.where(ORDER_FIELDS.STATUS, "in", [
|
|
35
|
-
ORDER_FIELDS.STATUS_VALUES.PENDING,
|
|
36
|
-
ORDER_FIELDS.STATUS_VALUES.CONFIRMED,
|
|
37
|
-
ORDER_FIELDS.STATUS_VALUES.PROCESSING,
|
|
38
|
-
])
|
|
39
|
-
.get();
|
|
40
|
-
let notified = 0;
|
|
41
|
-
for (const orderDoc of orders.docs) {
|
|
42
|
-
const order = orderDoc.data();
|
|
43
|
-
if (!order.userId || order.prizeWon)
|
|
44
|
-
continue;
|
|
45
|
-
try {
|
|
46
|
-
await sendNotification({
|
|
47
|
-
userId: order.userId,
|
|
48
|
-
type: "prize_reveal_ready",
|
|
49
|
-
priority: "high",
|
|
50
|
-
title: "Your reveal is ready!",
|
|
51
|
-
message: `Reveal your prize for "${product.title ?? "draw"}". You have ${product.prizeRevealDeadlineDays ?? 3} days to claim it.`,
|
|
52
|
-
relatedId: orderDoc.id,
|
|
53
|
-
relatedType: "order",
|
|
54
|
-
actionUrl: `/user/orders/view/${orderDoc.id}`,
|
|
55
|
-
});
|
|
56
|
-
notified++;
|
|
57
|
-
}
|
|
58
|
-
catch (err) {
|
|
59
|
-
void normalizeError(err);
|
|
60
|
-
ctx.logger.warn("Reveal-ready notification failed", { err: err instanceof Error ? err.message : String(err) });
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
ctx.logger.info("Opened prize draw", {
|
|
64
|
-
productId: doc.id,
|
|
65
|
-
buyersNotified: notified,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { normalizeError } from "../../../../errors/normalize";
|
|
2
|
-
import { sendNotification } from "../../../../features/admin/actions/notification-actions";
|
|
3
|
-
import { ORDER_FIELDS, PRODUCT_FIELDS } from "../../../../constants/field-names";
|
|
4
|
-
const ORDER_COLLECTION = "orders";
|
|
5
|
-
const ONE_DAY_MS = 86400000;
|
|
6
|
-
export async function runPrizeRevealReminder(ctx) {
|
|
7
|
-
if (ctx.env("FEATURE_PRIZE_DRAWS") !== "true") {
|
|
8
|
-
ctx.logger.info("FEATURE_PRIZE_DRAWS disabled — skipping prize reveal reminder");
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
ctx.logger.info("Prize reveal reminder sweep starting");
|
|
12
|
-
const cutoff = new Date(ctx.now.getTime() + ONE_DAY_MS);
|
|
13
|
-
const snap = await ctx.db
|
|
14
|
-
.collection(ORDER_COLLECTION)
|
|
15
|
-
.where(ORDER_FIELDS.PAYMENT_STATUS, "==", ORDER_FIELDS.PAYMENT_STATUS_VALUES.PAID)
|
|
16
|
-
.where(ORDER_FIELDS.STATUS, "in", [
|
|
17
|
-
ORDER_FIELDS.STATUS_VALUES.PENDING,
|
|
18
|
-
ORDER_FIELDS.STATUS_VALUES.CONFIRMED,
|
|
19
|
-
ORDER_FIELDS.STATUS_VALUES.PROCESSING,
|
|
20
|
-
])
|
|
21
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_DEADLINE, "<=", cutoff)
|
|
22
|
-
.where(PRODUCT_FIELDS.PRIZE_REVEAL_DEADLINE, ">", ctx.now)
|
|
23
|
-
.limit(500)
|
|
24
|
-
.get();
|
|
25
|
-
let notified = 0;
|
|
26
|
-
for (const doc of snap.docs) {
|
|
27
|
-
const order = doc.data();
|
|
28
|
-
if (!order.userId || order.prizeWon || !order.prizeDrawProductId)
|
|
29
|
-
continue;
|
|
30
|
-
try {
|
|
31
|
-
await sendNotification({
|
|
32
|
-
userId: order.userId,
|
|
33
|
-
type: "prize_reveal_reminder",
|
|
34
|
-
priority: "normal",
|
|
35
|
-
title: "Reveal expires within 24h",
|
|
36
|
-
message: `Reveal your prize for "${order.productTitle ?? "the draw"}" today — unclaimed reveals are auto-refunded after the deadline.`,
|
|
37
|
-
relatedId: doc.id,
|
|
38
|
-
relatedType: "order",
|
|
39
|
-
actionUrl: `/user/orders/view/${doc.id}`,
|
|
40
|
-
});
|
|
41
|
-
notified++;
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
void normalizeError(err);
|
|
45
|
-
ctx.logger.warn("Reveal reminder notification failed", { err: err instanceof Error ? err.message : String(err) });
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
ctx.logger.info("Prize reveal reminder sweep complete", { notified });
|
|
49
|
-
}
|