@mohasinac/appkit 2.7.58 → 2.7.59

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.
Files changed (112) hide show
  1. package/dist/_internal/server/features/scams/og.js +1 -1
  2. package/dist/_internal/shared/actions/bulk-helpers.d.ts +3 -0
  3. package/dist/_internal/shared/actions/bulk-helpers.js +19 -0
  4. package/dist/_internal/shared/config/schema.d.ts +4 -4
  5. package/dist/client.d.ts +3 -0
  6. package/dist/client.js +2 -0
  7. package/dist/configs/next.js +11 -0
  8. package/dist/features/account/components/AddressesIndexListing.js +3 -4
  9. package/dist/features/account/components/UserSidebar.js +14 -10
  10. package/dist/features/admin/components/AdminAllEventEntriesView.js +3 -9
  11. package/dist/features/admin/components/AdminBidsView.js +2 -8
  12. package/dist/features/admin/components/AdminBlogView.js +4 -9
  13. package/dist/features/admin/components/AdminBrandEditorView.js +14 -17
  14. package/dist/features/admin/components/AdminBrandsView.js +4 -9
  15. package/dist/features/admin/components/AdminBundlesView.js +39 -58
  16. package/dist/features/admin/components/AdminCarouselView.js +7 -20
  17. package/dist/features/admin/components/AdminCartsView.js +3 -4
  18. package/dist/features/admin/components/AdminCategoriesView.js +4 -9
  19. package/dist/features/admin/components/AdminCategoryEditorView.js +1 -5
  20. package/dist/features/admin/components/AdminContactView.js +6 -24
  21. package/dist/features/admin/components/AdminCouponEditorView.js +14 -17
  22. package/dist/features/admin/components/AdminCouponsView.js +8 -16
  23. package/dist/features/admin/components/AdminFaqEditorView.js +14 -17
  24. package/dist/features/admin/components/AdminFaqsView.js +18 -69
  25. package/dist/features/admin/components/AdminFeatureEditorView.js +7 -9
  26. package/dist/features/admin/components/AdminNewsletterView.js +4 -14
  27. package/dist/features/admin/components/AdminNotificationsView.js +2 -8
  28. package/dist/features/admin/components/AdminOrdersView.js +2 -8
  29. package/dist/features/admin/components/AdminPayoutsView.js +2 -8
  30. package/dist/features/admin/components/AdminPrizeDrawsView.js +4 -9
  31. package/dist/features/admin/components/AdminProductEditorView.js +1 -5
  32. package/dist/features/admin/components/AdminProductsView.js +4 -9
  33. package/dist/features/admin/components/AdminReviewsView.js +2 -8
  34. package/dist/features/admin/components/AdminScammersView.js +2 -8
  35. package/dist/features/admin/components/AdminSessionsView.js +2 -8
  36. package/dist/features/admin/components/AdminStoresView.js +2 -8
  37. package/dist/features/admin/components/AdminSublistingCategoriesView.js +2 -6
  38. package/dist/features/admin/components/AdminSublistingCategoryEditorView.js +17 -20
  39. package/dist/features/admin/components/AdminSupportTicketsView.js +2 -8
  40. package/dist/features/admin/components/AdminTeamView.js +5 -14
  41. package/dist/features/admin/components/AdminUsersView.js +2 -8
  42. package/dist/features/admin/hooks/useAdminListing.d.ts +58 -0
  43. package/dist/features/admin/hooks/useAdminListing.js +71 -0
  44. package/dist/features/auth/schemas/firestore.d.ts +1 -0
  45. package/dist/features/blog/components/BlogIndexListing.js +3 -6
  46. package/dist/features/categories/components/CategoriesIndexListing.js +3 -6
  47. package/dist/features/events/components/AdminEventsView.js +4 -4
  48. package/dist/features/events/components/EventsIndexListing.js +3 -4
  49. package/dist/features/homepage/components/AnnouncementBar.d.ts +4 -1
  50. package/dist/features/homepage/components/AnnouncementBar.js +51 -4
  51. package/dist/features/homepage/components/MarketplaceHomepageView.d.ts +3 -1
  52. package/dist/features/homepage/components/MarketplaceHomepageView.js +2 -2
  53. package/dist/features/homepage/components/index.d.ts +1 -1
  54. package/dist/features/homepage/components/index.js +1 -1
  55. package/dist/features/homepage/lib/section-renderer.d.ts +2 -2
  56. package/dist/features/homepage/lib/section-renderer.js +2 -2
  57. package/dist/features/orders/repository/orders.repository.d.ts +0 -1
  58. package/dist/features/orders/repository/orders.repository.js +0 -1
  59. package/dist/features/orders/server.d.ts +1 -1
  60. package/dist/features/orders/server.js +1 -1
  61. package/dist/features/products/components/GroupSettingsPanel.js +64 -48
  62. package/dist/features/products/repository/products.repository.d.ts +0 -2
  63. package/dist/features/products/repository/products.repository.js +0 -2
  64. package/dist/features/products/server.d.ts +1 -1
  65. package/dist/features/products/server.js +1 -1
  66. package/dist/features/promotions/components/CouponCard.js +5 -5
  67. package/dist/features/promotions/components/CouponsIndexListing.js +3 -2
  68. package/dist/features/reviews/components/ReviewsIndexListing.js +3 -4
  69. package/dist/features/reviews/repository/reviews.repository.d.ts +0 -1
  70. package/dist/features/reviews/repository/reviews.repository.js +0 -1
  71. package/dist/features/reviews/server.d.ts +1 -1
  72. package/dist/features/reviews/server.js +1 -1
  73. package/dist/features/seller/components/SellerAddressesView.js +10 -20
  74. package/dist/features/seller/components/SellerAuctionsView.js +13 -22
  75. package/dist/features/seller/components/SellerBidsView.js +5 -5
  76. package/dist/features/seller/components/SellerBundlesView.js +11 -19
  77. package/dist/features/seller/components/SellerClassifiedView.js +11 -19
  78. package/dist/features/seller/components/SellerCouponsView.js +14 -20
  79. package/dist/features/seller/components/SellerDigitalCodesView.js +11 -19
  80. package/dist/features/seller/components/SellerGroupedListingsView.js +6 -10
  81. package/dist/features/seller/components/SellerLiveView.js +11 -19
  82. package/dist/features/seller/components/SellerOffersView.js +3 -4
  83. package/dist/features/seller/components/SellerOrdersView.js +8 -22
  84. package/dist/features/seller/components/SellerPayoutMethodsView.js +11 -23
  85. package/dist/features/seller/components/SellerPayoutsView.js +3 -4
  86. package/dist/features/seller/components/SellerPreOrdersView.js +13 -22
  87. package/dist/features/seller/components/SellerPrizeDrawsView.js +13 -22
  88. package/dist/features/seller/components/SellerProductsFilterDrawer.d.ts +1 -1
  89. package/dist/features/seller/components/SellerProductsFilterDrawer.js +3 -6
  90. package/dist/features/seller/components/SellerProductsView.js +9 -22
  91. package/dist/features/seller/components/SellerShippingConfigsView.js +11 -23
  92. package/dist/features/seller/components/SellerStoreCategoriesView.js +14 -33
  93. package/dist/features/seller/components/SellerTemplatesView.js +25 -41
  94. package/dist/features/stores/components/StoreReviewsListing.js +3 -4
  95. package/dist/features/stores/components/StoresIndexListing.js +3 -4
  96. package/dist/index.d.ts +2 -6
  97. package/dist/index.js +3 -12
  98. package/dist/react/contexts/SessionContext.d.ts +2 -0
  99. package/dist/react/contexts/SessionContext.js +2 -0
  100. package/dist/react/hooks/useEntityDelete.d.ts +15 -0
  101. package/dist/react/hooks/useEntityDelete.js +39 -0
  102. package/dist/react/index.d.ts +2 -0
  103. package/dist/react/index.js +2 -0
  104. package/dist/repositories/index.d.ts +3 -3
  105. package/dist/repositories/index.js +3 -3
  106. package/dist/styles.css +1 -1
  107. package/dist/tailwind-utilities.css +1 -1
  108. package/dist/ui/components/ListingFilterDrawer.d.ts +10 -0
  109. package/dist/ui/components/ListingFilterDrawer.js +8 -0
  110. package/dist/ui/index.d.ts +2 -0
  111. package/dist/ui/index.js +1 -0
  112. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useMemo } from "react";
