@mohasinac/appkit 2.7.54 → 2.7.55
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/jobs/runtime/adapters/firebase.js +5 -14
- package/dist/_internal/shared/actions/action-registry.js +827 -4
- package/dist/_internal/shared/features/events/schema.d.ts +4 -4
- package/dist/constants/api-endpoints.d.ts +3 -0
- package/dist/constants/api-endpoints.js +1 -0
- package/dist/features/account/components/UserOffersPanel.js +2 -1
- package/dist/features/admin/components/AdminAllEventEntriesView.js +4 -3
- package/dist/features/admin/components/AdminBidsView.js +5 -3
- package/dist/features/admin/components/AdminBlogView.js +3 -2
- package/dist/features/admin/components/AdminBrandsView.js +2 -1
- package/dist/features/admin/components/AdminBundleEditorView.js +4 -5
- package/dist/features/admin/components/AdminBundlesView.js +3 -3
- package/dist/features/admin/components/AdminCarouselView.d.ts +2 -1
- package/dist/features/admin/components/AdminCarouselView.js +14 -5
- package/dist/features/admin/components/AdminCategoriesView.js +2 -1
- package/dist/features/admin/components/AdminContactView.d.ts +4 -1
- package/dist/features/admin/components/AdminContactView.js +27 -7
- package/dist/features/admin/components/AdminCouponsView.d.ts +3 -1
- package/dist/features/admin/components/AdminCouponsView.js +17 -3
- package/dist/features/admin/components/AdminFaqsView.d.ts +3 -1
- package/dist/features/admin/components/AdminFaqsView.js +18 -4
- package/dist/features/admin/components/AdminFeaturesView.js +2 -1
- package/dist/features/admin/components/AdminMediaView.js +3 -2
- package/dist/features/admin/components/AdminNavigationView.js +3 -2
- package/dist/features/admin/components/AdminNewsletterView.d.ts +2 -1
- package/dist/features/admin/components/AdminNewsletterView.js +13 -4
- package/dist/features/admin/components/AdminNotificationsView.js +6 -4
- package/dist/features/admin/components/AdminOrdersView.js +4 -3
- package/dist/features/admin/components/AdminPayoutsView.js +2 -2
- package/dist/features/admin/components/AdminPrizeDrawsView.js +2 -1
- package/dist/features/admin/components/AdminProductsView.js +3 -3
- package/dist/features/admin/components/AdminReviewsView.js +4 -3
- package/dist/features/admin/components/AdminScammersView.js +2 -1
- package/dist/features/admin/components/AdminSessionsView.js +5 -3
- package/dist/features/admin/components/AdminStoresView.js +2 -2
- package/dist/features/admin/components/AdminSublistingCategoriesView.d.ts +5 -1
- package/dist/features/admin/components/AdminSublistingCategoriesView.js +12 -3
- package/dist/features/admin/components/AdminSupportTicketsView.js +2 -1
- package/dist/features/admin/components/AdminTeamView.d.ts +2 -1
- package/dist/features/admin/components/AdminTeamView.js +13 -4
- package/dist/features/admin/components/AdminUsersView.js +2 -2
- package/dist/features/products/constants/action-defs.d.ts +86 -7
- package/dist/features/products/constants/action-defs.js +99 -7
- package/dist/features/seller/components/QuickProductForm.d.ts +13 -0
- package/dist/features/seller/components/QuickProductForm.js +50 -0
- package/dist/features/seller/components/SellerAuctionsView.d.ts +4 -1
- package/dist/features/seller/components/SellerAuctionsView.js +37 -3
- package/dist/features/seller/components/SellerBidsView.js +2 -1
- package/dist/features/seller/components/SellerBundlesView.d.ts +3 -1
- package/dist/features/seller/components/SellerBundlesView.js +38 -5
- package/dist/features/seller/components/SellerClassifiedView.d.ts +3 -1
- package/dist/features/seller/components/SellerClassifiedView.js +37 -4
- package/dist/features/seller/components/SellerDigitalCodesView.d.ts +3 -1
- package/dist/features/seller/components/SellerDigitalCodesView.js +37 -4
- package/dist/features/seller/components/SellerGoogleReviewsView.js +2 -1
- package/dist/features/seller/components/SellerGroupedListingsView.js +3 -2
- package/dist/features/seller/components/SellerLiveView.d.ts +3 -1
- package/dist/features/seller/components/SellerLiveView.js +37 -4
- package/dist/features/seller/components/SellerOffersPanel.js +2 -1
- package/dist/features/seller/components/SellerOffersView.d.ts +4 -1
- package/dist/features/seller/components/SellerOffersView.js +8 -3
- package/dist/features/seller/components/SellerPayoutsView.d.ts +3 -1
- package/dist/features/seller/components/SellerPayoutsView.js +7 -3
- package/dist/features/seller/components/SellerPreOrdersView.d.ts +2 -1
- package/dist/features/seller/components/SellerPreOrdersView.js +30 -7
- package/dist/features/seller/components/SellerPrizeDrawsView.d.ts +2 -1
- package/dist/features/seller/components/SellerPrizeDrawsView.js +30 -7
- package/dist/features/seller/components/SellerProductShell.js +12 -0
- package/dist/features/seller/components/SellerReviewsView.js +2 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +3 -2
- package/dist/features/seller/components/SellerStoreCategoriesView.js +6 -5
- package/dist/features/seller/components/SellerTemplatesView.js +4 -3
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +30 -16
- package/dist/styles.css +1 -1
- package/dist/tailwind-utilities.css +1 -1
- package/package.json +1 -1
|
@@ -147,13 +147,13 @@ export function AdminUsersView({ children, ...props }) {
|
|
|
147
147
|
return _jsx(ListingViewShell, { portal: "admin", ...props, children: children });
|
|
148
148
|
}
|
|
149
149
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search users, email, or seller handles", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), _jsx(BulkActionBar, { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: [
|
|
150
|
-
{ id: "manage", label: "
|
|
150
|
+
{ id: "manage", label: ACTIONS.ADMIN["manage-user"].label, variant: "primary", onClick: () => { setSelectedRow(rows.find(r => r.id === selection.selectedIds[0]) ?? null); setDrawerOpen(true); selection.clearSelection(); } },
|
|
151
151
|
] }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), view === "table" ? (_jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No users found", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: (next) => next ? selection.setSelectedIds(rows.map(r => r.id)) : selection.clearSelection(), renderRowActions: (row) => {
|
|
152
152
|
const ur = row;
|
|
153
153
|
const isBanned = ur.status === "Hard banned";
|
|
154
154
|
return (_jsx(RowActionMenu, { actions: [
|
|
155
155
|
{
|
|
156
|
-
label: "
|
|
156
|
+
label: ACTIONS.ADMIN["manage-user"].label,
|
|
157
157
|
onClick: () => { setSelectedRow(ur); setDrawerOpen(true); },
|
|
158
158
|
},
|
|
159
159
|
{
|
|
@@ -116,6 +116,19 @@ export declare const ROW_ACTION_ID: {
|
|
|
116
116
|
readonly REPLY: "row-reply";
|
|
117
117
|
readonly PUBLISH: "row-publish";
|
|
118
118
|
readonly ARCHIVE: "row-archive";
|
|
119
|
+
readonly MARK_SHIPPED: "row-mark-shipped";
|
|
120
|
+
readonly MARK_DELIVERED: "row-mark-delivered";
|
|
121
|
+
readonly MARK_PAID: "row-mark-paid";
|
|
122
|
+
readonly REVOKE: "row-revoke";
|
|
123
|
+
readonly MARK_READ: "row-mark-read";
|
|
124
|
+
readonly ACTIVATE: "row-activate";
|
|
125
|
+
readonly DEACTIVATE: "row-deactivate";
|
|
126
|
+
readonly FEATURE: "row-feature";
|
|
127
|
+
readonly PROMOTE: "row-promote";
|
|
128
|
+
readonly SALE: "row-sale";
|
|
129
|
+
readonly DRAFT: "row-draft";
|
|
130
|
+
readonly CONTEST: "row-contest";
|
|
131
|
+
readonly FEEDBACK: "row-feedback";
|
|
119
132
|
};
|
|
120
133
|
export type RowActionId = (typeof ROW_ACTION_ID)[keyof typeof ROW_ACTION_ID];
|
|
121
134
|
export interface RowActionMeta {
|
|
@@ -142,28 +155,61 @@ export declare const ADMIN_ROW_ACTIONS: {
|
|
|
142
155
|
readonly users: readonly ["row-view", "row-edit", "row-suspend", "row-restore", "row-delete"];
|
|
143
156
|
readonly stores: readonly ["row-manage", "row-approve", "row-reject", "row-suspend", "row-delete"];
|
|
144
157
|
readonly products: readonly ["row-view", "row-edit", "row-publish", "row-archive", "row-delete"];
|
|
145
|
-
readonly orders: readonly ["row-view", "row-edit", "row-
|
|
158
|
+
readonly orders: readonly ["row-view", "row-edit", "row-mark-shipped", "row-mark-delivered", "row-cancel"];
|
|
146
159
|
readonly reviews: readonly ["row-view", "row-approve", "row-reject", "row-delete"];
|
|
147
160
|
readonly events: readonly ["row-view", "row-edit", "row-archive", "row-delete"];
|
|
148
|
-
readonly payouts: readonly ["row-view", "row-approve", "row-
|
|
161
|
+
readonly payouts: readonly ["row-view", "row-approve", "row-mark-paid"];
|
|
149
162
|
readonly coupons: readonly ["row-edit", "row-duplicate", "row-archive", "row-delete"];
|
|
150
|
-
readonly blog: readonly ["row-view", "row-edit", "row-publish", "row-
|
|
163
|
+
readonly blog: readonly ["row-view", "row-edit", "row-publish", "row-draft", "row-delete"];
|
|
151
164
|
readonly faqs: readonly ["row-edit", "row-archive", "row-delete"];
|
|
152
165
|
readonly bids: readonly ["row-view", "row-cancel"];
|
|
166
|
+
readonly notifications: readonly ["row-resend", "row-delete"];
|
|
167
|
+
readonly sessions: readonly ["row-revoke"];
|
|
168
|
+
readonly bundles: readonly ["row-view", "row-edit", "row-activate", "row-deactivate", "row-delete"];
|
|
169
|
+
readonly brands: readonly ["row-edit"];
|
|
170
|
+
readonly categories: readonly ["row-edit"];
|
|
171
|
+
readonly features: readonly ["row-edit", "row-delete"];
|
|
172
|
+
readonly prizeDraws: readonly ["row-view", "row-delete"];
|
|
173
|
+
readonly carousel: readonly ["row-edit", "row-delete"];
|
|
174
|
+
readonly contact: readonly ["row-view", "row-mark-read", "row-archive", "row-delete"];
|
|
175
|
+
readonly newsletter: readonly ["row-delete"];
|
|
176
|
+
readonly team: readonly ["row-edit", "row-delete"];
|
|
177
|
+
readonly navigation: readonly ["row-edit", "row-delete"];
|
|
178
|
+
readonly sublistingCategories: readonly ["row-edit", "row-delete"];
|
|
179
|
+
readonly scammers: readonly ["row-view", "row-approve", "row-reject", "row-delete"];
|
|
180
|
+
readonly supportTickets: readonly ["row-view", "row-reply"];
|
|
181
|
+
readonly eventEntries: readonly ["row-view", "row-approve", "row-reject"];
|
|
182
|
+
readonly returnRequests: readonly ["row-view", "row-approve", "row-reject"];
|
|
153
183
|
};
|
|
154
184
|
export declare const SELLER_ROW_ACTIONS: {
|
|
155
185
|
readonly products: readonly ["row-view", "row-edit", "row-duplicate", "row-archive", "row-delete"];
|
|
156
186
|
readonly orders: readonly ["row-view", "row-edit", "row-track", "row-resend"];
|
|
157
|
-
readonly reviews: readonly ["row-view", "row-reply"];
|
|
187
|
+
readonly reviews: readonly ["row-view", "row-reply", "row-contest", "row-feedback"];
|
|
158
188
|
readonly payouts: readonly ["row-view", "row-export"];
|
|
159
189
|
readonly coupons: readonly ["row-edit", "row-duplicate", "row-delete"];
|
|
160
190
|
readonly bids: readonly ["row-view"];
|
|
161
191
|
readonly addresses: readonly ["row-edit", "row-delete"];
|
|
192
|
+
readonly bundles: readonly ["row-edit", "row-delete"];
|
|
193
|
+
readonly classified: readonly ["row-edit", "row-delete"];
|
|
194
|
+
readonly digitalCodes: readonly ["row-edit", "row-delete"];
|
|
195
|
+
readonly live: readonly ["row-edit", "row-delete"];
|
|
196
|
+
readonly auctions: readonly ["row-view", "row-edit", "row-delete"];
|
|
197
|
+
readonly preOrders: readonly ["row-view", "row-edit", "row-delete"];
|
|
198
|
+
readonly prizeDraws: readonly ["row-view", "row-edit", "row-delete"];
|
|
199
|
+
readonly templates: readonly ["row-edit", "row-delete"];
|
|
200
|
+
readonly shippingConfigs: readonly ["row-edit", "row-delete"];
|
|
201
|
+
readonly storeCategories: readonly ["row-edit", "row-delete"];
|
|
202
|
+
readonly groupedListings: readonly ["row-edit", "row-delete"];
|
|
203
|
+
readonly offers: readonly ["row-view", "row-approve", "row-reject"];
|
|
162
204
|
};
|
|
163
205
|
export declare const USER_ROW_ACTIONS: {
|
|
164
206
|
readonly orders: readonly ["row-view", "row-track", "row-cancel"];
|
|
165
207
|
readonly addresses: readonly ["row-edit", "row-delete"];
|
|
166
208
|
readonly bids: readonly ["row-view", "row-cancel"];
|
|
209
|
+
readonly reviews: readonly ["row-view", "row-edit"];
|
|
210
|
+
readonly returns: readonly ["row-view"];
|
|
211
|
+
readonly wishlist: readonly ["row-delete"];
|
|
212
|
+
readonly coupons: readonly ["row-view"];
|
|
167
213
|
};
|
|
168
214
|
export declare const FORM_ACTION_ID: {
|
|
169
215
|
readonly SUBMIT: "form-submit";
|
|
@@ -239,13 +285,46 @@ export declare const DASHBOARD_QUICK_ACTIONS: {
|
|
|
239
285
|
export declare const ADMIN_BULK_ACTIONS: {
|
|
240
286
|
readonly users: readonly ["row-suspend", "row-restore", "row-delete"];
|
|
241
287
|
readonly stores: readonly ["row-approve", "row-reject", "row-suspend"];
|
|
242
|
-
readonly products: readonly ["row-
|
|
243
|
-
readonly orders: readonly ["row-
|
|
288
|
+
readonly products: readonly ["row-feature", "row-promote", "row-sale"];
|
|
289
|
+
readonly orders: readonly ["row-mark-shipped", "row-mark-delivered", "row-cancel"];
|
|
244
290
|
readonly reviews: readonly ["row-approve", "row-reject", "row-delete"];
|
|
245
|
-
readonly blog: readonly ["row-publish", "row-
|
|
291
|
+
readonly blog: readonly ["row-publish", "row-draft", "row-delete"];
|
|
246
292
|
readonly faqs: readonly ["row-archive", "row-delete"];
|
|
293
|
+
readonly bids: readonly ["row-cancel"];
|
|
294
|
+
readonly notifications: readonly ["row-mark-read", "row-delete"];
|
|
295
|
+
readonly sessions: readonly ["row-revoke"];
|
|
296
|
+
readonly payouts: readonly ["row-mark-paid"];
|
|
297
|
+
readonly bundles: readonly ["row-activate", "row-deactivate", "row-delete"];
|
|
298
|
+
readonly brands: readonly ["row-edit"];
|
|
299
|
+
readonly categories: readonly ["row-edit"];
|
|
300
|
+
readonly features: readonly ["row-delete"];
|
|
301
|
+
readonly prizeDraws: readonly ["row-delete"];
|
|
302
|
+
readonly events: readonly ["row-delete"];
|
|
303
|
+
readonly carousel: readonly ["row-delete"];
|
|
304
|
+
readonly contact: readonly ["row-mark-read", "row-archive", "row-delete"];
|
|
305
|
+
readonly newsletter: readonly ["row-delete"];
|
|
306
|
+
readonly team: readonly ["row-delete"];
|
|
307
|
+
readonly navigation: readonly ["row-delete"];
|
|
308
|
+
readonly sublistingCategories: readonly ["row-delete"];
|
|
309
|
+
readonly scammers: readonly ["row-approve", "row-reject", "row-delete"];
|
|
310
|
+
readonly supportTickets: readonly ["row-archive"];
|
|
311
|
+
readonly eventEntries: readonly ["row-approve", "row-reject"];
|
|
312
|
+
readonly returnRequests: readonly ["row-approve", "row-reject"];
|
|
313
|
+
readonly coupons: readonly ["row-archive", "row-delete"];
|
|
247
314
|
};
|
|
248
315
|
export declare const SELLER_BULK_ACTIONS: {
|
|
249
316
|
readonly products: readonly ["row-publish", "row-archive", "row-delete"];
|
|
250
317
|
readonly coupons: readonly ["row-archive", "row-delete"];
|
|
318
|
+
readonly bids: readonly ["row-cancel"];
|
|
319
|
+
readonly bundles: readonly ["row-delete"];
|
|
320
|
+
readonly classified: readonly ["row-delete"];
|
|
321
|
+
readonly digitalCodes: readonly ["row-delete"];
|
|
322
|
+
readonly live: readonly ["row-delete"];
|
|
323
|
+
readonly auctions: readonly ["row-delete"];
|
|
324
|
+
readonly preOrders: readonly ["row-delete"];
|
|
325
|
+
readonly prizeDraws: readonly ["row-delete"];
|
|
326
|
+
readonly templates: readonly ["row-delete"];
|
|
327
|
+
readonly storeCategories: readonly ["row-activate", "row-deactivate", "row-delete"];
|
|
328
|
+
readonly groupedListings: readonly ["row-delete"];
|
|
329
|
+
readonly offers: readonly ["row-approve", "row-reject"];
|
|
251
330
|
};
|
|
@@ -141,6 +141,19 @@ export const ROW_ACTION_ID = {
|
|
|
141
141
|
REPLY: "row-reply",
|
|
142
142
|
PUBLISH: "row-publish",
|
|
143
143
|
ARCHIVE: "row-archive",
|
|
144
|
+
MARK_SHIPPED: "row-mark-shipped",
|
|
145
|
+
MARK_DELIVERED: "row-mark-delivered",
|
|
146
|
+
MARK_PAID: "row-mark-paid",
|
|
147
|
+
REVOKE: "row-revoke",
|
|
148
|
+
MARK_READ: "row-mark-read",
|
|
149
|
+
ACTIVATE: "row-activate",
|
|
150
|
+
DEACTIVATE: "row-deactivate",
|
|
151
|
+
FEATURE: "row-feature",
|
|
152
|
+
PROMOTE: "row-promote",
|
|
153
|
+
SALE: "row-sale",
|
|
154
|
+
DRAFT: "row-draft",
|
|
155
|
+
CONTEST: "row-contest",
|
|
156
|
+
FEEDBACK: "row-feedback",
|
|
144
157
|
};
|
|
145
158
|
export const ROW_ACTION_META = {
|
|
146
159
|
[ROW_ACTION_ID.EDIT]: { id: ROW_ACTION_ID.EDIT, label: "Edit", iconName: "Pencil", requiresAuth: true },
|
|
@@ -160,36 +173,82 @@ export const ROW_ACTION_META = {
|
|
|
160
173
|
[ROW_ACTION_ID.REPLY]: { id: ROW_ACTION_ID.REPLY, label: "Reply", iconName: "MessageSquare", requiresAuth: true },
|
|
161
174
|
[ROW_ACTION_ID.PUBLISH]: { id: ROW_ACTION_ID.PUBLISH, label: "Publish", iconName: "Upload", requiresAuth: true },
|
|
162
175
|
[ROW_ACTION_ID.ARCHIVE]: { id: ROW_ACTION_ID.ARCHIVE, label: "Archive", iconName: "Archive", requiresAuth: true, separator: true },
|
|
176
|
+
[ROW_ACTION_ID.MARK_SHIPPED]: { id: ROW_ACTION_ID.MARK_SHIPPED, label: "Mark as Shipped", iconName: "Truck", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.orders.update" },
|
|
177
|
+
[ROW_ACTION_ID.MARK_DELIVERED]: { id: ROW_ACTION_ID.MARK_DELIVERED, label: "Mark as Delivered", iconName: "PackageCheck", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.orders.update" },
|
|
178
|
+
[ROW_ACTION_ID.MARK_PAID]: { id: ROW_ACTION_ID.MARK_PAID, label: "Mark Paid", iconName: "Banknote", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.payouts.approve" },
|
|
179
|
+
[ROW_ACTION_ID.REVOKE]: { id: ROW_ACTION_ID.REVOKE, label: "Revoke", iconName: "ShieldOff", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.sessions.revoke", destructive: true },
|
|
180
|
+
[ROW_ACTION_ID.MARK_READ]: { id: ROW_ACTION_ID.MARK_READ, label: "Mark Read", iconName: "CheckCheck", requiresAuth: true, requiredRole: "admin" },
|
|
181
|
+
[ROW_ACTION_ID.ACTIVATE]: { id: ROW_ACTION_ID.ACTIVATE, label: "Activate", iconName: "ToggleRight", requiresAuth: true },
|
|
182
|
+
[ROW_ACTION_ID.DEACTIVATE]: { id: ROW_ACTION_ID.DEACTIVATE, label: "Deactivate", iconName: "ToggleLeft", requiresAuth: true },
|
|
183
|
+
[ROW_ACTION_ID.FEATURE]: { id: ROW_ACTION_ID.FEATURE, label: "Toggle Featured", iconName: "Star", requiresAuth: true, requiredRole: "admin", requiredPermission: "admin.content.approve" },
|
|
184
|
+
[ROW_ACTION_ID.PROMOTE]: { id: ROW_ACTION_ID.PROMOTE, label: "Toggle Promoted", iconName: "TrendingUp", requiresAuth: true, requiredRole: "admin" },
|
|
185
|
+
[ROW_ACTION_ID.SALE]: { id: ROW_ACTION_ID.SALE, label: "Toggle On Sale", iconName: "Percent", requiresAuth: true, requiredRole: "admin" },
|
|
186
|
+
[ROW_ACTION_ID.DRAFT]: { id: ROW_ACTION_ID.DRAFT, label: "Move to Draft", iconName: "FileEdit", requiresAuth: true },
|
|
187
|
+
[ROW_ACTION_ID.CONTEST]: { id: ROW_ACTION_ID.CONTEST, label: "Contest", iconName: "Flag", requiresAuth: true },
|
|
188
|
+
[ROW_ACTION_ID.FEEDBACK]: { id: ROW_ACTION_ID.FEEDBACK, label: "Feedback", iconName: "MessageCircle", requiresAuth: true },
|
|
163
189
|
};
|
|
164
190
|
// Admin dashboard row action groups per entity type
|
|
165
191
|
export const ADMIN_ROW_ACTIONS = {
|
|
166
192
|
users: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.SUSPEND, ROW_ACTION_ID.RESTORE, ROW_ACTION_ID.DELETE],
|
|
167
193
|
stores: [ROW_ACTION_ID.MANAGE, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.SUSPEND, ROW_ACTION_ID.DELETE],
|
|
168
194
|
products: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
169
|
-
orders: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.
|
|
195
|
+
orders: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.MARK_SHIPPED, ROW_ACTION_ID.MARK_DELIVERED, ROW_ACTION_ID.CANCEL],
|
|
170
196
|
reviews: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.DELETE],
|
|
171
197
|
events: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
172
|
-
payouts: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.
|
|
198
|
+
payouts: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.MARK_PAID],
|
|
173
199
|
coupons: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DUPLICATE, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
174
|
-
blog: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.
|
|
200
|
+
blog: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.DRAFT, ROW_ACTION_ID.DELETE],
|
|
175
201
|
faqs: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
176
202
|
bids: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.CANCEL],
|
|
203
|
+
notifications: [ROW_ACTION_ID.RESEND, ROW_ACTION_ID.DELETE],
|
|
204
|
+
sessions: [ROW_ACTION_ID.REVOKE],
|
|
205
|
+
bundles: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.ACTIVATE, ROW_ACTION_ID.DEACTIVATE, ROW_ACTION_ID.DELETE],
|
|
206
|
+
brands: [ROW_ACTION_ID.EDIT],
|
|
207
|
+
categories: [ROW_ACTION_ID.EDIT],
|
|
208
|
+
features: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
209
|
+
prizeDraws: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.DELETE],
|
|
210
|
+
carousel: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
211
|
+
contact: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.MARK_READ, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
212
|
+
newsletter: [ROW_ACTION_ID.DELETE],
|
|
213
|
+
team: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
214
|
+
navigation: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
215
|
+
sublistingCategories: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
216
|
+
scammers: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.DELETE],
|
|
217
|
+
supportTickets: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.REPLY],
|
|
218
|
+
eventEntries: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
219
|
+
returnRequests: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
177
220
|
};
|
|
178
221
|
// Seller / Store dashboard row action groups per entity type
|
|
179
222
|
export const SELLER_ROW_ACTIONS = {
|
|
180
223
|
products: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DUPLICATE, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
181
224
|
orders: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.TRACK, ROW_ACTION_ID.RESEND],
|
|
182
|
-
reviews: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.REPLY],
|
|
225
|
+
reviews: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.REPLY, ROW_ACTION_ID.CONTEST, ROW_ACTION_ID.FEEDBACK],
|
|
183
226
|
payouts: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EXPORT],
|
|
184
227
|
coupons: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DUPLICATE, ROW_ACTION_ID.DELETE],
|
|
185
228
|
bids: [ROW_ACTION_ID.VIEW],
|
|
186
229
|
addresses: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
230
|
+
bundles: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
231
|
+
classified: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
232
|
+
digitalCodes: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
233
|
+
live: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
234
|
+
auctions: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
235
|
+
preOrders: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
236
|
+
prizeDraws: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
237
|
+
templates: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
238
|
+
shippingConfigs: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
239
|
+
storeCategories: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
240
|
+
groupedListings: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
241
|
+
offers: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
187
242
|
};
|
|
188
243
|
// User dashboard row action groups per entity type
|
|
189
244
|
export const USER_ROW_ACTIONS = {
|
|
190
245
|
orders: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.TRACK, ROW_ACTION_ID.CANCEL],
|
|
191
246
|
addresses: [ROW_ACTION_ID.EDIT, ROW_ACTION_ID.DELETE],
|
|
192
247
|
bids: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.CANCEL],
|
|
248
|
+
reviews: [ROW_ACTION_ID.VIEW, ROW_ACTION_ID.EDIT],
|
|
249
|
+
returns: [ROW_ACTION_ID.VIEW],
|
|
250
|
+
wishlist: [ROW_ACTION_ID.DELETE],
|
|
251
|
+
coupons: [ROW_ACTION_ID.VIEW],
|
|
193
252
|
};
|
|
194
253
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
195
254
|
// § 3 Form actions
|
|
@@ -294,14 +353,47 @@ export const DASHBOARD_QUICK_ACTIONS = {
|
|
|
294
353
|
export const ADMIN_BULK_ACTIONS = {
|
|
295
354
|
users: [ROW_ACTION_ID.SUSPEND, ROW_ACTION_ID.RESTORE, ROW_ACTION_ID.DELETE],
|
|
296
355
|
stores: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.SUSPEND],
|
|
297
|
-
products: [ROW_ACTION_ID.
|
|
298
|
-
orders: [ROW_ACTION_ID.
|
|
356
|
+
products: [ROW_ACTION_ID.FEATURE, ROW_ACTION_ID.PROMOTE, ROW_ACTION_ID.SALE],
|
|
357
|
+
orders: [ROW_ACTION_ID.MARK_SHIPPED, ROW_ACTION_ID.MARK_DELIVERED, ROW_ACTION_ID.CANCEL],
|
|
299
358
|
reviews: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.DELETE],
|
|
300
|
-
blog: [ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.
|
|
359
|
+
blog: [ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.DRAFT, ROW_ACTION_ID.DELETE],
|
|
301
360
|
faqs: [ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
361
|
+
bids: [ROW_ACTION_ID.CANCEL],
|
|
362
|
+
notifications: [ROW_ACTION_ID.MARK_READ, ROW_ACTION_ID.DELETE],
|
|
363
|
+
sessions: [ROW_ACTION_ID.REVOKE],
|
|
364
|
+
payouts: [ROW_ACTION_ID.MARK_PAID],
|
|
365
|
+
bundles: [ROW_ACTION_ID.ACTIVATE, ROW_ACTION_ID.DEACTIVATE, ROW_ACTION_ID.DELETE],
|
|
366
|
+
brands: [ROW_ACTION_ID.EDIT],
|
|
367
|
+
categories: [ROW_ACTION_ID.EDIT],
|
|
368
|
+
features: [ROW_ACTION_ID.DELETE],
|
|
369
|
+
prizeDraws: [ROW_ACTION_ID.DELETE],
|
|
370
|
+
events: [ROW_ACTION_ID.DELETE],
|
|
371
|
+
carousel: [ROW_ACTION_ID.DELETE],
|
|
372
|
+
contact: [ROW_ACTION_ID.MARK_READ, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
373
|
+
newsletter: [ROW_ACTION_ID.DELETE],
|
|
374
|
+
team: [ROW_ACTION_ID.DELETE],
|
|
375
|
+
navigation: [ROW_ACTION_ID.DELETE],
|
|
376
|
+
sublistingCategories: [ROW_ACTION_ID.DELETE],
|
|
377
|
+
scammers: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT, ROW_ACTION_ID.DELETE],
|
|
378
|
+
supportTickets: [ROW_ACTION_ID.ARCHIVE],
|
|
379
|
+
eventEntries: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
380
|
+
returnRequests: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
381
|
+
coupons: [ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
302
382
|
};
|
|
303
383
|
// Seller bulk actions per listing entity
|
|
304
384
|
export const SELLER_BULK_ACTIONS = {
|
|
305
385
|
products: [ROW_ACTION_ID.PUBLISH, ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
306
386
|
coupons: [ROW_ACTION_ID.ARCHIVE, ROW_ACTION_ID.DELETE],
|
|
387
|
+
bids: [ROW_ACTION_ID.CANCEL],
|
|
388
|
+
bundles: [ROW_ACTION_ID.DELETE],
|
|
389
|
+
classified: [ROW_ACTION_ID.DELETE],
|
|
390
|
+
digitalCodes: [ROW_ACTION_ID.DELETE],
|
|
391
|
+
live: [ROW_ACTION_ID.DELETE],
|
|
392
|
+
auctions: [ROW_ACTION_ID.DELETE],
|
|
393
|
+
preOrders: [ROW_ACTION_ID.DELETE],
|
|
394
|
+
prizeDraws: [ROW_ACTION_ID.DELETE],
|
|
395
|
+
templates: [ROW_ACTION_ID.DELETE],
|
|
396
|
+
storeCategories: [ROW_ACTION_ID.ACTIVATE, ROW_ACTION_ID.DEACTIVATE, ROW_ACTION_ID.DELETE],
|
|
397
|
+
groupedListings: [ROW_ACTION_ID.DELETE],
|
|
398
|
+
offers: [ROW_ACTION_ID.APPROVE, ROW_ACTION_ID.REJECT],
|
|
307
399
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SellerProductDraft, SellerProductShellProps } from "./SellerProductShell";
|
|
2
|
+
export interface QuickProductFormProps {
|
|
3
|
+
values: SellerProductDraft;
|
|
4
|
+
onChange: (partial: Partial<SellerProductDraft>) => void;
|
|
5
|
+
onPublish: () => void;
|
|
6
|
+
onSave: () => void;
|
|
7
|
+
onSwitchToFull: () => void;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
storeSlug?: string;
|
|
10
|
+
renderCategorySelector?: SellerProductShellProps["renderCategorySelector"];
|
|
11
|
+
onUploadImage?: (file: File) => Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
export declare function QuickProductForm({ values, onChange, onPublish, onSave, onSwitchToFull, isLoading, renderCategorySelector, onUploadImage, }: QuickProductFormProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Alert, Button, Div, FormField, Stack, Text } from "../../../ui";
|
|
5
|
+
function toRupees(paise) {
|
|
6
|
+
return paise != null && paise > 0 ? String(Math.round(paise / 100)) : "";
|
|
7
|
+
}
|
|
8
|
+
function toPaise(rupeeStr) {
|
|
9
|
+
return Math.round((parseFloat(rupeeStr) || 0) * 100);
|
|
10
|
+
}
|
|
11
|
+
function validate(values) {
|
|
12
|
+
const errors = {};
|
|
13
|
+
if (!values.title?.trim() || (values.title.trim().length < 3)) {
|
|
14
|
+
errors.title = "Title must be at least 3 characters";
|
|
15
|
+
}
|
|
16
|
+
if (!values.price || values.price <= 0) {
|
|
17
|
+
errors.price = "Price is required";
|
|
18
|
+
}
|
|
19
|
+
if (!values.mainImage) {
|
|
20
|
+
errors.mainImage = "Product image is required";
|
|
21
|
+
}
|
|
22
|
+
if (!values.category?.trim()) {
|
|
23
|
+
errors.category = "Category is required";
|
|
24
|
+
}
|
|
25
|
+
return errors;
|
|
26
|
+
}
|
|
27
|
+
export function QuickProductForm({ values, onChange, onPublish, onSave, onSwitchToFull, isLoading, renderCategorySelector, onUploadImage, }) {
|
|
28
|
+
const [errors, setErrors] = useState({});
|
|
29
|
+
const [touched, setTouched] = useState(false);
|
|
30
|
+
const handlePublish = () => {
|
|
31
|
+
setTouched(true);
|
|
32
|
+
const errs = validate(values);
|
|
33
|
+
setErrors(errs);
|
|
34
|
+
if (Object.keys(errs).length === 0) {
|
|
35
|
+
onPublish();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const handleSave = () => {
|
|
39
|
+
if (!values.title?.trim()) {
|
|
40
|
+
setErrors({ title: "Title is required to save a draft" });
|
|
41
|
+
setTouched(true);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
onSave();
|
|
45
|
+
};
|
|
46
|
+
return (_jsxs(Stack, { gap: "lg", className: "p-5", children: [_jsx(Div, { children: _jsx(Text, { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "Quick add \u2014 fill the essentials and publish. You can add more details later." }) }), touched && Object.keys(errors).length > 0 && (_jsx(Alert, { variant: "error", children: "Please fix the highlighted fields before publishing." })), _jsx(FormField, { name: "title", label: "Product Name", type: "text", value: values.title ?? "", onChange: (v) => onChange({ title: v }), placeholder: "e.g. Charizard Base Set PSA 9", required: true, error: touched ? errors.title : undefined }), renderCategorySelector ? (_jsxs(Div, { children: [_jsx(Text, { className: "text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1", children: "Category" }), renderCategorySelector({
|
|
47
|
+
value: values.category ?? "",
|
|
48
|
+
onChange: (v) => onChange({ category: v }),
|
|
49
|
+
}), touched && errors.category && (_jsx(Text, { className: "text-xs text-[var(--appkit-color-error)] mt-1", children: errors.category }))] })) : (_jsx(FormField, { name: "category", label: "Category", type: "text", value: values.category ?? "", onChange: (v) => onChange({ category: v }), placeholder: "e.g. Trading Cards", error: touched ? errors.category : undefined })), _jsx(FormField, { name: "price", label: "Price (\u20B9)", type: "number", value: toRupees(values.price), onChange: (v) => onChange({ price: toPaise(v) }), placeholder: "e.g. 499", required: true, error: touched ? errors.price : undefined }), _jsx(FormField, { name: "mainImage", label: "Product Image", type: "image", value: values.mainImage ?? "", onChange: (v) => onChange({ mainImage: v }), onUpload: onUploadImage, required: true, error: touched ? errors.mainImage : undefined }), _jsx(FormField, { name: "description", label: "Description", type: "textarea", value: values.description ?? "", onChange: (v) => onChange({ description: v }), placeholder: "Brief description (optional)", rows: 3 }), _jsx(FormField, { name: "stockQuantity", label: "Stock Quantity", type: "number", value: String(values.stockQuantity ?? 1), onChange: (v) => onChange({ stockQuantity: Math.max(0, parseInt(v, 10) || 0) }), placeholder: "1", hint: "How many units are available" }), _jsxs(Div, { className: "flex flex-col gap-3 pt-2", children: [_jsxs(Div, { className: "flex gap-3", children: [_jsx(Button, { variant: "primary", onClick: handlePublish, disabled: isLoading, className: "flex-1", children: isLoading ? "Publishing..." : "Publish" }), _jsx(Button, { variant: "secondary", onClick: handleSave, disabled: isLoading, children: "Save Draft" })] }), _jsx(Button, { variant: "ghost", size: "sm", onClick: onSwitchToFull, className: "self-center text-xs", children: "Show all fields (advanced)" })] })] }));
|
|
50
|
+
}
|
|
@@ -2,5 +2,8 @@ import React from "react";
|
|
|
2
2
|
import type { ListingViewShellProps } from "../../../ui";
|
|
3
3
|
export interface SellerAuctionsViewProps extends ListingViewShellProps {
|
|
4
4
|
renderHeader?: (onAdd: () => void) => React.ReactNode;
|
|
5
|
+
onEditClick?: (id: string) => void;
|
|
6
|
+
onDelete?: (id: string) => Promise<void>;
|
|
7
|
+
onBulkDelete?: (ids: string[]) => Promise<void>;
|
|
5
8
|
}
|
|
6
|
-
export declare function SellerAuctionsView({ renderHeader, children, ...props }: SellerAuctionsViewProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare function SellerAuctionsView({ renderHeader, children, onEditClick, onDelete, onBulkDelete, ...props }: SellerAuctionsViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,9 +5,11 @@ import { X } from "lucide-react";
|
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
7
|
import { AdminViewCards } from "../../admin/components/AdminViewCards";
|
|
8
|
-
import { FilterChipGroup, ListingToolbar, Pagination, ListingViewShell } from "../../../ui";
|
|
8
|
+
import { BulkActionBar, ConfirmDeleteModal, FilterChipGroup, ListingToolbar, Pagination, ListingViewShell, RowActionMenu } from "../../../ui";
|
|
9
9
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
10
10
|
import { SELLER_AUCTION_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
11
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
12
|
+
import { ROUTES } from "../../../constants";
|
|
11
13
|
import { toRecordArray, toRelativeDate, toRupees, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
12
14
|
import { DataTable } from "../../admin/components/DataTable";
|
|
13
15
|
const PAGE_SIZE = 25;
|
|
@@ -20,9 +22,11 @@ const SORT_OPTIONS = [
|
|
|
20
22
|
{ value: "createdAt", label: "Oldest" },
|
|
21
23
|
];
|
|
22
24
|
const STATUS_OPTIONS = SELLER_AUCTION_STATUS_TABS;
|
|
23
|
-
export function SellerAuctionsView({ renderHeader, children, ...props }) {
|
|
25
|
+
export function SellerAuctionsView({ renderHeader, children, onEditClick, onDelete, onBulkDelete, ...props }) {
|
|
24
26
|
const hasChildren = React.Children.count(children) > 0;
|
|
25
27
|
const [view, setView] = useState("table");
|
|
28
|
+
const [deleteTargetId, setDeleteTargetId] = useState(null);
|
|
29
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
26
30
|
const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
|
|
27
31
|
const [searchInput, setSearchInput] = useState(table.get("q") || "");
|
|
28
32
|
const [filterOpen, setFilterOpen] = useState(false);
|
|
@@ -78,8 +82,38 @@ export function SellerAuctionsView({ renderHeader, children, ...props }) {
|
|
|
78
82
|
const currentPage = table.getNumber("page", 1);
|
|
79
83
|
const totalPages = Math.ceil(total / PAGE_SIZE);
|
|
80
84
|
const selection = useBulkSelection({ items: rows, keyExtractor: (r) => r.id });
|
|
85
|
+
const bulkActions = onBulkDelete
|
|
86
|
+
? [{
|
|
87
|
+
id: "bulk-delete",
|
|
88
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
89
|
+
variant: "danger",
|
|
90
|
+
onClick: async () => { await onBulkDelete(selection.selectedIds); selection.clearSelection(); },
|
|
91
|
+
}]
|
|
92
|
+
: [];
|
|
93
|
+
const handleDelete = useCallback(async (id) => {
|
|
94
|
+
setDeletingId(id);
|
|
95
|
+
try {
|
|
96
|
+
if (onDelete)
|
|
97
|
+
await onDelete(id);
|
|
98
|
+
else
|
|
99
|
+
await fetch(`/api/store/products/${id}`, { method: "DELETE", credentials: "include" });
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
setDeletingId(null);
|
|
103
|
+
setDeleteTargetId(null);
|
|
104
|
+
}
|
|
105
|
+
}, [onDelete]);
|
|
106
|
+
const handleEdit = useCallback((id) => {
|
|
107
|
+
if (onEditClick)
|
|
108
|
+
onEditClick(id);
|
|
109
|
+
else
|
|
110
|
+
window.location.href = String(ROUTES.STORE.PRODUCTS_EDIT(id));
|
|
111
|
+
}, [onEditClick]);
|
|
81
112
|
if (hasChildren) {
|
|
82
113
|
return _jsx(ListingViewShell, { portal: "seller", ...props, children: children });
|
|
83
114
|
}
|
|
84
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search auctions by product name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), view === "table" ? (_jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No auctions found"
|
|
115
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search auctions by product name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedCount > 0 && bulkActions.length > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx("div", { className: "mb-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-900/60 dark:bg-red-950/40 dark:text-red-200", children: errorMessage })), view === "table" ? (_jsx(DataTable, { rows: rows, isLoading: isLoading, emptyLabel: "No auctions found", selectedIds: selection.selectedIdSet, onToggleSelect: (id) => selection.toggle(id), onToggleSelectAll: () => selection.toggleAll(), renderRowActions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
116
|
+
{ label: ACTIONS.STORE["edit-listing"].label, onClick: () => handleEdit(row.id) },
|
|
117
|
+
{ label: ACTIONS.STORE["delete-listing"].label, destructive: true, onClick: () => setDeleteTargetId(row.id), disabled: deletingId === row.id },
|
|
118
|
+
] })) })) : (_jsx(AdminViewCards, { rows: rows, view: view, isLoading: isLoading, emptyLabel: "No auctions found", onRowClick: undefined, selectedIdSet: selection.selectedIdSet, onToggleSelect: selection.toggle }))] }), filterOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-40 bg-black/40", "aria-hidden": "true", onClick: () => setFilterOpen(false) }), _jsxs("div", { className: "fixed inset-y-0 left-0 z-50 flex w-80 flex-col bg-white dark:bg-slate-900 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: [_jsx("span", { className: "text-base font-semibold text-zinc-900 dark:text-zinc-100", children: "Filters" }), _jsxs("div", { className: "flex items-center gap-2", children: [activeFilterCount > 0 && (_jsx("button", { type: "button", onClick: clearFilters, className: "text-xs text-zinc-500 hover:text-rose-500 dark:text-zinc-400 transition-colors", children: "Clear all" })), _jsx("button", { type: "button", onClick: () => setFilterOpen(false), "aria-label": "Close", className: "rounded-lg p-1.5 text-zinc-500 hover:bg-zinc-100 dark:hover:bg-slate-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4 space-y-5", children: _jsx(FilterChipGroup, { label: "Status", tabs: STATUS_OPTIONS, value: pendingFilters.status ?? "", onChange: (id) => setPendingFilters((p) => ({ ...p, status: id })) }) }), _jsx("div", { className: "border-t border-zinc-200 dark:border-slate-700 px-4 py-3.5", children: _jsxs("button", { type: "button", onClick: applyFilters, className: "w-full rounded-lg bg-primary py-2.5 text-sm font-semibold text-white hover:bg-primary-600 transition-colors active:scale-[0.98]", children: ["Apply Filters", activeFilterCount > 0 ? ` (${activeFilterCount})` : ""] }) })] })] })), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Auction", message: "Are you sure you want to delete this auction? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
|
|
85
119
|
}
|
|
@@ -6,6 +6,7 @@ import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
7
|
import { Badge, BulkActionBar, Div, FilterChipGroup, ListingToolbar, Pagination, Text } from "../../../ui";
|
|
8
8
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
9
10
|
import { SELLER_BID_STATUS_TABS } from "../../admin/constants/filter-tabs";
|
|
10
11
|
import { toRecordArray, toRelativeDate, toRupees, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
11
12
|
import { DataTable } from "../../admin/components/DataTable";
|
|
@@ -147,7 +148,7 @@ export function SellerBidsView({ endpoint = SELLER_ENDPOINTS.BIDS }) {
|
|
|
147
148
|
selection.clearSelection();
|
|
148
149
|
}, [selection]);
|
|
149
150
|
const bulkActions = [
|
|
150
|
-
{ id: "cancel", label: "
|
|
151
|
+
{ id: "cancel", label: ACTIONS.SELLER["cancel-bid"].label, onClick: () => void bulkCancel(), variant: "danger" },
|
|
151
152
|
];
|
|
152
153
|
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search by bidder name", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get("sort") || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set("sort", v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedIds.length > 0 && (_jsx("div", { className: "sticky z-20 px-3 sm:px-4 py-2 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700", style: { top: "calc(var(--header-height, 0px) + 88px)" }, children: _jsx(BulkActionBar, { selectedCount: selection.selectedIds.length, onClearSelection: selection.clearSelection, actions: bulkActions }) })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-red-50 dark:bg-red-950/40 dark:border-red-900/60 px-4 py-3 text-sm text-red-700 dark:text-red-200", children: errorMessage })), table.get("grouped") === "0" ? (_jsx(DataTable, { rows: rows, columns: columns, isLoading: isLoading, emptyLabel: "No bids found for your auctions", selectedIds: selection.selectedIdSet, onToggleSelect: selection.toggle, onToggleSelectAll: () => selection.toggleAll() })) : (_jsxs("div", { className: "space-y-3", children: [groupedRows.length === 0 && !isLoading && (_jsx(Text, { className: "text-sm text-zinc-500", children: "No bids found for your auctions." })), groupedRows.map((group) => {
|
|
153
154
|
const collapsed = collapsedGroups.has(group.id);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export interface SellerBundlesViewProps {
|
|
2
2
|
onCreateClick?: () => void;
|
|
3
|
+
onEditClick?: (id: string) => void;
|
|
4
|
+
onDelete?: (id: string) => Promise<void>;
|
|
3
5
|
onBulkDelete?: (ids: string[]) => Promise<void>;
|
|
4
6
|
}
|
|
5
|
-
export declare function SellerBundlesView({ onCreateClick, onBulkDelete, }: SellerBundlesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function SellerBundlesView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }: SellerBundlesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,8 +4,9 @@ import { useState, useCallback } from "react";
|
|
|
4
4
|
import { Plus } from "lucide-react";
|
|
5
5
|
import { useUrlTable } from "../../../react/hooks/useUrlTable";
|
|
6
6
|
import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
|
|
7
|
-
import { BulkActionBar, Button, DataTable, Div, ListingToolbar, Pagination, Text, } from "../../../ui";
|
|
7
|
+
import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, ListingToolbar, Pagination, RowActionMenu, Text, } from "../../../ui";
|
|
8
8
|
import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
|
|
9
|
+
import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
|
|
9
10
|
import { ROUTES } from "../../..";
|
|
10
11
|
import { toRecordArray, toRelativeDate, toRupees, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
|
|
11
12
|
import { TABLE_KEYS } from "../../../constants/table-keys";
|
|
@@ -48,10 +49,12 @@ const COLUMNS = [
|
|
|
48
49
|
render: (row) => _jsx(Text, { className: "text-sm text-[var(--appkit-color-text-muted)]", children: row.createdAt }),
|
|
49
50
|
},
|
|
50
51
|
];
|
|
51
|
-
export function SellerBundlesView({ onCreateClick, onBulkDelete, }) {
|
|
52
|
+
export function SellerBundlesView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }) {
|
|
52
53
|
const table = useUrlTable({ defaults: { pageSize: String(PAGE_SIZE), sort: DEFAULT_SORT } });
|
|
53
54
|
const [searchInput, setSearchInput] = useState(table.get(TABLE_KEYS.QUERY) || "");
|
|
54
|
-
const [view] = useState("table");
|
|
55
|
+
const [view, setView] = useState("table");
|
|
56
|
+
const [deleteTargetId, setDeleteTargetId] = useState(null);
|
|
57
|
+
const [deletingId, setDeletingId] = useState(null);
|
|
55
58
|
const commitSearch = useCallback(() => {
|
|
56
59
|
table.set(TABLE_KEYS.QUERY, searchInput.trim());
|
|
57
60
|
}, [searchInput, table]);
|
|
@@ -87,11 +90,30 @@ export function SellerBundlesView({ onCreateClick, onBulkDelete, }) {
|
|
|
87
90
|
const bulkActions = onBulkDelete
|
|
88
91
|
? [{
|
|
89
92
|
id: "bulk-delete",
|
|
90
|
-
label: "
|
|
93
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
91
94
|
variant: "danger",
|
|
92
95
|
onClick: async () => { await onBulkDelete(selection.selectedIds); selection.clearSelection(); },
|
|
93
96
|
}]
|
|
94
97
|
: [];
|
|
98
|
+
const handleDelete = useCallback(async (id) => {
|
|
99
|
+
setDeletingId(id);
|
|
100
|
+
try {
|
|
101
|
+
if (onDelete)
|
|
102
|
+
await onDelete(id);
|
|
103
|
+
else
|
|
104
|
+
await fetch(`/api/store/products/${id}`, { method: "DELETE", credentials: "include" });
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
setDeletingId(null);
|
|
108
|
+
setDeleteTargetId(null);
|
|
109
|
+
}
|
|
110
|
+
}, [onDelete]);
|
|
111
|
+
const handleEdit = useCallback((id) => {
|
|
112
|
+
if (onEditClick)
|
|
113
|
+
onEditClick(id);
|
|
114
|
+
else
|
|
115
|
+
window.location.href = String(ROUTES.STORE.PRODUCTS_EDIT(id));
|
|
116
|
+
}, [onEditClick]);
|
|
95
117
|
const handleCreate = useCallback(() => {
|
|
96
118
|
if (onCreateClick) {
|
|
97
119
|
onCreateClick();
|
|
@@ -100,5 +122,16 @@ export function SellerBundlesView({ onCreateClick, onBulkDelete, }) {
|
|
|
100
122
|
window.location.href = String(ROUTES.STORE.PRODUCTS_NEW);
|
|
101
123
|
}
|
|
102
124
|
}, [onCreateClick]);
|
|
103
|
-
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search bundles...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: view, onViewChange: () =>
|
|
125
|
+
return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: 0, searchValue: searchInput, searchPlaceholder: "Search bundles...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: table.get(TABLE_KEYS.SORT) || DEFAULT_SORT, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: view, onViewChange: (v) => setView(v), onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: handleCreate, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "New Bundle" })] }) }), totalPages > 1 && (_jsx("div", { className: "sticky top-[calc(var(--header-height,0px)+44px)] z-10 flex justify-center bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-b border-zinc-200 dark:border-slate-700 px-3 py-1.5", children: _jsx(Pagination, { currentPage: currentPage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedCount > 0 && bulkActions.length > 0 && (_jsx(BulkActionBar, { selectedCount: selection.selectedCount, actions: bulkActions, onClearSelection: selection.clearSelection })), _jsxs("div", { className: "py-4 px-3 sm:px-4", children: [errorMessage && (_jsx(Div, { className: "mb-4 rounded-xl border border-red-200 bg-red-50 dark:bg-red-950/40 dark:border-red-900/60 px-4 py-3 text-sm text-red-700 dark:text-red-200", children: errorMessage })), isLoading ? (_jsx(Div, { className: "space-y-2", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Div, { className: "h-14 animate-pulse rounded-xl border border-zinc-100 dark:border-slate-700 bg-zinc-50 dark:bg-slate-800" }, i))) })) : rows.length === 0 ? (_jsx(Div, { className: "py-16 text-center", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-500", children: "No bundles yet \u2014 create a bundle to group multiple products together" }) })) : (_jsx(DataTable, { columns: COLUMNS, data: rows, keyExtractor: (r) => r.id, selectable: bulkActions.length > 0, selectedIds: selection.selectedIds, onSelectionChange: (ids) => selection.setSelectedIds(ids), actions: (row) => (_jsx(RowActionMenu, { actions: [
|
|
126
|
+
{
|
|
127
|
+
label: ACTIONS.STORE["edit-listing"].label,
|
|
128
|
+
onClick: () => handleEdit(row.id),
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
label: ACTIONS.STORE["delete-listing"].label,
|
|
132
|
+
destructive: true,
|
|
133
|
+
onClick: () => setDeleteTargetId(row.id),
|
|
134
|
+
disabled: deletingId === row.id,
|
|
135
|
+
},
|
|
136
|
+
] })) }))] }), deleteTargetId && (_jsx(ConfirmDeleteModal, { isOpen: true, title: "Delete Bundle", message: "Are you sure you want to delete this bundle? This cannot be undone.", onConfirm: () => handleDelete(deleteTargetId), onClose: () => setDeleteTargetId(null), isDeleting: deletingId === deleteTargetId }))] }));
|
|
104
137
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export interface SellerClassifiedViewProps {
|
|
2
2
|
onCreateClick?: () => void;
|
|
3
|
+
onEditClick?: (id: string) => void;
|
|
4
|
+
onDelete?: (id: string) => Promise<void>;
|
|
3
5
|
onBulkDelete?: (ids: string[]) => Promise<void>;
|
|
4
6
|
}
|
|
5
|
-
export declare function SellerClassifiedView({ onCreateClick, onBulkDelete, }: SellerClassifiedViewProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function SellerClassifiedView({ onCreateClick, onEditClick, onDelete, onBulkDelete, }: SellerClassifiedViewProps): import("react/jsx-runtime").JSX.Element;
|