@mohasinac/appkit 4.7.3 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/shared/features/cart/schema.d.ts +6 -6
- package/dist/_internal/shared/features/orders/schema.d.ts +2 -2
- package/dist/_internal/shared/features/products/schema.d.ts +8 -8
- package/dist/features/account/schemas/index.d.ts +12 -12
- package/dist/features/admin/components/AdminArtView.js +1 -0
- package/dist/features/admin/components/AdminBlogView.js +1 -0
- package/dist/features/admin/components/AdminClassifiedView.js +1 -0
- package/dist/features/admin/components/AdminDigitalCodesView.js +1 -0
- package/dist/features/admin/components/AdminLiveView.js +1 -0
- package/dist/features/admin/components/AdminPrizeDrawsView.js +1 -0
- package/dist/features/admin/components/AdminProductsView.js +1 -0
- package/dist/features/admin/components/AdminStickersView.js +1 -0
- package/dist/features/admin/components/AdminStoresView.js +1 -0
- package/dist/features/admin/components/AdminUsersView.js +1 -0
- package/dist/features/admin/components/AdminViewCards.d.ts +3 -1
- package/dist/features/admin/components/AdminViewCards.js +21 -7
- package/dist/features/admin/components/DataListingView.d.ts +2 -0
- package/dist/features/admin/components/DataListingView.js +4 -2
- package/dist/features/admin/components/DataTable.d.ts +3 -1
- package/dist/features/admin/components/DataTable.js +36 -21
- package/dist/features/collections/schemas/index.d.ts +3 -3
- package/dist/features/homepage/schemas/index.d.ts +4 -4
- package/dist/features/orders/schemas/index.d.ts +22 -22
- package/dist/features/pre-orders/schemas/index.d.ts +2 -2
- package/dist/features/products/schemas/index.d.ts +8 -8
- package/dist/features/products/schemas/product-features.validators.d.ts +6 -6
- package/dist/features/reviews/schemas/index.d.ts +4 -4
- package/dist/features/scams/schemas/index.d.ts +4 -4
- package/dist/features/seller/components/SellerAuctionsView.js +1 -0
- package/dist/features/seller/components/SellerPreOrdersView.js +1 -0
- package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -0
- package/dist/features/seller/components/SellerProductsView.js +1 -0
- package/dist/features/shipments/schemas/validation.d.ts +6 -6
- package/dist/features/support/schemas/index.d.ts +2 -2
- package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
- package/dist/schemas/registry.d.ts +70 -70
- package/dist/schemas/webhooks/razorpay.d.ts +50 -50
- package/dist/ui/columns/column-renderers.d.ts +5 -0
- package/dist/ui/columns/column-renderers.js +135 -0
- package/dist/ui/columns/index.d.ts +2 -2
- package/dist/ui/columns/index.js +1 -1
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +1 -1
- package/package.json +1 -1
|
@@ -15,7 +15,7 @@ export declare const addToCartSchema: z.ZodObject<{
|
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
16
|
currency: string;
|
|
17
17
|
storeId: string;
|
|
18
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
18
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
19
19
|
price: number;
|
|
20
20
|
storeName: string;
|
|
21
21
|
productId: string;
|
|
@@ -27,7 +27,7 @@ export declare const addToCartSchema: z.ZodObject<{
|
|
|
27
27
|
isOffer?: boolean | undefined;
|
|
28
28
|
}, {
|
|
29
29
|
storeId: string;
|
|
30
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
30
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
31
31
|
price: number;
|
|
32
32
|
productId: string;
|
|
33
33
|
productTitle: string;
|
|
@@ -73,7 +73,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
|
|
|
73
73
|
}, "strip", z.ZodTypeAny, {
|
|
74
74
|
currency: string;
|
|
75
75
|
storeId: string;
|
|
76
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
76
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
77
77
|
price: number;
|
|
78
78
|
storeName: string;
|
|
79
79
|
productId: string;
|
|
@@ -85,7 +85,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
|
|
|
85
85
|
isOffer?: boolean | undefined;
|
|
86
86
|
}, {
|
|
87
87
|
storeId: string;
|
|
88
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
88
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
89
89
|
price: number;
|
|
90
90
|
productId: string;
|
|
91
91
|
productTitle: string;
|
|
@@ -101,7 +101,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
|
|
|
101
101
|
guestItems: {
|
|
102
102
|
currency: string;
|
|
103
103
|
storeId: string;
|
|
104
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
104
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
105
105
|
price: number;
|
|
106
106
|
storeName: string;
|
|
107
107
|
productId: string;
|
|
@@ -115,7 +115,7 @@ export declare const mergeGuestCartSchema: z.ZodObject<{
|
|
|
115
115
|
}, {
|
|
116
116
|
guestItems: {
|
|
117
117
|
storeId: string;
|
|
118
|
-
listingType: "standard" | "auction" | "pre-order" | "prize-draw" | "
|
|
118
|
+
listingType: "classified" | "standard" | "auction" | "pre-order" | "prize-draw" | "digital-code" | "live";
|
|
119
119
|
price: number;
|
|
120
120
|
productId: string;
|
|
121
121
|
productTitle: string;
|
|
@@ -87,13 +87,13 @@ export declare const updateOrderStatusSchema: z.ZodObject<{
|
|
|
87
87
|
carrier: z.ZodOptional<z.ZodString>;
|
|
88
88
|
note: z.ZodOptional<z.ZodString>;
|
|
89
89
|
}, "strip", z.ZodTypeAny, {
|
|
90
|
-
status: "cancelled" | "processing" | "refunded" | "
|
|
90
|
+
status: "cancelled" | "processing" | "refunded" | "delivered" | "shipped" | "return_requested";
|
|
91
91
|
orderId: string;
|
|
92
92
|
note?: string | undefined;
|
|
93
93
|
trackingNumber?: string | undefined;
|
|
94
94
|
carrier?: string | undefined;
|
|
95
95
|
}, {
|
|
96
|
-
status: "cancelled" | "processing" | "refunded" | "
|
|
96
|
+
status: "cancelled" | "processing" | "refunded" | "delivered" | "shipped" | "return_requested";
|
|
97
97
|
orderId: string;
|
|
98
98
|
note?: string | undefined;
|
|
99
99
|
trackingNumber?: string | undefined;
|
|
@@ -33,12 +33,12 @@ export declare const productInputSchema: z.ZodObject<{
|
|
|
33
33
|
mainImage: string;
|
|
34
34
|
images: string[];
|
|
35
35
|
tags: string[];
|
|
36
|
+
features?: string[] | undefined;
|
|
36
37
|
description?: string | undefined;
|
|
37
38
|
seoTitle?: string | undefined;
|
|
38
39
|
seoDescription?: string | undefined;
|
|
39
40
|
seoKeywords?: string[] | undefined;
|
|
40
41
|
brandSlug?: string | undefined;
|
|
41
|
-
features?: string[] | undefined;
|
|
42
42
|
shippingInfo?: string | undefined;
|
|
43
43
|
returnPolicy?: string | undefined;
|
|
44
44
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -53,6 +53,7 @@ export declare const productInputSchema: z.ZodObject<{
|
|
|
53
53
|
price: number;
|
|
54
54
|
mainImage: string;
|
|
55
55
|
currency?: string | undefined;
|
|
56
|
+
features?: string[] | undefined;
|
|
56
57
|
description?: string | undefined;
|
|
57
58
|
seoTitle?: string | undefined;
|
|
58
59
|
seoDescription?: string | undefined;
|
|
@@ -62,7 +63,6 @@ export declare const productInputSchema: z.ZodObject<{
|
|
|
62
63
|
availableQuantity?: number | undefined;
|
|
63
64
|
images?: string[] | undefined;
|
|
64
65
|
tags?: string[] | undefined;
|
|
65
|
-
features?: string[] | undefined;
|
|
66
66
|
shippingInfo?: string | undefined;
|
|
67
67
|
returnPolicy?: string | undefined;
|
|
68
68
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -99,6 +99,7 @@ export declare const productUpdateSchema: z.ZodObject<{
|
|
|
99
99
|
}, "strip", z.ZodTypeAny, {
|
|
100
100
|
currency?: string | undefined;
|
|
101
101
|
title?: string | undefined;
|
|
102
|
+
features?: string[] | undefined;
|
|
102
103
|
category?: string | undefined;
|
|
103
104
|
description?: string | undefined;
|
|
104
105
|
seoTitle?: string | undefined;
|
|
@@ -111,7 +112,6 @@ export declare const productUpdateSchema: z.ZodObject<{
|
|
|
111
112
|
mainImage?: string | undefined;
|
|
112
113
|
images?: string[] | undefined;
|
|
113
114
|
tags?: string[] | undefined;
|
|
114
|
-
features?: string[] | undefined;
|
|
115
115
|
shippingInfo?: string | undefined;
|
|
116
116
|
returnPolicy?: string | undefined;
|
|
117
117
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -123,6 +123,7 @@ export declare const productUpdateSchema: z.ZodObject<{
|
|
|
123
123
|
}, {
|
|
124
124
|
currency?: string | undefined;
|
|
125
125
|
title?: string | undefined;
|
|
126
|
+
features?: string[] | undefined;
|
|
126
127
|
category?: string | undefined;
|
|
127
128
|
description?: string | undefined;
|
|
128
129
|
seoTitle?: string | undefined;
|
|
@@ -135,7 +136,6 @@ export declare const productUpdateSchema: z.ZodObject<{
|
|
|
135
136
|
mainImage?: string | undefined;
|
|
136
137
|
images?: string[] | undefined;
|
|
137
138
|
tags?: string[] | undefined;
|
|
138
|
-
features?: string[] | undefined;
|
|
139
139
|
shippingInfo?: string | undefined;
|
|
140
140
|
returnPolicy?: string | undefined;
|
|
141
141
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -193,12 +193,12 @@ export declare const auctionInputSchema: z.ZodObject<{
|
|
|
193
193
|
auctionEndDate: string;
|
|
194
194
|
startingBid: number;
|
|
195
195
|
autoExtendable: boolean;
|
|
196
|
+
features?: string[] | undefined;
|
|
196
197
|
description?: string | undefined;
|
|
197
198
|
seoTitle?: string | undefined;
|
|
198
199
|
seoDescription?: string | undefined;
|
|
199
200
|
seoKeywords?: string[] | undefined;
|
|
200
201
|
brandSlug?: string | undefined;
|
|
201
|
-
features?: string[] | undefined;
|
|
202
202
|
shippingInfo?: string | undefined;
|
|
203
203
|
returnPolicy?: string | undefined;
|
|
204
204
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -221,6 +221,7 @@ export declare const auctionInputSchema: z.ZodObject<{
|
|
|
221
221
|
auctionEndDate: string;
|
|
222
222
|
startingBid: number;
|
|
223
223
|
currency?: string | undefined;
|
|
224
|
+
features?: string[] | undefined;
|
|
224
225
|
description?: string | undefined;
|
|
225
226
|
seoTitle?: string | undefined;
|
|
226
227
|
seoDescription?: string | undefined;
|
|
@@ -230,7 +231,6 @@ export declare const auctionInputSchema: z.ZodObject<{
|
|
|
230
231
|
availableQuantity?: number | undefined;
|
|
231
232
|
images?: string[] | undefined;
|
|
232
233
|
tags?: string[] | undefined;
|
|
233
|
-
features?: string[] | undefined;
|
|
234
234
|
shippingInfo?: string | undefined;
|
|
235
235
|
returnPolicy?: string | undefined;
|
|
236
236
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -291,12 +291,12 @@ export declare const preOrderInputSchema: z.ZodObject<{
|
|
|
291
291
|
preOrderDeliveryDate: string;
|
|
292
292
|
preOrderProductionStatus: "upcoming" | "in_production" | "ready_to_ship";
|
|
293
293
|
preOrderCancellable: boolean;
|
|
294
|
+
features?: string[] | undefined;
|
|
294
295
|
description?: string | undefined;
|
|
295
296
|
seoTitle?: string | undefined;
|
|
296
297
|
seoDescription?: string | undefined;
|
|
297
298
|
seoKeywords?: string[] | undefined;
|
|
298
299
|
brandSlug?: string | undefined;
|
|
299
|
-
features?: string[] | undefined;
|
|
300
300
|
shippingInfo?: string | undefined;
|
|
301
301
|
returnPolicy?: string | undefined;
|
|
302
302
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -315,6 +315,7 @@ export declare const preOrderInputSchema: z.ZodObject<{
|
|
|
315
315
|
mainImage: string;
|
|
316
316
|
preOrderDeliveryDate: string;
|
|
317
317
|
currency?: string | undefined;
|
|
318
|
+
features?: string[] | undefined;
|
|
318
319
|
description?: string | undefined;
|
|
319
320
|
seoTitle?: string | undefined;
|
|
320
321
|
seoDescription?: string | undefined;
|
|
@@ -324,7 +325,6 @@ export declare const preOrderInputSchema: z.ZodObject<{
|
|
|
324
325
|
availableQuantity?: number | undefined;
|
|
325
326
|
images?: string[] | undefined;
|
|
326
327
|
tags?: string[] | undefined;
|
|
327
|
-
features?: string[] | undefined;
|
|
328
328
|
shippingInfo?: string | undefined;
|
|
329
329
|
returnPolicy?: string | undefined;
|
|
330
330
|
condition?: "new" | "used" | "refurbished" | "like_new" | "good" | "fair" | "poor" | "broken" | undefined;
|
|
@@ -42,14 +42,14 @@ export declare const notificationPreferencesSchema: z.ZodObject<{
|
|
|
42
42
|
push: z.ZodOptional<z.ZodBoolean>;
|
|
43
43
|
}, "strip", z.ZodTypeAny, {
|
|
44
44
|
push?: boolean | undefined;
|
|
45
|
-
promotions?: boolean | undefined;
|
|
46
45
|
newsletter?: boolean | undefined;
|
|
46
|
+
promotions?: boolean | undefined;
|
|
47
47
|
sms?: boolean | undefined;
|
|
48
48
|
orderUpdates?: boolean | undefined;
|
|
49
49
|
}, {
|
|
50
50
|
push?: boolean | undefined;
|
|
51
|
-
promotions?: boolean | undefined;
|
|
52
51
|
newsletter?: boolean | undefined;
|
|
52
|
+
promotions?: boolean | undefined;
|
|
53
53
|
sms?: boolean | undefined;
|
|
54
54
|
orderUpdates?: boolean | undefined;
|
|
55
55
|
}>;
|
|
@@ -113,14 +113,14 @@ export declare const userProfileSchema: z.ZodObject<{
|
|
|
113
113
|
push: z.ZodOptional<z.ZodBoolean>;
|
|
114
114
|
}, "strip", z.ZodTypeAny, {
|
|
115
115
|
push?: boolean | undefined;
|
|
116
|
-
promotions?: boolean | undefined;
|
|
117
116
|
newsletter?: boolean | undefined;
|
|
117
|
+
promotions?: boolean | undefined;
|
|
118
118
|
sms?: boolean | undefined;
|
|
119
119
|
orderUpdates?: boolean | undefined;
|
|
120
120
|
}, {
|
|
121
121
|
push?: boolean | undefined;
|
|
122
|
-
promotions?: boolean | undefined;
|
|
123
122
|
newsletter?: boolean | undefined;
|
|
123
|
+
promotions?: boolean | undefined;
|
|
124
124
|
sms?: boolean | undefined;
|
|
125
125
|
orderUpdates?: boolean | undefined;
|
|
126
126
|
}>>;
|
|
@@ -132,9 +132,6 @@ export declare const userProfileSchema: z.ZodObject<{
|
|
|
132
132
|
displayName?: string | undefined;
|
|
133
133
|
createdAt?: string | undefined;
|
|
134
134
|
updatedAt?: string | undefined;
|
|
135
|
-
phone?: string | undefined;
|
|
136
|
-
photoURL?: string | undefined;
|
|
137
|
-
bio?: string | undefined;
|
|
138
135
|
addresses?: {
|
|
139
136
|
country: string;
|
|
140
137
|
id: string;
|
|
@@ -147,10 +144,13 @@ export declare const userProfileSchema: z.ZodObject<{
|
|
|
147
144
|
phone?: string | undefined;
|
|
148
145
|
line2?: string | undefined;
|
|
149
146
|
}[] | undefined;
|
|
147
|
+
phone?: string | undefined;
|
|
148
|
+
photoURL?: string | undefined;
|
|
149
|
+
bio?: string | undefined;
|
|
150
150
|
notificationPreferences?: {
|
|
151
151
|
push?: boolean | undefined;
|
|
152
|
-
promotions?: boolean | undefined;
|
|
153
152
|
newsletter?: boolean | undefined;
|
|
153
|
+
promotions?: boolean | undefined;
|
|
154
154
|
sms?: boolean | undefined;
|
|
155
155
|
orderUpdates?: boolean | undefined;
|
|
156
156
|
} | undefined;
|
|
@@ -160,9 +160,6 @@ export declare const userProfileSchema: z.ZodObject<{
|
|
|
160
160
|
displayName?: string | undefined;
|
|
161
161
|
createdAt?: string | undefined;
|
|
162
162
|
updatedAt?: string | undefined;
|
|
163
|
-
phone?: string | undefined;
|
|
164
|
-
photoURL?: string | undefined;
|
|
165
|
-
bio?: string | undefined;
|
|
166
163
|
addresses?: {
|
|
167
164
|
country: string;
|
|
168
165
|
id: string;
|
|
@@ -175,10 +172,13 @@ export declare const userProfileSchema: z.ZodObject<{
|
|
|
175
172
|
phone?: string | undefined;
|
|
176
173
|
line2?: string | undefined;
|
|
177
174
|
}[] | undefined;
|
|
175
|
+
phone?: string | undefined;
|
|
176
|
+
photoURL?: string | undefined;
|
|
177
|
+
bio?: string | undefined;
|
|
178
178
|
notificationPreferences?: {
|
|
179
179
|
push?: boolean | undefined;
|
|
180
|
-
promotions?: boolean | undefined;
|
|
181
180
|
newsletter?: boolean | undefined;
|
|
181
|
+
promotions?: boolean | undefined;
|
|
182
182
|
sms?: boolean | undefined;
|
|
183
183
|
orderUpdates?: boolean | undefined;
|
|
184
184
|
} | undefined;
|
|
@@ -34,6 +34,7 @@ const ADMIN_ART_CONFIG = {
|
|
|
34
34
|
].join(" · "),
|
|
35
35
|
status: toStringValue(item.status, "draft"),
|
|
36
36
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
37
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
37
38
|
})),
|
|
38
39
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
39
40
|
buildFilters: () => "listingType==art",
|
|
@@ -42,6 +42,7 @@ export function AdminBlogView({ children, ...props }) {
|
|
|
42
42
|
].join(" · "),
|
|
43
43
|
status: toStringValue(item.status, "Draft"),
|
|
44
44
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
45
|
+
image: toStringValue(item.coverImage, "") || undefined,
|
|
45
46
|
})),
|
|
46
47
|
getTotal: (response, mappedRows) => {
|
|
47
48
|
if (typeof response.meta?.filteredTotal === "number")
|
|
@@ -34,6 +34,7 @@ const ADMIN_CLASSIFIED_CONFIG = {
|
|
|
34
34
|
].join(" · "),
|
|
35
35
|
status: toStringValue(item.status, "draft"),
|
|
36
36
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
37
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
37
38
|
})),
|
|
38
39
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
39
40
|
buildFilters: () => "listingType==classified",
|
|
@@ -40,6 +40,7 @@ const ADMIN_DIGITAL_CODES_CONFIG = {
|
|
|
40
40
|
.join(" · "),
|
|
41
41
|
status: toStringValue(item.status, "draft"),
|
|
42
42
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
43
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
43
44
|
};
|
|
44
45
|
}),
|
|
45
46
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
@@ -39,6 +39,7 @@ const ADMIN_LIVE_CONFIG = {
|
|
|
39
39
|
.join(" · "),
|
|
40
40
|
status: toStringValue(item.status, "draft"),
|
|
41
41
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
42
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
42
43
|
};
|
|
43
44
|
}),
|
|
44
45
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
@@ -86,6 +86,7 @@ export function AdminPrizeDrawsView({ children, ...props }) {
|
|
|
86
86
|
drawDate: item.prizeRevealWindowEnd
|
|
87
87
|
? toRelativeDate(item.prizeRevealWindowEnd)
|
|
88
88
|
: "TBA",
|
|
89
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
89
90
|
};
|
|
90
91
|
}),
|
|
91
92
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
@@ -154,6 +154,7 @@ export function AdminProductsView({ children, ...props }) {
|
|
|
154
154
|
isOnSale: Boolean(item.isOnSale),
|
|
155
155
|
isSold: Boolean(item.isSold),
|
|
156
156
|
barcodeId: typeof item.barcodeId === "string" ? item.barcodeId : undefined,
|
|
157
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
157
158
|
};
|
|
158
159
|
return overrides[id] ? { ...base, ...overrides[id] } : base;
|
|
159
160
|
}),
|
|
@@ -34,6 +34,7 @@ const ADMIN_STICKERS_CONFIG = {
|
|
|
34
34
|
].join(" · "),
|
|
35
35
|
status: toStringValue(item.status, "draft"),
|
|
36
36
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
37
|
+
image: toStringValue(item.mainImage, "") || undefined,
|
|
37
38
|
})),
|
|
38
39
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
39
40
|
buildFilters: () => "listingType==stickers",
|
|
@@ -64,6 +64,7 @@ export function AdminStoresView({ children, ...props }) {
|
|
|
64
64
|
].join(" · "),
|
|
65
65
|
status: toStringValue(item.status, "Pending"),
|
|
66
66
|
updatedAt: toRelativeDate(item.updatedAt ?? item.createdAt),
|
|
67
|
+
image: toStringValue(item.storeLogoURL, "") || undefined,
|
|
67
68
|
_raw: item,
|
|
68
69
|
})),
|
|
69
70
|
getTotal: (response, mappedRows) => typeof response.total === "number" ? response.total : mappedRows.length,
|
|
@@ -10,6 +10,8 @@ interface AdminViewCardsProps {
|
|
|
10
10
|
onToggleSelect?: (id: string) => void;
|
|
11
11
|
/** Same row-actions menu DataTable renders in its table view — mirrored here so cards carry the same quick actions, not just navigation. */
|
|
12
12
|
renderRowActions?: (row: AdminListingScaffoldRow) => React.ReactNode;
|
|
13
|
+
/** Resource-type emoji fallback for rows without their own `image` (e.g. 👤 for users, 🏪 for stores). */
|
|
14
|
+
resourceIcon?: string;
|
|
13
15
|
}
|
|
14
|
-
export declare function AdminViewCards({ rows, view, isLoading, emptyLabel, onRowClick, selectedIdSet, onToggleSelect, renderRowActions, }: AdminViewCardsProps): React.JSX.Element;
|
|
16
|
+
export declare function AdminViewCards({ rows, view, isLoading, emptyLabel, onRowClick, selectedIdSet, onToggleSelect, renderRowActions, resourceIcon, }: AdminViewCardsProps): React.JSX.Element;
|
|
15
17
|
export {};
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Checkbox, Div, Grid, Row, Span, Stack, Text } from "../../../ui";
|
|
4
|
+
import { getStatusTone } from "../../../ui/columns/column-renderers";
|
|
5
|
+
import { MediaImage } from "../../media/MediaImage";
|
|
4
6
|
const __P = {
|
|
5
7
|
p3: "p-[var(--appkit-space-3)]",
|
|
6
8
|
};
|
|
7
9
|
const __O = {
|
|
8
10
|
hidden: "overflow-hidden",
|
|
9
11
|
};
|
|
12
|
+
const STATUS_TONE_CLASSES = {
|
|
13
|
+
success: "bg-success-surface text-success",
|
|
14
|
+
warning: "bg-warning-surface text-warning",
|
|
15
|
+
error: "bg-error-surface text-error",
|
|
16
|
+
info: "bg-info-surface text-info",
|
|
17
|
+
neutral: "bg-primary-50 text-primary-800 dark:bg-secondary-900/30 dark:text-secondary-300",
|
|
18
|
+
};
|
|
19
|
+
function RowAvatar({ image, alt, icon, size = "9" }) {
|
|
20
|
+
const dims = size === "12" ? "h-12 w-12" : "h-9 w-9";
|
|
21
|
+
return (_jsx(Div, { className: `relative ${dims} shrink-0`, overflow: "hidden", rounded: "full", children: _jsx(MediaImage, { src: image, alt: alt, size: "avatar", fallback: icon }) }));
|
|
22
|
+
}
|
|
10
23
|
const FLAG_BADGES = [
|
|
11
24
|
{ key: "featured", label: "Featured", color: "bg-warning-surface text-warning dark:bg-warning-surface dark:text-warning" },
|
|
12
25
|
{ key: "isPromoted", label: "Promoted", color: "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300" },
|
|
@@ -14,7 +27,8 @@ const FLAG_BADGES = [
|
|
|
14
27
|
{ key: "isSold", label: "Sold", color: "bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text-muted)] bg-[var(--appkit-color-surface-elevated)] text-[var(--appkit-color-text-muted)]" },
|
|
15
28
|
];
|
|
16
29
|
function StatusBadge({ status }) {
|
|
17
|
-
|
|
30
|
+
const tone = getStatusTone(status);
|
|
31
|
+
return (_jsx(Span, { size: "xs", weight: "medium", className: `inline-flex truncate max-w-[120px] ${STATUS_TONE_CLASSES[tone]}`, rounded: "full", padding: "pill-xs", children: status }));
|
|
18
32
|
}
|
|
19
33
|
function SkeletonCard({ view }) {
|
|
20
34
|
if (view === "list") {
|
|
@@ -22,7 +36,7 @@ function SkeletonCard({ view }) {
|
|
|
22
36
|
}
|
|
23
37
|
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} animate-pulse`, children: _jsxs(Stack, { gap: "xs", padding: "md", children: [_jsx(Div, { className: "h-4 w-3/4", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-3 w-1/2", surface: "subtle", rounded: "default" }), _jsx(Div, { className: "h-5 w-20 mt-1", surface: "subtle", rounded: "full" }), _jsx(Div, { className: "h-3 w-1/3", surface: "subtle", rounded: "default" })] }) }));
|
|
24
38
|
}
|
|
25
|
-
function AdminCardItem({ row, view, selected, onToggleSelect, onRowClick, renderRowActions, }) {
|
|
39
|
+
function AdminCardItem({ row, view, selected, onToggleSelect, onRowClick, renderRowActions, resourceIcon, }) {
|
|
26
40
|
const flags = FLAG_BADGES.filter(({ key }) => Boolean(row[key]));
|
|
27
41
|
const handleClick = (e) => {
|
|
28
42
|
if (e.target.closest('[data-no-row-click]'))
|
|
@@ -33,16 +47,16 @@ function AdminCardItem({ row, view, selected, onToggleSelect, onRowClick, render
|
|
|
33
47
|
return (_jsxs(Row, { gap: "sm", className: [
|
|
34
48
|
"px-[var(--appkit-space-4)] py-[var(--appkit-space-3)] cursor-pointer transition-colors hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]/50",
|
|
35
49
|
selected ? "bg-primary-50/40 dark:bg-primary-900/10" : "",
|
|
36
|
-
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsx(Div, { "data-no-row-click": true, className: "shrink-0", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: _jsx(Checkbox, { bare: true, checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }) })), _jsxs(Stack, { gap: "none", className: "flex-1 min-w-0", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "truncate", color: "primary", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary }), row.barcodeId && (_jsx(Text, { size: "xs", color: "faint", className: "truncate font-mono", children: row.barcodeId }))] }), flags.length > 0 && (_jsx(Row, { gap: "xs", className: "hidden sm:flex shrink-0", children: flags.map(({ key, label, color }) => (_jsx(Span, { padding: "pill-2xs", weight: "medium", className: `inline-flex text-[10px] ${color}`, rounded: "full", children: label }, key))) })), _jsx(StatusBadge, { status: row.status }), _jsx(Span, { size: "xs", color: "muted", className: "hidden sm:block shrink-0 w-24", align: "end", children: row.updatedAt }), renderRowActions && (_jsx(Div, { "data-no-row-click": true, className: "shrink-0", onClick: (e) => e.stopPropagation(), children: renderRowActions(row) }))] }));
|
|
50
|
+
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsx(Div, { "data-no-row-click": true, className: "shrink-0", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: _jsx(Checkbox, { bare: true, checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }) })), _jsx(RowAvatar, { image: row.image, alt: row.primary, icon: resourceIcon }), _jsxs(Stack, { gap: "none", className: "flex-1 min-w-0", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "truncate", color: "primary", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary }), row.barcodeId && (_jsx(Text, { size: "xs", color: "faint", className: "truncate font-mono", children: row.barcodeId }))] }), flags.length > 0 && (_jsx(Row, { gap: "xs", className: "hidden sm:flex shrink-0", children: flags.map(({ key, label, color }) => (_jsx(Span, { padding: "pill-2xs", weight: "medium", className: `inline-flex text-[10px] ${color}`, rounded: "full", children: label }, key))) })), _jsx(StatusBadge, { status: row.status }), _jsx(Span, { size: "xs", color: "muted", className: "hidden sm:block shrink-0 w-24", align: "end", children: row.updatedAt }), renderRowActions && (_jsx(Div, { "data-no-row-click": true, className: "shrink-0", onClick: (e) => e.stopPropagation(), children: renderRowActions(row) }))] }));
|
|
37
51
|
}
|
|
38
52
|
return (_jsxs(Div, { rounded: "xl", className: [
|
|
39
53
|
"border overflow-hidden cursor-pointer transition-all hover:shadow-md hover:-translate-y-0.5",
|
|
40
54
|
selected
|
|
41
55
|
? "border-primary ring-1 ring-primary/20 bg-primary-50/30 dark:bg-primary-900/10"
|
|
42
56
|
: "border-zinc-100 border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)]",
|
|
43
|
-
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsxs(Row, { gap: "xs", "data-no-row-click": true, paddingY: "t-sm", padding: "x-sm", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: [_jsx(Checkbox, { bare: true, checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }), flags.length > 0 && (_jsx(Row, { gap: "xs", wrap: true, children: flags.map(({ key, label, color }) => (_jsx(Span, { padding: "pill-2xs", weight: "medium", className: `inline-flex text-[10px] ${color}`, rounded: "full", children: label }, key))) }))] })), _jsxs(Stack, { gap: "xs", className: `${__P.p3}.5`, children: [_jsxs(Stack, { gap: "none", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "line-clamp-2 leading-snug", color: "primary", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary }), row.barcodeId && (_jsx(Text, { size: "xs", color: "faint", className: "truncate font-mono", children: row.barcodeId }))
|
|
57
|
+
].filter(Boolean).join(" "), onClick: handleClick, role: onRowClick ? "button" : undefined, children: [onToggleSelect && (_jsxs(Row, { gap: "xs", "data-no-row-click": true, paddingY: "t-sm", padding: "x-sm", onClick: (e) => { e.stopPropagation(); onToggleSelect(row.id); }, children: [_jsx(Checkbox, { bare: true, checked: selected, onChange: () => onToggleSelect(row.id), className: "h-4 w-4 rounded border-zinc-300 text-primary accent-primary cursor-pointer", "aria-label": `Select ${row.primary}` }), flags.length > 0 && (_jsx(Row, { gap: "xs", wrap: true, children: flags.map(({ key, label, color }) => (_jsx(Span, { padding: "pill-2xs", weight: "medium", className: `inline-flex text-[10px] ${color}`, rounded: "full", children: label }, key))) }))] })), _jsxs(Stack, { gap: "xs", className: `${__P.p3}.5`, children: [_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(RowAvatar, { image: row.image, alt: row.primary, icon: resourceIcon, size: "12" }), _jsxs(Stack, { gap: "none", className: "min-w-0 flex-1", children: [_jsx(Text, { size: "sm", weight: "semibold", className: "line-clamp-2 leading-snug", color: "primary", children: row.primary }), _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: row.secondary })] })] }), row.barcodeId && (_jsx(Text, { size: "xs", color: "faint", className: "truncate font-mono", children: row.barcodeId })), _jsxs(Row, { justify: "between", gap: "xs", children: [_jsx(StatusBadge, { status: row.status }), _jsx(Span, { color: "muted", className: "text-[11px] shrink-0", children: row.updatedAt })] }), renderRowActions && (_jsx(Row, { "data-no-row-click": true, justify: "end", gap: "xs", className: "border-t border-[var(--appkit-color-border)] -mx-[var(--appkit-space-3)] -mb-[var(--appkit-space-3)] mt-[var(--appkit-space-1)] px-[var(--appkit-space-3)] py-[var(--appkit-space-2)]", onClick: (e) => e.stopPropagation(), children: renderRowActions(row) }))] })] }));
|
|
44
58
|
}
|
|
45
|
-
export function AdminViewCards({ rows, view, isLoading, emptyLabel = "No items found", onRowClick, selectedIdSet, onToggleSelect, renderRowActions, }) {
|
|
59
|
+
export function AdminViewCards({ rows, view, isLoading, emptyLabel = "No items found", onRowClick, selectedIdSet, onToggleSelect, renderRowActions, resourceIcon, }) {
|
|
46
60
|
if (isLoading) {
|
|
47
61
|
const count = view === "grid" ? 12 : 8;
|
|
48
62
|
if (view === "list") {
|
|
@@ -54,7 +68,7 @@ export function AdminViewCards({ rows, view, isLoading, emptyLabel = "No items f
|
|
|
54
68
|
return (_jsx(Text, { paddingY: "3xl", size: "sm", color: "muted", align: "center", children: emptyLabel }));
|
|
55
69
|
}
|
|
56
70
|
if (view === "list") {
|
|
57
|
-
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} divide-y divide-zinc-100 divide-[var(--appkit-color-border)]`, children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "list", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick, renderRowActions: renderRowActions }, row.id))) }));
|
|
71
|
+
return (_jsx(Div, { rounded: "xl", border: "subtle", className: `${__O.hidden} divide-y divide-zinc-100 divide-[var(--appkit-color-border)]`, children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "list", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick, renderRowActions: renderRowActions, resourceIcon: resourceIcon }, row.id))) }));
|
|
58
72
|
}
|
|
59
|
-
return (_jsx(Grid, { gap: "md", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "grid", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick, renderRowActions: renderRowActions }, row.id))) }));
|
|
73
|
+
return (_jsx(Grid, { gap: "md", className: "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4", children: rows.map((row) => (_jsx(AdminCardItem, { row: row, view: "grid", selected: selectedIdSet?.has(row.id) ?? false, onToggleSelect: onToggleSelect, onRowClick: onRowClick, renderRowActions: renderRowActions, resourceIcon: resourceIcon }, row.id))) }));
|
|
60
74
|
}
|
|
@@ -39,6 +39,8 @@ export interface AdminListingScaffoldRow {
|
|
|
39
39
|
isOnSale?: boolean;
|
|
40
40
|
isSold?: boolean;
|
|
41
41
|
barcodeId?: string;
|
|
42
|
+
/** Row photo/thumbnail (avatar, product image, store logo, cover image, etc). Falls back to the table's resource icon when omitted. */
|
|
43
|
+
image?: string;
|
|
42
44
|
}
|
|
43
45
|
export interface ListingSortOption {
|
|
44
46
|
value: string;
|
|
@@ -4,6 +4,7 @@ import { Plus } from "lucide-react";
|
|
|
4
4
|
import { BulkActionBar, Button, Div, ListingFilterDrawer, ListingToolbar, Pagination, Row, SideDrawer, StickyToolbar } from "../../../ui";
|
|
5
5
|
import { useBottomActions } from "../../layout";
|
|
6
6
|
import { useAdminListing } from "../hooks/useAdminListing";
|
|
7
|
+
import { getResourceIcon } from "../../../ui/columns/column-renderers";
|
|
7
8
|
import { AdminViewCards } from "./AdminViewCards";
|
|
8
9
|
import { DataTable } from "./DataTable";
|
|
9
10
|
export function DataListingView({ config, }) {
|
|
@@ -21,6 +22,7 @@ export function DataListingView({ config, }) {
|
|
|
21
22
|
rows,
|
|
22
23
|
openEditPanel: panel.openEditPanel,
|
|
23
24
|
};
|
|
25
|
+
const resourceIcon = getResourceIcon(typeof config.queryKey[1] === "string" ? config.queryKey[1] : undefined);
|
|
24
26
|
const bulkActionItems = config.buildBulkActions?.(selectionContext);
|
|
25
27
|
// Mobile bulk bar
|
|
26
28
|
useBottomActions(selection.selectedCount > 0 && bulkActionItems
|
|
@@ -64,7 +66,7 @@ export function DataListingView({ config, }) {
|
|
|
64
66
|
: undefined;
|
|
65
67
|
return (_jsxs(Div, { className: config.className ?? "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: config.searchPlaceholder, onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || config.defaultSort, sortOptions: config.sortOptions, onSortChange: (v) => table.set("sort", v), showTableView: !config.hideTableView, toggles: config.toggles, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: config.primaryAction || config.toolbarExtra ? (_jsxs(Row, { align: "center", gap: "sm", children: [config.toolbarExtra, config.primaryAction && (_jsxs(Button, { gap: "sm", size: "sm", onClick: () => config.primaryAction.onClick({
|
|
66
68
|
openCreatePanel: panel.openCreatePanel,
|
|
67
|
-
}), children: [config.primaryAction.icon ?? _jsx(Plus, { className: "h-4 w-4" }), config.primaryAction.label] }))] })) : undefined }), config.renderAboveContent?.(), bulkActionItems && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActionItems })), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p), pageSize: pageSize, onPageSizeChange: setPageSize, paginationConfig: { showPageSizeSelector: true, pageSizeOptions: [10, 25, 50, 100] } }) }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), view === "table" && !config.hideTableView ? (_jsx(DataTable, { columns: config.columns, rows: rows, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: (next) => next
|
|
69
|
+
}), children: [config.primaryAction.icon ?? _jsx(Plus, { className: "h-4 w-4" }), config.primaryAction.label] }))] })) : undefined }), config.renderAboveContent?.(), bulkActionItems && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActionItems })), totalPages > 1 && (_jsx(StickyToolbar, { offset: "header+pagination", tone: "translucent", border: true, padding: "toolbar", children: _jsx(Row, { justify: "center", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p), pageSize: pageSize, onPageSizeChange: setPageSize, paginationConfig: { showPageSizeSelector: true, pageSizeOptions: [10, 25, 50, 100] } }) }) })), _jsxs(Div, { paddingX: "x-sm-md", padding: "y-md", children: [errorMessage && (_jsx(Div, { textSize: "sm", className: "mb-4 border border-error/20", color: "error", surface: "danger-surface", padding: "inline", rounded: "xl", children: errorMessage })), view === "table" && !config.hideTableView ? (_jsx(DataTable, { columns: config.columns, rows: rows, resourceIcon: resourceIcon, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: (next) => next
|
|
68
70
|
? selection.setSelectedIds(rows.map((r) => r.id))
|
|
69
71
|
: selection.clearSelection(), rowHrefTemplate: config.rowHrefTemplate, onRowClick: config.onRowClick
|
|
70
72
|
? (row) => config.onRowClick(row, {
|
|
@@ -76,7 +78,7 @@ export function DataListingView({ config, }) {
|
|
|
76
78
|
// The persisted view-mode preference is global, so a "table"
|
|
77
79
|
// value can still reach here on a hideTableView-only view (see
|
|
78
80
|
// the DataTable branch's guard above) — fall back to "grid".
|
|
79
|
-
config.renderCards(rows, view === "table" ? "grid" : view, selectionContext, isLoading)) : (_jsx(AdminViewCards, { rows: rows, view: view === "table" ? "grid" : view, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, onRowClick: resolvedRowClick
|
|
81
|
+
config.renderCards(rows, view === "table" ? "grid" : view, selectionContext, isLoading)) : (_jsx(AdminViewCards, { rows: rows, view: view === "table" ? "grid" : view, resourceIcon: resourceIcon, isLoading: isLoading, emptyLabel: config.emptyLabel ?? `No ${config.title.toLowerCase()} found`, onRowClick: resolvedRowClick
|
|
80
82
|
? (row) => resolvedRowClick(row)
|
|
81
83
|
: undefined, selectedIdSet: selection.selectedIdSet, onToggleSelect: selection.toggle, renderRowActions: config.renderRowActions
|
|
82
84
|
? (row) => config.renderRowActions(row)
|
|
@@ -28,8 +28,10 @@ interface DataTableProps<T extends {
|
|
|
28
28
|
selectedIds?: Set<string>;
|
|
29
29
|
onToggleSelect?: (id: string, selected: boolean) => void;
|
|
30
30
|
onToggleSelectAll?: (nextAllSelected: boolean) => void;
|
|
31
|
+
/** Resource-type emoji fallback for the default "Name" column's avatar when a row has no `image` and no custom `columns` were supplied. */
|
|
32
|
+
resourceIcon?: string;
|
|
31
33
|
}
|
|
32
34
|
export declare function DataTable<T extends {
|
|
33
35
|
id: string;
|
|
34
|
-
}>({ columns: columnsProp, rows, isLoading, sortKey, sortDir, onSort, totalPages, currentPage, onPageChange, emptyLabel, rowHrefTemplate, onRowClick, renderRowActions, selectedIds, onToggleSelect, onToggleSelectAll, }: DataTableProps<T>): React.JSX.Element;
|
|
36
|
+
}>({ columns: columnsProp, rows, isLoading, sortKey, sortDir, onSort, totalPages, currentPage, onPageChange, emptyLabel, rowHrefTemplate, onRowClick, renderRowActions, selectedIds, onToggleSelect, onToggleSelectAll, resourceIcon, }: DataTableProps<T>): React.JSX.Element;
|
|
35
37
|
export {};
|
|
@@ -1,30 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { BaseListingCard, Button, Checkbox, Div, Row, Span, Stack, Table, Tbody, Td, Text, Th, Thead, Tr } from "../../../ui";
|
|
4
|
+
import { getStatusTone } from "../../../ui/columns/column-renderers";
|
|
5
|
+
import { MediaImage } from "../../media/MediaImage";
|
|
4
6
|
import { useLongPress } from "../../../react/hooks/useLongPress";
|
|
5
7
|
const __O = {
|
|
6
8
|
hidden: "overflow-hidden",
|
|
7
9
|
xAuto: "overflow-x-auto",
|
|
8
10
|
};
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
const STATUS_TONE_CLASSES = {
|
|
12
|
+
success: "bg-success-surface text-success",
|
|
13
|
+
warning: "bg-warning-surface text-warning",
|
|
14
|
+
error: "bg-error-surface text-error",
|
|
15
|
+
info: "bg-info-surface text-info",
|
|
16
|
+
neutral: "bg-primary-50 text-primary-800 dark:bg-secondary-900/30 dark:text-secondary-300",
|
|
17
|
+
};
|
|
18
|
+
function buildDefaultColumns(resourceIcon) {
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
key: "primary",
|
|
22
|
+
header: "Name",
|
|
23
|
+
render: (row) => (_jsxs(Row, { gap: "sm", align: "center", children: [_jsx(Div, { className: "relative h-8 w-8 shrink-0", overflow: "hidden", rounded: "full", children: _jsx(MediaImage, { src: typeof row.image === "string" ? row.image : undefined, alt: String(row.primary ?? ""), size: "avatar", fallback: resourceIcon }) }), _jsxs(Stack, { gap: "none", className: "min-w-0", children: [_jsx(Text, { weight: "medium", color: "primary", className: "truncate", children: String(row.primary ?? "") }), row.secondary ? _jsx(Text, { size: "xs", color: "muted", className: "truncate", children: String(row.secondary) }) : null] })] })),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: "status",
|
|
27
|
+
header: "Status",
|
|
28
|
+
className: "w-32",
|
|
29
|
+
render: (row) => {
|
|
30
|
+
const status = String(row.status ?? "—");
|
|
31
|
+
const tone = getStatusTone(status);
|
|
32
|
+
return (_jsx(Span, { size: "xs", weight: "medium", className: `inline-flex ${STATUS_TONE_CLASSES[tone]}`, rounded: "full", padding: "pill-sm-tall", children: status }));
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: "updatedAt",
|
|
37
|
+
header: "Updated",
|
|
38
|
+
className: "w-32",
|
|
39
|
+
render: (row) => _jsx(Span, { size: "sm", color: "muted", children: String(row.updatedAt ?? "") }),
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
}
|
|
28
43
|
function SelectableRow({ row, columns, isSelected, onToggle, renderRowActions, onRowClick, rowHref, selectionEnabled, }) {
|
|
29
44
|
const longPress = useLongPress(() => onToggle?.(row.id, !isSelected));
|
|
30
45
|
const handleClick = onRowClick
|
|
@@ -43,8 +58,8 @@ function SelectableRow({ row, columns, isSelected, onToggle, renderRowActions, o
|
|
|
43
58
|
? col.render(row)
|
|
44
59
|
: String(row[col.key] ?? "") }, col.key))), renderRowActions && (_jsx(Td, { padding: "xs-3", onClick: (e) => e.stopPropagation(), children: renderRowActions(row) }))] }));
|
|
45
60
|
}
|
|
46
|
-
export function DataTable({ columns: columnsProp, rows, isLoading, sortKey, sortDir, onSort, totalPages = 1, currentPage = 1, onPageChange, emptyLabel = "No records found", rowHrefTemplate, onRowClick, renderRowActions, selectedIds, onToggleSelect, onToggleSelectAll, }) {
|
|
47
|
-
const columns = (columnsProp ??
|
|
61
|
+
export function DataTable({ columns: columnsProp, rows, isLoading, sortKey, sortDir, onSort, totalPages = 1, currentPage = 1, onPageChange, emptyLabel = "No records found", rowHrefTemplate, onRowClick, renderRowActions, selectedIds, onToggleSelect, onToggleSelectAll, resourceIcon, }) {
|
|
62
|
+
const columns = (columnsProp ?? buildDefaultColumns(resourceIcon));
|
|
48
63
|
const selectionEnabled = Boolean(onToggleSelect);
|
|
49
64
|
const allRowsSelected = selectionEnabled && rows.length > 0 && rows.every((r) => selectedIds?.has(r.id));
|
|
50
65
|
return (_jsxs(Div, { surface: "card", className: `${__O.hidden}`, children: [_jsx(Div, { className: `${__O.xAuto}`, children: _jsxs(Table, { "data-testid": "data-table", size: "sm", children: [_jsx(Thead, { children: _jsxs(Tr, { className: "bg-[var(--appkit-color-bg)] dark:bg-[var(--appkit-color-surface-elevated)]", border: "default", children: [selectionEnabled && (_jsx(Th, { padding: "xs-3", scope: "col", className: "w-10", children: onToggleSelectAll && (_jsx(Checkbox, { bare: true, "data-testid": "select-all-checkbox", "aria-label": allRowsSelected ? "Deselect all" : "Select all", checked: allRowsSelected, onChange: () => onToggleSelectAll(!allRowsSelected), className: "h-4 w-4 rounded border-[var(--appkit-color-border)] accent-zinc-900 dark:accent-zinc-100" })) })), columns.map((col) => (_jsxs(Th, { scope: "col", onClick: col.sortable && onSort ? () => onSort(col.key) : undefined, className: `text-left text-[var(--appkit-color-text)] text-[var(--appkit-color-text)] ${col.sortable && onSort ? "cursor-pointer select-none hover:text-primary" : ""} ${col.className ?? ""}`, padding: "md", weight: "semibold", children: [col.header, col.sortable && sortKey === col.key && (_jsx(Span, { className: "ml-1", children: sortDir === "asc" ? "↑" : "↓" }))] }, col.key))), renderRowActions && _jsx(Th, { padding: "xs-3", scope: "col", className: "w-12" })] }) }), _jsx(Tbody, { children: isLoading ? (Array.from({ length: 5 }).map((_, i) => (_jsxs(Tr, { border: "default", children: [selectionEnabled && _jsx(Td, { padding: "xs-3", className: "w-10" }), columns.map((col) => (_jsx(Td, { padding: "md", children: _jsx(Div, { className: "h-4 w-full animate-pulse bg-neutral-200", rounded: "default" }) }, col.key)))] }, i)))) : rows.length === 0 ? (_jsx(Tr, { children: _jsx(Td, { colSpan: columns.length + (selectionEnabled ? 1 : 0) + (renderRowActions ? 1 : 0), align: "center", color: "faint", paddingX: "md", paddingY: "md", children: emptyLabel }) })) : (rows.map((row) => (_jsx(SelectableRow, { row: row, columns: columns, isSelected: selectedIds?.has(row.id) ?? false, onToggle: onToggleSelect, renderRowActions: renderRowActions, onRowClick: onRowClick, rowHref: typeof rowHrefTemplate === "function"
|