4
+ import { useEntityDelete } from "../../../react/hooks/useEntityDelete";
4
5
  import { Plus } from "lucide-react";
5
6
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
7
  import { useBulkSelection } from "../../../react/hooks/useBulkSelection";
@@ -8,6 +9,7 @@ import { BulkActionBar, Button, ConfirmDeleteModal, DataTable, Div, FilterDrawer
8
9
  import { useBottomActions } from "../../layout";
9
10
  import { SELLER_ENDPOINTS } from "../../../constants/api-endpoints";
10
11
  import { ACTIONS } from "../../../_internal/shared/actions/action-registry";
12
+ import { buildBulkAction } from "../../../_internal/shared/actions/bulk-helpers";
11
13
  import { toRecordArray, toStringValue, useSellerListingData, } from "../hooks/useSellerListingData";
12
14
  import { TABLE_KEYS } from "../../../constants/table-keys";
13
15
  const PAGE_SIZE = 25;
@@ -68,7 +70,13 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
68
70
  const [savingError, setSavingError] = useState(null);
69
71
  // Delete state
70
72
  const [deleteTargetId, setDeleteTargetId] = useState(null);
71
- const [deletingId, setDeletingId] = useState(null);
73
+ const { deletingId, handleDelete: performDelete } = useEntityDelete({
74
+ endpoint: SELLER_ENDPOINTS.TEMPLATE_BY_ID,
75
+ deleteFn: onDelete,
76
+ successMessage: "Template deleted.",
77
+ onSuccess: () => { refetch?.(); },
78
+ fetchOptions: { credentials: "include" },
79
+ });
72
80
  const [duplicatingId, setDuplicatingId] = useState(null);
73
81
  const { showToast } = useToast();
74
82
  const commitSearch = useCallback(() => {
@@ -184,28 +192,9 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
184
192
  }
185
193
  }, [draft, drawerMode, editingId, closeDrawer, refetch, showToast]);
