@mohasinac/appkit 4.57.0 → 4.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.build-stamp.json +4 -4
- package/dist/_internal/server/features/beys/data.d.ts +44 -0
- package/dist/_internal/server/features/beys/data.js +107 -0
- package/dist/_internal/server/features/beys/og.d.ts +42 -0
- package/dist/_internal/server/features/beys/og.js +89 -0
- package/dist/_internal/server/features/parts/data.js +3 -2
- package/dist/_internal/server/jobs/handlers/messages.d.ts +1 -1
- package/dist/_internal/server/jobs/handlers/messages.js +1 -1
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +86 -0
- package/dist/_internal/shared/types/base-document.d.ts +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.js +1 -0
- package/dist/constants/api-endpoints.d.ts +12 -0
- package/dist/constants/api-endpoints.js +10 -0
- package/dist/constants/field-names.d.ts +46 -0
- package/dist/constants/field-names.js +46 -0
- package/dist/constants/seed-meta.d.ts +113 -0
- package/dist/constants/seed-meta.js +91 -0
- package/dist/features/admin/components/AdminBeysView.d.ts +27 -0
- package/dist/features/admin/components/AdminBeysView.js +178 -0
- package/dist/features/admin/components/AdminPartsView.d.ts +27 -0
- package/dist/features/admin/components/AdminPartsView.js +160 -0
- package/dist/features/admin/components/OwnerQuickActions.d.ts +19 -2
- package/dist/features/admin/components/OwnerQuickActions.js +31 -3
- package/dist/features/admin/components/RecordOwnerQuickActions.d.ts +31 -0
- package/dist/features/admin/components/RecordOwnerQuickActions.js +128 -0
- package/dist/features/admin/components/ReferenceRecordEditor.d.ts +45 -0
- package/dist/features/admin/components/ReferenceRecordEditor.js +153 -0
- package/dist/features/admin/schemas/firestore.d.ts +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +15 -2
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +12 -1
- package/dist/features/beys/components/BeyDetailPageView.d.ts +50 -0
- package/dist/features/beys/components/BeyDetailPageView.js +98 -0
- package/dist/features/beys/schemas/firestore.d.ts +417 -0
- package/dist/features/beys/schemas/firestore.js +65 -0
- package/dist/features/blog/components/BlogFeaturedCard.js +15 -2
- package/dist/features/blog/components/BlogPostView.js +2 -2
- package/dist/features/categories/components/BrandDetailPageView.js +4 -2
- package/dist/features/categories/components/BundleDetailView.js +2 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +36 -3
- package/dist/features/categories/components/CategoryGrid.js +24 -2
- package/dist/features/categories/components/FranchiseDetailPageView.js +2 -3
- package/dist/features/events/components/EventCard.js +15 -2
- package/dist/features/grouped/components/GroupedListingDetailView.js +2 -3
- package/dist/features/homepage/components/CustomCardsSection.js +67 -50
- package/dist/features/homepage/components/ShopByCategorySection.js +23 -10
- package/dist/features/homepage/schemas/index.d.ts +10 -10
- package/dist/features/parts/components/PartDetailPageView.js +5 -3
- package/dist/features/parts/components/PartsSearchBox.js +79 -4
- package/dist/features/parts/schemas/admin-edit.d.ts +81 -0
- package/dist/features/parts/schemas/admin-edit.js +89 -0
- package/dist/features/parts/schemas/firestore.d.ts +2 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +15 -2
- package/dist/features/products/components/MarketplaceBundleCard.js +15 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +15 -2
- package/dist/features/products/components/ProductGrid.js +18 -2
- package/dist/features/products/schemas/firestore.d.ts +18 -0
- package/dist/features/seller/components/CategoryInlineSelect.d.ts +10 -1
- package/dist/features/seller/components/CategoryInlineSelect.js +53 -5
- package/dist/features/seller/components/SellerProductShell.d.ts +39 -0
- package/dist/features/seller/components/SellerProductShell.js +31 -3
- package/dist/index.d.ts +6 -129
- package/dist/index.js +61 -292
- package/dist/next/routing/route-map.d.ts +13 -1
- package/dist/next/routing/route-map.js +37 -0
- package/dist/schemas/registry.d.ts +6 -6
- package/dist/server.d.ts +2 -69
- package/dist/server.js +8 -69
- package/dist/styles.css +468 -1
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/PosterCard.d.ts +99 -0
- package/dist/ui/components/PosterCard.js +109 -0
- package/dist/ui/components/PosterCard.style.css +466 -0
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +2 -0
- package/package.json +4 -2
- package/scripts/seed-cli.mjs +177 -2
- package/dist/features/tester/seed-data/_happy-path.d.ts +0 -23
- package/dist/features/tester/seed-data/_happy-path.js +0 -710
- package/dist/features/tester/seed-data/_money-flows.d.ts +0 -23
- package/dist/features/tester/seed-data/_money-flows.js +0 -610
- package/dist/features/tester/seed-data/authored/_types.d.ts +0 -57
- package/dist/features/tester/seed-data/authored/_types.js +0 -35
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/account-auth__profile-settings.js +0 -226
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/account-auth__signup-login.js +0 -329
- package/dist/features/tester/seed-data/authored/addresses__address-filters.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/addresses__address-filters.js +0 -41
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/addresses__postal-lookup.js +0 -76
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/addresses__postal-validation.js +0 -78
- package/dist/features/tester/seed-data/authored/addresses__state-picker.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/addresses__state-picker.js +0 -59
- package/dist/features/tester/seed-data/authored/addresses__unban-request.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/addresses__unban-request.js +0 -77
- package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__admin-detail-round-trips.js +0 -151
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__bans-and-trust.js +0 -265
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__blog-faqs.js +0 -131
- package/dist/features/tester/seed-data/authored/admin__bug-hunter-rewards.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__bug-hunter-rewards.js +0 -143
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__bulk-actions.js +0 -207
- package/dist/features/tester/seed-data/authored/admin__bundles.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__bundles.js +0 -144
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__buyer-data-admin.js +0 -265
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__catalog-listings.js +0 -318
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__category-brand-authoring.js +0 -177
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__classifieds-digitalcodes-live.js +0 -165
- package/dist/features/tester/seed-data/authored/admin__content-deletes.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__content-deletes.js +0 -267
- package/dist/features/tester/seed-data/authored/admin__content-marketing.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__content-marketing.js +0 -188
- package/dist/features/tester/seed-data/authored/admin__coupons.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__coupons.js +0 -215
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__events-raffles-spin.js +0 -202
- package/dist/features/tester/seed-data/authored/admin__firebase-function-effects.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__firebase-function-effects.js +0 -249
- package/dist/features/tester/seed-data/authored/admin__media-watermark.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__media-watermark.js +0 -148
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__orders-fulfillment.js +0 -350
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__prize-draws-lotteries.js +0 -129
- package/dist/features/tester/seed-data/authored/admin__site-system.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -586
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__uncovered-admin-pages.js +0 -260
- package/dist/features/tester/seed-data/authored/admin__users-trust.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/admin__users-trust.js +0 -569
- package/dist/features/tester/seed-data/authored/buying__bidding.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__bidding.js +0 -449
- package/dist/features/tester/seed-data/authored/buying__browsing-search.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__browsing-search.js +0 -684
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -546
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__buying-coupons.js +0 -379
- package/dist/features/tester/seed-data/authored/buying__cart.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__cart.js +0 -1264
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__image-tile-layout.js +0 -122
- package/dist/features/tester/seed-data/authored/buying__my-orders.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__my-orders.js +0 -279
- package/dist/features/tester/seed-data/authored/buying__offers.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__offers.js +0 -1127
- package/dist/features/tester/seed-data/authored/buying__order-detail-actions.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__order-detail-actions.js +0 -153
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__order-status-lifecycle.js +0 -252
- package/dist/features/tester/seed-data/authored/buying__product-detail.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__product-detail.js +0 -474
- package/dist/features/tester/seed-data/authored/buying__return-request.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__return-request.js +0 -165
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__reviews-pagination.js +0 -260
- package/dist/features/tester/seed-data/authored/buying__reviews.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__reviews.js +0 -128
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__spares-and-groups.js +0 -96
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-extras.js +0 -283
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__user-dashboard-navigation.js +0 -169
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__user-uncovered-pages.js +0 -105
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/buying__wishlist-history.js +0 -374
- package/dist/features/tester/seed-data/authored/community-support__messages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/community-support__messages.js +0 -200
- package/dist/features/tester/seed-data/authored/community-support__public-profile.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/community-support__public-profile.js +0 -54
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/community-support__support-tickets.js +0 -76
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.d.ts +0 -4
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +0 -590
- package/dist/features/tester/seed-data/authored/content-discovery__blog.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__blog.js +0 -110
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__category-brand-relations.js +0 -149
- package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__category-counts-and-rollup.js +0 -145
- package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__category-tabs-franchise-bundles.js +0 -174
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__coupons.js +0 -169
- package/dist/features/tester/seed-data/authored/content-discovery__event-detail-subroutes.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__event-detail-subroutes.js +0 -209
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__event-participation.js +0 -207
- package/dist/features/tester/seed-data/authored/content-discovery__events.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__events.js +0 -377
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__faq-help.js +0 -87
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__notifications.js +0 -147
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__overflowing-pill-rows.js +0 -209
- package/dist/features/tester/seed-data/authored/content-discovery__parts-database.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__parts-database.js +0 -167
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__price-index-and-compare.js +0 -73
- package/dist/features/tester/seed-data/authored/content-discovery__search.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__search.js +0 -363
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__site-wide-index.js +0 -340
- package/dist/features/tester/seed-data/authored/content-discovery__store-reviews-aggregate.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/content-discovery__store-reviews-aggregate.js +0 -88
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +0 -78
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/cta-layout__dialog-footers.js +0 -76
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/cta-layout__editor-action-bar.js +0 -62
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/cta-layout__navbar-ctas.js +0 -163
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/cta-layout__product-bottom-bar.js +0 -61
- package/dist/features/tester/seed-data/authored/design-ux__action-bar-placement.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__action-bar-placement.js +0 -89
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__back-to-top-button.js +0 -95
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__carousel-arrow-bounds.js +0 -191
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__dashboard-layout.js +0 -158
- package/dist/features/tester/seed-data/authored/design-ux__feature-badge-picker.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__feature-badge-picker.js +0 -82
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__footer-theme.js +0 -106
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__form-validation-errors.js +0 -88
- package/dist/features/tester/seed-data/authored/design-ux__general-design.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__general-design.js +0 -204
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__hand-mode-layout.js +0 -301
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__header-brand-mark-centring.js +0 -90
- package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__header-controls-and-messages.js +0 -85
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__homepage-carousels.js +0 -407
- package/dist/features/tester/seed-data/authored/design-ux__nav-reachability.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__nav-reachability.js +0 -88
- package/dist/features/tester/seed-data/authored/design-ux__rich-text-readability.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__rich-text-readability.js +0 -84
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__status-badge-legibility.js +0 -214
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/design-ux__sticky-cta-bar.js +0 -275
- package/dist/features/tester/seed-data/authored/index.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/index.js +0 -301
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/page-wiring__data-loss.js +0 -125
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/page-wiring__detail-pages.js +0 -85
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/page-wiring__drawer-pages.js +0 -92
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/page-wiring__reachability.js +0 -115
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__auth-error-pages.js +0 -137
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__core-listing-pages.js +0 -263
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__help-how-it-works.js +0 -229
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__help-scams-guides-subpages.js +0 -325
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__legal-policy-pages.js +0 -126
- package/dist/features/tester/seed-data/authored/public-pages__newly-wired-browse-indexes.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__newly-wired-browse-indexes.js +0 -141
- package/dist/features/tester/seed-data/authored/public-pages__store-tabs.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__store-tabs.js +0 -115
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/public-pages__stores-sellers-directories.js +0 -253
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/search-and-nav__employee-permissions.js +0 -93
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.d.ts +0 -3
- package/dist/features/tester/seed-data/authored/search-and-nav__header-search.js +0 -185
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/search-and-nav__settings-deep-links.js +0 -82
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/search-and-nav__sidebar-search.js +0 -60
- package/dist/features/tester/seed-data/authored/selling__become-seller.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__become-seller.js +0 -117
- package/dist/features/tester/seed-data/authored/selling__digital-content-delivery.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__digital-content-delivery.js +0 -148
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__final-sale-authoring.js +0 -108
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__listing-a-product.js +0 -274
- package/dist/features/tester/seed-data/authored/selling__listing-edit-roundtrip.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__listing-edit-roundtrip.js +0 -145
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__listing-lifecycle.js +0 -336
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__listing-type-fields-roundtrip.js +0 -136
- package/dist/features/tester/seed-data/authored/selling__media-limits.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__media-limits.js +0 -135
- package/dist/features/tester/seed-data/authored/selling__product-upload-details.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__product-upload-details.js +0 -155
- package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -138
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__sectionised-forms.js +0 -191
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-analytics-payouts.js +0 -138
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-bids-bundles-filters.js +0 -106
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-catalog-org.js +0 -192
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-custom-brands.js +0 -109
- package/dist/features/tester/seed-data/authored/selling__seller-guide.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-guide.js +0 -34
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-listing-types.js +0 -348
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -87
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-ops-comms.js +0 -90
- package/dist/features/tester/seed-data/authored/selling__seller-orders-at-scale.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-orders-at-scale.js +0 -85
- package/dist/features/tester/seed-data/authored/selling__seller-orders.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-orders.js +0 -213
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__seller-shipping-payouts-setup.js +0 -192
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__spares-and-group-editing.js +0 -77
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__store-dashboard-navigation.js +0 -165
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/selling__store-uncovered-pages.js +0 -116
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/seo__canonical-and-host.js +0 -127
- package/dist/features/tester/seed-data/authored/seo__og-images.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/seo__og-images.js +0 -107
- package/dist/features/tester/seed-data/authored/seo__page-metadata.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/seo__page-metadata.js +0 -120
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/seo__sitemap-and-robots.js +0 -105
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/tools__sticker-promote-to-listings.js +0 -58
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.d.ts +0 -2
- package/dist/features/tester/seed-data/authored/tools__sticker-tracer.js +0 -284
- package/dist/features/tester/seed-data/index.d.ts +0 -2
- package/dist/features/tester/seed-data/index.js +0 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.d.ts +0 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +0 -7601
- package/dist/features/tester/seed-data/tester-responses-seed-data.d.ts +0 -2
- package/dist/features/tester/seed-data/tester-responses-seed-data.js +0 -95
- package/dist/features/tester/seed-data/tester-window.d.ts +0 -25
- package/dist/features/tester/seed-data/tester-window.js +0 -66
- package/dist/seed/_helpers/brand-rows.d.ts +0 -35
- package/dist/seed/_helpers/brand-rows.js +0 -600
- package/dist/seed/_helpers/category-content-generated.d.ts +0 -24
- package/dist/seed/_helpers/category-content-generated.js +0 -1853
- package/dist/seed/_helpers/category-content.d.ts +0 -68
- package/dist/seed/_helpers/category-content.js +0 -731
- package/dist/seed/_helpers/category-forest.d.ts +0 -4
- package/dist/seed/_helpers/category-forest.js +0 -824
- package/dist/seed/_helpers/category-images-generated.d.ts +0 -57
- package/dist/seed/_helpers/category-images-generated.js +0 -618
- package/dist/seed/_helpers/category-models/chunk0.d.ts +0 -2
- package/dist/seed/_helpers/category-models/chunk0.js +0 -2648
- package/dist/seed/_helpers/category-models/chunk1.d.ts +0 -2
- package/dist/seed/_helpers/category-models/chunk1.js +0 -2318
- package/dist/seed/_helpers/category-models/chunk2.d.ts +0 -2
- package/dist/seed/_helpers/category-models/chunk2.js +0 -2560
- package/dist/seed/_helpers/category-models/chunk3.d.ts +0 -2
- package/dist/seed/_helpers/category-models/chunk3.js +0 -2196
- package/dist/seed/_helpers/category-models/chunk4.d.ts +0 -2
- package/dist/seed/_helpers/category-models/chunk4.js +0 -1732
- package/dist/seed/_helpers/category-models.d.ts +0 -12
- package/dist/seed/_helpers/category-models.js +0 -45
- package/dist/seed/_helpers/category-names.d.ts +0 -54
- package/dist/seed/_helpers/category-names.js +0 -118
- package/dist/seed/_helpers/category-parts-glossary-map.d.ts +0 -1
- package/dist/seed/_helpers/category-parts-glossary-map.js +0 -2499
- package/dist/seed/_helpers/category-parts.d.ts +0 -9
- package/dist/seed/_helpers/category-parts.js +0 -15022
- package/dist/seed/_helpers/category-tree.d.ts +0 -27
- package/dist/seed/_helpers/category-tree.js +0 -119
- package/dist/seed/_helpers/character-features.d.ts +0 -10
- package/dist/seed/_helpers/character-features.js +0 -120
- package/dist/seed/_helpers/final-sale-fixtures.d.ts +0 -35
- package/dist/seed/_helpers/final-sale-fixtures.js +0 -61
- package/dist/seed/_helpers/franchise-rows.d.ts +0 -43
- package/dist/seed/_helpers/franchise-rows.js +0 -189
- package/dist/seed/_helpers/media.d.ts +0 -67
- package/dist/seed/_helpers/media.js +0 -172
- package/dist/seed/_helpers/part-colours-generated.d.ts +0 -18
- package/dist/seed/_helpers/part-colours-generated.js +0 -273
- package/dist/seed/_helpers/product-search-txt.d.ts +0 -18
- package/dist/seed/_helpers/product-search-txt.js +0 -23
- package/dist/seed/_helpers/search-txt-wrappers.d.ts +0 -26
- package/dist/seed/_helpers/search-txt-wrappers.js +0 -58
- package/dist/seed/addresses-seed-data.d.ts +0 -2
- package/dist/seed/addresses-seed-data.js +0 -78
- package/dist/seed/authenticity-knowledge-seed-data.d.ts +0 -78
- package/dist/seed/authenticity-knowledge-seed-data.js +0 -10729
- package/dist/seed/bids-seed-data.d.ts +0 -2
- package/dist/seed/bids-seed-data.js +0 -206
- package/dist/seed/blog-posts-seed-data.d.ts +0 -6
- package/dist/seed/blog-posts-seed-data.js +0 -442
- package/dist/seed/carousel-slides-seed-data.d.ts +0 -2
- package/dist/seed/carousel-slides-seed-data.js +0 -411
- package/dist/seed/carousels-seed-data.d.ts +0 -2
- package/dist/seed/carousels-seed-data.js +0 -36
- package/dist/seed/cart-seed-data.d.ts +0 -2
- package/dist/seed/cart-seed-data.js +0 -241
- package/dist/seed/catalogue-seed-data.d.ts +0 -2
- package/dist/seed/catalogue-seed-data.js +0 -112
- package/dist/seed/categories-seed-data.d.ts +0 -3
- package/dist/seed/categories-seed-data.js +0 -816
- package/dist/seed/claimed-coupons-seed-data.d.ts +0 -2
- package/dist/seed/claimed-coupons-seed-data.js +0 -85
- package/dist/seed/coupon-usage-seed-data.d.ts +0 -9
- package/dist/seed/coupon-usage-seed-data.js +0 -55
- package/dist/seed/coupons-seed-data.d.ts +0 -2
- package/dist/seed/coupons-seed-data.js +0 -226
- package/dist/seed/defaults/categories.d.ts +0 -2
- package/dist/seed/defaults/categories.js +0 -12
- package/dist/seed/defaults/faqs.d.ts +0 -2
- package/dist/seed/defaults/faqs.js +0 -40
- package/dist/seed/events-seed-data.d.ts +0 -7
- package/dist/seed/events-seed-data.js +0 -482
- package/dist/seed/factories/address.factory.d.ts +0 -21
- package/dist/seed/factories/address.factory.js +0 -44
- package/dist/seed/factories/bid.factory.d.ts +0 -15
- package/dist/seed/factories/bid.factory.js +0 -33
- package/dist/seed/factories/blog-post.factory.d.ts +0 -15
- package/dist/seed/factories/blog-post.factory.js +0 -22
- package/dist/seed/factories/carousel.factory.d.ts +0 -11
- package/dist/seed/factories/carousel.factory.js +0 -17
- package/dist/seed/factories/cart.factory.d.ts +0 -25
- package/dist/seed/factories/cart.factory.js +0 -35
- package/dist/seed/factories/category.factory.d.ts +0 -11
- package/dist/seed/factories/category.factory.js +0 -16
- package/dist/seed/factories/coupon.factory.d.ts +0 -21
- package/dist/seed/factories/coupon.factory.js +0 -43
- package/dist/seed/factories/faq.factory.d.ts +0 -10
- package/dist/seed/factories/faq.factory.js +0 -15
- package/dist/seed/factories/notification.factory.d.ts +0 -18
- package/dist/seed/factories/notification.factory.js +0 -39
- package/dist/seed/factories/order.factory.d.ts +0 -20
- package/dist/seed/factories/order.factory.js +0 -20
- package/dist/seed/factories/payout.factory.d.ts +0 -21
- package/dist/seed/factories/payout.factory.js +0 -38
- package/dist/seed/factories/product.factory.d.ts +0 -27
- package/dist/seed/factories/product.factory.js +0 -80
- package/dist/seed/factories/review.factory.d.ts +0 -14
- package/dist/seed/factories/review.factory.js +0 -52
- package/dist/seed/factories/session.factory.d.ts +0 -15
- package/dist/seed/factories/session.factory.js +0 -31
- package/dist/seed/factories/store.factory.d.ts +0 -23
- package/dist/seed/factories/store.factory.js +0 -47
- package/dist/seed/factories/user.factory.d.ts +0 -19
- package/dist/seed/factories/user.factory.js +0 -56
- package/dist/seed/faq-seed-data.d.ts +0 -18
- package/dist/seed/faq-seed-data.js +0 -1956
- package/dist/seed/firestore-indexes.d.ts +0 -12
- package/dist/seed/firestore-indexes.js +0 -31
- package/dist/seed/grouped-listings-seed-data.d.ts +0 -2
- package/dist/seed/grouped-listings-seed-data.js +0 -283
- package/dist/seed/history-seed-data.d.ts +0 -12
- package/dist/seed/history-seed-data.js +0 -70
- package/dist/seed/homepage-sections-seed-data.d.ts +0 -2
- package/dist/seed/homepage-sections-seed-data.js +0 -1018
- package/dist/seed/index.d.ts +0 -98
- package/dist/seed/index.js +0 -112
- package/dist/seed/lottery-entries-seed-data.d.ts +0 -2
- package/dist/seed/lottery-entries-seed-data.js +0 -108
- package/dist/seed/manifest.d.ts +0 -16
- package/dist/seed/manifest.js +0 -235
- package/dist/seed/media-assets-seed-data.d.ts +0 -22
- package/dist/seed/media-assets-seed-data.js +0 -5593
- package/dist/seed/model-composition-seed-data.d.ts +0 -15
- package/dist/seed/model-composition-seed-data.js +0 -9032
- package/dist/seed/notifications-seed-data.d.ts +0 -2
- package/dist/seed/notifications-seed-data.js +0 -606
- package/dist/seed/offers-seed-data.d.ts +0 -2
- package/dist/seed/offers-seed-data.js +0 -398
- package/dist/seed/orders-seed-data.d.ts +0 -2
- package/dist/seed/orders-seed-data.js +0 -845
- package/dist/seed/part-glossary/chunk0.d.ts +0 -9
- package/dist/seed/part-glossary/chunk0.js +0 -35448
- package/dist/seed/part-glossary/chunk1.d.ts +0 -9
- package/dist/seed/part-glossary/chunk1.js +0 -40494
- package/dist/seed/part-glossary/chunk2.d.ts +0 -9
- package/dist/seed/part-glossary/chunk2.js +0 -51242
- package/dist/seed/part-glossary/chunk3.d.ts +0 -9
- package/dist/seed/part-glossary/chunk3.js +0 -53337
- package/dist/seed/part-glossary/chunk4.d.ts +0 -9
- package/dist/seed/part-glossary/chunk4.js +0 -51454
- package/dist/seed/part-glossary-seed-data.d.ts +0 -15
- package/dist/seed/part-glossary-seed-data.js +0 -25
- package/dist/seed/payouts-seed-data.d.ts +0 -2
- package/dist/seed/payouts-seed-data.js +0 -302
- package/dist/seed/product-features-seed-data.d.ts +0 -3
- package/dist/seed/product-features-seed-data.js +0 -366
- package/dist/seed/products-art-seed-data.d.ts +0 -2
- package/dist/seed/products-art-seed-data.js +0 -289
- package/dist/seed/products-auctions-seed-data.d.ts +0 -2
- package/dist/seed/products-auctions-seed-data.js +0 -475
- package/dist/seed/products-beyblade-x-seed-data.d.ts +0 -2
- package/dist/seed/products-beyblade-x-seed-data.js +0 -476
- package/dist/seed/products-catalogue-seed-data.d.ts +0 -22
- package/dist/seed/products-catalogue-seed-data.js +0 -86384
- package/dist/seed/products-classifieds-seed-data.d.ts +0 -7
- package/dist/seed/products-classifieds-seed-data.js +0 -435
- package/dist/seed/products-digital-codes-seed-data.d.ts +0 -7
- package/dist/seed/products-digital-codes-seed-data.js +0 -395
- package/dist/seed/products-live-items-seed-data.d.ts +0 -7
- package/dist/seed/products-live-items-seed-data.js +0 -269
- package/dist/seed/products-preorders-seed-data.d.ts +0 -2
- package/dist/seed/products-preorders-seed-data.js +0 -360
- package/dist/seed/products-prize-draws-seed-data.d.ts +0 -7
- package/dist/seed/products-prize-draws-seed-data.js +0 -427
- package/dist/seed/products-spares-seed-data.d.ts +0 -2
- package/dist/seed/products-spares-seed-data.js +0 -368
- package/dist/seed/products-standard-seed-data.d.ts +0 -2
- package/dist/seed/products-standard-seed-data.js +0 -632
- package/dist/seed/products-stickers-seed-data.d.ts +0 -2
- package/dist/seed/products-stickers-seed-data.js +0 -319
- package/dist/seed/reviews-seed-data.d.ts +0 -1
- package/dist/seed/reviews-seed-data.js +0 -185
- package/dist/seed/runner.d.ts +0 -2
- package/dist/seed/runner.js +0 -125
- package/dist/seed/scammers-seed-data.d.ts +0 -2
- package/dist/seed/scammers-seed-data.js +0 -235
- package/dist/seed/seed-market-config.d.ts +0 -48
- package/dist/seed/seed-market-config.js +0 -199
- package/dist/seed/seed-purpose.d.ts +0 -299
- package/dist/seed/seed-purpose.js +0 -431
- package/dist/seed/sessions-seed-data.d.ts +0 -3
- package/dist/seed/sessions-seed-data.js +0 -116
- package/dist/seed/shipments-seed-data.d.ts +0 -5
- package/dist/seed/shipments-seed-data.js +0 -185
- package/dist/seed/site-settings-seed-data.d.ts +0 -2
- package/dist/seed/site-settings-seed-data.js +0 -1069
- package/dist/seed/store-addresses-seed-data.d.ts +0 -18
- package/dist/seed/store-addresses-seed-data.js +0 -71
- package/dist/seed/store-extensions-seed-data.d.ts +0 -11
- package/dist/seed/store-extensions-seed-data.js +0 -292
- package/dist/seed/stores-seed-data.d.ts +0 -6
- package/dist/seed/stores-seed-data.js +0 -242
- package/dist/seed/support-tickets-seed-data.d.ts +0 -16
- package/dist/seed/support-tickets-seed-data.js +0 -239
- package/dist/seed/tax-codes-seed-data.d.ts +0 -34
- package/dist/seed/tax-codes-seed-data.js +0 -100
- package/dist/seed/test-data-ttl.d.ts +0 -29
- package/dist/seed/test-data-ttl.js +0 -31
- package/dist/seed/test-utils.d.ts +0 -49
- package/dist/seed/test-utils.js +0 -110
- package/dist/seed/types.d.ts +0 -89
- package/dist/seed/types.js +0 -15
- package/dist/seed/users-seed-data.d.ts +0 -2
- package/dist/seed/users-seed-data.js +0 -597
- package/dist/seed/wishlists-seed-data.d.ts +0 -12
- package/dist/seed/wishlists-seed-data.js +0 -54
|
@@ -57,6 +57,15 @@ import { toUserMessage } from "../../../errors/error-display-map.js";
|
|
|
57
57
|
const RESOURCE_LEAVES = {
|
|
58
58
|
PRODUCT: { bucket: "PRODUCT", edit: "edit", remove: "delete", duplicate: "duplicate" },
|
|
59
59
|
CATEGORY: { bucket: "CATEGORY", edit: "edit", remove: "delete" },
|
|
60
|
+
/*
|
|
61
|
+
* Both get a bin. Unlike the three pencil-only resources below, the blast
|
|
62
|
+
* radius of removing one reference row is SMALL and bounded: a bey keeps
|
|
63
|
+
* its parts list (`partName` sits beside `partId` for exactly this), a
|
|
64
|
+
* boxed set keeps its contents, and a category page keeps its listings.
|
|
65
|
+
* Nothing cascades, and the committed seed can put the row back.
|
|
66
|
+
*/
|
|
67
|
+
PART: { bucket: "PART", edit: "edit", remove: "delete" },
|
|
68
|
+
BEY: { bucket: "BEY", edit: "edit", remove: "delete" },
|
|
60
69
|
BRAND: { bucket: "BRAND", edit: "edit", remove: "delete" },
|
|
61
70
|
BUNDLE: { bucket: "BUNDLE", edit: "edit", remove: "delete" },
|
|
62
71
|
GROUP: { bucket: "GROUP", edit: "edit", remove: "delete" },
|
|
@@ -93,7 +102,7 @@ const RESOURCE_LEAVES = {
|
|
|
93
102
|
USER: { bucket: "ADMIN", edit: "manage-user" },
|
|
94
103
|
SECTION: { bucket: "ADMIN", edit: "edit-section" },
|
|
95
104
|
};
|
|
96
|
-
export function OwnerQuickActions({ resource, editHref, onDelete, onClone, ownerId, storeId, recordLabel, placement = "card", className = "", }) {
|
|
105
|
+
export function OwnerQuickActions({ resource, editHref, onDelete, onClone, ownerId, storeId, recordLabel, placement = "card", onMedia = false, className = "", }) {
|
|
97
106
|
const session = useOptionalSession();
|
|
98
107
|
const isOwnerOrAdmin = useIsOwner(ownerId);
|
|
99
108
|
const isAdmin = useIsAdmin();
|
|
@@ -164,6 +173,25 @@ export function OwnerQuickActions({ resource, editHref, onDelete, onClone, owner
|
|
|
164
173
|
* resource, not to each of its call sites, or the next call site re-opens it.
|
|
165
174
|
*/
|
|
166
175
|
const showDelete = Boolean(onDelete) && Boolean(leaves.remove);
|
|
176
|
+
/*
|
|
177
|
+
* 🛑 The scrim is for ANY dark backdrop, not only a card.
|
|
178
|
+
*
|
|
179
|
+
* `detail` used to hard-map to `ghost` (`color: var(--appkit-color-zinc-600)`),
|
|
180
|
+
* which is right on a page-surface header row and invisible on a cover photo
|
|
181
|
+
* — and every detail view with a hero puts this toolbar inside that hero,
|
|
182
|
+
* beside siblings it has already flipped to `color="inverse"`. The pencil
|
|
183
|
+
* therefore rendered near-black on near-black and read as "admins get no
|
|
184
|
+
* edit button at all". See `onMedia` above and Root Cause #67.
|
|
185
|
+
*/
|
|
186
|
+
const onDark = placement === "card" || onMedia;
|
|
187
|
+
const neutralVariant = onDark ? "scrim" : "ghost";
|
|
188
|
+
/*
|
|
189
|
+
* Danger ink is dropped on a dark backdrop for the same reason: `danger`
|
|
190
|
+
* resolves to a theme-relative red that disappears against the hero. The bin
|
|
191
|
+
* keeps its confirm dialog, which is where the destructive intent is
|
|
192
|
+
* actually communicated — colour was never the safeguard.
|
|
193
|
+
*/
|
|
194
|
+
const dangerVariant = onDark ? "scrim" : "danger";
|
|
167
195
|
return (_jsxs(_Fragment, { children: [_jsxs(Row, { gap: "xs", align: "center", className: className,
|
|
168
196
|
/*
|
|
169
197
|
* Stops the click reaching an ancestor `<Link>` or the card's own
|
|
@@ -172,7 +200,7 @@ export function OwnerQuickActions({ resource, editHref, onDelete, onClone, owner
|
|
|
172
200
|
*/
|
|
173
201
|
onClick: (e) => {
|
|
174
202
|
e.stopPropagation();
|
|
175
|
-
}, children: [_jsx(IconButton, { "aria-label": editDef?.ariaLabel ?? editDef?.label ?? "Edit", size: "touch", variant:
|
|
203
|
+
}, children: [_jsx(IconButton, { "aria-label": editDef?.ariaLabel ?? editDef?.label ?? "Edit", size: "touch", variant: neutralVariant, icon: _jsx(Icon, { name: "edit" }), onClick: () => {
|
|
176
204
|
/*
|
|
177
205
|
* `window.location`, not `next/link`. This component is rendered
|
|
178
206
|
* inside cards whose whole body is already an anchor, and nesting
|
|
@@ -183,7 +211,7 @@ export function OwnerQuickActions({ resource, editHref, onDelete, onClone, owner
|
|
|
183
211
|
if (typeof window !== "undefined")
|
|
184
212
|
window.location.assign(editHref);
|
|
185
213
|
} }), showClone && (_jsx(IconButton, { "aria-label": (leaves.duplicate ? bucket[leaves.duplicate]?.ariaLabel ?? bucket[leaves.duplicate]?.label : undefined) ||
|
|
186
|
-
"Duplicate", size: "touch", variant:
|
|
214
|
+
"Duplicate", size: "touch", variant: neutralVariant, icon: _jsx(Icon, { name: "duplicate" }), onClick: () => void onClone?.() })), showDelete && (_jsx(IconButton, { "aria-label": deleteDef?.ariaLabel ?? deleteDef?.label ?? "Delete", size: "touch", variant: dangerVariant, icon: _jsx(Icon, { name: "delete" }), onClick: () => setConfirmOpen(true) }))] }), showDelete && (_jsx(ConfirmDeleteModal, { isOpen: confirmOpen, onClose: () => setConfirmOpen(false), onConfirm: handleConfirmedDelete, isDeleting: deleting, title: confirmation?.title ?? "Delete this record?", message: recordLabel && confirmation
|
|
187
215
|
? `${confirmation.body}\n\nDeleting: ${recordLabel}`
|
|
188
216
|
: confirmation?.body, confirmText: confirmation?.confirmLabel ?? deleteDef?.label ?? "Delete", variant: "danger" }))] }));
|
|
189
217
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The admin-owned resources this wrapper can delete.
|
|
3
|
+
*
|
|
4
|
+
* 🛑 Deliberately NOT every `OwnerQuickActionsResource`. `STORE`, `USER` and
|
|
5
|
+
* `SECTION` omit a `remove` leaf in `RESOURCE_LEAVES` because their blast
|
|
6
|
+
* radius is far wider than the page a bin would sit on, and `REVIEW` has no
|
|
7
|
+
* admin edit route to send the pencil to. Adding one here without adding its
|
|
8
|
+
* leaf there still renders no bin — the resource owns that decision, which is
|
|
9
|
+
* the point of gating it in two places.
|
|
10
|
+
*/
|
|
11
|
+
export type RecordQuickActionResource = "CATEGORY" | "BRAND" | "BUNDLE" | "GROUP" | "EVENT" | "BLOG" | "FRANCHISE" | "SUBLISTING" | "PART" | "BEY";
|
|
12
|
+
export interface RecordOwnerQuickActionsProps {
|
|
13
|
+
resource: RecordQuickActionResource;
|
|
14
|
+
/** The record's document id — what the endpoint and the editor are keyed on. */
|
|
15
|
+
recordId: string;
|
|
16
|
+
/** Names the record in the delete confirmation. */
|
|
17
|
+
recordLabel?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Forwarded to `OwnerQuickActions` so a store-owned record (a grouped
|
|
20
|
+
* listing, a store-authored bundle) stays visible to the seller who owns it
|
|
21
|
+
* and not only to an admin. `SessionUser.storeId` holds the store SLUG, not
|
|
22
|
+
* the Auth UID — two different id spaces, hence two props.
|
|
23
|
+
*/
|
|
24
|
+
ownerId?: string;
|
|
25
|
+
storeId?: string;
|
|
26
|
+
placement?: "card" | "detail";
|
|
27
|
+
/** Pass the hero's own `hasCover` flag. See `OwnerQuickActions.onMedia`. */
|
|
28
|
+
onMedia?: boolean;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function RecordOwnerQuickActions({ resource, recordId, recordLabel, ownerId, storeId, placement, onMedia, className, }: RecordOwnerQuickActionsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* The client half of `OwnerQuickActions` for every admin-owned collection.
|
|
5
|
+
*
|
|
6
|
+
* ## 🛑 Why a wrapper is REQUIRED, not a convenience
|
|
7
|
+
*
|
|
8
|
+
* `OwnerQuickActions` takes `onDelete` / `onClone` as FUNCTIONS, and every
|
|
9
|
+
* detail view that renders it (`CategoryDetailPageView`, `BrandDetailPageView`,
|
|
10
|
+
* `BundleDetailView`, …) is a Server Component. A closure cannot cross that
|
|
11
|
+
* boundary — React throws
|
|
12
|
+
*
|
|
13
|
+
* Event handlers cannot be passed to Client Component props.
|
|
14
|
+
*
|
|
15
|
+
* at render. `ProductOwnerQuickActions` records that this exact mistake took
|
|
16
|
+
* down every `/products/[slug]` page in production, with an opaque digest per
|
|
17
|
+
* handler.
|
|
18
|
+
*
|
|
19
|
+
* That is why ten detail views were passing `editHref` and nothing else: the
|
|
20
|
+
* bin and the clone are rendered behind `{showDelete && …}` / `{showClone && …}`,
|
|
21
|
+
* so with no handler they silently do not exist. It read as "admins get no
|
|
22
|
+
* delete button", and the cause was a serialization boundary, not a permission.
|
|
23
|
+
*
|
|
24
|
+
* ## 🛑 Why ONE wrapper and not one per resource
|
|
25
|
+
*
|
|
26
|
+
* `ProductOwnerQuickActions` is resource-specific because products are the one
|
|
27
|
+
* collection a SELLER can also own, so its endpoints live under
|
|
28
|
+
* `SELLER_ENDPOINTS` and its clone has a bespoke redirect to the copy's editor.
|
|
29
|
+
* Everything here is admin-owned and differs only by three strings, so eight
|
|
30
|
+
* near-identical files would trip the Duplication Framework's Rule of Three
|
|
31
|
+
* immediately. One table, one component.
|
|
32
|
+
*
|
|
33
|
+
* ## Why the redirect lands on the ADMIN list
|
|
34
|
+
*
|
|
35
|
+
* You deleted the record from its own public page, so that page is now a 404 —
|
|
36
|
+
* staying is not an option and the public index tells you nothing about whether
|
|
37
|
+
* the delete worked. The admin list is where the absence is verifiable.
|
|
38
|
+
* `ProductOwnerQuickActions` differs deliberately: a seller may delete a
|
|
39
|
+
* product and has no admin list to land on.
|
|
40
|
+
*
|
|
41
|
+
* @tag domain:admin
|
|
42
|
+
* @tag layer:components
|
|
43
|
+
* @tag access:client
|
|
44
|
+
*/
|
|
45
|
+
import { useCallback } from "react";
|
|
46
|
+
import { OwnerQuickActions } from "./OwnerQuickActions.js";
|
|
47
|
+
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints.js";
|
|
48
|
+
import { ROUTES } from "../../../next/routing/route-map.js";
|
|
49
|
+
const WIRING = {
|
|
50
|
+
CATEGORY: {
|
|
51
|
+
endpoint: ADMIN_ENDPOINTS.CATEGORY_BY_ID,
|
|
52
|
+
editHref: (id) => String(ROUTES.ADMIN.CATEGORIES_EDIT(id)),
|
|
53
|
+
afterDelete: String(ROUTES.ADMIN.CATEGORIES),
|
|
54
|
+
},
|
|
55
|
+
PART: {
|
|
56
|
+
endpoint: ADMIN_ENDPOINTS.PART_BY_ID,
|
|
57
|
+
editHref: (id) => String(ROUTES.ADMIN.PARTS_EDIT(id)),
|
|
58
|
+
afterDelete: String(ROUTES.ADMIN.PARTS),
|
|
59
|
+
},
|
|
60
|
+
BEY: {
|
|
61
|
+
endpoint: ADMIN_ENDPOINTS.BEY_BY_ID,
|
|
62
|
+
editHref: (id) => String(ROUTES.ADMIN.BEYS_EDIT(id)),
|
|
63
|
+
afterDelete: String(ROUTES.ADMIN.BEYS),
|
|
64
|
+
},
|
|
65
|
+
BRAND: {
|
|
66
|
+
endpoint: ADMIN_ENDPOINTS.BRAND_BY_ID,
|
|
67
|
+
editHref: (id) => String(ROUTES.ADMIN.BRANDS_EDIT(id)),
|
|
68
|
+
afterDelete: String(ROUTES.ADMIN.BRANDS),
|
|
69
|
+
},
|
|
70
|
+
BUNDLE: {
|
|
71
|
+
endpoint: ADMIN_ENDPOINTS.BUNDLE_BY_ID,
|
|
72
|
+
editHref: (id) => String(ROUTES.ADMIN.BUNDLES_EDIT(id)),
|
|
73
|
+
afterDelete: String(ROUTES.ADMIN.BUNDLES),
|
|
74
|
+
},
|
|
75
|
+
GROUP: {
|
|
76
|
+
endpoint: ADMIN_ENDPOINTS.GROUPED_LISTING_BY_ID,
|
|
77
|
+
editHref: (id) => String(ROUTES.ADMIN.GROUPED_LISTINGS_EDIT(id)),
|
|
78
|
+
afterDelete: String(ROUTES.ADMIN.GROUPED_LISTINGS),
|
|
79
|
+
},
|
|
80
|
+
EVENT: {
|
|
81
|
+
endpoint: ADMIN_ENDPOINTS.EVENT_BY_ID,
|
|
82
|
+
editHref: (id) => String(ROUTES.ADMIN.EVENTS_EDIT(id)),
|
|
83
|
+
afterDelete: String(ROUTES.ADMIN.EVENTS),
|
|
84
|
+
},
|
|
85
|
+
BLOG: {
|
|
86
|
+
endpoint: ADMIN_ENDPOINTS.BLOG_BY_ID,
|
|
87
|
+
editHref: (id) => String(ROUTES.ADMIN.BLOG_EDIT(id)),
|
|
88
|
+
afterDelete: String(ROUTES.ADMIN.BLOG),
|
|
89
|
+
},
|
|
90
|
+
/*
|
|
91
|
+
* A franchise row IS a category (`categoryType: "franchise"`), so it shares
|
|
92
|
+
* the category endpoint and editor — the same reasoning `RESOURCE_LEAVES`
|
|
93
|
+
* uses to give it the category copy. Only the landing page differs.
|
|
94
|
+
*/
|
|
95
|
+
FRANCHISE: {
|
|
96
|
+
endpoint: ADMIN_ENDPOINTS.CATEGORY_BY_ID,
|
|
97
|
+
editHref: (id) => String(ROUTES.ADMIN.CATEGORIES_EDIT(id)),
|
|
98
|
+
afterDelete: String(ROUTES.ADMIN.CATEGORIES),
|
|
99
|
+
},
|
|
100
|
+
SUBLISTING: {
|
|
101
|
+
endpoint: ADMIN_ENDPOINTS.SUBLISTING_CATEGORY_BY_ID,
|
|
102
|
+
editHref: (id) => String(ROUTES.ADMIN.SUBLISTING_CATEGORIES_EDIT(id)),
|
|
103
|
+
afterDelete: String(ROUTES.ADMIN.SUBLISTING_CATEGORIES),
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
export function RecordOwnerQuickActions({ resource, recordId, recordLabel, ownerId, storeId, placement = "detail", onMedia, className, }) {
|
|
107
|
+
const wiring = WIRING[resource];
|
|
108
|
+
/*
|
|
109
|
+
* 🛑 THROWS on a failed DELETE rather than returning quietly.
|
|
110
|
+
*
|
|
111
|
+
* `OwnerQuickActions.handleConfirmedDelete` catches and toasts, and success
|
|
112
|
+
* navigates away — so a swallowed failure is indistinguishable from "it
|
|
113
|
+
* worked but the page did not move", and the obvious user response is to
|
|
114
|
+
* press the button again. Returning early on `!res.ok` is the bug
|
|
115
|
+
* `ProductOwnerQuickActions` documents having had.
|
|
116
|
+
*/
|
|
117
|
+
const handleDelete = useCallback(async () => {
|
|
118
|
+
const res = await fetch(wiring.endpoint(recordId), { method: "DELETE" });
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
const body = (await res.json().catch(() => null));
|
|
121
|
+
throw Object.assign(new Error("Delete failed"), { code: body?.code });
|
|
122
|
+
}
|
|
123
|
+
if (typeof window !== "undefined") {
|
|
124
|
+
window.location.assign(wiring.afterDelete);
|
|
125
|
+
}
|
|
126
|
+
}, [wiring, recordId]);
|
|
127
|
+
return (_jsx(OwnerQuickActions, { resource: resource, placement: placement, onMedia: onMedia, className: className, recordLabel: recordLabel, ownerId: ownerId, storeId: storeId, editHref: wiring.editHref(recordId), onDelete: handleDelete }));
|
|
128
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReferenceRecordEditor — correct one row of a GENERATED reference database.
|
|
3
|
+
*
|
|
4
|
+
* ── 🛑 ONE COMPONENT, TWO FIELD LISTS ────────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* Parts and beys differ only in WHICH fields a human may own. Loading the row,
|
|
7
|
+
* PATCHing it, surfacing a server error on the right field, and telling the
|
|
8
|
+
* operator what a correction means for the next reseed are identical — so they
|
|
9
|
+
* are written once. The Duplication Framework's "same prop surface, same
|
|
10
|
+
* return shape" test points here, and the alternative was two files whose
|
|
11
|
+
* error handling would drift.
|
|
12
|
+
*
|
|
13
|
+
* ── 🛑 WHAT THIS DELIBERATELY IS NOT ─────────────────────────────────────
|
|
14
|
+
*
|
|
15
|
+
* It is not a create form. Both collections are generated, so a row authored
|
|
16
|
+
* by hand has no source and vanishes on the next regeneration. There is no
|
|
17
|
+
* code path here that POSTs.
|
|
18
|
+
*
|
|
19
|
+
* It also shows no DERIVED field as editable. A bey's summed mass, its ratings
|
|
20
|
+
* and its coverage records are computed from the composition and each carries a
|
|
21
|
+
* coverage claim; a hand-typed derived value is a number whose stated
|
|
22
|
+
* provenance is no longer true.
|
|
23
|
+
*
|
|
24
|
+
* @tag domain:admin
|
|
25
|
+
* @tag layer:feature
|
|
26
|
+
* @tag access:client
|
|
27
|
+
*/
|
|
28
|
+
import React from "react";
|
|
29
|
+
/** One editable field. `kind` picks the input, nothing more. */
|
|
30
|
+
export interface ReferenceEditorField {
|
|
31
|
+
name: string;
|
|
32
|
+
label: string;
|
|
33
|
+
kind?: "text" | "number";
|
|
34
|
+
hint?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ReferenceRecordEditorProps {
|
|
37
|
+
/** `ADMIN_ENDPOINTS.PART_BY_ID(id)` / `BEY_BY_ID(id)` — already applied. */
|
|
38
|
+
endpoint: string;
|
|
39
|
+
/** What the record is called, for copy. "part" / "Beyblade". */
|
|
40
|
+
noun: string;
|
|
41
|
+
fields: readonly ReferenceEditorField[];
|
|
42
|
+
/** Where the reference page for this record lives, so the operator can check their work. */
|
|
43
|
+
publicHref?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function ReferenceRecordEditor({ endpoint, noun, fields, publicHref, }: ReferenceRecordEditorProps): React.JSX.Element;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* ReferenceRecordEditor — correct one row of a GENERATED reference database.
|
|
5
|
+
*
|
|
6
|
+
* ── 🛑 ONE COMPONENT, TWO FIELD LISTS ────────────────────────────────────
|
|
7
|
+
*
|
|
8
|
+
* Parts and beys differ only in WHICH fields a human may own. Loading the row,
|
|
9
|
+
* PATCHing it, surfacing a server error on the right field, and telling the
|
|
10
|
+
* operator what a correction means for the next reseed are identical — so they
|
|
11
|
+
* are written once. The Duplication Framework's "same prop surface, same
|
|
12
|
+
* return shape" test points here, and the alternative was two files whose
|
|
13
|
+
* error handling would drift.
|
|
14
|
+
*
|
|
15
|
+
* ── 🛑 WHAT THIS DELIBERATELY IS NOT ─────────────────────────────────────
|
|
16
|
+
*
|
|
17
|
+
* It is not a create form. Both collections are generated, so a row authored
|
|
18
|
+
* by hand has no source and vanishes on the next regeneration. There is no
|
|
19
|
+
* code path here that POSTs.
|
|
20
|
+
*
|
|
21
|
+
* It also shows no DERIVED field as editable. A bey's summed mass, its ratings
|
|
22
|
+
* and its coverage records are computed from the composition and each carries a
|
|
23
|
+
* coverage claim; a hand-typed derived value is a number whose stated
|
|
24
|
+
* provenance is no longer true.
|
|
25
|
+
*
|
|
26
|
+
* @tag domain:admin
|
|
27
|
+
* @tag layer:feature
|
|
28
|
+
* @tag access:client
|
|
29
|
+
*/
|
|
30
|
+
import React from "react";
|
|
31
|
+
import { Alert, Button, Form, FieldInput, Stack, Text, TextLink } from "../../../ui/index.js";
|
|
32
|
+
import { apiClient } from "../../../http/index.js";
|
|
33
|
+
import { useToast } from "../../../ui/components/toast-context.js";
|
|
34
|
+
import { normalizeError } from "../../../errors/normalize.js";
|
|
35
|
+
import { toUserMessage } from "../../../errors/error-display-map.js";
|
|
36
|
+
export function ReferenceRecordEditor({ endpoint, noun, fields, publicHref, }) {
|
|
37
|
+
const { showToast } = useToast();
|
|
38
|
+
const [values, setValues] = React.useState({});
|
|
39
|
+
const [owned, setOwned] = React.useState([]);
|
|
40
|
+
const [loading, setLoading] = React.useState(true);
|
|
41
|
+
const [saving, setSaving] = React.useState(false);
|
|
42
|
+
const [loadError, setLoadError] = React.useState(null);
|
|
43
|
+
React.useEffect(() => {
|
|
44
|
+
let cancelled = false;
|
|
45
|
+
(async () => {
|
|
46
|
+
try {
|
|
47
|
+
const row = await apiClient.get(endpoint);
|
|
48
|
+
if (cancelled)
|
|
49
|
+
return;
|
|
50
|
+
const next = {};
|
|
51
|
+
for (const f of fields) {
|
|
52
|
+
const v = row?.[f.name];
|
|
53
|
+
/*
|
|
54
|
+
* 🛑 An ABSENT field becomes an empty string, not "undefined". Both
|
|
55
|
+
* render, and only one of them is honest — and on save an empty
|
|
56
|
+
* string is dropped rather than written, so an untouched empty field
|
|
57
|
+
* cannot blank a value the generator owns.
|
|
58
|
+
*/
|
|
59
|
+
next[f.name] = v === null || v === undefined ? "" : String(v);
|
|
60
|
+
}
|
|
61
|
+
setValues(next);
|
|
62
|
+
setOwned(Array.isArray(row?.adminEditedFields) ? row.adminEditedFields : []);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
const e = normalizeError(err);
|
|
66
|
+
if (!cancelled)
|
|
67
|
+
setLoadError(e.message);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
if (!cancelled)
|
|
71
|
+
setLoading(false);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
return () => {
|
|
75
|
+
cancelled = true;
|
|
76
|
+
};
|
|
77
|
+
}, [endpoint, fields]);
|
|
78
|
+
/**
|
|
79
|
+
* Build the PATCH body.
|
|
80
|
+
*
|
|
81
|
+
* 🛑 Only NON-EMPTY values are sent, and numbers are coerced.
|
|
82
|
+
*
|
|
83
|
+
* An empty input means "I did not set this", not "write an empty string".
|
|
84
|
+
* Sending it would both blank a real value AND mark the field as
|
|
85
|
+
* admin-owned, freezing the blank in place against every future reseed —
|
|
86
|
+
* a one-click way to permanently delete data from a generated row.
|
|
87
|
+
*/
|
|
88
|
+
const buildPatch = React.useCallback(() => {
|
|
89
|
+
const patch = {};
|
|
90
|
+
for (const f of fields) {
|
|
91
|
+
const raw = (values[f.name] ?? "").trim();
|
|
92
|
+
if (!raw)
|
|
93
|
+
continue;
|
|
94
|
+
patch[f.name] = f.kind === "number" ? Number(raw) : raw;
|
|
95
|
+
}
|
|
96
|
+
return patch;
|
|
97
|
+
}, [fields, values]);
|
|
98
|
+
/**
|
|
99
|
+
* Put a failure where the operator can act on it.
|
|
100
|
+
*
|
|
101
|
+
* 🛑 Zod issues go to their OWN FIELD; everything else becomes one toast
|
|
102
|
+
* built by `toUserMessage`. Never the server's own message: a raw fallback
|
|
103
|
+
* is what rendered a Node MODULE_NOT_FOUND with a full require stack inside
|
|
104
|
+
* a bid modal (Root Cause #86), and `mapToHttpError` scrubs 5xx text in
|
|
105
|
+
* production anyway.
|
|
106
|
+
*/
|
|
107
|
+
const reportFailure = React.useCallback((err,
|
|
108
|
+
/** Already normalized by the caller — see the note at the catch site. */
|
|
109
|
+
fallbackMessage, setFieldError) => {
|
|
110
|
+
const issues = err?.issues;
|
|
111
|
+
if (issues?.length) {
|
|
112
|
+
for (const issue of issues)
|
|
113
|
+
setFieldError(String(issue.path?.[0] ?? ""), issue.message);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const code = err?.code;
|
|
117
|
+
const message = code ? toUserMessage(code, undefined) : fallbackMessage;
|
|
118
|
+
showToast(message, "error");
|
|
119
|
+
}, [showToast]);
|
|
120
|
+
const save = React.useCallback(async (setFieldError, clearErrors) => {
|
|
121
|
+
clearErrors();
|
|
122
|
+
setSaving(true);
|
|
123
|
+
try {
|
|
124
|
+
await apiClient.patch(endpoint, buildPatch());
|
|
125
|
+
showToast(`${noun[0].toUpperCase()}${noun.slice(1)} updated.`, "success");
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const e = normalizeError(err);
|
|
129
|
+
reportFailure(err, e.message, setFieldError);
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
setSaving(false);
|
|
133
|
+
}
|
|
134
|
+
}, [endpoint, buildPatch, noun, showToast, reportFailure]);
|
|
135
|
+
if (loading)
|
|
136
|
+
return _jsx(Text, { color: "muted", children: "Loading\u2026" });
|
|
137
|
+
if (loadError) {
|
|
138
|
+
return (_jsx(Alert, { variant: "error", title: `Could not load this ${noun}`, children: _jsx(Text, { size: "sm", children: loadError }) }));
|
|
139
|
+
}
|
|
140
|
+
/*
|
|
141
|
+
* 🛑 No `className` on `<Form>` — the `<Stack gap="md">` inside already owns
|
|
142
|
+
* the spacing, so `space-y-4` was a second, competing source of it
|
|
143
|
+
* (audit-variant-prop-coverage: a layout token belongs in a variant prop).
|
|
144
|
+
*
|
|
145
|
+
* 🛑 And this is a PLAIN comment, above the `return`, not a `{/* … *␣/}` JSX
|
|
146
|
+
* one below it. I wrote it as JSX first and it broke the parse: a JSX comment
|
|
147
|
+
* between `return (` and the root element is a second expression, so the
|
|
148
|
+
* return has two children and no wrapper. `tsc` caught it — the first
|
|
149
|
+
* typecheck this session was allowed to run — which is exactly the class of
|
|
150
|
+
* error the 4 GB no-build cap was hiding.
|
|
151
|
+
*/
|
|
152
|
+
return (_jsx(Form, { children: ({ setFieldError, clearErrors }) => (_jsxs(Stack, { gap: "md", className: "min-w-0", children: [_jsxs(Alert, { variant: "info", title: "This record is generated", children: [_jsxs(Text, { size: "sm", children: [`This ${noun} is built from a crawled source by a committed generator. A field you `, "change here is marked as yours and will not be overwritten the next time the database is regenerated \u2014 every field you leave alone keeps getting the generator's improvements."] }), owned.length > 0 && (_jsx(Text, { size: "sm", color: "muted", children: `Already corrected by hand: ${owned.join(", ")}` }))] }), fields.map((f) => (_jsx(FieldInput, { name: f.name, label: f.label, type: f.kind === "number" ? "number" : "text", hint: f.hint, value: values[f.name] ?? "", onChange: (v) => setValues((p) => ({ ...p, [f.name]: v })) }, f.name))), _jsx(Button, { type: "button", isLoading: saving, onClick: () => save(setFieldError, clearErrors), children: "Save correction" }), publicHref && (_jsx(Text, { size: "sm", color: "muted", children: _jsx(TextLink, { href: publicHref, children: "View the public reference page" }) }))] })) }));
|
|
153
|
+
}
|
|
@@ -73,7 +73,7 @@ export type NotificationUpdateInput = Partial<Pick<NotificationDocument, "isRead
|
|
|
73
73
|
export declare const notificationQueryHelpers: {
|
|
74
74
|
readonly byUser: (userId: string) => readonly ["userId", "==", string];
|
|
75
75
|
readonly unread: (userId: string) => readonly [readonly ["userId", "==", string], readonly ["isRead", "==", false]];
|
|
76
|
-
readonly byType: (type: NotificationType) => readonly ["type", "==", "welcome" | "promotion" | "order_placed" | "order_confirmed" | "order_shipped" | "order_delivered" | "order_cancelled" | "bid_placed" | "bid_outbid" | "bid_won" | "bid_lost" | "auction_ended" | "review_approved" | "review_replied" | "product_available" | "
|
|
76
|
+
readonly byType: (type: NotificationType) => readonly ["type", "==", "system" | "welcome" | "promotion" | "order_placed" | "order_confirmed" | "order_shipped" | "order_delivered" | "order_cancelled" | "bid_placed" | "bid_outbid" | "bid_won" | "bid_lost" | "auction_ended" | "review_approved" | "review_replied" | "product_available" | "account_action" | "support_ticket_update" | "scam_report_update" | "offer_received" | "offer_responded" | "offer_expired" | "offer_counter_accepted" | "refund_initiated" | "prize_won" | "prize_reveal_expired" | "emi_installment_due_soon" | "emi_installment_overdue" | "payment_review" | "catalogue_images_stale" | "message_received"];
|
|
77
77
|
};
|
|
78
78
|
export interface TrustBarItem {
|
|
79
79
|
icon: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { ProductOwnerQuickActions } from "../../products/components/ProductOwnerQuickActions.js";
|
|
3
4
|
import { normalizeError } from "../../../errors/normalize.js";
|
|
4
5
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
6
|
import { useRouter } from "next/navigation.js";
|
|
@@ -181,11 +182,23 @@ export function MarketplaceAuctionCard({ product, buyoutPrice, className = "", v
|
|
|
181
182
|
countdownClass, mergedLabels, handleWishlist, handleNavigate,
|
|
182
183
|
};
|
|
183
184
|
const card = (_jsxs(BaseListingCard, { isSelected: isSelected, isDisabled: isEnded, variant: baseVariant, className: className, onMouseDown: !isSelected ? longPress.onMouseDown : undefined, onMouseUp: !isSelected ? longPress.onMouseUp : undefined, onMouseLeave: !isSelected ? longPress.onMouseLeave : undefined, onTouchStart: !isSelected ? longPress.onTouchStart : undefined, onTouchEnd: !isSelected ? longPress.onTouchEnd : undefined, onTouchCancel: !isSelected ? longPress.onTouchCancel : undefined, children: [renderAuctionCardHero({ product, auctionHref, currentSrc, hovered, images, imageIndex, hasVideo, isEnded, isEndingSoon, isSelected, selectable, mergedLabels, onSelect, setHovered, handleSelect }), _jsx(BaseListingCard.Info, { variant: baseVariant, children: baseVariant === "list" ? renderAuctionCardInfoList(cardInfoProps) : renderAuctionCardInfoGrid(cardInfoProps) })] }));
|
|
184
|
-
|
|
185
|
+
/*
|
|
186
|
+
* 🛑 Default, not opt-in. Nothing in either repo ever passed
|
|
187
|
+
* `renderOwnerActions`, so this toolbar was unreachable on every grid that
|
|
188
|
+
* mounts this card (Root Cause #8 — a slot shell rendered with zero render
|
|
189
|
+
* props). A card is resource-specific by construction, so it names its own
|
|
190
|
+
* resource rather than being threaded one; the prop stays as an override.
|
|
191
|
+
*/
|
|
192
|
+
const ownerActions = renderOwnerActions
|
|
193
|
+
? renderOwnerActions()
|
|
194
|
+
: product.id
|
|
195
|
+
? (_jsx(ProductOwnerQuickActions, { productId: String(product.id), storeId: product.storeId ? String(product.storeId) : undefined, recordLabel: product.title, placement: "card" }))
|
|
196
|
+
: null;
|
|
197
|
+
if (!ownerActions)
|
|
185
198
|
return card;
|
|
186
199
|
/*
|
|
187
200
|
* Sibling of the card, never a child — see the prop's docstring. `z-20`
|
|
188
201
|
* clears this card's own overlays, which all sit at `z-10`.
|
|
189
202
|
*/
|
|
190
|
-
return (_jsxs(Div, { className: "relative h-full", children: [card, _jsx(Div, { className: "absolute right-2 bottom-2 z-20", children:
|
|
203
|
+
return (_jsxs(Div, { className: "relative h-full", children: [card, _jsx(Div, { className: "absolute right-2 bottom-2 z-20", children: ownerActions })] }));
|
|
191
204
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Permission naming: admin:resource:action
|
|
12
12
|
* Ban action naming: plain verb phrase — write_reviews, place_bids, etc.
|
|
13
13
|
*/
|
|
14
|
-
export type Permission = "admin:dashboard:view" | "admin:users:read" | "admin:users:write" | "admin:users:delete" | "admin:user-bans:read" | "admin:user-bans:write" | "admin:products:read" | "admin:products:write" | "admin:products:delete" | "admin:orders:read" | "admin:orders:write" | "admin:returns:read" | "admin:returns:write" | "admin:stores:read" | "admin:stores:write" | "admin:store-addresses:read" | "admin:addresses:read" | "admin:addresses:write" | "admin:analytics:view" | "admin:payouts:read" | "admin:payouts:write" | "admin:audit-log:read" | "admin:categories:read" | "admin:categories:write" | "admin:categories:delete" | "admin:brands:read" | "admin:brands:write" | "admin:brands:delete" | "admin:coupons:read" | "admin:coupons:write" | "admin:coupons:delete" | "admin:deals:read" | "admin:deals:write" | "admin:featured:read" | "admin:featured:write" | "admin:reviews:read" | "admin:reviews:write" | "admin:reviews:delete" | "admin:blog:read" | "admin:blog:write" | "admin:blog:delete" | "admin:blog:publish" | "admin:bids:read" | "admin:bids:write" | "admin:offers:read" | "admin:offers:write" | "admin:media:read" | "admin:media:write" | "admin:media:delete" | "admin:site:read" | "admin:site:write" | "admin:settings:write" | "admin:navigation:read" | "admin:navigation:write" | "admin:sections:read" | "admin:sections:write" | "admin:carousel:read" | "admin:carousel:write" | "admin:carousel:delete" | "admin:ads:read" | "admin:ads:write" | "admin:ads:delete" | "admin:faqs:read" | "admin:faqs:write" | "admin:faqs:delete" | "admin:tester-checklist:read" | "admin:tester-checklist:write" | "admin:tester-checklist:delete" | "admin:tester-feedback:read" | "admin:tester-feedback:write" | "admin:newsletter:read" | "admin:newsletter:write" | "admin:contact:read"
|
|
14
|
+
export type Permission = "admin:dashboard:view" | "admin:users:read" | "admin:users:write" | "admin:users:delete" | "admin:user-bans:read" | "admin:user-bans:write" | "admin:products:read" | "admin:products:write" | "admin:products:delete" | "admin:orders:read" | "admin:orders:write" | "admin:returns:read" | "admin:returns:write" | "admin:stores:read" | "admin:stores:write" | "admin:store-addresses:read" | "admin:addresses:read" | "admin:addresses:write" | "admin:analytics:view" | "admin:payouts:read" | "admin:payouts:write" | "admin:audit-log:read" | "admin:categories:read" | "admin:categories:write" | "admin:categories:delete" | "admin:parts:read" | "admin:parts:write" | "admin:parts:delete" | "admin:beys:read" | "admin:beys:write" | "admin:beys:delete" | "admin:brands:read" | "admin:brands:write" | "admin:brands:delete" | "admin:coupons:read" | "admin:coupons:write" | "admin:coupons:delete" | "admin:deals:read" | "admin:deals:write" | "admin:featured:read" | "admin:featured:write" | "admin:reviews:read" | "admin:reviews:write" | "admin:reviews:delete" | "admin:blog:read" | "admin:blog:write" | "admin:blog:delete" | "admin:blog:publish" | "admin:bids:read" | "admin:bids:write" | "admin:offers:read" | "admin:offers:write" | "admin:media:read" | "admin:media:write" | "admin:media:delete" | "admin:site:read" | "admin:site:write" | "admin:settings:write" | "admin:navigation:read" | "admin:navigation:write" | "admin:sections:read" | "admin:sections:write" | "admin:carousel:read" | "admin:carousel:write" | "admin:carousel:delete" | "admin:ads:read" | "admin:ads:write" | "admin:ads:delete" | "admin:faqs:read" | "admin:faqs:write" | "admin:faqs:delete" | "admin:tester-checklist:read" | "admin:tester-checklist:write" | "admin:tester-checklist:delete" | "admin:tester-feedback:read" | "admin:tester-feedback:write" | "admin:newsletter:read" | "admin:newsletter:write" | "admin:contact:read"
|
|
15
15
|
/** Destructive/mutating contact-submission actions. Added 2026-08-29 —
|
|
16
16
|
* `DELETE /api/admin/contact-submissions/[id]` declared `admin:contact:delete`,
|
|
17
17
|
* which is not a member of this union and therefore could never be granted. */
|
|
@@ -131,6 +131,12 @@ export const PERMISSION_GROUPS = {
|
|
|
131
131
|
"admin:categories:read",
|
|
132
132
|
"admin:categories:write",
|
|
133
133
|
"admin:categories:delete",
|
|
134
|
+
"admin:parts:read",
|
|
135
|
+
"admin:parts:write",
|
|
136
|
+
"admin:parts:delete",
|
|
137
|
+
"admin:beys:read",
|
|
138
|
+
"admin:beys:write",
|
|
139
|
+
"admin:beys:delete",
|
|
134
140
|
"admin:brands:read",
|
|
135
141
|
"admin:brands:write",
|
|
136
142
|
"admin:brands:delete",
|
|
@@ -281,6 +287,8 @@ export const ROUTE_PERMISSION_MAP = {
|
|
|
281
287
|
"/admin/catalogue-approvals": "admin:catalogue:read",
|
|
282
288
|
"/admin/grouped-listings": "admin:grouped-listings:read",
|
|
283
289
|
"/admin/categories": "admin:categories:read",
|
|
290
|
+
"/admin/parts": "admin:parts:read",
|
|
291
|
+
"/admin/beys": "admin:beys:read",
|
|
284
292
|
"/admin/brands": "admin:brands:read",
|
|
285
293
|
"/admin/coupons": "admin:coupons:read",
|
|
286
294
|
"/admin/deals": "admin:deals:read",
|
|
@@ -437,7 +445,10 @@ export const PERMISSION_DOMAINS = [
|
|
|
437
445
|
{ label: "Orders & Returns", prefix: "admin:orders:|admin:returns:|admin:offers:" },
|
|
438
446
|
{ label: "Stores", prefix: "admin:stores:|admin:store-addresses:" },
|
|
439
447
|
{ label: "Finance", prefix: "admin:analytics:|admin:payouts:" },
|
|
440
|
-
{
|
|
448
|
+
{
|
|
449
|
+
label: "Catalog",
|
|
450
|
+
prefix: "admin:categories:|admin:parts:|admin:beys:|admin:brands:|admin:coupons:|admin:deals:|admin:featured:",
|
|
451
|
+
},
|
|
441
452
|
{
|
|
442
453
|
label: "Content",
|
|
443
454
|
prefix: "admin:reviews:|admin:blog:|admin:bids:|admin:media:",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One bey's public page — what it is, what it is built from, who used it.
|
|
3
|
+
*
|
|
4
|
+
* ── 🛑 NO MONEY ON THIS PAGE, DELIBERATELY ─────────────────────────────────
|
|
5
|
+
*
|
|
6
|
+
* Prices are hidden from signed-out visitors, so any amount here would need
|
|
7
|
+
* `<GatedPrice>` and make this a client component. Listing rows carry a title,
|
|
8
|
+
* a condition and a link; the price lives one click away on the listing, where
|
|
9
|
+
* the gate already is. Same rule as `PartDetailPageView` and `/search`: a row
|
|
10
|
+
* with nothing to gate has nothing to leak, and no `offers.price` is emitted
|
|
11
|
+
* so no paywall declaration is needed either.
|
|
12
|
+
*
|
|
13
|
+
* 🛑 `price` IS on the document and is deliberately not rendered. It is the
|
|
14
|
+
* source's original retail price (`1404¥`), not our listing price — showing it
|
|
15
|
+
* beside real listings would read as an offer.
|
|
16
|
+
*
|
|
17
|
+
* ── 🛑 THE SOURCE LINK IS NOT OPTIONAL ────────────────────────────────────
|
|
18
|
+
*
|
|
19
|
+
* The facts here are extracted from a CC-BY-SA corpus. Taking facts only and
|
|
20
|
+
* linking back is what keeps us clear of share-alike, and `sourceUrl` was
|
|
21
|
+
* stored on ~5,500 rows while being rendered on NONE of them. Storing it is
|
|
22
|
+
* not discharging the obligation.
|
|
23
|
+
*/
|
|
24
|
+
import React from "react";
|
|
25
|
+
import type { BeyDocument, BeyProductDocument } from "../schemas/firestore";
|
|
26
|
+
/** One live listing row. Deliberately money-free — see the header. */
|
|
27
|
+
export interface BeyListingRow {
|
|
28
|
+
id: string;
|
|
29
|
+
title: string;
|
|
30
|
+
slug?: string;
|
|
31
|
+
condition?: string;
|
|
32
|
+
href: string;
|
|
33
|
+
}
|
|
34
|
+
export interface BeyDetailPageViewProps {
|
|
35
|
+
bey: BeyDocument;
|
|
36
|
+
/** Products whose assortment contains this bey. */
|
|
37
|
+
products: readonly BeyProductDocument[];
|
|
38
|
+
/** Live listings, from the shared public product query. */
|
|
39
|
+
listings: readonly BeyListingRow[];
|
|
40
|
+
/** `total` is a FLOOR when the bounded fetch saturated. */
|
|
41
|
+
listingsTruncated?: boolean;
|
|
42
|
+
allListingsHref: string;
|
|
43
|
+
/** A part's own page, when the composition entry resolved to a glossary id. */
|
|
44
|
+
hrefForPart: (partId: string) => string | null;
|
|
45
|
+
/** This bey's category leaf, when one exists (116 beys have no leaf). */
|
|
46
|
+
categoryHref?: string | null;
|
|
47
|
+
/** A character's page, for a resolved owner. */
|
|
48
|
+
hrefForCharacter?: (slug: string) => string;
|
|
49
|
+
}
|
|
50
|
+
export declare function BeyDetailPageView({ bey, products, listings, listingsTruncated, allListingsHref, hrefForPart, categoryHref, hrefForCharacter, }: BeyDetailPageViewProps): React.JSX.Element;
|