@mohasinac/appkit 4.11.2 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/server/features/checkout/actions.d.ts +40 -3
- package/dist/_internal/server/features/checkout/actions.js +232 -47
- package/dist/_internal/server/features/checkout/data.d.ts +10 -0
- package/dist/_internal/server/features/orders/adapters.js +20 -0
- package/dist/_internal/server/features/products/data.d.ts +12 -3
- package/dist/_internal/server/features/products/data.js +55 -4
- package/dist/_internal/server/features/products/index.d.ts +1 -1
- package/dist/_internal/server/features/products/index.js +1 -1
- package/dist/_internal/server/features/products/list-public.d.ts +47 -0
- package/dist/_internal/server/features/products/list-public.js +131 -6
- package/dist/_internal/server/features/reviews/data.d.ts +1 -1
- package/dist/_internal/server/features/reviews/data.js +3 -2
- package/dist/_internal/server/features/tester/visibility.js +3 -3
- package/dist/_internal/server/jobs/core/auctionSettlement.js +5 -2
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -1
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
- package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +2 -0
- package/dist/_internal/server/jobs/handlers/_helpers.js +4 -1
- package/dist/_internal/shared/checkout/lanes.d.ts +20 -0
- package/dist/_internal/shared/checkout/lanes.js +28 -0
- package/dist/_internal/shared/features/checkout/config.d.ts +4 -0
- package/dist/_internal/shared/features/checkout/config.js +8 -0
- package/dist/_internal/shared/features/promotions/schema.d.ts +0 -16
- package/dist/_internal/shared/features/promotions/schema.js +0 -2
- package/dist/_internal/shared/features/reviews/config.d.ts +8 -1
- package/dist/_internal/shared/features/reviews/config.js +8 -1
- package/dist/_internal/shared/fees/calculator.d.ts +34 -2
- package/dist/_internal/shared/fees/calculator.js +45 -1
- package/dist/_internal/shared/listing-types/_registry.d.ts +88 -1
- package/dist/_internal/shared/listing-types/_registry.js +63 -1
- package/dist/_internal/shared/listing-types/art/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/art/config.js +12 -0
- package/dist/_internal/shared/listing-types/auction/config.d.ts +53 -0
- package/dist/_internal/shared/listing-types/auction/config.js +17 -0
- package/dist/_internal/shared/listing-types/classified/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/classified/config.js +14 -0
- package/dist/_internal/shared/listing-types/digital-code/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/digital-code/config.js +12 -0
- package/dist/_internal/shared/listing-types/live/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/live/config.js +14 -0
- package/dist/_internal/shared/listing-types/pre-order/config.d.ts +110 -0
- package/dist/_internal/shared/listing-types/pre-order/config.js +14 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +44 -0
- package/dist/_internal/shared/listing-types/prize-draw/config.js +10 -0
- package/dist/_internal/shared/listing-types/standard/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/standard/config.js +9 -0
- package/dist/_internal/shared/listing-types/stickers/config.d.ts +59 -0
- package/dist/_internal/shared/listing-types/stickers/config.js +12 -0
- package/dist/client.d.ts +12 -2
- package/dist/client.js +8 -2
- package/dist/constants/api-endpoints.d.ts +6 -0
- package/dist/constants/api-endpoints.js +2 -0
- package/dist/constants/field-names.d.ts +12 -0
- package/dist/constants/field-names.js +12 -0
- package/dist/constants/table-keys.d.ts +2 -0
- package/dist/constants/table-keys.js +2 -0
- package/dist/features/account/components/UserOrdersView.js +27 -5
- package/dist/features/admin/components/AdminAddressesView.js +21 -11
- package/dist/features/admin/components/AdminArtView.d.ts +9 -0
- package/dist/features/admin/components/AdminArtView.js +11 -35
- package/dist/features/admin/components/AdminClassifiedView.d.ts +9 -0
- package/dist/features/admin/components/AdminClassifiedView.js +11 -35
- package/dist/features/admin/components/AdminCouponEditorView.js +1 -4
- package/dist/features/admin/components/AdminDigitalCodesView.d.ts +9 -0
- package/dist/features/admin/components/AdminDigitalCodesView.js +11 -42
- package/dist/features/admin/components/AdminLiveView.d.ts +9 -0
- package/dist/features/admin/components/AdminLiveView.js +11 -41
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +8 -1
- package/dist/features/admin/components/AdminOrderEditorView.js +4 -3
- package/dist/features/admin/components/AdminOrdersView.js +14 -1
- package/dist/features/admin/components/AdminPaymentMethodsView.js +18 -11
- package/dist/features/admin/components/AdminProductsView.js +34 -18
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +4 -2
- package/dist/features/admin/components/AdminStickersView.d.ts +9 -0
- package/dist/features/admin/components/AdminStickersView.js +11 -35
- package/dist/features/admin/constants/filter-tabs.d.ts +26 -9
- package/dist/features/admin/constants/filter-tabs.js +22 -9
- package/dist/features/admin/hooks/useAdminListing.js +7 -2
- package/dist/features/admin/schemas/firestore.d.ts +5 -0
- package/dist/features/admin/schemas/firestore.js +1 -0
- package/dist/features/auctions/actions/bid-actions.js +2 -2
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionBottomActions.js +1 -0
- package/dist/features/auctions/components/AuctionDetailPageView.js +13 -11
- package/dist/features/cart/components/CartDrawer.d.ts +9 -1
- package/dist/features/cart/components/CartDrawer.js +4 -3
- package/dist/features/cart/components/CartPriceBreakdown.d.ts +61 -0
- package/dist/features/cart/components/CartPriceBreakdown.js +25 -0
- package/dist/features/cart/components/StoreAddonsPicker.d.ts +47 -0
- package/dist/features/cart/components/StoreAddonsPicker.js +21 -0
- package/dist/features/cart/components/index.d.ts +4 -0
- package/dist/features/cart/components/index.js +2 -0
- package/dist/features/cart/repository/cart.repository.d.ts +20 -2
- package/dist/features/cart/repository/cart.repository.js +49 -0
- package/dist/features/cart/schemas/firestore.d.ts +26 -2
- package/dist/features/categories/components/BrandDetailTabs.js +31 -11
- package/dist/features/categories/components/CategoryDetailTabs.js +27 -7
- package/dist/features/categories/components/CategoryProductsListing.d.ts +9 -1
- package/dist/features/categories/components/CategoryProductsListing.js +5 -2
- package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
- package/dist/features/contact/email.js +5 -1
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +17 -16
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/homepage/components/ShopByCategorySection.js +1 -1
- package/dist/features/layout/AppLayoutShell.js +9 -2
- package/dist/features/layout/BottomActions.js +62 -6
- package/dist/features/layout/BottomActionsContext.d.ts +26 -0
- package/dist/features/layout/BottomActionsContext.js +18 -1
- package/dist/features/layout/hooks/useBottomActions.d.ts +12 -1
- package/dist/features/layout/hooks/useBottomActions.js +14 -1
- package/dist/features/layout/index.d.ts +1 -1
- package/dist/features/live/components/LiveItemDetailPageView.js +7 -6
- package/dist/features/orders/components/OrderAddonBadges.d.ts +36 -0
- package/dist/features/orders/components/OrderAddonBadges.js +28 -0
- package/dist/features/orders/components/index.d.ts +1 -0
- package/dist/features/orders/components/index.js +1 -0
- package/dist/features/orders/repository/orders.repository.d.ts +36 -0
- package/dist/features/orders/repository/orders.repository.js +18 -0
- package/dist/features/orders/types/index.d.ts +38 -0
- package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +1 -1
- package/dist/features/pre-orders/components/PreOrderBottomActions.js +3 -19
- package/dist/features/products/components/ArtStickersListView.js +5 -4
- package/dist/features/products/components/AuctionsIndexListing.js +1 -2
- package/dist/features/products/components/ListingBottomActions.d.ts +28 -0
- package/dist/features/products/components/ListingBottomActions.js +25 -0
- package/dist/features/products/components/PrizeDrawBottomActions.d.ts +1 -1
- package/dist/features/products/components/PrizeDrawBottomActions.js +3 -21
- package/dist/features/products/components/PrizeDrawsListingView.js +18 -33
- package/dist/features/products/components/ProductDetailActions.js +4 -0
- package/dist/features/products/components/ProductDetailPageView.js +7 -7
- package/dist/features/products/components/ProductsIndexListing.js +87 -11
- package/dist/features/products/components/ProductsIndexPageView.js +14 -2
- package/dist/features/products/config/listing-type-listing-config.d.ts +31 -0
- package/dist/features/products/config/listing-type-listing-config.js +74 -0
- package/dist/features/products/constants/listing-tabs.d.ts +43 -198
- package/dist/features/products/constants/listing-tabs.js +71 -58
- package/dist/features/products/constants/sieve.d.ts +104 -1
- package/dist/features/products/constants/sieve.js +27 -7
- package/dist/features/products/hooks/useProducts.js +14 -0
- package/dist/features/products/repository/products.repository.d.ts +45 -1
- package/dist/features/products/repository/products.repository.js +26 -3
- package/dist/features/products/types/index.d.ts +15 -0
- package/dist/features/products/utils/listing-badge-variant.d.ts +20 -1
- package/dist/features/products/utils/listing-badge-variant.js +26 -1
- package/dist/features/products/utils/listing-type.d.ts +24 -0
- package/dist/features/products/utils/listing-type.js +48 -0
- package/dist/features/promotions/actions/coupon-actions.d.ts +7 -0
- package/dist/features/promotions/actions/coupon-actions.js +12 -1
- package/dist/features/promotions/actions/coupon-stacking.d.ts +24 -0
- package/dist/features/promotions/actions/coupon-stacking.js +21 -0
- package/dist/features/promotions/actions/index.d.ts +1 -0
- package/dist/features/promotions/actions/index.js +1 -0
- package/dist/features/promotions/actions/seller-coupon-actions.d.ts +0 -1
- package/dist/features/promotions/actions/seller-coupon-actions.js +0 -1
- package/dist/features/promotions/components/CouponHelpDetails.d.ts +20 -0
- package/dist/features/promotions/components/CouponHelpDetails.js +17 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -1
- package/dist/features/promotions/components/index.d.ts +2 -0
- package/dist/features/promotions/components/index.js +1 -0
- package/dist/features/promotions/constants/coupon-help.d.ts +27 -0
- package/dist/features/promotions/constants/coupon-help.js +42 -0
- package/dist/features/promotions/repository/coupons.repository.d.ts +10 -1
- package/dist/features/promotions/repository/coupons.repository.js +22 -8
- package/dist/features/promotions/schemas/firestore.d.ts +0 -1
- package/dist/features/promotions/schemas/firestore.js +1 -1
- package/dist/features/promotions/schemas/index.d.ts +0 -20
- package/dist/features/promotions/schemas/index.js +0 -1
- package/dist/features/reviews/actions/review-actions.js +5 -1
- package/dist/features/reviews/components/ReviewDetailPageView.js +2 -1
- package/dist/features/reviews/components/ReviewFilters.d.ts +7 -1
- package/dist/features/reviews/components/ReviewFilters.js +4 -3
- package/dist/features/reviews/components/ReviewsIndexListing.d.ts +6 -0
- package/dist/features/reviews/components/ReviewsIndexListing.js +9 -109
- package/dist/features/reviews/components/ReviewsListingPanel.d.ts +41 -0
- package/dist/features/reviews/components/ReviewsListingPanel.js +226 -0
- package/dist/features/reviews/components/index.d.ts +2 -0
- package/dist/features/reviews/components/index.js +1 -0
- package/dist/features/reviews/hooks/useReviews.d.ts +8 -0
- package/dist/features/reviews/hooks/useReviews.js +14 -6
- package/dist/features/reviews/repository/reviews.repository.d.ts +29 -1
- package/dist/features/reviews/repository/reviews.repository.js +77 -41
- package/dist/features/reviews/types/index.d.ts +8 -1
- package/dist/features/seller/components/SellerOrdersView.js +2 -1
- package/dist/features/seller/components/SellerProductsCards.js +2 -2
- package/dist/features/seller/components/SellerProductsView.js +21 -18
- package/dist/features/stores/actions/store-query-actions.js +1 -1
- package/dist/features/stores/components/StoreArtStickersPageView.d.ts +21 -0
- package/dist/features/stores/components/StoreArtStickersPageView.js +30 -0
- package/dist/features/stores/components/StoreAuctionsListing.js +5 -11
- package/dist/features/stores/components/StoreAuctionsPageView.d.ts +4 -1
- package/dist/features/stores/components/StoreAuctionsPageView.js +17 -17
- package/dist/features/stores/components/StoreClassifiedsListing.js +7 -0
- package/dist/features/stores/components/StoreClassifiedsPageView.d.ts +4 -1
- package/dist/features/stores/components/StoreClassifiedsPageView.js +16 -12
- package/dist/features/stores/components/StoreDetailLayoutView.js +4 -3
- package/dist/features/stores/components/StoreDigitalCodesListing.js +5 -0
- package/dist/features/stores/components/StoreDigitalCodesPageView.d.ts +4 -1
- package/dist/features/stores/components/StoreDigitalCodesPageView.js +16 -12
- package/dist/features/stores/components/StoreLiveItemsListing.js +7 -0
- package/dist/features/stores/components/StoreLiveItemsPageView.d.ts +4 -1
- package/dist/features/stores/components/StoreLiveItemsPageView.js +16 -12
- package/dist/features/stores/components/StorePreOrdersListing.js +6 -11
- package/dist/features/stores/components/StorePreOrdersPageView.d.ts +4 -1
- package/dist/features/stores/components/StorePreOrdersPageView.js +17 -17
- package/dist/features/stores/components/StorePrizeDrawsPageView.d.ts +4 -8
- package/dist/features/stores/components/StorePrizeDrawsPageView.js +17 -22
- package/dist/features/stores/components/StoreProductsListing.d.ts +7 -1
- package/dist/features/stores/components/StoreProductsListing.js +3 -2
- package/dist/features/stores/components/StoreProductsPageView.d.ts +1 -1
- package/dist/features/stores/components/StoreProductsPageView.js +16 -21
- package/dist/features/stores/components/StoreReviewsListing.d.ts +4 -0
- package/dist/features/stores/components/StoreReviewsListing.js +7 -108
- package/dist/features/stores/schemas/index.d.ts +2 -2
- package/dist/features/tester/seed-data/coupons-tester-seed-data.js +3 -3
- package/dist/features/tester/seed-data/index.d.ts +1 -0
- package/dist/features/tester/seed-data/index.js +1 -0
- package/dist/features/tester/seed-data/offers-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/offers-tester-seed-data.js +61 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +939 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.js +11 -2
- package/dist/next/routing/route-map.d.ts +2 -0
- package/dist/next/routing/route-map.js +5 -0
- package/dist/react/hooks/useListingTypeFlags.d.ts +12 -19
- package/dist/react/hooks/useListingTypeFlags.js +4 -9
- package/dist/schemas/registry.d.ts +0 -12
- package/dist/seed/claimed-coupons-seed-data.js +3 -3
- package/dist/seed/coupons-seed-data.js +29 -10
- package/dist/seed/faq-seed-data.js +2 -2
- package/dist/seed/manifest.js +2 -2
- package/dist/seed/reviews-seed-data.js +52 -0
- package/dist/server-entry.d.ts +1 -0
- package/dist/server-entry.js +1 -0
- package/dist/styles.css +55 -39
- package/dist/tailwind-utilities.css +1 -1
- package/dist/ui/components/Checkbox.d.ts +10 -1
- package/dist/ui/components/Checkbox.js +14 -2
- package/dist/ui/components/Checkbox.style.css +11 -0
- package/dist/ui/components/FilterChipGroup.d.ts +21 -3
- package/dist/ui/components/FilterChipGroup.js +33 -4
- package/dist/ui/components/HorizontalScroller.d.ts +1 -2
- package/dist/ui/components/HorizontalScroller.js +9 -5
- package/dist/ui/components/HorizontalScroller.style.css +43 -38
- package/package.json +1 -1
|
@@ -47,6 +47,8 @@ export declare const TABLE_KEYS: {
|
|
|
47
47
|
readonly DELIVERY_METHOD: "deliveryMethod";
|
|
48
48
|
readonly SPECIES: "species";
|
|
49
49
|
readonly JURISDICTION: "jurisdiction";
|
|
50
|
+
readonly LIVE_SEX: "liveSex";
|
|
51
|
+
readonly LIVE_TRANSPORT_METHOD: "liveTransportMethod";
|
|
50
52
|
};
|
|
51
53
|
export type TableKey = (typeof TABLE_KEYS)[keyof typeof TABLE_KEYS];
|
|
52
54
|
export declare const VIEW_MODE: {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { sortBy, sieveFilter, SIEVE_OP } from "../../../utils/sieve-builder";
|
|
4
4
|
import { ACCOUNT_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
5
5
|
import { ROUTES } from "../../../constants/index";
|
|
6
6
|
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
7
|
-
import { Button, Div, Grid, Stack, Text, TextLink } from "../../../ui";
|
|
7
|
+
import { Button, Div, FilterChipGroup, Grid, Stack, Text, TextLink } from "../../../ui";
|
|
8
8
|
import { PaginatedSelect } from "../../../ui/components/PaginatedSelect";
|
|
9
9
|
import { DataListingView } from "../../admin/components/DataListingView";
|
|
10
10
|
import { OrderCard } from "../../orders/components/OrdersList";
|
|
@@ -16,6 +16,23 @@ const SORT_OPTIONS = [
|
|
|
16
16
|
{ value: sortBy("totalPrice", "DESC"), label: "Highest total" },
|
|
17
17
|
{ value: sortBy("totalPrice", "ASC"), label: "Lowest total" },
|
|
18
18
|
];
|
|
19
|
+
/**
|
|
20
|
+
* Lane tabs — the same auction > offer > standard split the cart and checkout
|
|
21
|
+
* use, viewed after the fact. Every `id` is EXACTLY a stored
|
|
22
|
+
* `OrderDocument.orderType` value (or "" for All): a tab id that doesn't
|
|
23
|
+
* match a real stored value returns zero rows forever with no error anywhere
|
|
24
|
+
* (CLAUDE.md Root Cause #33).
|
|
25
|
+
*
|
|
26
|
+
* "standard" is filtered in memory server-side, because orders written before
|
|
27
|
+
* `orderType` existed have no such field and a Firestore `==` would exclude
|
|
28
|
+
* every one of them.
|
|
29
|
+
*/
|
|
30
|
+
const ORDER_LANE_TABS = [
|
|
31
|
+
{ id: "", label: "All" },
|
|
32
|
+
{ id: "standard", label: "Normal" },
|
|
33
|
+
{ id: "auction", label: "Auction wins" },
|
|
34
|
+
{ id: "offer", label: "Offer wins" },
|
|
35
|
+
];
|
|
19
36
|
const STATUS_OPTIONS = [
|
|
20
37
|
{ value: "pending", label: "Pending" },
|
|
21
38
|
{ value: "processing", label: "Processing" },
|
|
@@ -31,7 +48,7 @@ export function UserOrdersView({ onOrderClick }) {
|
|
|
31
48
|
title: "My Orders",
|
|
32
49
|
searchPlaceholder: "Search by order id…",
|
|
33
50
|
emptyLabel: "You haven't placed any orders yet.",
|
|
34
|
-
filterKeys: ["status"],
|
|
51
|
+
filterKeys: ["status", "orderType"],
|
|
35
52
|
defaultSort: sortBy("createdAt", "DESC"),
|
|
36
53
|
queryKey: ["user", "orders", "listing"],
|
|
37
54
|
endpoint: ACCOUNT_ENDPOINTS.ORDERS,
|
|
@@ -39,8 +56,13 @@ export function UserOrdersView({ onOrderClick }) {
|
|
|
39
56
|
hideTableView: true,
|
|
40
57
|
mapRows: (response) => response.items ?? [],
|
|
41
58
|
getTotal: (response, rows) => response.total ?? rows.length,
|
|
42
|
-
buildFilters: (state) =>
|
|
43
|
-
|
|
59
|
+
buildFilters: (state) => [
|
|
60
|
+
state.status ? sieveFilter("status", SIEVE_OP.EQ, state.status) : null,
|
|
61
|
+
state.orderType ? sieveFilter("orderType", SIEVE_OP.EQ, state.orderType) : null,
|
|
62
|
+
]
|
|
63
|
+
.filter(Boolean)
|
|
64
|
+
.join(",") || undefined,
|
|
65
|
+
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(Stack, { gap: "md", children: [_jsx(FilterChipGroup, { label: "Type", tabs: ORDER_LANE_TABS, value: pendingFilters.orderType ?? "", onChange: (id) => setPendingFilters((prev) => ({ ...prev, orderType: id })) }), _jsx(Div, { children: _jsx(PaginatedSelect, { value: pendingFilters.status || null, onChange: (v) => setPendingFilters((p) => ({ ...p, status: v ?? "" })), options: STATUS_OPTIONS, placeholder: "All statuses", ariaLabel: "Filter by order status" }) })] })),
|
|
44
66
|
renderCards: (rows, _view, _selection, isLoading) => {
|
|
45
67
|
if (isLoading) {
|
|
46
68
|
return (_jsx(Stack, { gap: "md", children: Array.from({ length: 3 }).map((_, i) => (_jsx(Div, { className: "h-24 animate-pulse border border-[var(--appkit-color-border)]", rounded: "xl" }, i))) }));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { sortBy } from "@mohasinac/appkit/client";
|
|
4
|
-
import {
|
|
4
|
+
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
5
5
|
import { useQueryClient } from "@tanstack/react-query";
|
|
6
6
|
import { Badge, Div, FilterChipGroup, Span, Stack, Text, useToast } from "../../../ui";
|
|
7
7
|
import { ADMIN_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
@@ -47,20 +47,26 @@ const ADDRESS_COLUMNS = [
|
|
|
47
47
|
render: (row) => _jsx(Span, { size: "sm", color: "muted", children: row.updatedAt }),
|
|
48
48
|
},
|
|
49
49
|
];
|
|
50
|
-
function buildAddressConfig(
|
|
50
|
+
function buildAddressConfig(onAction) {
|
|
51
51
|
return {
|
|
52
52
|
portal: "admin",
|
|
53
53
|
title: "Address Management",
|
|
54
54
|
searchPlaceholder: "Search by city or owner",
|
|
55
55
|
emptyLabel: "No addresses found",
|
|
56
|
-
filterKeys
|
|
56
|
+
// URL-synced via filterKeys (2026-08-21). The ban-status chips used to
|
|
57
|
+
// live outside this config in local useState, so the selection was not in
|
|
58
|
+
// the URL, not shareable, not counted by activeFilterCount, and lost on
|
|
59
|
+
// back-navigation. banStatus is a plain query param rather than a Sieve
|
|
60
|
+
// clause, which is exactly what buildExtraParams is for.
|
|
61
|
+
filterKeys: ["banStatus"],
|
|
57
62
|
defaultSort: sortBy("bannedAt", "DESC"),
|
|
58
|
-
queryKey: ["admin", "addresses"
|
|
59
|
-
endpoint:
|
|
60
|
-
|
|
61
|
-
: ADMIN_ENDPOINTS.ADDRESSES,
|
|
63
|
+
queryKey: ["admin", "addresses"],
|
|
64
|
+
endpoint: ADMIN_ENDPOINTS.ADDRESSES,
|
|
65
|
+
buildExtraParams: (state) => state.banStatus ? { banStatus: state.banStatus } : undefined,
|
|
62
66
|
sortOptions: [
|
|
63
|
-
|
|
67
|
+
// -bannedAt (newest flagged first) to match defaultSort — the option was
|
|
68
|
+
// "bannedAt" (oldest first), so the dropdown opened with nothing selected.
|
|
69
|
+
{ value: sortBy("bannedAt", "DESC"), label: "Flagged Date" },
|
|
64
70
|
{ value: "city", label: "City" },
|
|
65
71
|
],
|
|
66
72
|
columns: ADDRESS_COLUMNS,
|
|
@@ -119,7 +125,11 @@ function buildAddressConfig(banStatus, onAction) {
|
|
|
119
125
|
};
|
|
120
126
|
}
|
|
121
127
|
export function AdminAddressesView(_props) {
|
|
122
|
-
|
|
128
|
+
// Independent useUrlTable() against the same URL param DataListingView's own
|
|
129
|
+
// table reads via filterKeys — safe because useUrlTable holds no local state
|
|
130
|
+
// (the documented Root Cause #35 pattern).
|
|
131
|
+
const chipTable = useUrlTable({ defaults: {} });
|
|
132
|
+
const banStatus = chipTable.get("banStatus");
|
|
123
133
|
const queryClient = useQueryClient();
|
|
124
134
|
const { showToast } = useToast();
|
|
125
135
|
const actionMutation = useApiMutation({
|
|
@@ -137,6 +147,6 @@ export function AdminAddressesView(_props) {
|
|
|
137
147
|
const handleAction = (id, action) => {
|
|
138
148
|
actionMutation.mutate({ id, action });
|
|
139
149
|
};
|
|
140
|
-
const config = buildAddressConfig(
|
|
141
|
-
return (_jsxs(Stack, { gap: "md", children: [_jsx(Div, { padding: "inline", border: "default", className: "border-b", children: _jsx(FilterChipGroup, { label: "Status", tabs: BAN_STATUS_TABS, value: banStatus, onChange: (v) =>
|
|
150
|
+
const config = buildAddressConfig(handleAction);
|
|
151
|
+
return (_jsxs(Stack, { gap: "md", children: [_jsx(Div, { padding: "inline", border: "default", className: "border-b", children: _jsx(FilterChipGroup, { label: "Status", tabs: BAN_STATUS_TABS, value: banStatus, onChange: (v) => chipTable.set("banStatus", v) }) }), _jsx(DataListingView, { config: config })] }));
|
|
142
152
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdminArtView — admin browse of art listings.
|
|
3
|
+
*
|
|
4
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
5
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
6
|
+
* were the same config with a different listingType, and all five shipped
|
|
7
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
8
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
9
|
+
*/
|
|
1
10
|
import React from "react";
|
|
2
11
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
12
|
export type AdminArtViewProps = ListingLayoutProps;
|
|
@@ -1,50 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
|
-
* AdminArtView — admin browse of art
|
|
5
|
-
*
|
|
4
|
+
* AdminArtView — admin browse of art listings.
|
|
5
|
+
*
|
|
6
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
7
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
8
|
+
* were the same config with a different listingType, and all five shipped
|
|
9
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
10
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
6
11
|
*/
|
|
7
|
-
import { sortBy } from "@mohasinac/appkit/client";
|
|
8
12
|
import React from "react";
|
|
9
13
|
import { ListingLayout } from "../../../ui";
|
|
10
|
-
import {
|
|
11
|
-
import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../hooks/useAdminListingData";
|
|
14
|
+
import { buildListingTypeListingConfig } from "../../products/config/listing-type-listing-config";
|
|
12
15
|
import { DataListingView } from "./DataListingView";
|
|
13
|
-
|
|
14
|
-
const ADMIN_ART_CONFIG = {
|
|
15
|
-
portal: "admin",
|
|
16
|
+
const CONFIG = buildListingTypeListingConfig("art", {
|
|
16
17
|
title: "Art",
|
|
17
18
|
searchPlaceholder: "Search art prints by name or seller",
|
|
18
19
|
emptyLabel: "No art listings",
|
|
19
|
-
|
|
20
|
-
defaultSort: sortBy("createdAt", "DESC"),
|
|
21
|
-
queryKey: ["admin", "art", "listing"],
|
|
22
|
-
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
23
|
-
sortOptions: [
|
|
24
|
-
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
25
|
-
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
26
|
-
{ value: "title", label: "Title A–Z" },
|
|
27
|
-
],
|
|
28
|
-
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
29
|
-
id: toStringValue(item.id, `art-${index}`),
|
|
30
|
-
primary: toStringValue(item.title ?? item.productTitle, "Untitled print"),
|
|
31
|
-
secondary: [
|
|
32
|
-
toStringValue(item.sellerName, "Unknown seller"),
|
|
33
|
-
toCurrency(item.price),
|
|
34
|
-
].join(" · "),
|
|
35
|
-
status: toStringValue(item.status, "draft"),
|
|
36
|
-
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
37
|
-
image: toStringValue(item.mainImage, "") || undefined,
|
|
38
|
-
})),
|
|
39
|
-
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
40
|
-
buildFilters: () => "listingType==art",
|
|
41
|
-
// Art listings are products (filtered by listingType) — reuse the real
|
|
42
|
-
// admin product edit page rather than leaving rows non-navigable.
|
|
43
|
-
rowHrefTemplate: String(ROUTES.ADMIN.PRODUCTS_EDIT("{id}")),
|
|
44
|
-
};
|
|
20
|
+
});
|
|
45
21
|
export function AdminArtView({ children, ...props }) {
|
|
46
22
|
if (React.Children.count(children) > 0) {
|
|
47
23
|
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
48
24
|
}
|
|
49
|
-
return _jsx(DataListingView, { config:
|
|
25
|
+
return _jsx(DataListingView, { config: CONFIG });
|
|
50
26
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdminClassifiedView — admin browse of classified listings.
|
|
3
|
+
*
|
|
4
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
5
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
6
|
+
* were the same config with a different listingType, and all five shipped
|
|
7
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
8
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
9
|
+
*/
|
|
1
10
|
import React from "react";
|
|
2
11
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
12
|
export type AdminClassifiedViewProps = ListingLayoutProps;
|
|
@@ -1,50 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
|
-
* AdminClassifiedView — admin browse of classified listings
|
|
5
|
-
*
|
|
4
|
+
* AdminClassifiedView — admin browse of classified listings.
|
|
5
|
+
*
|
|
6
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
7
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
8
|
+
* were the same config with a different listingType, and all five shipped
|
|
9
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
10
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
6
11
|
*/
|
|
7
|
-
import { sortBy } from "@mohasinac/appkit/client";
|
|
8
12
|
import React from "react";
|
|
9
13
|
import { ListingLayout } from "../../../ui";
|
|
10
|
-
import {
|
|
11
|
-
import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../hooks/useAdminListingData";
|
|
14
|
+
import { buildListingTypeListingConfig } from "../../products/config/listing-type-listing-config";
|
|
12
15
|
import { DataListingView } from "./DataListingView";
|
|
13
|
-
|
|
14
|
-
const ADMIN_CLASSIFIED_CONFIG = {
|
|
15
|
-
portal: "admin",
|
|
16
|
+
const CONFIG = buildListingTypeListingConfig("classified", {
|
|
16
17
|
title: "Classified",
|
|
17
18
|
searchPlaceholder: "Search classified by name or seller",
|
|
18
19
|
emptyLabel: "No classified listings",
|
|
19
|
-
|
|
20
|
-
defaultSort: sortBy("createdAt", "DESC"),
|
|
21
|
-
queryKey: ["admin", "classified", "listing"],
|
|
22
|
-
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
23
|
-
sortOptions: [
|
|
24
|
-
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
25
|
-
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
26
|
-
{ value: "title", label: "Title A–Z" },
|
|
27
|
-
],
|
|
28
|
-
mapRows: (response) => toRecordArray(response.items).map((item, index) => ({
|
|
29
|
-
id: toStringValue(item.id, `classified-${index}`),
|
|
30
|
-
primary: toStringValue(item.title ?? item.productTitle, "Untitled classified"),
|
|
31
|
-
secondary: [
|
|
32
|
-
toStringValue(item.sellerName, "Unknown seller"),
|
|
33
|
-
toCurrency(item.price),
|
|
34
|
-
].join(" · "),
|
|
35
|
-
status: toStringValue(item.status, "draft"),
|
|
36
|
-
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
37
|
-
image: toStringValue(item.mainImage, "") || undefined,
|
|
38
|
-
})),
|
|
39
|
-
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
40
|
-
buildFilters: () => "listingType==classified",
|
|
41
|
-
// Classified listings are products (filtered by listingType) — reuse the
|
|
42
|
-
// real admin product edit page rather than leaving rows non-navigable.
|
|
43
|
-
rowHrefTemplate: String(ROUTES.ADMIN.PRODUCTS_EDIT("{id}")),
|
|
44
|
-
};
|
|
20
|
+
});
|
|
45
21
|
export function AdminClassifiedView({ children, ...props }) {
|
|
46
22
|
if (React.Children.count(children) > 0) {
|
|
47
23
|
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
48
24
|
}
|
|
49
|
-
return _jsx(DataListingView, { config:
|
|
25
|
+
return _jsx(DataListingView, { config: CONFIG });
|
|
50
26
|
}
|
|
@@ -81,7 +81,6 @@ export function AdminCouponEditorView({ couponId, onSaved, onDeleted, embedded,
|
|
|
81
81
|
const [isActive, setIsActive] = React.useState(true);
|
|
82
82
|
// restrictions
|
|
83
83
|
const [firstTimeOnly, setFirstTimeOnly] = React.useState(false);
|
|
84
|
-
const [combinable, setCombinable] = React.useState(false);
|
|
85
84
|
const [appliesToAuctions, setAppliesToAuctions] = React.useState(false);
|
|
86
85
|
const [applicableProducts, setApplicableProducts] = React.useState([]);
|
|
87
86
|
const [applicableCategories, setApplicableCategories] = React.useState([]);
|
|
@@ -122,7 +121,6 @@ export function AdminCouponEditorView({ couponId, onSaved, onDeleted, embedded,
|
|
|
122
121
|
setEndDate(toDateInputValue(c.validity?.endDate));
|
|
123
122
|
setIsActive(c.validity?.isActive ?? false);
|
|
124
123
|
setFirstTimeOnly(c.restrictions?.firstTimeUserOnly ?? false);
|
|
125
|
-
setCombinable(c.restrictions?.combineWithSellerCoupons ?? false);
|
|
126
124
|
setApplicableProducts(Array.isArray(c.restrictions?.applicableProducts) ? c.restrictions.applicableProducts : []);
|
|
127
125
|
setApplicableCategories(Array.isArray(c.restrictions?.applicableCategories) ? c.restrictions.applicableCategories : []);
|
|
128
126
|
setAppliesToAuctions(c.applicableToAuctions ?? false);
|
|
@@ -162,7 +160,6 @@ export function AdminCouponEditorView({ couponId, onSaved, onDeleted, embedded,
|
|
|
162
160
|
},
|
|
163
161
|
restrictions: {
|
|
164
162
|
firstTimeUserOnly: firstTimeOnly,
|
|
165
|
-
combineWithSellerCoupons: combinable,
|
|
166
163
|
...(applicableProducts.length > 0 && { applicableProducts }),
|
|
167
164
|
...(applicableCategories.length > 0 && { applicableCategories }),
|
|
168
165
|
},
|
|
@@ -208,7 +205,7 @@ export function AdminCouponEditorView({ couponId, onSaved, onDeleted, embedded,
|
|
|
208
205
|
const formSection = (_jsxs(_Fragment, { children: [_jsx(Form, { schema: couponFormSchema, onSubmit: (e) => e.preventDefault(), spacing: "md", children: ({ setFieldError, clearErrors }) => (_jsxs(_Fragment, { children: [_jsx(Select, { label: "Coupon type", options: TYPE_OPTIONS, value: type, onValueChange: (v) => setType(v), required: true }), _jsx(FieldInput, { name: "name", label: "Campaign name", value: name, onChange: (v) => handleNameChange(v), required: true, placeholder: "e.g. Summer Sale 20%" }), !isEdit && (_jsx(Input, { label: "Coupon code", value: code, onChange: (e) => {
|
|
209
206
|
setCode(toCouponCode(e.target.value));
|
|
210
207
|
setCodeManual(true);
|
|
211
|
-
}, required: true, placeholder: "e.g. SUMMER20", helperText: "Auto-generated from name. Uppercase alphanumeric + hyphens only." })), isEdit && (_jsx(Input, { label: "Coupon code", value: code, disabled: true, helperText: "Code cannot be changed after creation." })), _jsx(Input, { label: "Description (optional)", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Internal notes about this coupon" }), _jsx(CouponDiscountFields, { type: type, discountValue: discountValue, setDiscountValue: setDiscountValue, maxDiscount: maxDiscount, setMaxDiscount: setMaxDiscount, minPurchase: minPurchase, setMinPurchase: setMinPurchase, buyQty: buyQty, setBuyQty: setBuyQty, getQty: getQty, setGetQty: setGetQty, discountLabel: discountLabel }), _jsx(CouponValidityFields, { startDate: startDate, setStartDate: setStartDate, endDate: endDate, setEndDate: setEndDate, isActive: isActive, setIsActive: setIsActive, totalLimit: totalLimit, setTotalLimit: setTotalLimit, perUserLimit: perUserLimit, setPerUserLimit: setPerUserLimit, isEdit: isEdit, currentUsage: currentUsage }), _jsx(Toggle, { label: "First-time users only", checked: firstTimeOnly, onChange: setFirstTimeOnly }), _jsx(Toggle, { label: "
|
|
208
|
+
}, required: true, placeholder: "e.g. SUMMER20", helperText: "Auto-generated from name. Uppercase alphanumeric + hyphens only." })), isEdit && (_jsx(Input, { label: "Coupon code", value: code, disabled: true, helperText: "Code cannot be changed after creation." })), _jsx(Input, { label: "Description (optional)", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Internal notes about this coupon" }), _jsx(CouponDiscountFields, { type: type, discountValue: discountValue, setDiscountValue: setDiscountValue, maxDiscount: maxDiscount, setMaxDiscount: setMaxDiscount, minPurchase: minPurchase, setMinPurchase: setMinPurchase, buyQty: buyQty, setBuyQty: setBuyQty, getQty: getQty, setGetQty: setGetQty, discountLabel: discountLabel }), _jsx(CouponValidityFields, { startDate: startDate, setStartDate: setStartDate, endDate: endDate, setEndDate: setEndDate, isActive: isActive, setIsActive: setIsActive, totalLimit: totalLimit, setTotalLimit: setTotalLimit, perUserLimit: perUserLimit, setPerUserLimit: setPerUserLimit, isEdit: isEdit, currentUsage: currentUsage }), _jsx(Toggle, { label: "First-time users only", checked: firstTimeOnly, onChange: setFirstTimeOnly }), _jsx(Toggle, { label: "Applies to auctions", checked: appliesToAuctions, onChange: setAppliesToAuctions }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Applicable products (optional)" }), _jsx(ProductInlineSelect, { scope: "admin", multiple: true, value: applicableProducts, onChange: setApplicableProducts, placeholder: "Restrict to specific products\u2026" }), _jsx(Text, { size: "xs", color: "muted", children: "Leave empty to apply the coupon to every eligible product." })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Applicable categories (optional)" }), _jsx(CategoryInlineSelect, { value: "", onChange: (id) => {
|
|
212
209
|
if (!id || applicableCategories.includes(id))
|
|
213
210
|
return;
|
|
214
211
|
setApplicableCategories([...applicableCategories, id]);
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdminDigitalCodesView — admin browse of digital codes listings.
|
|
3
|
+
*
|
|
4
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
5
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
6
|
+
* were the same config with a different listingType, and all five shipped
|
|
7
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
8
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
9
|
+
*/
|
|
1
10
|
import React from "react";
|
|
2
11
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
12
|
export type AdminDigitalCodesViewProps = ListingLayoutProps;
|
|
@@ -1,57 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
|
-
* AdminDigitalCodesView — admin browse of digital
|
|
4
|
+
* AdminDigitalCodesView — admin browse of digital codes listings.
|
|
5
|
+
*
|
|
6
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
7
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
8
|
+
* were the same config with a different listingType, and all five shipped
|
|
9
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
10
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
5
11
|
*/
|
|
6
|
-
import { sortBy } from "@mohasinac/appkit/client";
|
|
7
12
|
import React from "react";
|
|
8
13
|
import { ListingLayout } from "../../../ui";
|
|
9
|
-
import {
|
|
10
|
-
import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../hooks/useAdminListingData";
|
|
14
|
+
import { buildListingTypeListingConfig } from "../../products/config/listing-type-listing-config";
|
|
11
15
|
import { DataListingView } from "./DataListingView";
|
|
12
|
-
|
|
13
|
-
const ADMIN_DIGITAL_CODES_CONFIG = {
|
|
14
|
-
portal: "admin",
|
|
16
|
+
const CONFIG = buildListingTypeListingConfig("digital-code", {
|
|
15
17
|
title: "Digital Codes",
|
|
16
18
|
searchPlaceholder: "Search digital code listings",
|
|
17
19
|
emptyLabel: "No digital code listings",
|
|
18
|
-
|
|
19
|
-
defaultSort: sortBy("createdAt", "DESC"),
|
|
20
|
-
queryKey: ["admin", "digital-codes", "listing"],
|
|
21
|
-
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
22
|
-
sortOptions: [
|
|
23
|
-
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
24
|
-
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
25
|
-
{ value: "title", label: "Title A–Z" },
|
|
26
|
-
],
|
|
27
|
-
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
28
|
-
const dc = (item.digitalCode ?? {});
|
|
29
|
-
return {
|
|
30
|
-
id: toStringValue(item.id, `dc-${index}`),
|
|
31
|
-
primary: toStringValue(item.title ?? item.productTitle, "Untitled digital code"),
|
|
32
|
-
secondary: [
|
|
33
|
-
toStringValue(item.sellerName, "Unknown seller"),
|
|
34
|
-
toCurrency(item.price),
|
|
35
|
-
typeof dc.codesAvailable === "number"
|
|
36
|
-
? `${dc.codesAvailable} avail`
|
|
37
|
-
: null,
|
|
38
|
-
]
|
|
39
|
-
.filter(Boolean)
|
|
40
|
-
.join(" · "),
|
|
41
|
-
status: toStringValue(item.status, "draft"),
|
|
42
|
-
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
43
|
-
image: toStringValue(item.mainImage, "") || undefined,
|
|
44
|
-
};
|
|
45
|
-
}),
|
|
46
|
-
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
47
|
-
buildFilters: () => "listingType==digital-code",
|
|
48
|
-
// Digital-code listings are products (filtered by listingType) — reuse
|
|
49
|
-
// the real admin product edit page rather than leaving rows non-navigable.
|
|
50
|
-
rowHrefTemplate: String(ROUTES.ADMIN.PRODUCTS_EDIT("{id}")),
|
|
51
|
-
};
|
|
20
|
+
});
|
|
52
21
|
export function AdminDigitalCodesView({ children, ...props }) {
|
|
53
22
|
if (React.Children.count(children) > 0) {
|
|
54
23
|
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
55
24
|
}
|
|
56
|
-
return _jsx(DataListingView, { config:
|
|
25
|
+
return _jsx(DataListingView, { config: CONFIG });
|
|
57
26
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdminLiveView — admin browse of live items listings.
|
|
3
|
+
*
|
|
4
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
5
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
6
|
+
* were the same config with a different listingType, and all five shipped
|
|
7
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
8
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
9
|
+
*/
|
|
1
10
|
import React from "react";
|
|
2
11
|
import type { ListingLayoutProps } from "../../../ui";
|
|
3
12
|
export type AdminLiveViewProps = ListingLayoutProps;
|
|
@@ -1,56 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
/**
|
|
4
|
-
* AdminLiveView — admin browse of live
|
|
4
|
+
* AdminLiveView — admin browse of live items listings.
|
|
5
|
+
*
|
|
6
|
+
* A thin wrapper over the shared per-listing-type config. This file (and its
|
|
7
|
+
* four siblings) used to carry a full hand-written ListingViewConfig; all five
|
|
8
|
+
* were the same config with a different listingType, and all five shipped
|
|
9
|
+
* an empty filterKeys array — no filter drawer at all — plus their own copy
|
|
10
|
+
* of a three-option sort array. See listing-type-listing-config.ts.
|
|
5
11
|
*/
|
|
6
|
-
import { sortBy } from "@mohasinac/appkit/client";
|
|
7
12
|
import React from "react";
|
|
8
13
|
import { ListingLayout } from "../../../ui";
|
|
9
|
-
import {
|
|
10
|
-
import { toRecordArray, toRelativeDate, toCurrency, toStringValue, } from "../hooks/useAdminListingData";
|
|
14
|
+
import { buildListingTypeListingConfig } from "../../products/config/listing-type-listing-config";
|
|
11
15
|
import { DataListingView } from "./DataListingView";
|
|
12
|
-
|
|
13
|
-
const ADMIN_LIVE_CONFIG = {
|
|
14
|
-
portal: "admin",
|
|
16
|
+
const CONFIG = buildListingTypeListingConfig("live", {
|
|
15
17
|
title: "Live Items",
|
|
16
18
|
searchPlaceholder: "Search live items",
|
|
17
19
|
emptyLabel: "No live item listings",
|
|
18
|
-
|
|
19
|
-
defaultSort: sortBy("createdAt", "DESC"),
|
|
20
|
-
queryKey: ["admin", "live-items", "listing"],
|
|
21
|
-
endpoint: ADMIN_ENDPOINTS.PRODUCTS,
|
|
22
|
-
sortOptions: [
|
|
23
|
-
{ value: sortBy("createdAt", "DESC"), label: "Newest" },
|
|
24
|
-
{ value: sortBy("createdAt", "ASC"), label: "Oldest" },
|
|
25
|
-
{ value: "title", label: "Title A–Z" },
|
|
26
|
-
],
|
|
27
|
-
mapRows: (response) => toRecordArray(response.items).map((item, index) => {
|
|
28
|
-
const live = (item.liveItem ?? {});
|
|
29
|
-
return {
|
|
30
|
-
id: toStringValue(item.id, `live-${index}`),
|
|
31
|
-
primary: toStringValue(item.title ?? item.productTitle, "Untitled live item"),
|
|
32
|
-
secondary: [
|
|
33
|
-
toStringValue(item.sellerName, "Unknown seller"),
|
|
34
|
-
toCurrency(item.price),
|
|
35
|
-
toStringValue(live.species, ""),
|
|
36
|
-
Boolean(live.vendorVerified) ? "verified" : "pending",
|
|
37
|
-
]
|
|
38
|
-
.filter(Boolean)
|
|
39
|
-
.join(" · "),
|
|
40
|
-
status: toStringValue(item.status, "draft"),
|
|
41
|
-
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
42
|
-
image: toStringValue(item.mainImage, "") || undefined,
|
|
43
|
-
};
|
|
44
|
-
}),
|
|
45
|
-
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
46
|
-
buildFilters: () => "listingType==live",
|
|
47
|
-
// Live-item listings are products (filtered by listingType) — reuse the
|
|
48
|
-
// real admin product edit page rather than leaving rows non-navigable.
|
|
49
|
-
rowHrefTemplate: String(ROUTES.ADMIN.PRODUCTS_EDIT("{id}")),
|
|
50
|
-
};
|
|
20
|
+
});
|
|
51
21
|
export function AdminLiveView({ children, ...props }) {
|
|
52
22
|
if (React.Children.count(children) > 0) {
|
|
53
23
|
return (_jsx(ListingLayout, { portal: "admin", ...props, children: children }));
|
|
54
24
|
}
|
|
55
|
-
return _jsx(DataListingView, { config:
|
|
25
|
+
return _jsx(DataListingView, { config: CONFIG });
|
|
56
26
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type OrderAddonBadgesOrder } from "../../orders/components/OrderAddonBadges";
|
|
1
2
|
import React from "react";
|
|
2
3
|
export interface AdminOrderItemRow {
|
|
3
4
|
productId: string;
|
|
@@ -23,5 +24,11 @@ export interface AdminOrderEditorViewProps {
|
|
|
23
24
|
paymentUpiMismatch?: boolean;
|
|
24
25
|
buyerMarkedPaid?: boolean;
|
|
25
26
|
buyerFraudAgreementAccepted?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Paid add-ons + applied coupon for this order. Operational, not decorative:
|
|
29
|
+
* `whatsappNotifyAddon` is who a status change should message, and the
|
|
30
|
+
* coupon is what an admin needs when reconciling a discounted order.
|
|
31
|
+
*/
|
|
32
|
+
addons?: OrderAddonBadgesOrder;
|
|
26
33
|
}
|
|
27
|
-
export declare function AdminOrderEditorView({ open, onClose, orderId, orderLabel, currentStatus, items, paymentProofUrl, paymentTransactionId, paymentMethod, paymentStatus, displayedUpiId, buyerReportedUpiId, paymentUpiMismatch, buyerMarkedPaid, buyerFraudAgreementAccepted, }: AdminOrderEditorViewProps): React.JSX.Element;
|
|
34
|
+
export declare function AdminOrderEditorView({ open, onClose, orderId, orderLabel, currentStatus, items, paymentProofUrl, paymentTransactionId, paymentMethod, paymentStatus, displayedUpiId, buyerReportedUpiId, paymentUpiMismatch, buyerMarkedPaid, buyerFraudAgreementAccepted, addons, }: AdminOrderEditorViewProps): React.JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { OrderAddonBadges } from "../../orders/components/OrderAddonBadges";
|
|
3
4
|
import { useApiMutation } from "@mohasinac/appkit/client";
|
|
4
5
|
import React, { useState } from "react";
|
|
5
6
|
import { normalizeError } from "../../../errors/normalize";
|
|
@@ -29,7 +30,7 @@ const CARRIER_OPTIONS = [
|
|
|
29
30
|
{ label: "Other", value: "Other" },
|
|
30
31
|
];
|
|
31
32
|
// --- Component ---------------------------------------------------------------
|
|
32
|
-
export function AdminOrderEditorView({ open, onClose, orderId, orderLabel, currentStatus, items, paymentProofUrl, paymentTransactionId, paymentMethod, paymentStatus, displayedUpiId, buyerReportedUpiId, paymentUpiMismatch, buyerMarkedPaid, buyerFraudAgreementAccepted, }) {
|
|
33
|
+
export function AdminOrderEditorView({ open, onClose, orderId, orderLabel, currentStatus, items, paymentProofUrl, paymentTransactionId, paymentMethod, paymentStatus, displayedUpiId, buyerReportedUpiId, paymentUpiMismatch, buyerMarkedPaid, buyerFraudAgreementAccepted, addons, }) {
|
|
33
34
|
const queryClient = useQueryClient();
|
|
34
35
|
const { showToast } = useToast();
|
|
35
36
|
const [status, setStatus] = React.useState(currentStatus ?? "pending");
|
|
@@ -136,5 +137,5 @@ export function AdminOrderEditorView({ open, onClose, orderId, orderLabel, curre
|
|
|
136
137
|
return (_jsx(SideDrawer, { isOpen: open, onClose: onClose, title: orderLabel ? `Order: ${orderLabel}` : "Update Order", children: _jsxs(Form, { onSubmit: (e) => {
|
|
137
138
|
e.preventDefault();
|
|
138
139
|
saveMutation.mutate();
|
|
139
|
-
}, spacing: "md", padding: "md", children: [items && items.length > 0 && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Label, { size: "sm", weight: "medium", color: "primary", children: ["Items (", items.length, ")"] }), _jsx(Div, { className: "divide-y divide-[var(--appkit-color-border)] border border-[var(--appkit-color-border)]", rounded: "lg", children: items.map((item, i) => (_jsxs(Div, { layout: "flex", align: "center", gap: "3", padding: "sm", children: [_jsx(Div, { className: "h-10 w-10 shrink-0", rounded: "md", overflow: "hidden", children: _jsx(MediaImage, { src: item.image, alt: item.title, size: "thumbnail" }) }), _jsxs(Div, { className: "min-w-0 flex-1", children: [_jsx(Text, { size: "sm", className: "truncate", weight: "medium", children: item.title }), _jsxs(Text, { size: "xs", color: "muted", children: ["Qty: ", item.quantity, " \u00D7 ", toCurrency(item.unitPrice)] })] }), _jsx(Text, { size: "sm", className: "shrink-0", weight: "semibold", children: toCurrency(item.totalPrice) })] }, item.productId || i))) })] })), _jsx(Select, { label: "Order status", options: STATUS_OPTIONS, value: status, onValueChange: setStatus }), _jsx(Input, { label: "Tracking number (optional)", value: trackingNumber, onChange: (e) => setTrackingNumber(e.target.value), placeholder: "e.g. DEL1234567890IN" }), _jsx(Select, { label: "Carrier (optional)", options: CARRIER_OPTIONS, value: carrier, onValueChange: setCarrier }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Internal note (optional)" }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), rows: 3, placeholder: "Reason for status change, escalation notes\u2026" })] }), (status === "refunded" || status === "return_requested") && (_jsx(Input, { label: "Refund amount \u20B9 (optional)", type: "number", min: "0", step: "0.01", value: refundAmount, onChange: (e) => setRefundAmount(e.target.value), placeholder: "e.g. 499.00" })), isCashOrUpi && (_jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Payment Proof" }), paymentProofUrl ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Div, { border: "default", rounded: "lg", overflow: "hidden", children: _jsx(MediaImage, { src: paymentProofUrl, alt: "Payment screenshot", size: "card" }) }), paymentTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: ["UTR: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: paymentTransactionId })] })), needsVerification && (_jsxs(Stack, { gap: "xs", children: [(displayedUpiId || buyerReportedUpiId) && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "xs", color: "muted", children: ["Expected UPI: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: displayedUpiId || "—" }), " · ", "Buyer reported: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerReportedUpiId || "—" })] }), paymentUpiMismatch && (_jsx(Div, { rounded: "lg", padding: "inlineSm", className: "border border-error/20", surface: "danger-surface", children: _jsx(Text, { size: "xs", className: "text-error", weight: "semibold", children: "UPI mismatch \u2014 buyer-reported ID doesn't match the one shown for this order." }) }))] })), _jsxs(Text, { size: "xs", color: "muted", children: ["Buyer marked as paid: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerMarkedPaid ? "Yes" : "No" }), " · ", "Fraud agreement accepted: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerFraudAgreementAccepted ? "Yes" : "No" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Review note (required for re-upload / reject)" }), _jsx(Textarea, { value: reviewNote, onChange: (e) => setReviewNote(e.target.value), rows: 2, placeholder: "e.g. Screenshot is blurry \u2014 amount not readable / UPI ID doesn't match order" })] }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["verify-payment"], onClick: handleVerifyPayment, isLoading: isVerifyingPayment, disabled: isVerifyingPayment, variant: "primary", className: "w-full" }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["request-payment-reupload"], onClick: handleRequestReupload, isLoading: isRequestingReupload, disabled: isRequestingReupload || !reviewNote.trim(), variant: "secondary", className: "w-full" }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["reject-payment-fraud"], onClick: handleRejectFraud, isLoading: isRejectingFraud, disabled: isRejectingFraud || !reviewNote.trim(), variant: "danger", className: "w-full" })] })), !needsVerification && paymentStatus === "paid" && (_jsx(Div, { rounded: "lg", padding: "inlineSm", className: "border border-success/20", surface: "success-surface", children: _jsx(Text, { size: "xs", className: "text-success", weight: "medium", children: "Payment verified" }) }))] })) : (_jsx(Text, { size: "xs", color: "faint", children: "No proof uploaded yet." }))] })), _jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "secondary", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: !orderId || saveMutation.isPending, children: "Save changes" })] })] }) }));
|
|
140
|
+
}, spacing: "md", padding: "md", children: [addons && _jsx(OrderAddonBadges, { order: addons, variant: "detail" }), items && items.length > 0 && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Label, { size: "sm", weight: "medium", color: "primary", children: ["Items (", items.length, ")"] }), _jsx(Div, { className: "divide-y divide-[var(--appkit-color-border)] border border-[var(--appkit-color-border)]", rounded: "lg", children: items.map((item, i) => (_jsxs(Div, { layout: "flex", align: "center", gap: "3", padding: "sm", children: [_jsx(Div, { className: "h-10 w-10 shrink-0", rounded: "md", overflow: "hidden", children: _jsx(MediaImage, { src: item.image, alt: item.title, size: "thumbnail" }) }), _jsxs(Div, { className: "min-w-0 flex-1", children: [_jsx(Text, { size: "sm", className: "truncate", weight: "medium", children: item.title }), _jsxs(Text, { size: "xs", color: "muted", children: ["Qty: ", item.quantity, " \u00D7 ", toCurrency(item.unitPrice)] })] }), _jsx(Text, { size: "sm", className: "shrink-0", weight: "semibold", children: toCurrency(item.totalPrice) })] }, item.productId || i))) })] })), _jsx(Select, { label: "Order status", options: STATUS_OPTIONS, value: status, onValueChange: setStatus }), _jsx(Input, { label: "Tracking number (optional)", value: trackingNumber, onChange: (e) => setTrackingNumber(e.target.value), placeholder: "e.g. DEL1234567890IN" }), _jsx(Select, { label: "Carrier (optional)", options: CARRIER_OPTIONS, value: carrier, onValueChange: setCarrier }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Internal note (optional)" }), _jsx(Textarea, { value: notes, onChange: (e) => setNotes(e.target.value), rows: 3, placeholder: "Reason for status change, escalation notes\u2026" })] }), (status === "refunded" || status === "return_requested") && (_jsx(Input, { label: "Refund amount \u20B9 (optional)", type: "number", min: "0", step: "0.01", value: refundAmount, onChange: (e) => setRefundAmount(e.target.value), placeholder: "e.g. 499.00" })), isCashOrUpi && (_jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Payment Proof" }), paymentProofUrl ? (_jsxs(Stack, { gap: "xs", children: [_jsx(Div, { border: "default", rounded: "lg", overflow: "hidden", children: _jsx(MediaImage, { src: paymentProofUrl, alt: "Payment screenshot", size: "card" }) }), paymentTransactionId && (_jsxs(Text, { size: "xs", color: "muted", children: ["UTR: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: paymentTransactionId })] })), needsVerification && (_jsxs(Stack, { gap: "xs", children: [(displayedUpiId || buyerReportedUpiId) && (_jsxs(Stack, { gap: "xs", children: [_jsxs(Text, { size: "xs", color: "muted", children: ["Expected UPI: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: displayedUpiId || "—" }), " · ", "Buyer reported: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerReportedUpiId || "—" })] }), paymentUpiMismatch && (_jsx(Div, { rounded: "lg", padding: "inlineSm", className: "border border-error/20", surface: "danger-surface", children: _jsx(Text, { size: "xs", className: "text-error", weight: "semibold", children: "UPI mismatch \u2014 buyer-reported ID doesn't match the one shown for this order." }) }))] })), _jsxs(Text, { size: "xs", color: "muted", children: ["Buyer marked as paid: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerMarkedPaid ? "Yes" : "No" }), " · ", "Fraud agreement accepted: ", _jsx(Text, { as: "span", size: "xs", weight: "medium", children: buyerFraudAgreementAccepted ? "Yes" : "No" })] }), _jsxs(Stack, { gap: "xs", children: [_jsx(Label, { size: "sm", weight: "medium", color: "primary", children: "Review note (required for re-upload / reject)" }), _jsx(Textarea, { value: reviewNote, onChange: (e) => setReviewNote(e.target.value), rows: 2, placeholder: "e.g. Screenshot is blurry \u2014 amount not readable / UPI ID doesn't match order" })] }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["verify-payment"], onClick: handleVerifyPayment, isLoading: isVerifyingPayment, disabled: isVerifyingPayment, variant: "primary", className: "w-full" }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["request-payment-reupload"], onClick: handleRequestReupload, isLoading: isRequestingReupload, disabled: isRequestingReupload || !reviewNote.trim(), variant: "secondary", className: "w-full" }), _jsx(Button, { type: "button", action: ACTIONS.ADMIN["reject-payment-fraud"], onClick: handleRejectFraud, isLoading: isRejectingFraud, disabled: isRejectingFraud || !reviewNote.trim(), variant: "danger", className: "w-full" })] })), !needsVerification && paymentStatus === "paid" && (_jsx(Div, { rounded: "lg", padding: "inlineSm", className: "border border-success/20", surface: "success-surface", children: _jsx(Text, { size: "xs", className: "text-success", weight: "medium", children: "Payment verified" }) }))] })) : (_jsx(Text, { size: "xs", color: "faint", children: "No proof uploaded yet." }))] })), _jsxs(FormActions, { align: "right", children: [_jsx(Button, { type: "button", variant: "secondary", onClick: onClose, children: "Cancel" }), _jsx(Button, { type: "submit", isLoading: saveMutation.isPending, disabled: !orderId || saveMutation.isPending, children: "Save changes" })] })] }) }));
|
|
140
141
|
}
|
|
@@ -122,6 +122,19 @@ export function AdminOrdersView({ children, ...props }) {
|
|
|
122
122
|
paymentUpiMismatch: Boolean(item.paymentUpiMismatch),
|
|
123
123
|
buyerMarkedPaid: Boolean(item.buyerMarkedPaid),
|
|
124
124
|
buyerFraudAgreementAccepted: Boolean(item.buyerFraudAgreementAccepted),
|
|
125
|
+
// Straight off the order document — the admin list route returns
|
|
126
|
+
// raw docs, so these need no serializer entry (cf. Root Cause #38).
|
|
127
|
+
addons: {
|
|
128
|
+
whatsappNotifyAddon: Boolean(item.whatsappNotifyAddon),
|
|
129
|
+
whatsappNotifyFee: Number(item.whatsappNotifyFee ?? 0) || undefined,
|
|
130
|
+
giftWrapAddon: Boolean(item.giftWrapAddon),
|
|
131
|
+
giftWrapFee: Number(item.giftWrapFee ?? 0) || undefined,
|
|
132
|
+
giftWrapMessage: toStringValue(item.giftWrapMessage) || undefined,
|
|
133
|
+
shipmentProtectionAddon: Boolean(item.shipmentProtectionAddon),
|
|
134
|
+
shipmentProtectionFee: Number(item.shipmentProtectionFee ?? 0) || undefined,
|
|
135
|
+
couponCode: toStringValue(item.couponCode) || undefined,
|
|
136
|
+
couponDiscount: Number(item.couponDiscount ?? 0) || undefined,
|
|
137
|
+
},
|
|
125
138
|
};
|
|
126
139
|
}),
|
|
127
140
|
getTotal: (response, mappedRows) => typeof response.meta?.total === "number" ? response.meta.total : mappedRows.length,
|
|
@@ -198,5 +211,5 @@ export function AdminOrdersView({ children, ...props }) {
|
|
|
198
211
|
] })),
|
|
199
212
|
renderFilterPanel: ({ pendingFilters, setPendingFilters }) => (_jsxs(_Fragment, { children: [_jsx(FilterChipGroup, { label: "Status", tabs: ADMIN_ORDER_STATUS_TABS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id, paymentReview: "" })) }), _jsx(FilterChipGroup, { label: "Manual payment", tabs: ADMIN_ORDER_PAYMENT_REVIEW_TABS, value: pendingFilters.paymentReview ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, paymentReview: id, status: "" })) })] })),
|
|
200
213
|
};
|
|
201
|
-
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(AdminOrderEditorView, { open: drawerOpen, onClose: () => setDrawerOpen(false), orderId: selectedRow?.id, orderLabel: selectedRow?.primary, currentStatus: selectedRow?.status, items: selectedRow?.items, paymentProofUrl: selectedRow?.paymentProofUrl, paymentTransactionId: selectedRow?.paymentTransactionId, paymentMethod: selectedRow?.paymentMethod, paymentStatus: selectedRow?.paymentStatus, displayedUpiId: selectedRow?.displayedUpiId, buyerReportedUpiId: selectedRow?.buyerReportedUpiId, paymentUpiMismatch: selectedRow?.paymentUpiMismatch, buyerMarkedPaid: selectedRow?.buyerMarkedPaid, buyerFraudAgreementAccepted: selectedRow?.buyerFraudAgreementAccepted })] }));
|
|
214
|
+
return (_jsxs(_Fragment, { children: [_jsx(DataListingView, { config: config }), _jsx(AdminOrderEditorView, { open: drawerOpen, onClose: () => setDrawerOpen(false), orderId: selectedRow?.id, orderLabel: selectedRow?.primary, currentStatus: selectedRow?.status, items: selectedRow?.items, paymentProofUrl: selectedRow?.paymentProofUrl, paymentTransactionId: selectedRow?.paymentTransactionId, paymentMethod: selectedRow?.paymentMethod, paymentStatus: selectedRow?.paymentStatus, displayedUpiId: selectedRow?.displayedUpiId, buyerReportedUpiId: selectedRow?.buyerReportedUpiId, paymentUpiMismatch: selectedRow?.paymentUpiMismatch, buyerMarkedPaid: selectedRow?.buyerMarkedPaid, buyerFraudAgreementAccepted: selectedRow?.buyerFraudAgreementAccepted, addons: selectedRow?.addons })] }));
|
|
202
215
|
}
|