186
194
  const handleDelete = useCallback(async (id) => {
187
- setDeletingId(id);
188
- try {
189
- if (onDelete) {
190
- await onDelete(id);
191
- }
192
- else {
193
- await fetch(SELLER_ENDPOINTS.TEMPLATE_BY_ID(id), {
194
- method: "DELETE",
195
- credentials: "include",
196
- });
197
- }
198
- refetch?.();
199
- showToast("Template deleted.", "success");
200
- }
201
- catch (err) {
202
- showToast(err instanceof Error ? err.message : "Failed to delete template.", "error");
203
- }
204
- finally {
205
- setDeletingId(null);
206
- setDeleteTargetId(null);
207
- }
208
- }, [onDelete, refetch, showToast]);
195
+ await performDelete(id);
196
+ setDeleteTargetId(null);
197
+ }, [performDelete]);
209
198
  const handleDuplicate = useCallback(async (row) => {
210
199
  setDuplicatingId(row.id);
211
200
  try {
@@ -237,24 +226,19 @@ export function SellerTemplatesView({ onDelete, onBulkDelete, onDuplicate, }) {
237
226
  }
238
227
  }, [onDuplicate, refetch, showToast]);
239
228
  const bulkActions = [
240
- {
241
- id: "bulk-delete",
242
- label: ACTIONS.STORE["delete-template"].label,
243
- variant: "danger",
244
- onClick: async () => {
245
- if (onBulkDelete) {
246
- await onBulkDelete(selection.selectedIds);
247
- }
248
- else {
249
- await Promise.all(selection.selectedIds.map((id) => fetch(SELLER_ENDPOINTS.TEMPLATE_BY_ID(id), {
250
- method: "DELETE",
251
- credentials: "include",
252
- })));
253
- }
254
- selection.clearSelection();
255
- refetch?.();
256
- },
257
- },
229
+ buildBulkAction(ACTIONS.STORE["delete-template"], async () => {
230
+ if (onBulkDelete) {
231
+ await onBulkDelete(selection.selectedIds);
232
+ }
233
+ else {
234
+ await Promise.all(selection.selectedIds.map((id) => fetch(SELLER_ENDPOINTS.TEMPLATE_BY_ID(id), {
235
+ method: "DELETE",
236
+ credentials: "include",
237
+ })));
238
+ }
239
+ selection.clearSelection();
240
+ refetch?.();
241
+ }),
258
242
  ];
259
243
  useBottomActions(selection.selectedCount > 0 ? { bulk: { selectedCount: selection.selectedCount, onClearSelection: selection.clearSelection, actions: bulkActions } } : {});
260
244
  return (_jsxs("div", { className: "min-h-screen", children: [_jsx(ListingToolbar, { filterCount: filterActiveCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search templates by name...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: SORT_OPTIONS, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, showTableView: true, view: "table", onViewChange: () => { }, onResetAll: resetAll, hasActiveState: hasActiveState, extra: _jsxs(Button, { size: "sm", onClick: openCreate, className: "flex items-center gap-1.5", children: [_jsx(Plus, { className: "h-4 w-4" }), _jsx("span", { children: "New Template" })] }) }), 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: safePage, totalPages: totalPages, onPageChange: (p) => table.setPage(p) }) })), selection.selectedCount > 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-error-surface dark:border-red-900/60 px-4 py-3 text-sm text-error", 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))) })) : pageRows.length === 0 ? (_jsx(Div, { className: "py-16 text-center", children: _jsx(Text, { className: "text-zinc-400 dark:text-zinc-400", children: q || conditionFilter
@@ -1,9 +1,8 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useMemo } from "react";
4
- import { X } from "lucide-react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
- import { ListingToolbar, Pagination, Row, Span, Text } from "../../../ui";
5
+ import { ListingFilterDrawer, ListingToolbar, Pagination, Row, Span, Text } from "../../../ui";
7
6
  import { ReviewCard } from "../../reviews/components/ReviewsList";
