@withwiz/toolkit 0.2.0 → 0.2.2

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 (95) hide show
  1. package/dist/auth/index.js +19 -19
  2. package/dist/chunk-7IY3RQQL.js +151 -0
  3. package/dist/chunk-GSUQE3SZ.js +225 -0
  4. package/dist/chunk-IPXPCBDO.js +127 -0
  5. package/dist/chunk-LJEGM4OO.js +136 -0
  6. package/dist/chunk-MAATEX2R.js +81 -0
  7. package/dist/chunk-NY5QXT33.js +31 -0
  8. package/dist/chunk-TH45RVP7.js +110 -0
  9. package/dist/components/ui/DataTable.d.ts +8 -103
  10. package/dist/components/ui/DataTable.js +17 -602
  11. package/dist/components/ui/data-table/DataTable.d.ts +2 -0
  12. package/dist/components/ui/data-table/DataTable.js +22 -0
  13. package/dist/components/ui/data-table/DataTableBody.d.ts +19 -0
  14. package/dist/components/ui/data-table/DataTableBody.js +10 -0
  15. package/dist/components/ui/data-table/DataTableBulkActions.d.ts +17 -0
  16. package/dist/components/ui/data-table/DataTableBulkActions.js +12 -0
  17. package/dist/components/ui/data-table/DataTableFilters.d.ts +15 -0
  18. package/dist/components/ui/data-table/DataTableFilters.js +13 -0
  19. package/dist/components/ui/data-table/DataTablePagination.d.ts +10 -0
  20. package/dist/components/ui/data-table/DataTablePagination.js +11 -0
  21. package/dist/components/ui/data-table/DataTableSearch.d.ts +24 -0
  22. package/dist/components/ui/data-table/DataTableSearch.js +12 -0
  23. package/dist/components/ui/data-table/index.d.ts +13 -0
  24. package/dist/components/ui/data-table/types.d.ts +115 -0
  25. package/dist/error/index.d.ts +0 -4
  26. package/dist/error/index.js +1 -69
  27. package/dist/geolocation/index.js +4 -4
  28. package/dist/geolocation/providers/index.js +4 -4
  29. package/dist/hooks/useDataTable.d.ts +45 -0
  30. package/dist/hooks/useDataTable.js +13 -11
  31. package/dist/utils/format-number.js +30 -4
  32. package/dist/utils/short-code-generator.js +36 -4
  33. package/dist/utils/url-normalizer.js +194 -10
  34. package/package.json +3 -2
  35. package/dist/chunk-5ATB5D6S.js +0 -40
  36. package/dist/chunk-6C7HQIX4.js +0 -13
  37. package/dist/chunk-7VJNLGAS.js +0 -110
  38. package/dist/chunk-7XFHGAJP.js +0 -0
  39. package/dist/chunk-A6EAAWMK.js +0 -50
  40. package/dist/chunk-COK4ZXNG.js +0 -0
  41. package/dist/chunk-EQYTE7WD.js +0 -139
  42. package/dist/chunk-FW3IEJ7H.js +0 -71
  43. package/dist/chunk-HGC4CCKB.js +0 -29
  44. package/dist/chunk-IAJNC34M.js +0 -102
  45. package/dist/chunk-JS5VI3OW.js +0 -143
  46. package/dist/chunk-MYLGYX4K.js +0 -57
  47. package/dist/chunk-TDZJ6SAI.js +0 -34
  48. package/dist/chunk-TEIYA7U4.js +0 -72
  49. package/dist/chunk-ULF5RDDX.js +0 -0
  50. package/dist/chunk-VWODEQ5C.js +0 -204
  51. package/dist/chunk-Y2TUZFCP.js +0 -0
  52. package/dist/chunk-YJ3TLEW3.js +0 -100
  53. package/dist/chunk-ZHVUK5OY.js +0 -314
  54. package/dist/chunk-ZZIKRBJU.js +0 -96
  55. package/dist/error/components/EmptyState.d.ts +0 -50
  56. package/dist/error/components/ErrorAlert.d.ts +0 -50
  57. package/dist/error/components/ErrorPage.d.ts +0 -39
  58. package/dist/error/components/LoadingState.d.ts +0 -37
  59. package/dist/error/components/index.d.ts +0 -13
  60. package/dist/error/components/index.js +0 -18
  61. package/dist/error/hooks/index.d.ts +0 -7
  62. package/dist/error/hooks/index.js +0 -14
  63. package/dist/error/hooks/useErrorHandler.d.ts +0 -67
  64. package/dist/error/hooks/useErrorHandler.js +0 -14
  65. package/dist/error/logging/error-logger.d.ts +0 -77
  66. package/dist/error/logging/error-logger.js +0 -10
  67. package/dist/error/logging/index.d.ts +0 -9
  68. package/dist/error/logging/index.js +0 -35
  69. package/dist/error/logging/transports/base.d.ts +0 -30
  70. package/dist/error/logging/transports/base.js +0 -7
  71. package/dist/error/logging/transports/console.d.ts +0 -40
  72. package/dist/error/logging/transports/console.js +0 -9
  73. package/dist/error/logging/transports/file.d.ts +0 -49
  74. package/dist/error/logging/transports/file.js +0 -8
  75. package/dist/error/logging/transports/index.d.ts +0 -12
  76. package/dist/error/logging/transports/index.js +0 -25
  77. package/dist/error/logging/transports/sentry.d.ts +0 -44
  78. package/dist/error/logging/transports/sentry.js +0 -9
  79. package/dist/error/logging/transports/slack.d.ts +0 -51
  80. package/dist/error/logging/transports/slack.js +0 -9
  81. package/dist/error/logging/types.d.ts +0 -83
  82. package/dist/error/logging/types.js +0 -7
  83. package/dist/error/recovery/circuit-breaker.d.ts +0 -85
  84. package/dist/error/recovery/circuit-breaker.js +0 -9
  85. package/dist/error/recovery/degradation.d.ts +0 -56
  86. package/dist/error/recovery/degradation.js +0 -7
  87. package/dist/error/recovery/fallback.d.ts +0 -55
  88. package/dist/error/recovery/fallback.js +0 -11
  89. package/dist/error/recovery/index.d.ts +0 -12
  90. package/dist/error/recovery/index.js +0 -26
  91. package/dist/error/recovery/retry.d.ts +0 -44
  92. package/dist/error/recovery/retry.js +0 -7
  93. package/dist/utils/shared-utils.d.ts +0 -25
  94. package/dist/utils/shared-utils.js +0 -43
  95. package/dist/{chunk-S73334QY.js → chunk-QF6FH4GZ.js} +3 -3
