@mohasinac/appkit 4.10.0 → 4.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_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/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/grouped/data.d.ts +4 -0
- package/dist/_internal/server/features/grouped/data.js +24 -0
- 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 +2 -2
- package/dist/_internal/server/features/products/data.js +5 -23
- 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/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/features/products/to-product-item.d.ts +25 -0
- package/dist/_internal/shared/features/products/to-product-item.js +45 -0
- package/dist/client.d.ts +21 -6
- package/dist/client.js +13 -3
- package/dist/constants/api-endpoints.d.ts +6 -9
- package/dist/constants/api-endpoints.js +2 -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 +20 -1
- 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 +12 -0
- package/dist/features/analytics/types.d.ts +1 -1
- package/dist/features/analytics/types.js +8 -0
- 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/categories/components/BrandDetailPageView.js +14 -12
- 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/contact/components/ContactForm.js +17 -4
- package/dist/features/contact/email.d.ts +1 -0
- package/dist/features/contact/email.js +3 -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.js +4 -1
- package/dist/features/grouped/repository/grouped-listings.repository.d.ts +4 -0
- package/dist/features/grouped/repository/grouped-listings.repository.js +18 -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/TitleBarLayout.d.ts +1 -1
- package/dist/features/layout/TitleBarLayout.js +3 -3
- package/dist/features/media/MediaImage.js +39 -3
- 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/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 +1 -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/ProductGrid.js +15 -1
- 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 +89 -36
- 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 +404 -15
- package/dist/index.d.ts +15 -3
- package/dist/index.js +22 -5
- package/dist/next/routing/route-map.d.ts +11 -0
- package/dist/next/routing/route-map.js +5 -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/categories-seed-data.js +69 -0
- package/dist/seed/products-auctions-seed-data.js +11 -0
- package/dist/seed/products-standard-seed-data.js +93 -4
- package/dist/seed/site-settings-seed-data.js +13 -1
- package/dist/seed/store-extensions-seed-data.js +1 -1
- package/dist/server-entry.d.ts +2 -1
- package/dist/server-entry.js +20 -2
- package/dist/server.d.ts +7 -2
- package/dist/server.js +8 -3
- package/dist/styles.css +1 -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/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 +3 -1
- package/dist/utils/media-url.js +20 -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
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
4
4
|
import { Check } from "lucide-react";
|
|
5
5
|
import { Button } from "../../ui/components/Button";
|
|
6
6
|
import { classNames } from "../../ui/style.helper";
|
|
7
7
|
import { Div, Nav, Row, Span, Stack, Text, useToast } from "../../ui";
|
|
8
8
|
import { normalizeError } from "../../errors/normalize";
|
|
9
|
+
import { FormSchemaContext } from "./FormShell";
|
|
9
10
|
/** Standalone step nav bar — use as `renderBottomBar` in FormShell. */
|
|
10
11
|
export function StepFormActions({ currentStep, totalSteps, onNext, onPrev, completeLabel = "Publish Now", isLoading = false, disabled = false, }) {
|
|
11
12
|
const isFirst = currentStep === 0;
|
|
@@ -34,10 +35,52 @@ export function StepIndicator({ steps, currentStep, onStepClick, stepErrors, })
|
|
|
34
35
|
: "bg-[var(--appkit-color-border)]") }))] }, i));
|
|
35
36
|
}) }));
|
|
36
37
|
}
|
|
37
|
-
export function StepForm({ steps, values, onChange, onComplete, completeLabel = "Publish Now", isLoading = false, formId, currentStep, onStepChange, hideActions = false, stepErrors, }) {
|
|
38
|
+
export function StepForm({ steps, values, onChange, onComplete, completeLabel = "Publish Now", isLoading = false, formId, currentStep, onStepChange, hideActions = false, stepErrors, schema, onValidationChange, }) {
|
|
38
39
|
const { showToast } = useToast();
|
|
39
|
-
const
|
|
40
|
+
const inheritedSchema = useContext(FormSchemaContext);
|
|
41
|
+
const [fieldErrors, setFieldErrors] = useState({});
|
|
40
42
|
const [stepError, setStepError] = useState(null);
|
|
43
|
+
const fieldToStepIndex = useMemo(() => {
|
|
44
|
+
const map = {};
|
|
45
|
+
steps.forEach((step, i) => {
|
|
46
|
+
step.fields?.forEach((field) => { map[field] = i; });
|
|
47
|
+
});
|
|
48
|
+
return map;
|
|
49
|
+
}, [steps]);
|
|
50
|
+
const runValidation = useCallback((nextValues) => {
|
|
51
|
+
const activeSchema = steps[currentStep]?.schema ?? schema ?? inheritedSchema;
|
|
52
|
+
if (!activeSchema)
|
|
53
|
+
return;
|
|
54
|
+
// audit-unvalidated-safeparse-ok: bulk-replaces fieldErrors from the full
|
|
55
|
+
// parse result (clears fields that just became valid); applyZodIssues'
|
|
56
|
+
// incremental setFieldError-per-issue can't do that.
|
|
57
|
+
const parsed = activeSchema.safeParse(nextValues);
|
|
58
|
+
if (parsed.success) {
|
|
59
|
+
setFieldErrors({});
|
|
60
|
+
onValidationChange?.({}, fieldToStepIndex);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const next = {};
|
|
64
|
+
for (const issue of parsed.error.issues) {
|
|
65
|
+
if (!issue.path || issue.path.length === 0)
|
|
66
|
+
continue;
|
|
67
|
+
next[issue.path.map(String).join(".")] = issue.message;
|
|
68
|
+
}
|
|
69
|
+
setFieldErrors(next);
|
|
70
|
+
onValidationChange?.(next, fieldToStepIndex);
|
|
71
|
+
}, [steps, currentStep, schema, inheritedSchema, fieldToStepIndex, onValidationChange]);
|
|
72
|
+
// Re-run validation whenever the active step or schema changes, so
|
|
73
|
+
// switching steps (or arriving with pre-filled values) shows accurate
|
|
74
|
+
// live errors immediately rather than only after the next keystroke.
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
runValidation(values);
|
|
77
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
78
|
+
}, [currentStep, steps[currentStep]?.schema, schema, inheritedSchema]);
|
|
79
|
+
const handleFieldChange = useCallback((partial) => {
|
|
80
|
+
const merged = { ...values, ...partial };
|
|
81
|
+
onChange(partial);
|
|
82
|
+
runValidation(merged);
|
|
83
|
+
}, [values, onChange, runValidation]);
|
|
41
84
|
// Persist step to localStorage if formId provided
|
|
42
85
|
useEffect(() => {
|
|
43
86
|
if (formId)
|
|
@@ -89,5 +132,5 @@ export function StepForm({ steps, values, onChange, onComplete, completeLabel =
|
|
|
89
132
|
return (_jsxs(Stack, { children: [_jsx(StepIndicator, { steps: steps, currentStep: currentStep, stepErrors: stepErrors, onStepClick: (i) => { if (i !== currentStep) {
|
|
90
133
|
setStepError(null);
|
|
91
134
|
onStepChange(i);
|
|
92
|
-
} } }), _jsx(Div, { className: "flex-1", children: currentStepDef?.render({ values, onChange, errors: fieldErrors }) }), !hideActions && stepError && (_jsx(Text, { className: "mt-3 text-[var(--appkit-color-error)]", size: "sm", children: stepError })), !hideActions && (_jsx(StepFormActions, { currentStep: currentStep, totalSteps: steps.length, onNext: () => void goNext(), onPrev: currentStep > 0 ? goPrev : undefined, completeLabel: completeLabel, isLoading: isLoading && isLast, disabled: isLoading }))] }));
|
|
135
|
+
} } }), _jsx(Div, { className: "flex-1", children: currentStepDef?.render({ values, onChange: handleFieldChange, errors: fieldErrors }) }), !hideActions && stepError && (_jsx(Text, { className: "mt-3 text-[var(--appkit-color-error)]", size: "sm", children: stepError })), !hideActions && (_jsx(StepFormActions, { currentStep: currentStep, totalSteps: steps.length, onNext: () => void goNext(), onPrev: currentStep > 0 ? goPrev : undefined, completeLabel: completeLabel, isLoading: isLoading && isLast, disabled: isLoading }))] }));
|
|
93
136
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { FormShellSection, FormShellProps, UseFormShellResult } from "./FormShell";
|
|
2
|
-
export { FormShell, useFormShell } from "./FormShell";
|
|
2
|
+
export { FormShell, useFormShell, FormSchemaContext } from "./FormShell";
|
|
3
3
|
export type { CommandPaletteGroup, CommandPaletteProps } from "./CommandPalette";
|
|
4
4
|
export { CommandPalette, useCommandPaletteHotkey } from "./CommandPalette";
|
|
5
5
|
export type { QuickFieldType, QuickFieldDef, QuickFormDrawerProps } from "./QuickFormDrawer";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { FormShell, useFormShell } from "./FormShell";
|
|
1
|
+
export { FormShell, useFormShell, FormSchemaContext } from "./FormShell";
|
|
2
2
|
export { CommandPalette, useCommandPaletteHotkey } from "./CommandPalette";
|
|
3
3
|
export { QuickFormDrawer } from "./QuickFormDrawer";
|
|
4
4
|
export { StepForm, StepFormActions, StepIndicator } from "./StepForm";
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useQueryClient } from "@tanstack/react-query";
|
|
5
5
|
import { useApiMutation } from "@mohasinac/appkit/client";
|
|
6
|
-
import { Alert, Button, Div, Form, FieldInput, FieldSelect, FieldTextarea, Grid, Heading, Stack, Table, Thead, Tbody, Tr, Th, Td, Text, TextLink, } from "../../../ui";
|
|
6
|
+
import { Alert, Button, Div, Form, FieldInput, FieldSelect, FieldTextarea, Grid, Heading, Stack, Table, Thead, Tbody, Tr, Th, Td, Text, TextLink, FormErrorSummary, } from "../../../ui";
|
|
7
7
|
import { apiClient } from "../../../http";
|
|
8
8
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
9
|
import { ROUTES } from "../../../next/routing/route-map";
|
|
@@ -77,7 +77,7 @@ export function AdminShipmentEditorView({ shipmentId, onSaved }) {
|
|
|
77
77
|
onSaved?.(saved.id);
|
|
78
78
|
},
|
|
79
79
|
});
|
|
80
|
-
return (_jsx(Form, { schema: createShipmentSchema, spacing: "md", children: ({ setFieldError }) => (_jsxs(_Fragment, { children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(FieldInput, { name: "shipmentNumber", label: "Shipment Number", required: true, value: shipmentNumber, onChange: setShipmentNumber, placeholder: "SH-2026-0001" }), _jsx(FieldInput, { name: "supplierName", label: "Supplier Name", required: true, value: supplierName, onChange: setSupplierName }), _jsx(FieldInput, { name: "originCountry", label: "Origin Country", value: originCountry, onChange: setOriginCountry }), _jsx(FieldSelect, { name: "status", label: "Status", required: true, value: status, onChange: setStatus, options: STATUS_OPTIONS }), _jsx(FieldInput, { name: "trackingNumber", label: "Tracking Number", value: trackingNumber, onChange: setTrackingNumber }), _jsx(FieldInput, { name: "carrier", label: "Carrier", value: carrier, onChange: setCarrier }), _jsx(FieldInput, { name: "etaDate", label: "ETA Date", type: "date", value: etaDate, onChange: setEtaDate }), _jsx(FieldInput, { name: "laborHoursSpent", label: "Labor Hours Spent", type: "number", min: "0", value: laborHoursSpent, onChange: setLaborHoursSpent }), _jsx(FieldInput, { name: "customsTotal", label: "Customs Total (\u20B9)", type: "number", min: "0", value: customsTotalRupees, onChange: setCustomsTotalRupees, hint: "Split across lots by declared value" }), _jsx(FieldInput, { name: "shippingTotal", label: "Shipping Total (\u20B9)", type: "number", min: "0", value: shippingTotalRupees, onChange: setShippingTotalRupees, hint: "Split across lots by weight" })] }), _jsx(FieldTextarea, { name: "notes", label: "Notes", value: notes, onChange: setNotes, rows: 3 }), _jsx(Button, { type: "button", isLoading: saveMutation.isPending, onClick: () => {
|
|
80
|
+
return (_jsx(Form, { schema: createShipmentSchema, spacing: "md", children: ({ setFieldError }) => (_jsxs(_Fragment, { children: [_jsxs(Grid, { cols: 2, gap: "md", children: [_jsx(FieldInput, { name: "shipmentNumber", label: "Shipment Number", required: true, value: shipmentNumber, onChange: setShipmentNumber, placeholder: "SH-2026-0001" }), _jsx(FieldInput, { name: "supplierName", label: "Supplier Name", required: true, value: supplierName, onChange: setSupplierName }), _jsx(FieldInput, { name: "originCountry", label: "Origin Country", value: originCountry, onChange: setOriginCountry }), _jsx(FieldSelect, { name: "status", label: "Status", required: true, value: status, onChange: setStatus, options: STATUS_OPTIONS }), _jsx(FieldInput, { name: "trackingNumber", label: "Tracking Number", value: trackingNumber, onChange: setTrackingNumber }), _jsx(FieldInput, { name: "carrier", label: "Carrier", value: carrier, onChange: setCarrier }), _jsx(FieldInput, { name: "etaDate", label: "ETA Date", type: "date", value: etaDate, onChange: setEtaDate }), _jsx(FieldInput, { name: "laborHoursSpent", label: "Labor Hours Spent", type: "number", min: "0", value: laborHoursSpent, onChange: setLaborHoursSpent }), _jsx(FieldInput, { name: "customsTotal", label: "Customs Total (\u20B9)", type: "number", min: "0", value: customsTotalRupees, onChange: setCustomsTotalRupees, hint: "Split across lots by declared value" }), _jsx(FieldInput, { name: "shippingTotal", label: "Shipping Total (\u20B9)", type: "number", min: "0", value: shippingTotalRupees, onChange: setShippingTotalRupees, hint: "Split across lots by weight" })] }), _jsx(FieldTextarea, { name: "notes", label: "Notes", value: notes, onChange: setNotes, rows: 3 }), _jsx(FormErrorSummary, {}), _jsx(Button, { type: "button", isLoading: saveMutation.isPending, onClick: () => {
|
|
81
81
|
const parsed = createShipmentSchema.safeParse({
|
|
82
82
|
shipmentNumber,
|
|
83
83
|
supplierName,
|
|
@@ -22,9 +22,9 @@ export declare const createShipmentSchema: z.ZodObject<{
|
|
|
22
22
|
shippingTotal: number;
|
|
23
23
|
notes?: string | undefined;
|
|
24
24
|
trackingNumber?: string | undefined;
|
|
25
|
+
carrier?: string | undefined;
|
|
25
26
|
etaDate?: string | Date | undefined;
|
|
26
27
|
originCountry?: string | undefined;
|
|
27
|
-
carrier?: string | undefined;
|
|
28
28
|
receivedDate?: string | Date | undefined;
|
|
29
29
|
laborHoursSpent?: number | undefined;
|
|
30
30
|
laborRatePerHour?: number | undefined;
|
|
@@ -36,9 +36,9 @@ export declare const createShipmentSchema: z.ZodObject<{
|
|
|
36
36
|
shippingTotal: number;
|
|
37
37
|
notes?: string | undefined;
|
|
38
38
|
trackingNumber?: string | undefined;
|
|
39
|
+
carrier?: string | undefined;
|
|
39
40
|
etaDate?: string | Date | undefined;
|
|
40
41
|
originCountry?: string | undefined;
|
|
41
|
-
carrier?: string | undefined;
|
|
42
42
|
receivedDate?: string | Date | undefined;
|
|
43
43
|
laborHoursSpent?: number | undefined;
|
|
44
44
|
laborRatePerHour?: number | undefined;
|
|
@@ -61,11 +61,11 @@ export declare const updateShipmentSchema: z.ZodObject<{
|
|
|
61
61
|
status?: "received" | "cancelled" | "processing" | "completed" | "ordered" | "planning" | "in_transit" | "customs" | undefined;
|
|
62
62
|
notes?: string | undefined;
|
|
63
63
|
trackingNumber?: string | undefined;
|
|
64
|
+
carrier?: string | undefined;
|
|
64
65
|
shipmentNumber?: string | undefined;
|
|
65
66
|
etaDate?: string | Date | undefined;
|
|
66
67
|
supplierName?: string | undefined;
|
|
67
68
|
originCountry?: string | undefined;
|
|
68
|
-
carrier?: string | undefined;
|
|
69
69
|
receivedDate?: string | Date | undefined;
|
|
70
70
|
customsTotal?: number | undefined;
|
|
71
71
|
shippingTotal?: number | undefined;
|
|
@@ -75,11 +75,11 @@ export declare const updateShipmentSchema: z.ZodObject<{
|
|
|
75
75
|
status?: "received" | "cancelled" | "processing" | "completed" | "ordered" | "planning" | "in_transit" | "customs" | undefined;
|
|
76
76
|
notes?: string | undefined;
|
|
77
77
|
trackingNumber?: string | undefined;
|
|
78
|
+
carrier?: string | undefined;
|
|
78
79
|
shipmentNumber?: string | undefined;
|
|
79
80
|
etaDate?: string | Date | undefined;
|
|
80
81
|
supplierName?: string | undefined;
|
|
81
82
|
originCountry?: string | undefined;
|
|
82
|
-
carrier?: string | undefined;
|
|
83
83
|
receivedDate?: string | Date | undefined;
|
|
84
84
|
customsTotal?: number | undefined;
|
|
85
85
|
shippingTotal?: number | undefined;
|
|
@@ -98,6 +98,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
|
|
|
98
98
|
thumbnailUrl: z.ZodOptional<z.ZodString>;
|
|
99
99
|
source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
|
|
100
100
|
youtubeId: z.ZodOptional<z.ZodString>;
|
|
101
|
+
duration: z.ZodOptional<z.ZodNumber>;
|
|
101
102
|
}, "strip", z.ZodTypeAny, {
|
|
102
103
|
type: "video" | "image" | "file";
|
|
103
104
|
url: string;
|
|
@@ -105,6 +106,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
|
|
|
105
106
|
alt?: string | undefined;
|
|
106
107
|
thumbnailUrl?: string | undefined;
|
|
107
108
|
youtubeId?: string | undefined;
|
|
109
|
+
duration?: number | undefined;
|
|
108
110
|
}, {
|
|
109
111
|
type: "video" | "image" | "file";
|
|
110
112
|
url: string;
|
|
@@ -112,6 +114,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
|
|
|
112
114
|
alt?: string | undefined;
|
|
113
115
|
thumbnailUrl?: string | undefined;
|
|
114
116
|
youtubeId?: string | undefined;
|
|
117
|
+
duration?: number | undefined;
|
|
115
118
|
}>, "many">>>;
|
|
116
119
|
remainderItemCount: z.ZodOptional<z.ZodNumber>;
|
|
117
120
|
remainderEstimatedValue: z.ZodOptional<z.ZodNumber>;
|
|
@@ -123,6 +126,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
|
|
|
123
126
|
alt?: string | undefined;
|
|
124
127
|
thumbnailUrl?: string | undefined;
|
|
125
128
|
youtubeId?: string | undefined;
|
|
129
|
+
duration?: number | undefined;
|
|
126
130
|
}[];
|
|
127
131
|
lotName: string;
|
|
128
132
|
weightGrams: number;
|
|
@@ -141,6 +145,7 @@ export declare const createShipmentLotSchema: z.ZodObject<{
|
|
|
141
145
|
alt?: string | undefined;
|
|
142
146
|
thumbnailUrl?: string | undefined;
|
|
143
147
|
youtubeId?: string | undefined;
|
|
148
|
+
duration?: number | undefined;
|
|
144
149
|
}[] | undefined;
|
|
145
150
|
supplierOrderRef?: string | undefined;
|
|
146
151
|
remainderItemCount?: number | undefined;
|
|
@@ -158,6 +163,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
|
|
|
158
163
|
thumbnailUrl: z.ZodOptional<z.ZodString>;
|
|
159
164
|
source: z.ZodOptional<z.ZodEnum<["upload", "youtube", "external"]>>;
|
|
160
165
|
youtubeId: z.ZodOptional<z.ZodString>;
|
|
166
|
+
duration: z.ZodOptional<z.ZodNumber>;
|
|
161
167
|
}, "strip", z.ZodTypeAny, {
|
|
162
168
|
type: "video" | "image" | "file";
|
|
163
169
|
url: string;
|
|
@@ -165,6 +171,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
|
|
|
165
171
|
alt?: string | undefined;
|
|
166
172
|
thumbnailUrl?: string | undefined;
|
|
167
173
|
youtubeId?: string | undefined;
|
|
174
|
+
duration?: number | undefined;
|
|
168
175
|
}, {
|
|
169
176
|
type: "video" | "image" | "file";
|
|
170
177
|
url: string;
|
|
@@ -172,6 +179,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
|
|
|
172
179
|
alt?: string | undefined;
|
|
173
180
|
thumbnailUrl?: string | undefined;
|
|
174
181
|
youtubeId?: string | undefined;
|
|
182
|
+
duration?: number | undefined;
|
|
175
183
|
}>, "many">>>>;
|
|
176
184
|
remainderItemCount: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
177
185
|
remainderEstimatedValue: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
|
|
@@ -183,6 +191,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
|
|
|
183
191
|
alt?: string | undefined;
|
|
184
192
|
thumbnailUrl?: string | undefined;
|
|
185
193
|
youtubeId?: string | undefined;
|
|
194
|
+
duration?: number | undefined;
|
|
186
195
|
}[] | undefined;
|
|
187
196
|
lotName?: string | undefined;
|
|
188
197
|
supplierOrderRef?: string | undefined;
|
|
@@ -198,6 +207,7 @@ export declare const updateShipmentLotSchema: z.ZodObject<{
|
|
|
198
207
|
alt?: string | undefined;
|
|
199
208
|
thumbnailUrl?: string | undefined;
|
|
200
209
|
youtubeId?: string | undefined;
|
|
210
|
+
duration?: number | undefined;
|
|
201
211
|
}[] | undefined;
|
|
202
212
|
lotName?: string | undefined;
|
|
203
213
|
supplierOrderRef?: string | undefined;
|
|
@@ -4,8 +4,9 @@ import { useApiMutation } from "../../../client";
|
|
|
4
4
|
import { SIEVE_OP, sieveFilter } from "../../../utils/sieve-builder";
|
|
5
5
|
import { sortBy } from "../../../constants/sort";
|
|
6
6
|
import { TESTER_CHECKLIST_RESPONSE_FIELDS } from "../schemas/firestore";
|
|
7
|
+
import React from "react";
|
|
7
8
|
import { useQueryClient } from "@tanstack/react-query";
|
|
8
|
-
import { FilterChipGroup, RowActionMenu, Stack, Text } from "../../../ui";
|
|
9
|
+
import { FilterChipGroup, RecordDetailModal, RowActionMenu, Stack, Text } from "../../../ui";
|
|
9
10
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
10
11
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
11
12
|
import { toRecordArray, toRelativeDate, toStringValue, } from "../../admin/hooks/useAdminListingData";
|
|
@@ -39,6 +40,7 @@ const COLUMNS = [
|
|
|
39
40
|
];
|
|
40
41
|
export function AdminTesterFeedbackListView(_props) {
|
|
41
42
|
const queryClient = useQueryClient();
|
|
43
|
+
const [selected, setSelected] = React.useState(null);
|
|
42
44
|
const patchMutation = useApiMutation({
|
|
43
45
|
mutationFn: async (id) => {
|
|
44
46
|
await apiClient.patch(ADMIN_ENDPOINTS.TESTER_FEEDBACK_BY_ID(id), {});
|
|
@@ -78,6 +80,7 @@ export function AdminTesterFeedbackListView(_props) {
|
|
|
78
80
|
status: toStringValue(item.status, "new"),
|
|
79
81
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
80
82
|
screenshotUrl: item.screenshotUrl ? toStringValue(item.screenshotUrl, "") : undefined,
|
|
83
|
+
_raw: item,
|
|
81
84
|
})),
|
|
82
85
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
83
86
|
buildFilters: (state) => {
|
|
@@ -97,7 +100,14 @@ export function AdminTesterFeedbackListView(_props) {
|
|
|
97
100
|
{ id: "new", label: "New" },
|
|
98
101
|
{ id: "reviewed", label: "Reviewed" },
|
|
99
102
|
], value: pendingFilters.status || "", onChange: (v) => setPendingFilters((p) => ({ ...p, status: v })) })] })),
|
|
103
|
+
// "Confirm bug" used to be reachable without ever reading the tester's
|
|
104
|
+
// own comment or opening their screenshot — the row truncates both.
|
|
105
|
+
onRowClick: (row) => setSelected(row),
|
|
100
106
|
renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
107
|
+
{
|
|
108
|
+
label: "View details",
|
|
109
|
+
onClick: () => setSelected(row),
|
|
110
|
+
},
|
|
101
111
|
{
|
|
102
112
|
label: ACTIONS.ADMIN["mark-feedback-reviewed"].label,
|
|
103
113
|
disabled: row.status === "reviewed",
|
|
@@ -110,5 +120,16 @@ export function AdminTesterFeedbackListView(_props) {
|
|
|
110
120
|
},
|
|
111
121
|
] })),
|
|
112
122
|
};
|
|
113
|
-
|
|
123
|
+
const raw = selected?._raw ?? {};
|
|
124
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(RecordDetailModal, { isOpen: Boolean(selected), onClose: () => setSelected(null), title: selected?.primary ?? "Tester Feedback", badges: [
|
|
125
|
+
{ label: selected?.answer === "no" ? "Reported a problem" : "Passed", variant: selected?.answer === "no" ? "danger" : "success" },
|
|
126
|
+
{ label: selected?.status ?? "new", variant: "default" },
|
|
127
|
+
], description: toStringValue(raw.comment, "") || undefined, fields: [
|
|
128
|
+
{ label: "Checklist item", value: toStringValue(raw.checklistItemId, "—") },
|
|
129
|
+
{ label: "Phase", value: toStringValue(raw.phase, "—") },
|
|
130
|
+
{ label: "Group / page", value: `${toStringValue(raw.groupKey, "—")} / ${toStringValue(raw.pageKey, "—")}` },
|
|
131
|
+
{ label: "Answered", value: selected?.updatedAt ?? "—" },
|
|
132
|
+
], items: selected?.screenshotUrl
|
|
133
|
+
? { heading: "Screenshot", entries: [{ image: selected.screenshotUrl, title: "Tester screenshot" }] }
|
|
134
|
+
: undefined })] }));
|
|
114
135
|
}
|
|
@@ -25,5 +25,5 @@ export function TesterChecklistStepRow({ item, testerDisplayName, onAnswer, onSa
|
|
|
25
25
|
setSaving(false);
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
|
-
return (_jsxs(Stack, { gap: "xs", padding: "sm", border: "default", rounded: "md", children: [_jsxs(Row, { gap: "sm", justify: "between", align: "center", wrap: true, children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { weight: "medium", children: item.label }), item.description && (_jsx(Text, { size: "xs", color: "muted", children: item.description })), item.href && (_jsx(Anchor, { href: item.href, tone: "brand", underline: "hover", children: "Go test this \u2192" }))] }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { type: "button", size: "sm", variant: item.answer === "yes" ? "primary" : "outline", onClick: () => onAnswer(item.checklistItemId, "yes"), children: "Yes" }), _jsx(Button, { type: "button", size: "sm", variant: item.answer === "no" ? "danger" : "outline", onClick: () => onAnswer(item.checklistItemId, "no"), children: "No" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setExpanded((v) => !v), children: expanded ? "Hide note" : "Add note" })] })] }), expanded && (_jsx(Div, { padding: "t-sm", border: "default", className: "border-t", children: _jsxs(Stack, { gap: "sm", children: [_jsx(FieldTextarea, { name: `comment-${item.checklistItemId}`, label: "Comment", value: comment, onChange: setComment, placeholder: "What did you notice? Colors, styles, readability, bugs..." }), _jsx(MediaUploadField, { label: "Screenshot (optional)", value: screenshotUrl, onChange: setScreenshotUrl, onUpload: handleUpload, kind: "image" }), _jsx(Row, { children: _jsx(Button, { type: "button", action: ACTIONS.TESTER["save-note"], isLoading: saving, onClick: handleSave }) })] }) }))] }));
|
|
28
|
+
return (_jsxs(Stack, { gap: "xs", padding: "sm", border: "default", rounded: "md", children: [_jsxs(Row, { gap: "sm", justify: "between", align: "center", wrap: true, children: [_jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { weight: "medium", children: item.label }), item.description && (_jsx(Text, { size: "xs", color: "muted", children: item.description })), item.href && (_jsx(Anchor, { href: item.href, tone: "brand", underline: "hover", target: "_blank", rel: "noopener noreferrer", children: "Go test this \u2192" }))] }), _jsxs(Row, { gap: "xs", children: [_jsx(Button, { type: "button", size: "sm", variant: item.answer === "yes" ? "primary" : "outline", onClick: () => onAnswer(item.checklistItemId, "yes"), children: "Yes" }), _jsx(Button, { type: "button", size: "sm", variant: item.answer === "no" ? "danger" : "outline", onClick: () => onAnswer(item.checklistItemId, "no"), children: "No" }), _jsx(Button, { type: "button", size: "sm", variant: "ghost", onClick: () => setExpanded((v) => !v), children: expanded ? "Hide note" : "Add note" })] })] }), expanded && (_jsx(Div, { padding: "t-sm", border: "default", className: "border-t", children: _jsxs(Stack, { gap: "sm", children: [_jsx(FieldTextarea, { name: `comment-${item.checklistItemId}`, label: "Comment", value: comment, onChange: setComment, placeholder: "What did you notice? Colors, styles, readability, bugs..." }), _jsx(MediaUploadField, { label: "Screenshot (optional)", value: screenshotUrl, onChange: setScreenshotUrl, onUpload: handleUpload, kind: "image" }), _jsx(Row, { children: _jsx(Button, { type: "button", action: ACTIONS.TESTER["save-note"], isLoading: saving, onClick: handleSave }) })] }) }))] }));
|
|
29
29
|
}
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
|
-
import { Alert, Details, Div, FieldInput, Heading, Stack, Summary, Text } from "../../../ui";
|
|
5
|
+
import { Alert, Details, Div, FieldInput, Heading, Stack, Summary, Text, TextLink } from "../../../ui";
|
|
6
6
|
import { apiClient } from "../../../http";
|
|
7
7
|
import { useApiMutation } from "../../../client";
|
|
8
8
|
import { useSession } from "../../../react";
|
|
9
9
|
import { ACCOUNT_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
10
|
+
import { ROUTES } from "../../../next/routing/route-map";
|
|
10
11
|
import { TesterChecklistStepRow } from "./TesterChecklistStepRow";
|
|
11
12
|
function matchesQuery(item, query) {
|
|
12
13
|
if (!query)
|
|
@@ -88,7 +89,7 @@ export function TesterHubView({ sandboxExpiresAt }) {
|
|
|
88
89
|
const handleSaveNote = async (checklistItemId, comment, screenshotUrl) => {
|
|
89
90
|
await upsertMutation.mutateAsync({ checklistItemId, patch: { comment, screenshotUrl } });
|
|
90
91
|
};
|
|
91
|
-
return (_jsxs(Stack, { gap: "lg", children: [_jsx(Heading, { level: 1, children: "Tester Hub" }), _jsx(Text, { color: "muted", children: "Work through the checklist below and answer Yes/No for each test case. Add a comment and screenshot wherever something looks off \u2014 colors, styles, readability, bugs. Your answers save automatically." }), sandboxExpiresAt && (_jsxs(Alert, { variant: "info", title: "Shared test sandbox", children: ["The shared test store/products/categories expire on ", new Date(sandboxExpiresAt).toLocaleDateString(), "."] })), _jsx(FieldInput, { name: "checklist-search", label: "Search test cases", value: search, onChange: setSearch, placeholder: "Search by title or route, e.g. checkout, /store/payouts..." }), sortedPhaseNumbers.map((phaseNumber) => {
|
|
92
|
+
return (_jsxs(Stack, { gap: "lg", children: [_jsx(Heading, { level: 1, children: "Tester Hub" }), _jsx(Text, { color: "muted", children: "Work through the checklist below and answer Yes/No for each test case. Add a comment and screenshot wherever something looks off \u2014 colors, styles, readability, bugs. Your answers save automatically." }), _jsx(TextLink, { href: String(ROUTES.PUBLIC.BUG_HUNTERS), variant: "underline", weight: "medium", children: "View Bug Hunters Leaderboard \u2192" }), sandboxExpiresAt && (_jsxs(Alert, { variant: "info", title: "Shared test sandbox", children: ["The shared test store/products/categories expire on ", new Date(sandboxExpiresAt).toLocaleDateString(), "."] })), _jsx(FieldInput, { name: "checklist-search", label: "Search test cases", value: search, onChange: setSearch, placeholder: "Search by title or route, e.g. checkout, /store/payouts..." }), sortedPhaseNumbers.map((phaseNumber) => {
|
|
92
93
|
const groups = phases.get(phaseNumber);
|
|
93
94
|
const phaseItemCount = Array.from(groups.values())
|
|
94
95
|
.flatMap((g) => Array.from(g.pages.values()))
|
|
@@ -82,7 +82,15 @@ const _rawOrdersTesterSeedData = [
|
|
|
82
82
|
key: "shipped",
|
|
83
83
|
status: "shipped",
|
|
84
84
|
paymentStatus: "paid",
|
|
85
|
-
extra: {
|
|
85
|
+
extra: {
|
|
86
|
+
trackingNumber: "TEST-TRACK-001",
|
|
87
|
+
shippingCarrier: "Test Carrier",
|
|
88
|
+
shippingDate: daysAgo(1),
|
|
89
|
+
// Real-looking passthrough URL — exercises the "opens in new tab"
|
|
90
|
+
// tracking-link case on /user/orders/[id]/track (no live courier
|
|
91
|
+
// API integration; this is exactly what a seller/admin would type in).
|
|
92
|
+
trackingUrl: "https://www.example.com/track/TEST-TRACK-001",
|
|
93
|
+
},
|
|
86
94
|
}),
|
|
87
95
|
standardOrder({
|
|
88
96
|
key: "delivered",
|
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
* pre-ordering against real code paths — including navigating every entry of the store
|
|
6
6
|
* detail page's listing-type dropdown (see StoreNavTabs). Auto-expires after 7 days
|
|
7
7
|
* (testerSandboxCleanup cascades into any bids on the auction).
|
|
8
|
-
* WHAT: Exports productsTesterSeedData — 2 standard +
|
|
8
|
+
* WHAT: Exports productsTesterSeedData — 2 standard + 4 auction (3 staggered 1h/2h/3h "still
|
|
9
|
+
* open" cycling fixtures + 1 already-ended "won" fixture) + 1 pre-order + 1 prize-draw +
|
|
9
10
|
* 1 classified + 1 digital-code + 1 live + 1 art + 1 stickers product + 1 product-group
|
|
10
11
|
* ("Set") parent (product-tester-standard-1/2 are its children, linked via groupId).
|
|
12
|
+
* The 3 staggered auction ids/end-dates are recomputed on every seed run (including the
|
|
13
|
+
* testerSandboxRefresh job, every 4h) so testers can watch one actually end mid-session.
|
|
11
14
|
*
|
|
12
15
|
* EXPORTS:
|
|
13
16
|
* productsTesterSeedData — Array of Partial<ProductDocument> for the seed runner
|
|
@@ -42,7 +45,46 @@ function withTokens(p) {
|
|
|
42
45
|
searchTokens: buildSearchTokens(p.title, p.description, p.brand, p.brandSlug, p.categoryNames, p.tags),
|
|
43
46
|
};
|
|
44
47
|
}
|
|
48
|
+
// Staggered, incrementing-id auction fixtures so testers can watch a live
|
|
49
|
+
// auction actually cross its end time within a single sandbox refresh cycle
|
|
50
|
+
// (testerSandboxRefresh re-imports this module every 4 hours, recomputing
|
|
51
|
+
// these Date.now()-relative offsets fresh each time) instead of the old
|
|
52
|
+
// single fixture that always sat 5 days out. A loop (not hand-typed ids)
|
|
53
|
+
// avoids id collisions if the stagger list is ever extended.
|
|
54
|
+
const AUCTION_CYCLE_STAGGER_HOURS = [1, 2, 3];
|
|
55
|
+
const stagedAuctions = AUCTION_CYCLE_STAGGER_HOURS.map((hours, i) => withTokens({
|
|
56
|
+
id: `auction-tester-sandbox-cycle-${i + 1}`,
|
|
57
|
+
slug: `auction-tester-sandbox-cycle-${i + 1}`,
|
|
58
|
+
title: `Test Auction — Ends in ~${hours}h`,
|
|
59
|
+
description: `Disposable test auction for the tester QA program, staggered to end roughly ${hours} hour(s) after the last sandbox refresh so testers can watch the end-of-auction flow live. Place a bid — it auto-expires in 7 days, cascading to any bids.`,
|
|
60
|
+
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
61
|
+
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
62
|
+
brandSlug: "brand-tester-sandbox",
|
|
63
|
+
brand: "TestBrand",
|
|
64
|
+
startingBid: 15000,
|
|
65
|
+
currentBid: 15000,
|
|
66
|
+
currency: "INR",
|
|
67
|
+
price: 150,
|
|
68
|
+
stockQuantity: 1,
|
|
69
|
+
availableQuantity: 1,
|
|
70
|
+
auctionEndDate: new Date(Date.now() + hours * 60 * 60 * 1000),
|
|
71
|
+
bidCount: 0,
|
|
72
|
+
bidsHaveStarted: false,
|
|
73
|
+
isSold: false,
|
|
74
|
+
mainImage: seedExtMedia(`https://picsum.photos/seed/auction-image-tester-sandbox-cycle-${i + 1}-20260101/900/900`),
|
|
75
|
+
images: [seedExtMedia(`https://picsum.photos/seed/auction-image-tester-sandbox-cycle-${i + 1}-20260101/900/900`)],
|
|
76
|
+
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
77
|
+
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
78
|
+
listingType: "auction",
|
|
79
|
+
customFields: [],
|
|
80
|
+
customSections: [],
|
|
81
|
+
isPromoted: false,
|
|
82
|
+
isOnSale: false,
|
|
83
|
+
createdAt: new Date(),
|
|
84
|
+
updatedAt: new Date(),
|
|
85
|
+
}));
|
|
45
86
|
export const productsTesterSeedData = [
|
|
87
|
+
...stagedAuctions,
|
|
46
88
|
withTokens({
|
|
47
89
|
id: "product-tester-standard-1",
|
|
48
90
|
slug: "product-tester-standard-1",
|
|
@@ -131,37 +173,6 @@ export const productsTesterSeedData = [
|
|
|
131
173
|
createdAt: new Date(),
|
|
132
174
|
updatedAt: new Date(),
|
|
133
175
|
}),
|
|
134
|
-
withTokens({
|
|
135
|
-
id: "auction-tester-sandbox-1",
|
|
136
|
-
slug: "auction-tester-sandbox-1",
|
|
137
|
-
title: "Test Auction — Bid Me!",
|
|
138
|
-
description: "Disposable test auction for the tester QA program. Place a bid — it auto-expires in 7 days, cascading to any bids.",
|
|
139
|
-
categorySlugs: COLLECTIBLES_CATEGORY_SLUGS,
|
|
140
|
-
categoryNames: COLLECTIBLES_CATEGORY_NAMES,
|
|
141
|
-
brandSlug: "brand-tester-sandbox",
|
|
142
|
-
brand: "TestBrand",
|
|
143
|
-
startingBid: 15000,
|
|
144
|
-
currentBid: 15000,
|
|
145
|
-
currency: "INR",
|
|
146
|
-
price: 150,
|
|
147
|
-
stockQuantity: 1,
|
|
148
|
-
availableQuantity: 1,
|
|
149
|
-
auctionEndDate: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000),
|
|
150
|
-
bidCount: 0,
|
|
151
|
-
bidsHaveStarted: false,
|
|
152
|
-
isSold: false,
|
|
153
|
-
mainImage: seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-1-20260101/900/900"),
|
|
154
|
-
images: [seedExtMedia("https://picsum.photos/seed/auction-image-tester-sandbox-1-20260101/900/900")],
|
|
155
|
-
status: PRODUCT_FIELDS.STATUS_VALUES.PUBLISHED,
|
|
156
|
-
condition: PRODUCT_FIELDS.CONDITION_VALUES.NEW,
|
|
157
|
-
listingType: "auction",
|
|
158
|
-
customFields: [],
|
|
159
|
-
customSections: [],
|
|
160
|
-
isPromoted: false,
|
|
161
|
-
isOnSale: false,
|
|
162
|
-
createdAt: new Date(),
|
|
163
|
-
updatedAt: new Date(),
|
|
164
|
-
}),
|
|
165
176
|
withTokens({
|
|
166
177
|
id: "auction-tester-sandbox-won",
|
|
167
178
|
slug: "auction-tester-sandbox-won",
|