8
7
  import { ReviewFilters, REVIEW_PUBLIC_SORT_OPTIONS } from "../../reviews/components/ReviewFilters";
9
8
  import { useStoreReviews } from "../hooks/useStores";
@@ -102,5 +101,5 @@ export function StoreReviewsListing({ storeSlug }) {
102
101
  value: opt.value,
103
102
  label: SORT_OPTION_LABELS[opt.key] ?? opt.key,
104
103
  }));
105
- return (_jsxs("div", { className: "min-h-screen", children: [totalReviews > 0 && (_jsxs(Row, { align: "center", gap: "sm", className: "px-4 py-3 border-b border-zinc-200 dark:border-slate-700", children: [_jsx(Span, { className: "text-2xl font-bold text-zinc-900 dark:text-zinc-100", children: averageRating.toFixed(1) }), _jsxs(Span, { className: "text-zinc-500 dark:text-zinc-400 text-sm", children: ["/ 5 \u00B7 ", totalReviews, " reviews"] })] })), _jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, 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) }) })), _jsx("div", { className: "py-6 px-4", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsx("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: _jsxs("div", { className: "p-4 space-y-3", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No reviews found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) }), 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: "flex items-center gap-2 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 filters", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(ReviewFilters, { table: pendingTable, variant: "public" }) }), _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})` : ""] }) })] })] }))] }));
104
+ return (_jsxs("div", { className: "min-h-screen", children: [totalReviews > 0 && (_jsxs(Row, { align: "center", gap: "sm", className: "px-4 py-3 border-b border-zinc-200 dark:border-slate-700", children: [_jsx(Span, { className: "text-2xl font-bold text-zinc-900 dark:text-zinc-100", children: averageRating.toFixed(1) }), _jsxs(Span, { className: "text-zinc-500 dark:text-zinc-400 text-sm", children: ["/ 5 \u00B7 ", totalReviews, " reviews"] })] })), _jsx(ListingToolbar, { filterCount: activeFilterCount, onFiltersClick: openFilters, searchValue: searchInput, searchPlaceholder: "Search reviews...", onSearchChange: setSearchInput, onSearchCommit: commitSearch, sortValue: sort, sortOptions: sortOptions, onSortChange: (v) => { table.set(TABLE_KEYS.SORT, v); }, view: view, onViewChange: handleViewToggle, 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) }) })), _jsx("div", { className: "py-6 px-4", children: isLoading ? (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: Array.from({ length: 6 }).map((_, i) => (_jsx("div", { className: "rounded-xl border border-zinc-100 dark:border-slate-700 overflow-hidden animate-pulse", children: _jsxs("div", { className: "p-4 space-y-3", children: [_jsx("div", { className: "h-4 bg-zinc-200 dark:bg-slate-700 rounded w-3/4" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-full" }), _jsx("div", { className: "h-3 bg-zinc-200 dark:bg-slate-700 rounded w-2/3" })] }) }, i))) })) : reviews.length === 0 ? (_jsx(Text, { className: "py-12 text-center text-sm text-zinc-500 dark:text-zinc-400", children: "No reviews found." })) : view === "list" ? (_jsx("div", { className: "flex flex-col divide-y divide-zinc-100 dark:divide-zinc-800 rounded-xl border border-zinc-100 dark:border-zinc-800", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) : (_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: reviews.map((review) => (_jsx(ReviewCard, { review: review, context: "store" }, review.id))) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: activeFilterCount, children: _jsx(ReviewFilters, { table: pendingTable, variant: "public" }) })] }));
106
105
  }
@@ -1,10 +1,9 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useCallback, useMemo } from "react";
4
- import { SlidersHorizontal, X } from "lucide-react";
5
4
  import { useUrlTable } from "../../../react/hooks/useUrlTable";
6
5
  import { useStores } from "../hooks/useStores";
7
- import { BulkActionBar, ListingToolbar, Pagination, Text } from "../../../ui";
6
+ import { BulkActionBar, ListingFilterDrawer, ListingToolbar, Pagination, Text } from "../../../ui";
8
7
  import { ROUTES } from "../../../next";
9
8
  import { InteractiveStoreCard } from "./InteractiveStoreCard";
10
9
  import { StoreFilters } from "./StoreFilters";
@@ -150,5 +149,5 @@ export function StoresIndexListing({ initialData }) {
150
149
  },
151
150
  ] } } : {});
152
151
  return (_jsx(InteractiveStoreCard, { store: store, href: String(ROUTES.PUBLIC.STORE_DETAIL(storeKey)), selectable: selection.isSelecting, isSelected: selection.isSelected(store.id ?? store.storeSlug), onSelect: (id, sel) => { void sel; selection.toggle(id); } }, storeKey));
153
- }) })) }), 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: [_jsxs("span", { className: "flex items-center gap-2 text-base font-semibold text-zinc-900 dark:text-zinc-100", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), "Filters"] }), _jsxs("div", { className: "flex items-center gap-2", children: [pendingFilterCount > 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 filters", className: "rounded-lg p-1.5 text-zinc-500 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors", children: _jsx(X, { className: "h-5 w-5" }) })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 py-4", children: _jsx(StoreFilters, { table: pendingTable }) }), _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", pendingFilterCount > 0 ? ` (${pendingFilterCount})` : ""] }) })] })] }))] }));
152
+ }) })) }), _jsx(ListingFilterDrawer, { open: filterOpen, onClose: () => setFilterOpen(false), onApply: applyFilters, onClear: clearFilters, activeCount: pendingFilterCount, children: _jsx(StoreFilters, { table: pendingTable }) })] }));
154
153
  }