@@ -1,6 +1,25 @@
1
+ import {
2
+ JWTClientManager,
3
+ clearStoredTokens,
4
+ clearTokens,
5
+ createApiHeaders,
6
+ createAuthHeader,
7
+ decodeJWTPayload,
8
+ extractUserFromToken,
9
+ getStoredTokens,
10
+ getTokenExpirationString,
11
+ getTokenIssuedAtString,
12
+ getTokenRemainingTime,
13
+ isTokenExpired,
14
+ isTokenExpiringSoon,
15
+ storeTokens
16
+ } from "../chunk-XRRPEBKB.js";
1
17
  import {
2
18
  OAuthManager
3
19
  } from "../chunk-V5K5FYU7.js";
20
+ import {
21
+ TokenGenerator
22
+ } from "../chunk-GDWEDUHO.js";
4
23
  import {
5
24
  DEFAULT_PASSWORD_CONFIG,
6
25
  createPasswordHasher,
@@ -16,25 +35,6 @@ import {
16
35
  defaultPasswordSchema,
17
36
  strongPasswordSchema
18
37
  } from "../chunk-IHXRF3BH.js";
19
- import {
20
- TokenGenerator
21
- } from "../chunk-GDWEDUHO.js";
22
- import {
23
- JWTClientManager,
24
- clearStoredTokens,
25
- clearTokens,
26
- createApiHeaders,
27
- createAuthHeader,
28
- decodeJWTPayload,
29
- extractUserFromToken,
30
- getStoredTokens,
31
- getTokenExpirationString,
32
- getTokenIssuedAtString,
33
- getTokenRemainingTime,
34
- isTokenExpired,
35
- isTokenExpiringSoon,
36
- storeTokens
37
- } from "../chunk-XRRPEBKB.js";
38
38
  import {
39
39
  OAuthProvider,
40
40
  PasswordStrength,
@@ -0,0 +1,151 @@
1
+ import {
2
+ LoadingBar
3
+ } from "./chunk-34WAGUT5.js";
4
+ import {
5
+ cn
6
+ } from "./chunk-62FLBG6B.js";
7
+
8
+ // src/components/ui/data-table/DataTableBody.tsx
9
+ import { useRef, useEffect } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ function DataTableBody({
12
+ data,
13
+ visibleColumns,
14
+ loading,
15
+ error,
16
+ emptyMessage,
17
+ selectable,
18
+ localSelectedIds,
19
+ getRowId,
20
+ onSelectAll,
21
+ onSelect,
22
+ sort,
23
+ onSort,
24
+ labels
25
+ }) {
26
+ const selectAllRef = useRef(null);
27
+ useEffect(() => {
28
+ if (selectAllRef.current) {
29
+ selectAllRef.current.indeterminate = localSelectedIds.length > 0 && localSelectedIds.length < data.length;
30
+ }
31
+ }, [localSelectedIds, data.length]);
32
+ return /* @__PURE__ */ jsx("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto max-w-full", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm min-w-full", children: [
33
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
34
+ selectable && /* @__PURE__ */ jsx("th", { className: "px-1 py-2 text-left font-medium w-8", children: /* @__PURE__ */ jsx(
35
+ "input",
36
+ {
37
+ "data-testid": "select-all-checkbox",
38
+ type: "checkbox",
39
+ ref: selectAllRef,
40
+ checked: data.length > 0 && localSelectedIds.length === data.length,
41
+ onChange: (e) => onSelectAll(e.target.checked),
42
+ className: "h-4 w-4"
43
+ }
44
+ ) }),
45
+ visibleColumns.map((column) => {
46
+ var _a, _b, _c, _d;
47
+ const width = column.width === "auto" ? void 0 : column.width;
48
+ const minWidth = column.minWidth;
49
+ return /* @__PURE__ */ jsx(
50
+ "th",
51
+ {
52
+ className: cn(
53
+ "px-2 py-2 font-medium",
54
+ column.sortable && "cursor-pointer",
55
+ column.className,
56
+ ((_a = column.responsive) == null ? void 0 : _a.sm) && "hidden sm:table-cell",
57
+ ((_b = column.responsive) == null ? void 0 : _b.md) && "hidden md:table-cell",
58
+ ((_c = column.responsive) == null ? void 0 : _c.lg) && "hidden lg:table-cell",
59
+ ((_d = column.responsive) == null ? void 0 : _d.xl) && "hidden xl:table-cell"
60
+ ),
61
+ style: {
62
+ width,
63
+ minWidth: minWidth || width || void 0,
64
+ maxWidth: column.maxWidth || void 0
65
+ },
66
+ onClick: column.sortable ? () => onSort(column.key) : void 0,
67
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1", children: [
68
+ column.header,
69
+ column.sortable && sort && sort.sort === column.key && /* @__PURE__ */ jsx("span", { children: sort.order === "asc" ? "\u25B2" : "\u25BC" })
70
+ ] })
71
+ },
72
+ column.key
73
+ );
74
+ })
75
+ ] }) }),
76
+ /* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
77
+ "td",
78
+ {
79
+ colSpan: visibleColumns.length + (selectable ? 1 : 0),
80
+ className: "text-center py-8",
81
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-3", children: [
82
+ /* @__PURE__ */ jsx(LoadingBar, { size: "md", variant: "primary", className: "w-64" }),
83
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: labels.loading })
84
+ ] })
85
+ }
86
+ ) }) : error ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
87
+ "td",
88
+ {
89
+ colSpan: visibleColumns.length + (selectable ? 1 : 0),
90
+ className: "text-center py-8 text-destructive",
91
+ children: error
92
+ }
93
+ ) }) : data.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
94
+ "td",
95
+ {
96
+ colSpan: visibleColumns.length + (selectable ? 1 : 0),
97
+ className: "text-center py-8 text-muted-foreground",
98
+ children: emptyMessage
99
+ }
100
+ ) }) : data.map((item) => {
101
+ const rowId = getRowId(item);
102
+ return /* @__PURE__ */ jsxs(
103
+ "tr",
104
+ {
105
+ className: cn(
106
+ "border-b last:border-0 hover:bg-muted/30",
107
+ localSelectedIds.includes(rowId) && "bg-primary/5"
108
+ ),
109
+ children: [
110
+ selectable && /* @__PURE__ */ jsx("td", { className: "px-1 py-2 w-8", children: /* @__PURE__ */ jsx(
111
+ "input",
112
+ {
113
+ "data-testid": `row-checkbox-${rowId}`,
114
+ type: "checkbox",
115
+ checked: localSelectedIds.includes(rowId),
116
+ onChange: (e) => onSelect(rowId, e.target.checked),
117
+ className: "h-4 w-4"
118
+ }
119
+ ) }),
120
+ visibleColumns.map((column) => {
121
+ var _a, _b, _c, _d;
122
+ return /* @__PURE__ */ jsx(
123
+ "td",
124
+ {
125
+ className: cn(
126
+ "px-2 py-3 overflow-hidden",
127
+ column.className,
128
+ ((_a = column.responsive) == null ? void 0 : _a.sm) && "hidden sm:table-cell",
129
+ ((_b = column.responsive) == null ? void 0 : _b.md) && "hidden md:table-cell",
130
+ ((_c = column.responsive) == null ? void 0 : _c.lg) && "hidden lg:table-cell",
131
+ ((_d = column.responsive) == null ? void 0 : _d.xl) && "hidden xl:table-cell"
132
+ ),
133
+ style: {
134
+ maxWidth: column.maxWidth || column.width || void 0
135
+ },
136
+ children: column.cell ? column.cell(item) : column.accessorKey ? String(item[column.accessorKey] || "") : ""
137
+ },
138
+ column.key
139
+ );
140
+ })
141
+ ]
142
+ },
143
+ rowId
144
+ );
145
+ }) })
146
+ ] }) }) });
147
+ }
148
+
149
+ export {
150
+ DataTableBody
151
+ };
@@ -0,0 +1,225 @@
1
+ import {
2
+ DataTableFilters
3
+ } from "./chunk-LJEGM4OO.js";
4
+ import {
5
+ DataTablePagination
6
+ } from "./chunk-IPXPCBDO.js";
7
+ import {
8
+ DataTableSearch
9
+ } from "./chunk-TH45RVP7.js";
10
+ import {
11
+ DataTableBody
12
+ } from "./chunk-7IY3RQQL.js";
13
+ import {
14
+ DataTableBulkActions
15
+ } from "./chunk-MAATEX2R.js";
16
+ import {
17
+ DEFAULT_LABELS
18
+ } from "./chunk-NY5QXT33.js";
19
+ import {
20
+ Alert,
21
+ AlertDescription
22
+ } from "./chunk-F6LCSFSU.js";
23
+ import {
24
+ cn
25
+ } from "./chunk-62FLBG6B.js";
26
+ import {
27
+ __spreadValues
28
+ } from "./chunk-ORMEWXMH.js";
29
+
30
+ // src/components/ui/data-table/DataTable.tsx
31
+ import { useState, useEffect, useMemo } from "react";
32
+ import { jsx, jsxs } from "react/jsx-runtime";
33
+ function DataTable({
34
+ data,
35
+ columns,
36
+ loading = false,
37
+ error = null,
38
+ pagination,
39
+ sort,
40
+ bulkActions = [],
41
+ filters = [],
42
+ filterValues = {},
43
+ onFilterChange,
44
+ onClearFilters,
45
+ selectable = false,
46
+ onSelectionChange,
47
+ selectedIds = [],
48
+ getRowId,
49
+ className,
50
+ emptyMessage = "No data",
51
+ searchPlaceholder = "Search...",
52
+ onSearch,
53
+ onSearchValueChange,
54
+ searchValue = "",
55
+ showFilters = false,
56
+ onToggleFilters,
57
+ createButton,
58
+ labels: customLabels,
59
+ syncWithUrl = false
60
+ }) {
61
+ const labels = __spreadValues(__spreadValues({}, DEFAULT_LABELS), customLabels);
62
+ const [localSelectedIds, setLocalSelectedIds] = useState(selectedIds);
63
+ const [bulkActionLoading, setBulkActionLoading] = useState(null);
64
+ useEffect(() => {
65
+ setLocalSelectedIds(selectedIds);
66
+ }, [selectedIds]);
67
+ const hasActiveFilters = useMemo(() => {
68
+ if (searchValue && searchValue.trim()) return true;
69
+ for (const [key, value] of Object.entries(filterValues)) {
70
+ if (value === void 0 || value === null || value === "") continue;
71
+ if (value === "all") continue;
72
+ if (typeof value === "object" && value !== null) {
73
+ if (key === "dateRange" && (value.start || value.end)) return true;
74
+ if (key === "clickRange" && (value.min || value.max)) return true;
75
+ if (key === "lastClickedRange" && (value.start || value.end)) return true;
76
+ } else {
77
+ if (key === "activeFilter" && value !== "all") return true;
78
+ if (key === "publicFilter" && value !== "all") return true;
79
+ if (key === "expirationFilter" && value !== "all") return true;
80
+ }
81
+ }
82
+ return false;
83
+ }, [searchValue, filterValues]);
84
+ useEffect(() => {
85
+ if (!syncWithUrl || typeof window === "undefined") return;
86
+ const params = new URLSearchParams(window.location.search);
87
+ let changed = false;
88
+ if (searchValue) {
89
+ if (params.get("search") !== searchValue) {
90
+ params.set("search", searchValue);
91
+ changed = true;
92
+ }
93
+ } else {
94
+ if (params.has("search")) {
95
+ params.delete("search");
96
+ changed = true;
97
+ }
98
+ }
99
+ if (sort) {
100
+ if (params.get("sort") !== sort.sort) {
101
+ params.set("sort", sort.sort);
102
+ changed = true;
103
+ }
104
+ if (params.get("order") !== sort.order) {
105
+ params.set("order", sort.order);
106
+ changed = true;
107
+ }
108
+ }
109
+ if (pagination) {
110
+ const pageStr = String(pagination.page);
111
+ const pageSizeStr = String(pagination.pageSize);
112
+ if (params.get("page") !== pageStr) {
113
+ params.set("page", pageStr);
114
+ changed = true;
115
+ }
116
+ if (params.get("pageSize") !== pageSizeStr) {
117
+ params.set("pageSize", pageSizeStr);
118
+ changed = true;
119
+ }
120
+ }
121
+ if (changed) {
122
+ const newUrl = `${window.location.pathname}?${params.toString()}`;
123
+ window.history.replaceState(null, "", newUrl);
124
+ }
125
+ }, [syncWithUrl, searchValue, sort == null ? void 0 : sort.sort, sort == null ? void 0 : sort.order, pagination == null ? void 0 : pagination.page, pagination == null ? void 0 : pagination.pageSize]);
126
+ const handleSelectAll = (checked) => {
127
+ const newSelection = checked ? data.map((item) => getRowId(item)) : [];
128
+ setLocalSelectedIds(newSelection);
129
+ onSelectionChange == null ? void 0 : onSelectionChange(newSelection);
130
+ };
131
+ const handleSelect = (id, checked) => {
132
+ const newSelection = checked ? [...localSelectedIds, id] : localSelectedIds.filter((item) => item !== id);
133
+ setLocalSelectedIds(newSelection);
134
+ onSelectionChange == null ? void 0 : onSelectionChange(newSelection);
135
+ };
136
+ const handleSort = (columnKey) => {
137
+ if (!sort) return;
138
+ if (sort.sort === columnKey) {
139
+ sort.onSortChange(columnKey, sort.order === "asc" ? "desc" : "asc");
140
+ } else {
141
+ sort.onSortChange(columnKey, "asc");
142
+ }
143
+ };
144
+ const handleBulkAction = async (action) => {
145
+ if (localSelectedIds.length === 0 || bulkActionLoading) return;
146
+ setBulkActionLoading(action.key);
147
+ try {
148
+ await action.onClick(localSelectedIds);
149
+ } finally {
150
+ setBulkActionLoading(null);
151
+ }
152
+ };
153
+ const visibleColumns = columns.filter((col) => !col.hidden);
154
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
155
+ (onSearch || createButton) && /* @__PURE__ */ jsx(
156
+ DataTableSearch,
157
+ {
158
+ onSearch,
159
+ onSearchValueChange,
160
+ searchValue,
161
+ searchPlaceholder,
162
+ labels,
163
+ filters,
164
+ onToggleFilters,
165
+ showFilters,
166
+ hasActiveFilters,
167
+ pagination,
168
+ createButton
169
+ }
170
+ ),
171
+ showFilters && filters.length > 0 && /* @__PURE__ */ jsx(
172
+ DataTableFilters,
173
+ {
174
+ filters,
175
+ filterValues,
176
+ onFilterChange,
177
+ onClearFilters,
178
+ hasActiveFilters,
179
+ labels
180
+ }
181
+ ),
182
+ selectable && bulkActions.length > 0 && /* @__PURE__ */ jsx(
183
+ DataTableBulkActions,
184
+ {
185
+ bulkActions,
186
+ localSelectedIds,
187
+ dataLength: data.length,
188
+ bulkActionLoading,
189
+ onSelectAll: handleSelectAll,
190
+ onBulkAction: handleBulkAction,
191
+ labels
192
+ }
193
+ ),
194
+ error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
195
+ /* @__PURE__ */ jsx(
196
+ DataTableBody,
197
+ {
198
+ data,
199
+ visibleColumns,
200
+ loading,
201
+ error,
202
+ emptyMessage,
203
+ selectable,
204
+ localSelectedIds,
205
+ getRowId,
206
+ onSelectAll: handleSelectAll,
207
+ onSelect: handleSelect,
208
+ sort,
209
+ onSort: handleSort,
210
+ labels
211
+ }
212
+ ),
213
+ pagination && pagination.total > 0 && /* @__PURE__ */ jsx(
214
+ DataTablePagination,
215
+ {
216
+ pagination,
217
+ labels
218
+ }
219
+ )
220
+ ] });
221
+ }
222
+
223
+ export {
224
+ DataTable
225
+ };
@@ -0,0 +1,127 @@
1
+ import {
2
+ formatLabel
3
+ } from "./chunk-NY5QXT33.js";
4
+ import {
5
+ Pagination,
6
+ PaginationContent,
7
+ PaginationEllipsis,
8
+ PaginationItem,
9
+ PaginationLink,
10
+ PaginationNext,
11
+ PaginationPrevious
12
+ } from "./chunk-YJWLWUFK.js";
13
+
14
+ // src/components/ui/data-table/DataTablePagination.tsx
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ function DataTablePagination({
17
+ pagination,
18
+ labels
19
+ }) {
20
+ const totalPages = Math.ceil(pagination.total / pagination.pageSize);
21
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-3 p-3 bg-muted/50 rounded-lg", children: /* @__PURE__ */ jsx(Pagination, { className: "w-full", children: /* @__PURE__ */ jsxs(PaginationContent, { className: "flex-wrap gap-1 justify-between w-full items-center", children: [
22
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground text-center sm:text-left whitespace-nowrap", children: formatLabel(labels.showing, {
23
+ start: (pagination.page - 1) * pagination.pageSize + 1,
24
+ end: Math.min(pagination.page * pagination.pageSize, pagination.total),
25
+ total: pagination.total
26
+ }) }),
27
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsxs(
28
+ PaginationPrevious,
29
+ {
30
+ href: "#",
31
+ onClick: (e) => {
32
+ e.preventDefault();
33
+ if (pagination.page > 1) pagination.onPageChange(pagination.page - 1);
34
+ },
35
+ className: pagination.page <= 1 ? "pointer-events-none opacity-50" : "",
36
+ children: [
37
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: labels.previous }),
38
+ /* @__PURE__ */ jsx("span", { className: "sm:hidden", children: "\u2190" })
39
+ ]
40
+ }
41
+ ) }),
42
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:flex", children: (() => {
43
+ const pages = [];
44
+ if (pagination.page > 3) {
45
+ pages.push(
46
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
47
+ PaginationLink,
48
+ {
49
+ href: "#",
50
+ onClick: (e) => {
51
+ e.preventDefault();
52
+ pagination.onPageChange(1);
53
+ },
54
+ children: "1"
55
+ }
56
+ ) }, 1)
57
+ );
58
+ if (pagination.page > 4) {
59
+ pages.push(
60
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, "ellipsis1")
61
+ );
62
+ }
63
+ }
64
+ for (let i = Math.max(1, pagination.page - 2); i <= Math.min(totalPages, pagination.page + 2); i++) {
65
+ pages.push(
66
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
67
+ PaginationLink,
68
+ {
69
+ href: "#",
70
+ isActive: i === pagination.page,
71
+ onClick: (e) => {
72
+ e.preventDefault();
73
+ pagination.onPageChange(i);
74
+ },
75
+ children: i
76
+ }
77
+ ) }, i)
78
+ );
79
+ }
80
+ if (pagination.page < totalPages - 2) {
81
+ if (pagination.page < totalPages - 3) {
82
+ pages.push(
83
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, "ellipsis2")
84
+ );
85
+ }
86
+ pages.push(
87
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
88
+ PaginationLink,
89
+ {
90
+ href: "#",
91
+ onClick: (e) => {
92
+ e.preventDefault();
93
+ pagination.onPageChange(totalPages);
94
+ },
95
+ children: totalPages
96
+ }
97
+ ) }, totalPages)
98
+ );
99
+ }
100
+ return pages;
101
+ })() }),
102
+ /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("span", { className: "px-3 py-2 text-sm font-medium", children: [
103
+ pagination.page,
104
+ " / ",
105
+ totalPages
106
+ ] }) }),
107
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsxs(
108
+ PaginationNext,
109
+ {
110
+ href: "#",
111
+ onClick: (e) => {
112
+ e.preventDefault();
113
+ if (pagination.page < totalPages) pagination.onPageChange(pagination.page + 1);
114
+ },
115
+ className: pagination.page >= totalPages ? "pointer-events-none opacity-50" : "",
116
+ children: [
117
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: labels.next }),
118
+ /* @__PURE__ */ jsx("span", { className: "sm:hidden", children: "\u2192" })
119
+ ]
120
+ }
121
+ ) })
122
+ ] }) }) });
123
+ }
124
+
125
+ export {
126
+ DataTablePagination
127
+ };
@@ -0,0 +1,136 @@
1
+ import {
2
+ Label
3
+ } from "./chunk-IJEZ7G7S.js";
4
+ import {
5
+ Select,
6
+ SelectContent,
7
+ SelectItem,
8
+ SelectTrigger,
9
+ SelectValue
10
+ } from "./chunk-WDUFQFDP.js";
11
+ import {
12
+ Button
13
+ } from "./chunk-L25BNU3E.js";
14
+ import {
15
+ Input
16
+ } from "./chunk-RJUVBBZG.js";
17
+ import {
18
+ cn
19
+ } from "./chunk-62FLBG6B.js";
20
+ import {
21
+ __spreadProps,
22
+ __spreadValues
23
+ } from "./chunk-ORMEWXMH.js";
24
+
25
+ // src/components/ui/data-table/DataTableFilters.tsx
26
+ import { RefreshCw } from "lucide-react";
27
+ import { jsx, jsxs } from "react/jsx-runtime";
28
+ function DataTableFilters({
29
+ filters,
30
+ filterValues,
31
+ onFilterChange,
32
+ onClearFilters,
33
+ hasActiveFilters,
34
+ labels
35
+ }) {
36
+ return /* @__PURE__ */ jsxs("div", { className: "p-2 bg-muted/50 rounded-lg space-y-2", children: [
37
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4", children: filters.map((filter) => {
38
+ var _a, _b, _c, _d, _e;
39
+ return /* @__PURE__ */ jsxs("div", { className: cn("space-y-1", filter.className), children: [
40
+ /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: filter.label }),
41
+ filter.type === "text" && /* @__PURE__ */ jsx(
42
+ Input,
43
+ {
44
+ "data-testid": `filter-${filter.key}`,
45
+ type: "text",
46
+ value: filterValues[filter.key] || "",
47
+ onChange: (e) => onFilterChange == null ? void 0 : onFilterChange(filter.key, e.target.value),
48
+ placeholder: filter.placeholder,
49
+ className: "text-xs"
50
+ }
51
+ ),
52
+ filter.type === "select" && /* @__PURE__ */ jsxs(
53
+ Select,
54
+ {
55
+ value: filterValues[filter.key] || "all",
56
+ onValueChange: (value) => onFilterChange == null ? void 0 : onFilterChange(filter.key, value),
57
+ children: [
58
+ /* @__PURE__ */ jsx(SelectTrigger, { "data-testid": `filter-${filter.key}`, className: "text-xs w-full h-9", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: filter.placeholder }) }),
59
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
60
+ /* @__PURE__ */ jsx(SelectItem, { value: "all", children: labels.all }),
61
+ (_a = filter.options) == null ? void 0 : _a.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value))
62
+ ] })
63
+ ]
64
+ }
65
+ ),
66
+ filter.type === "date" && /* @__PURE__ */ jsx(
67
+ Input,
68
+ {
69
+ type: "date",
70
+ value: filterValues[filter.key] || "",
71
+ onChange: (e) => onFilterChange == null ? void 0 : onFilterChange(filter.key, e.target.value),
72
+ className: "text-xs"
73
+ }
74
+ ),
75
+ filter.type === "number" && /* @__PURE__ */ jsx(
76
+ Input,
77
+ {
78
+ type: "number",
79
+ value: filterValues[filter.key] || "",
80
+ onChange: (e) => onFilterChange == null ? void 0 : onFilterChange(filter.key, e.target.value),
81
+ placeholder: filter.placeholder,
82
+ className: "text-xs"
83
+ }
84
+ ),
85
+ filter.type === "range" && /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
86
+ /* @__PURE__ */ jsx(
87
+ Input,
88
+ {
89
+ type: filter.inputType || "text",
90
+ value: ((_b = filterValues[filter.key]) == null ? void 0 : _b.min) || ((_c = filterValues[filter.key]) == null ? void 0 : _c.start) || "",
91
+ onChange: (e) => {
92
+ const currentValue = filterValues[filter.key] || {};
93
+ const newValue = filter.key.includes("date") || filter.key.includes("Date") ? __spreadProps(__spreadValues({}, currentValue), { start: e.target.value }) : __spreadProps(__spreadValues({}, currentValue), { min: e.target.value });
94
+ onFilterChange == null ? void 0 : onFilterChange(filter.key, newValue);
95
+ },
96
+ className: "text-xs",
97
+ placeholder: filter.minPlaceholder || labels.min
98
+ }
99
+ ),
100
+ /* @__PURE__ */ jsx(
101
+ Input,
102
+ {
103
+ type: filter.inputType || "text",
104
+ value: ((_d = filterValues[filter.key]) == null ? void 0 : _d.max) || ((_e = filterValues[filter.key]) == null ? void 0 : _e.end) || "",
105
+ onChange: (e) => {
106
+ const currentValue = filterValues[filter.key] || {};
107
+ const newValue = filter.key.includes("date") || filter.key.includes("Date") ? __spreadProps(__spreadValues({}, currentValue), { end: e.target.value }) : __spreadProps(__spreadValues({}, currentValue), { max: e.target.value });
108
+ onFilterChange == null ? void 0 : onFilterChange(filter.key, newValue);
109
+ },
110
+ className: "text-xs",
111
+ placeholder: filter.maxPlaceholder || labels.max
112
+ }
113
+ )
114
+ ] })
115
+ ] }, filter.key);
116
+ }) }),
117
+ hasActiveFilters && onClearFilters && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
118
+ Button,
119
+ {
120
+ "data-testid": "clear-filters-btn",
121
+ variant: "outline",
122
+ size: "sm",
123
+ onClick: onClearFilters,
124
+ className: "flex items-center gap-2",
125
+ children: [
126
+ /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }),
127
+ labels.clearFilters
128
+ ]
129
+ }
130
+ ) })
131
+ ] });
132
+ }
133
+
134
+ export {
135
+ DataTableFilters
136
+ };