package/dist/index.d.ts CHANGED
@@ -501,12 +501,9 @@ export { FirebaseFAQsRepository } from "./repositories/index";
501
501
  export { NewsletterRepository } from "./repositories/index";
502
502
  export { OfferRepository } from "./repositories/index";
503
503
  export { OrderRepository } from "./repositories/index";
504
- export { OrdersRepository } from "./repositories/index";
505
504
  export { PasswordResetTokenRepository } from "./repositories/index";
506
505
  export { ProductRepository } from "./repositories/index";
507
- export { ProductsRepository } from "./repositories/index";
508
506
  export { ReviewRepository } from "./repositories/index";
509
- export { ReviewsRepository } from "./repositories/index";
510
507
  export { SessionRepository } from "./repositories/index";
511
508
  export { SmsCounterRepository } from "./repositories/index";
512
509
  export { StoreRepository } from "./repositories/index";
@@ -1162,7 +1159,6 @@ export { DEFAULT_NOTIFICATION_DATA } from "./features/admin/index";
1162
1159
  export { DEFAULT_SITE_SETTINGS_DATA } from "./features/admin/index";
1163
1160
  export { DEFAULT_TRUST_BAR_ITEMS } from "./features/admin/index";
1164
1161
  export { DashboardStatsGrid } from "./features/admin/index";
1165
- export { DemoSeedView } from "./features/admin/index";
1166
1162
  export { AdminTeamView } from "./features/admin/index";
1167
1163
  export { AdminEmployeeEditorView } from "./features/admin/index";
1168
1164
  export { AdminSupportTicketsView } from "./features/admin/index";
@@ -1240,7 +1236,6 @@ export type { ChatRoomCreateInput } from "./features/admin/index";
1240
1236
  export type { ChatRoomDocument } from "./features/admin/index";
1241
1237
  export type { ChatRoomUpdateInput } from "./features/admin/index";
1242
1238
  export type { DashboardStats } from "./features/admin/index";
1243
- export type { DemoSeedViewProps } from "./features/admin/index";
1244
1239
  export type { AdminTeamViewProps } from "./features/admin/index";
1245
1240
  export type { AdminEmployeeEditorViewProps } from "./features/admin/index";
1246
1241
  export type { AdminSupportTicketsViewProps } from "./features/admin/index";
@@ -2384,6 +2379,7 @@ export { isListingTypeEnabled, isCategoryTypeEnabled, enabledListingTypes, enabl
2384
2379
  export { actionTracker, setActionTrackerSink, resetActionTrackerSink, type ActionEvent, type ActionTrackerSink, } from "./_internal/shared/listing-types/action-tracker";
2385
2380
  export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_internal/shared/listing-types/cart-shipping";
2386
2381
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, type ActionDef, type ActionKind, type ActionResource, type ActionTree, type ActionConfirmation, } from "./_internal/shared/actions/action-registry";
2382
+ export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers";
2387
2383
  export { isAdminUser, isSellerUser, isModeratorUser, isEmployeeUser, isBuyerUser, } from "./features/auth/role-predicates";
2388
2384
  export { sanitizeProductForPublic, sanitizeProductsForPublic } from "./features/products/index";
2389
2385
  export { productAdminColumns } from "./features/products/index";
@@ -3006,7 +3002,7 @@ export { API_ENDPOINTS, API_ROUTES, LOGS_ENDPOINTS, AUTH_ENDPOINTS, ACCOUNT_ENDP
3006
3002
  export { WishlistFullError } from "./features/wishlist/server";
3007
3003
  export { useHistory, useHistoryMergeOnLogin, getGuestHistory, trackGuestHistory, removeGuestHistoryItem, clearGuestHistory, getGuestHistoryCount, type GuestHistoryItem, type GuestHistoryType, type UserHistoryItem, type HistoryProductType, type HistoryItemSnapshot, type TrackArgs as TrackHistoryArgs, } from "./features/history";
3008
3004
  export { historyRepository, UserHistoryRepository, trackHistoryView, getHistoryForUser, removeHistoryItem, clearHistory, mergeGuestHistory, } from "./features/history/server";
3009
- export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, ThemeProvider, useTheme, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useContainerGrid, useMessage, useVisibleItems, useModalStack, RTDBPayloadStatus, } from "./react/index";
3005
+ export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, ThemeProvider, useTheme, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage, useVisibleItems, useModalStack, RTDBPayloadStatus, } from "./react/index";
3010
3006
  export { RoleGate, ProtectedRoute, SocialAuthButtons, AuthStatusPanel, LoginForm, RegisterForm, ForgotPasswordView, ResetPasswordView, VerifyEmailView, OAuthLoadingView, } from "./features/auth/index";
3011
3007
  export type { RoleGateProps, ProtectedRouteProps, AuthGuardUser, AuthRouteConfig, LoginFormProps, LoginFormValues, RegisterFormProps, RegisterFormValues, ForgotPasswordViewProps, ResetPasswordViewProps, VerifyEmailViewProps, } from "./features/auth/index";
3012
3008
  export { CartItemRow, CartDrawer, CartView, CartSummary, ShippingPicker } from "./features/cart/index";
package/dist/index.js CHANGED
@@ -977,24 +977,15 @@ export { OfferRepository } from "./repositories/index";
977
977
  // OrderRepository - Shared export for order repository.
978
978
  export { OrderRepository } from "./repositories/index";
979
979
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
980
- // OrdersRepository - Shared export for orders repository.
981
- export { OrdersRepository } from "./repositories/index";
982
- // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
983
980
  // PasswordResetTokenRepository - Shared export for password reset token repository.
984
981
  export { PasswordResetTokenRepository } from "./repositories/index";
985
982
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
986
983
  // ProductRepository - Shared export for product repository.
987
984
  export { ProductRepository } from "./repositories/index";
988
985
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
989
- // ProductsRepository - Shared export for products repository.
990
- export { ProductsRepository } from "./repositories/index";
991
- // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
992
986
  // ReviewRepository - Shared export for review repository.
993
987
  export { ReviewRepository } from "./repositories/index";
994
988
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
995
- // ReviewsRepository - Shared export for reviews repository.
996
- export { ReviewsRepository } from "./repositories/index";
997
- // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
998
989
  // SessionRepository - Shared export for session repository.
999
990
  export { SessionRepository } from "./repositories/index";
1000
991
  // [DB]-Database layer â€" uses firebase-admin or another server-side DB SDK; can only run in a trusted server environment.
@@ -2258,8 +2249,7 @@ export { DEFAULT_TRUST_BAR_ITEMS } from "./features/admin/index";
2258
2249
  // DashboardStatsGrid - Component for dashboard stats grid.
2259
2250
  export { DashboardStatsGrid } from "./features/admin/index";
2260
2251
  // [CLIENT-SSR]-Runs in both SSR and browser â€" React component or hook that does not depend on browser-only APIs.
2261
- // DemoSeedView - Component for demo seed view.
2262
- export { DemoSeedView } from "./features/admin/index";
2252
+ // DemoSeedView — removed from main barrel (dev-only, load via dynamic import)
2263
2253
  // AdminTeamView - Employee management list view.
2264
2254
  export { AdminTeamView } from "./features/admin/index";
2265
2255
  // AdminEmployeeEditorView - Invite/edit employee permissions SideDrawer.
@@ -4435,6 +4425,7 @@ export { actionTracker, setActionTrackerSink, resetActionTrackerSink, } from "./
4435
4425
  export { cartRequiresShipping, cartIsDigitalOnly, cartIsChatOnly, } from "./_internal/shared/listing-types/cart-shipping";
4436
4426
  // SB-UNI-W-1 2026-05-13 â€" CTA action registry shell.
4437
4427
  export { ACTIONS, action, act, canPerformAction, actionsForListingType, actionLabel, } from "./_internal/shared/actions/action-registry";
4428
+ export { buildBulkAction } from "./_internal/shared/actions/bulk-helpers";
4438
4429
  // User-role predicates â€" SB-UNI-E 2026-05-13.
4439
4430
  export { isAdminUser, isSellerUser, isModeratorUser, isEmployeeUser, isBuyerUser, } from "./features/auth/role-predicates";
4440
4431
  // [SERVER-ONLY]-Safe in browser but intended for server routes.
@@ -5440,7 +5431,7 @@ export { WishlistFullError } from "./features/wishlist/server";
5440
5431
  export { useHistory, useHistoryMergeOnLogin, getGuestHistory, trackGuestHistory, removeGuestHistoryItem, clearGuestHistory, getGuestHistoryCount, } from "./features/history";
5441
5432
  export { historyRepository, UserHistoryRepository, trackHistoryView, getHistoryForUser, removeHistoryItem, clearHistory, mergeGuestHistory, } from "./features/history/server";
5442
5433
  // Missing React hooks and providers
5443
- export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, ThemeProvider, useTheme, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useContainerGrid, useMessage, useVisibleItems, useModalStack, RTDBPayloadStatus, } from "./react/index";
5434
+ export { useMediaQuery, useBreakpoint, useClickOutside, useKeyPress, useLongPress, useGesture, useSwipe, ThemeProvider, useTheme, useSession, useAuth, useCountdown, useCamera, useBulkSelection, useUrlTable, usePendingFilters, usePendingTable, useUnsavedChanges, UNSAVED_CHANGES_EVENT, useBulkAction, useEntityDelete, useContainerGrid, useMessage, useVisibleItems, useModalStack, RTDBPayloadStatus, } from "./react/index";
5444
5435
  // Missing core types (already exported above; skipped to avoid duplicates)
5445
5436
  // Missing auth feature components
5446
5437
  export { RoleGate, ProtectedRoute, SocialAuthButtons, AuthStatusPanel, LoginForm, RegisterForm, ForgotPasswordView, ResetPasswordView, VerifyEmailView, OAuthLoadingView, } from "./features/auth/index";
@@ -32,6 +32,8 @@ export interface SessionUser {
32
32
  scamAwarenessAcknowledgedAt?: Date | null;
33
33
  /** RBAC permission keys granted to this user (from their role's permission set). */
34
34
  permissions?: string[];
35
+ /** Hash of the last dismissed announcement banner. */
36
+ dismissedBannerHash?: string;
35
37
  }
36
38
  export interface SessionContextValue {
37
39
  user: SessionUser | null;
@@ -74,6 +74,7 @@ function buildSessionUser(authUser, serverData) {
74
74
  scamAwarenessAcknowledgedAt: serverData.scamAwarenessAcknowledgedAt
75
75
  ? new Date(serverData.scamAwarenessAcknowledgedAt)
76
76
  : null,
77
+ dismissedBannerHash: serverData.dismissedBannerHash,
77
78
  };
78
79
  }
79
80
  // ---------------------------------------------------------------------------
@@ -140,6 +141,7 @@ export function SessionProvider({ children, initialUser, endpoints: endpointOver
140
141
  scamAwarenessAcknowledgedAt: data.scamAwarenessAcknowledgedAt
141
142
  ? new Date(data.scamAwarenessAcknowledgedAt)
142
143
  : null,
144
+ dismissedBannerHash: data.dismissedBannerHash,
143
145
  };
144
146
  }
145
147
  catch {
@@ -0,0 +1,15 @@
1
+ export interface UseEntityDeleteOptions {
2
+ endpoint?: string | ((id: string) => string);
3
+ deleteFn?: (id: string) => Promise<void>;
4
+ successMessage?: string;
5
+ errorMessage?: string;
6
+ onSuccess?: (id: string) => void;
7
+ onError?: (id: string, error: unknown) => void;
8
+ fetchOptions?: Omit<RequestInit, "method">;
9
+ }
10
+ export interface UseEntityDeleteReturn {
11
+ deletingId: string | null;
12
+ handleDelete: (id: string) => Promise<void>;
13
+ isDeleting: boolean;
14
+ }
15
+ export declare function useEntityDelete(opts: UseEntityDeleteOptions): UseEntityDeleteReturn;
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ import { useState, useCallback } from "react";
3
+ import { useToast } from "../../ui";
4
+ export function useEntityDelete(opts) {
5
+ const [deletingId, setDeletingId] = useState(null);
6
+ const { showToast } = useToast();
7
+ const handleDelete = useCallback(async (id) => {
8
+ setDeletingId(id);
9
+ try {
10
+ if (opts.deleteFn) {
11
+ await opts.deleteFn(id);
12
+ }
13
+ else {
14
+ const url = typeof opts.endpoint === "function" ? opts.endpoint(id) : `${opts.endpoint}/${id}`;
15
+ const res = await fetch(url, { method: "DELETE", ...opts.fetchOptions });
16
+ if (!res.ok) {
17
+ const body = await res.json().catch(() => ({}));
18
+ throw new Error(body.message || `Delete failed (${res.status})`);
19
+ }
20
+ }
21
+ if (opts.successMessage)
22
+ showToast(opts.successMessage, "success");
23
+ opts.onSuccess?.(id);
24
+ }
25
+ catch (err) {
26
+ const msg = opts.errorMessage ?? (err instanceof Error ? err.message : "Delete failed.");
27
+ showToast(msg, "error");
28
+ opts.onError?.(id, err);
29
+ }
30
+ finally {
31
+ setDeletingId(null);
32
+ }
33
+ }, [opts, showToast]);
34
+ return {
35
+ deletingId,
36
+ handleDelete,
37
+ isDeleting: deletingId !== null,
38
+ };
39
+ }
@@ -40,6 +40,8 @@ export { usePendingTable } from "./hooks/usePendingTable";
40
40
  export type { PendingTable, UsePendingTableReturn, } from "./hooks/usePendingTable";
41
41
  export { useUnsavedChanges, UNSAVED_CHANGES_EVENT, } from "./hooks/useUnsavedChanges";
42
42
  export type { UseUnsavedChangesOptions, UseUnsavedChangesReturn, } from "./hooks/useUnsavedChanges";
43
+ export { useEntityDelete } from "./hooks/useEntityDelete";
44
+ export type { UseEntityDeleteOptions, UseEntityDeleteReturn } from "./hooks/useEntityDelete";
43
45
  export { useBulkAction } from "./hooks/useBulkAction";
44
46
  export type { BulkActionPayload, BulkActionResult, BulkActionSummary, BulkActionItemFailure, UseBulkActionOptions, UseBulkActionReturn, } from "./hooks/useBulkAction";
45
47
  export { useContainerGrid } from "./hooks/useContainerGrid";
@@ -37,6 +37,8 @@ export { usePendingFilters } from "./hooks/usePendingFilters";
37
37
  export { usePendingTable } from "./hooks/usePendingTable";
38
38
  // Unsaved changes tracking
39
39
  export { useUnsavedChanges, UNSAVED_CHANGES_EVENT, } from "./hooks/useUnsavedChanges";
40
+ // Entity delete
41
+ export { useEntityDelete } from "./hooks/useEntityDelete";
40
42
  // Bulk action mutation
41
43
  export { useBulkAction } from "./hooks/useBulkAction";
42
44
  // Container-aware fluid grid column counter (ResizeObserver-based)
@@ -10,9 +10,9 @@ export type { UnitOfWork } from "../core";
10
10
  export { UserRepository, userRepository, EmailVerificationTokenRepository, PasswordResetTokenRepository, emailVerificationTokenRepository, passwordResetTokenRepository, tokenRepository, SessionRepository, sessionRepository, } from "../features/auth/repository";
11
11
  export { SmsCounterRepository, smsCounterRepository, } from "../features/auth/repository/sms-counter.repository";
12
12
  export { AddressesRepository, addressesRepository, } from "../features/addresses";
13
- export { ProductRepository, ProductsRepository, productRepository, } from "../features/products/repository/products.repository";
14
- export { OrderRepository, OrdersRepository, orderRepository, } from "../features/orders/repository/orders.repository";
15
- export { ReviewRepository, ReviewsRepository, reviewRepository, } from "../features/reviews/repository/reviews.repository";
13
+ export { ProductRepository, productRepository, } from "../features/products/repository/products.repository";
14
+ export { OrderRepository, orderRepository, } from "../features/orders/repository/orders.repository";
15
+ export { ReviewRepository, reviewRepository, } from "../features/reviews/repository/reviews.repository";
16
16
  export { bidRepository } from "../features/auctions/repository/bid.repository";
17
17
  export { CartRepository, cartRepository, } from "../features/cart/repository/cart.repository";
18
18
  export { StoreRepository, storeRepository, } from "../features/stores/repository/store.repository";
@@ -14,9 +14,9 @@ export { SmsCounterRepository, smsCounterRepository, } from "../features/auth/re
14
14
  // SB-UNI-A 2026-05-13 — top-level `addresses` collection with ownerType discriminator.
15
15
  // Replaces the two prior subcollection repositories (account/address + stores/store-address).
16
16
  export { AddressesRepository, addressesRepository, } from "../features/addresses";
17
- export { ProductRepository, ProductsRepository, productRepository, } from "../features/products/repository/products.repository";
18
- export { OrderRepository, OrdersRepository, orderRepository, } from "../features/orders/repository/orders.repository";
19
- export { ReviewRepository, ReviewsRepository, reviewRepository, } from "../features/reviews/repository/reviews.repository";
17
+ export { ProductRepository, productRepository, } from "../features/products/repository/products.repository";
18
+ export { OrderRepository, orderRepository, } from "../features/orders/repository/orders.repository";
19
+ export { ReviewRepository, reviewRepository, } from "../features/reviews/repository/reviews.repository";
20
20
  // Canonical appkit-owned repositories
21
21
  export { bidRepository } from "../features/auctions/repository/bid.repository";
22
22
  export { CartRepository, cartRepository, } from "../features/cart/repository/cart.repository";