@fayz-ai/ui 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/chunk-22J2RTMN.js +1397 -0
  2. package/dist/chunk-22J2RTMN.js.map +1 -0
  3. package/dist/chunk-2P7T6QQK.cjs +206 -0
  4. package/dist/chunk-2P7T6QQK.cjs.map +1 -0
  5. package/dist/chunk-7TBDPNLY.cjs +649 -0
  6. package/dist/chunk-7TBDPNLY.cjs.map +1 -0
  7. package/dist/chunk-CZ6X6PZT.js +1237 -0
  8. package/dist/chunk-CZ6X6PZT.js.map +1 -0
  9. package/dist/chunk-D6SXPF4F.cjs +397 -0
  10. package/dist/chunk-D6SXPF4F.cjs.map +1 -0
  11. package/dist/chunk-DNYVEOAX.js +11 -0
  12. package/dist/chunk-DNYVEOAX.js.map +1 -0
  13. package/dist/chunk-E526FHZ4.js +169 -0
  14. package/dist/chunk-E526FHZ4.js.map +1 -0
  15. package/dist/chunk-GE6XUREM.cjs +1277 -0
  16. package/dist/chunk-GE6XUREM.cjs.map +1 -0
  17. package/dist/chunk-GFH5HOCO.js +605 -0
  18. package/dist/chunk-GFH5HOCO.js.map +1 -0
  19. package/dist/chunk-IWBXYV4U.js +203 -0
  20. package/dist/chunk-IWBXYV4U.js.map +1 -0
  21. package/dist/chunk-MYZT2OG7.js +350 -0
  22. package/dist/chunk-MYZT2OG7.js.map +1 -0
  23. package/dist/chunk-O5F4LLSL.js +445 -0
  24. package/dist/chunk-O5F4LLSL.js.map +1 -0
  25. package/dist/chunk-TDGSY5W6.cjs +474 -0
  26. package/dist/chunk-TDGSY5W6.cjs.map +1 -0
  27. package/dist/chunk-VVVZO2LE.cjs +13 -0
  28. package/dist/chunk-VVVZO2LE.cjs.map +1 -0
  29. package/dist/chunk-W4XXXJRW.cjs +196 -0
  30. package/dist/chunk-W4XXXJRW.cjs.map +1 -0
  31. package/dist/chunk-YB5ZJKNG.cjs +1484 -0
  32. package/dist/chunk-YB5ZJKNG.cjs.map +1 -0
  33. package/dist/dashboard/index.cjs +102 -0
  34. package/dist/dashboard/index.cjs.map +1 -0
  35. package/dist/dashboard/index.js +5 -0
  36. package/dist/dashboard/index.js.map +1 -0
  37. package/dist/index.cjs +569 -4304
  38. package/dist/index.cjs.map +1 -1
  39. package/dist/index.js +15 -4152
  40. package/dist/index.js.map +1 -1
  41. package/dist/layout/index.cjs +90 -0
  42. package/dist/layout/index.cjs.map +1 -0
  43. package/dist/layout/index.js +5 -0
  44. package/dist/layout/index.js.map +1 -0
  45. package/dist/preset.cjs +18 -0
  46. package/dist/preset.cjs.map +1 -0
  47. package/dist/preset.js +3 -0
  48. package/dist/preset.js.map +1 -0
  49. package/dist/primitives/index.cjs +347 -0
  50. package/dist/primitives/index.cjs.map +1 -0
  51. package/dist/primitives/index.js +6 -0
  52. package/dist/primitives/index.js.map +1 -0
  53. package/dist/theme/index.cjs +41 -0
  54. package/dist/theme/index.cjs.map +1 -0
  55. package/dist/theme/index.js +4 -0
  56. package/dist/theme/index.js.map +1 -0
  57. package/package.json +10 -10
@@ -0,0 +1,1484 @@
1
+ 'use strict';
2
+
3
+ var chunkW4XXXJRW_cjs = require('./chunk-W4XXXJRW.cjs');
4
+ var chunkD6SXPF4F_cjs = require('./chunk-D6SXPF4F.cjs');
5
+ var chunkVVVZO2LE_cjs = require('./chunk-VVVZO2LE.cjs');
6
+ var React11 = require('react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var classVarianceAuthority = require('class-variance-authority');
9
+ var DialogPrimitive = require('@radix-ui/react-dialog');
10
+ var lucideReact = require('lucide-react');
11
+ var SelectPrimitive = require('@radix-ui/react-select');
12
+ var sonner = require('sonner');
13
+ var TabsPrimitive = require('@radix-ui/react-tabs');
14
+ var SeparatorPrimitive = require('@radix-ui/react-separator');
15
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
16
+ var reactDom = require('react-dom');
17
+ var core = require('@fayz-ai/core');
18
+ var PopoverPrimitive = require('@radix-ui/react-popover');
19
+
20
+ function _interopNamespace(e) {
21
+ if (e && e.__esModule) return e;
22
+ var n = Object.create(null);
23
+ if (e) {
24
+ Object.keys(e).forEach(function (k) {
25
+ if (k !== 'default') {
26
+ var d = Object.getOwnPropertyDescriptor(e, k);
27
+ Object.defineProperty(n, k, d.get ? d : {
28
+ enumerable: true,
29
+ get: function () { return e[k]; }
30
+ });
31
+ }
32
+ });
33
+ }
34
+ n.default = e;
35
+ return Object.freeze(n);
36
+ }
37
+
38
+ var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
39
+ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
40
+ var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
41
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
42
+ var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
43
+ var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
44
+ var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
45
+
46
+ var Input = React11__namespace.forwardRef(
47
+ ({ className, type, error, description, id, ...props }, ref) => {
48
+ const inputId = id ?? React11__namespace.useId();
49
+ const descriptionId = description ? `${inputId}-description` : void 0;
50
+ const errorId = error ? `${inputId}-error` : void 0;
51
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
52
+ /* @__PURE__ */ jsxRuntime.jsx(
53
+ "input",
54
+ {
55
+ type,
56
+ id: inputId,
57
+ className: chunkVVVZO2LE_cjs.cn(
58
+ "flex h-8 w-full rounded-input border border-input bg-card px-2 py-1 text-sm text-foreground shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
59
+ error && "border-destructive focus-visible:ring-destructive",
60
+ className
61
+ ),
62
+ ref,
63
+ "aria-invalid": error ? true : void 0,
64
+ "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || void 0,
65
+ ...props
66
+ }
67
+ ),
68
+ description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: descriptionId, className: "mt-1.5 text-xs text-muted-foreground", children: description }),
69
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "mt-1.5 text-xs text-destructive", children: error })
70
+ ] });
71
+ }
72
+ );
73
+ Input.displayName = "Input";
74
+ var badgeVariants = classVarianceAuthority.cva(
75
+ "inline-flex items-center gap-1.5 rounded px-2 py-0.5 text-xs font-medium leading-[18px] transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
76
+ {
77
+ variants: {
78
+ variant: {
79
+ default: "bg-muted text-muted-foreground",
80
+ secondary: "bg-muted text-muted-foreground",
81
+ info: "bg-info-soft text-info-soft-foreground",
82
+ success: "bg-success-soft text-success-soft-foreground",
83
+ warning: "bg-warning-soft text-warning-soft-foreground",
84
+ destructive: "bg-destructive-soft text-destructive-soft-foreground",
85
+ magic: "bg-magic-soft text-magic-soft-foreground",
86
+ strong: "bg-primary text-primary-foreground",
87
+ outline: "border border-border text-foreground"
88
+ }
89
+ },
90
+ defaultVariants: {
91
+ variant: "default"
92
+ }
93
+ }
94
+ );
95
+ var VARIANTS_WITH_DOT = /* @__PURE__ */ new Set([
96
+ "info",
97
+ "success",
98
+ "warning",
99
+ "destructive",
100
+ "magic"
101
+ ]);
102
+ var DOT_COLOR = {
103
+ info: "hsl(var(--info))",
104
+ success: "hsl(var(--success))",
105
+ warning: "hsl(var(--warning))",
106
+ destructive: "hsl(var(--destructive))",
107
+ magic: "hsl(var(--magic))"
108
+ };
109
+ function Badge({ className, variant, dot, children, ...props }) {
110
+ const v = variant ?? "default";
111
+ const showDot = dot ?? VARIANTS_WITH_DOT.has(v);
112
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn(badgeVariants({ variant }), className), ...props, children: [
113
+ showDot && /* @__PURE__ */ jsxRuntime.jsx(
114
+ "span",
115
+ {
116
+ className: "inline-block size-1.5 rounded-full",
117
+ style: { background: DOT_COLOR[v] ?? "currentColor" }
118
+ }
119
+ ),
120
+ children
121
+ ] });
122
+ }
123
+ var SIZE_MAP = {
124
+ sm: "sm:max-w-sm",
125
+ md: "sm:max-w-md",
126
+ lg: "sm:max-w-lg",
127
+ xl: "sm:max-w-xl",
128
+ "2xl": "sm:max-w-2xl",
129
+ "3xl": "sm:max-w-3xl",
130
+ full: "sm:max-w-[calc(100vw-4rem)]"
131
+ };
132
+ var Modal = DialogPrimitive__namespace.Root;
133
+ var ModalTrigger = DialogPrimitive__namespace.Trigger;
134
+ var ModalClose = DialogPrimitive__namespace.Close;
135
+ var ModalPortal = DialogPrimitive__namespace.Portal;
136
+ var ModalOverlay = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
137
+ DialogPrimitive__namespace.Overlay,
138
+ {
139
+ ref,
140
+ className: chunkVVVZO2LE_cjs.cn(
141
+ "fayz-modal-overlay saas-mdl-ov fixed inset-0 z-50",
142
+ "flex items-center justify-center p-0 sm:p-6",
143
+ className
144
+ ),
145
+ ...props
146
+ }
147
+ ));
148
+ ModalOverlay.displayName = "ModalOverlay";
149
+ var ModalContent = React11__namespace.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(ModalPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(ModalOverlay, { children: /* @__PURE__ */ jsxRuntime.jsxs(
150
+ DialogPrimitive__namespace.Content,
151
+ {
152
+ ref,
153
+ onCloseAutoFocus: (e) => {
154
+ e.preventDefault();
155
+ onCloseAutoFocus?.(e);
156
+ },
157
+ onPointerDownOutside: (e) => {
158
+ const target = e.target;
159
+ if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
160
+ e.preventDefault();
161
+ }
162
+ onPointerDownOutside?.(e);
163
+ },
164
+ onInteractOutside: (e) => {
165
+ const target = e.target;
166
+ if (target.closest("[data-modal-passthrough]") || target.closest("[data-radix-popper-content-wrapper]")) {
167
+ e.preventDefault();
168
+ }
169
+ onInteractOutside?.(e);
170
+ },
171
+ className: chunkVVVZO2LE_cjs.cn(
172
+ "fayz-glass-surface fayz-modal-content saas-mdl-ct relative z-50 flex flex-col w-full outline-none",
173
+ // Mobile fullscreen
174
+ "h-full rounded-none border-0",
175
+ // Desktop centered card
176
+ "sm:h-auto sm:max-h-[85vh] sm:rounded-2xl sm:border",
177
+ SIZE_MAP[size],
178
+ noPadding ? "" : "p-6 gap-4",
179
+ className
180
+ ),
181
+ ...props,
182
+ children: [
183
+ children,
184
+ !hideClose && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 z-10 flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring", children: [
185
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
186
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
187
+ ] })
188
+ ]
189
+ }
190
+ ) }) }));
191
+ ModalContent.displayName = "ModalContent";
192
+ function ModalHeader({ className, ...props }) {
193
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("flex flex-col space-y-1.5 text-center sm:text-left shrink-0", className), ...props });
194
+ }
195
+ function ModalBody({ className, ...props }) {
196
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("flex-1 overflow-y-auto min-h-0", className), ...props });
197
+ }
198
+ function ModalFooter({ className, ...props }) {
199
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 shrink-0", className), ...props });
200
+ }
201
+ var ModalTitle = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { ref, className: chunkVVVZO2LE_cjs.cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
202
+ ModalTitle.displayName = "ModalTitle";
203
+ var ModalDescription = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Description, { ref, className: chunkVVVZO2LE_cjs.cn("text-sm text-muted-foreground", className), ...props }));
204
+ ModalDescription.displayName = "ModalDescription";
205
+ var COLOR_CLASSES = {
206
+ primary: "border-primary bg-primary text-primary-foreground",
207
+ success: "border-success bg-success text-white dark:border-success dark:bg-success",
208
+ warning: "border-warning bg-warning text-white",
209
+ destructive: "border-destructive bg-destructive text-destructive-foreground"
210
+ };
211
+ var Checkbox = React11__namespace.forwardRef(
212
+ ({ checked = false, onChange, disabled, className, color = "primary", id, ...props }, ref) => {
213
+ return /* @__PURE__ */ jsxRuntime.jsx(
214
+ "button",
215
+ {
216
+ ref,
217
+ id,
218
+ type: "button",
219
+ role: "checkbox",
220
+ "aria-checked": checked,
221
+ disabled,
222
+ onClick: () => onChange?.(!checked),
223
+ className: chunkVVVZO2LE_cjs.cn(
224
+ "peer inline-flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border-2 transition-all duration-150",
225
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
226
+ "disabled:cursor-not-allowed disabled:opacity-50",
227
+ checked ? `${COLOR_CLASSES[color]} shadow-sm` : "border-muted-foreground/40 bg-background hover:border-muted-foreground/60",
228
+ className
229
+ ),
230
+ ...props,
231
+ children: checked && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5", strokeWidth: 3 })
232
+ }
233
+ );
234
+ }
235
+ );
236
+ Checkbox.displayName = "Checkbox";
237
+ var STYLE_ID = "saas-sheet-styles";
238
+ if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
239
+ const style = document.createElement("style");
240
+ style.id = STYLE_ID;
241
+ style.textContent = `
242
+ @keyframes saas-sheet-fade-in { from { opacity: 0 } to { opacity: 1 } }
243
+ @keyframes saas-sheet-fade-out { from { opacity: 1 } to { opacity: 0 } }
244
+ @keyframes saas-sheet-slide-in { from { transform: translateX(100%) } to { transform: translateX(0) } }
245
+ @keyframes saas-sheet-slide-out { from { transform: translateX(0) } to { transform: translateX(100%) } }
246
+ .saas-sheet-overlay[data-state="open"] { animation: saas-sheet-fade-in 200ms ease-out }
247
+ .saas-sheet-overlay[data-state="closed"] { animation: saas-sheet-fade-out 150ms ease-in }
248
+ .saas-sheet-content[data-state="open"] { animation: saas-sheet-slide-in 280ms cubic-bezier(0.16, 1, 0.3, 1) }
249
+ .saas-sheet-content[data-state="closed"] { animation: saas-sheet-slide-out 200ms ease-in }
250
+ `;
251
+ document.head.appendChild(style);
252
+ }
253
+ var Sheet = DialogPrimitive__namespace.Root;
254
+ var SheetTrigger = DialogPrimitive__namespace.Trigger;
255
+ var SheetClose = DialogPrimitive__namespace.Close;
256
+ var SheetPortal = DialogPrimitive__namespace.Portal;
257
+ var SheetOverlay = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
258
+ DialogPrimitive__namespace.Overlay,
259
+ {
260
+ ref,
261
+ className: chunkVVVZO2LE_cjs.cn(
262
+ "saas-sheet-overlay fixed inset-0 z-50 bg-black/40 backdrop-blur-[2px]",
263
+ className
264
+ ),
265
+ ...props
266
+ }
267
+ ));
268
+ SheetOverlay.displayName = "SheetOverlay";
269
+ var SheetContent = React11__namespace.forwardRef(({ className, children, width, hideClose, overlay = "blur", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(SheetPortal, { children: [
270
+ /* @__PURE__ */ jsxRuntime.jsx(SheetOverlay, { className: overlay === "none" ? "bg-transparent backdrop-blur-0" : overlay === "dim" ? "backdrop-blur-0" : void 0 }),
271
+ /* @__PURE__ */ jsxRuntime.jsxs(
272
+ DialogPrimitive__namespace.Content,
273
+ {
274
+ ref,
275
+ className: chunkVVVZO2LE_cjs.cn(
276
+ "fayz-glass-surface saas-sheet-content fixed inset-y-0 right-0 z-50 flex flex-col border-l bg-card shadow-2xl outline-none",
277
+ "w-full",
278
+ width ?? "max-w-md",
279
+ className
280
+ ),
281
+ ...props,
282
+ children: [
283
+ children,
284
+ !hideClose && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "absolute right-4 top-4 z-10 flex h-7 w-7 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring", children: [
285
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" }),
286
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
287
+ ] })
288
+ ]
289
+ }
290
+ )
291
+ ] }));
292
+ SheetContent.displayName = "SheetContent";
293
+ function SheetHeader({ className, ...props }) {
294
+ return /* @__PURE__ */ jsxRuntime.jsx(
295
+ "div",
296
+ {
297
+ className: chunkVVVZO2LE_cjs.cn("flex flex-col gap-1 px-5 py-4 border-b shrink-0", className),
298
+ ...props
299
+ }
300
+ );
301
+ }
302
+ SheetHeader.displayName = "SheetHeader";
303
+ function SheetFooter({ className, ...props }) {
304
+ return /* @__PURE__ */ jsxRuntime.jsx(
305
+ "div",
306
+ {
307
+ className: chunkVVVZO2LE_cjs.cn("flex items-center gap-2 px-5 py-3 border-t shrink-0", className),
308
+ ...props
309
+ }
310
+ );
311
+ }
312
+ SheetFooter.displayName = "SheetFooter";
313
+ var SheetTitle = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
314
+ DialogPrimitive__namespace.Title,
315
+ {
316
+ ref,
317
+ className: chunkVVVZO2LE_cjs.cn("text-sm font-semibold leading-none tracking-tight", className),
318
+ ...props
319
+ }
320
+ ));
321
+ SheetTitle.displayName = "SheetTitle";
322
+ var SheetDescription = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
323
+ DialogPrimitive__namespace.Description,
324
+ {
325
+ ref,
326
+ className: chunkVVVZO2LE_cjs.cn("text-xs text-muted-foreground", className),
327
+ ...props
328
+ }
329
+ ));
330
+ SheetDescription.displayName = "SheetDescription";
331
+ function SheetBody({ className, ...props }) {
332
+ return /* @__PURE__ */ jsxRuntime.jsx(
333
+ "div",
334
+ {
335
+ className: chunkVVVZO2LE_cjs.cn("flex-1 overflow-y-auto px-5 py-5", className),
336
+ ...props
337
+ }
338
+ );
339
+ }
340
+ SheetBody.displayName = "SheetBody";
341
+ var Select = SelectPrimitive__namespace.Root;
342
+ var SelectGroup = SelectPrimitive__namespace.Group;
343
+ var SelectValue = SelectPrimitive__namespace.Value;
344
+ var SelectTrigger = React11__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
345
+ SelectPrimitive__namespace.Trigger,
346
+ {
347
+ ref,
348
+ className: chunkVVVZO2LE_cjs.cn(
349
+ "flex h-10 w-full items-center justify-between rounded-input border border-input bg-background px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
350
+ className
351
+ ),
352
+ ...props,
353
+ children: [
354
+ children,
355
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4 opacity-50" }) })
356
+ ]
357
+ }
358
+ ));
359
+ SelectTrigger.displayName = SelectPrimitive__namespace.Trigger.displayName;
360
+ var SelectScrollUpButton = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
361
+ SelectPrimitive__namespace.ScrollUpButton,
362
+ {
363
+ ref,
364
+ className: chunkVVVZO2LE_cjs.cn(
365
+ "flex cursor-default items-center justify-center py-1",
366
+ className
367
+ ),
368
+ ...props,
369
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { className: "h-4 w-4" })
370
+ }
371
+ ));
372
+ SelectScrollUpButton.displayName = SelectPrimitive__namespace.ScrollUpButton.displayName;
373
+ var SelectScrollDownButton = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
374
+ SelectPrimitive__namespace.ScrollDownButton,
375
+ {
376
+ ref,
377
+ className: chunkVVVZO2LE_cjs.cn(
378
+ "flex cursor-default items-center justify-center py-1",
379
+ className
380
+ ),
381
+ ...props,
382
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-4 w-4" })
383
+ }
384
+ ));
385
+ SelectScrollDownButton.displayName = SelectPrimitive__namespace.ScrollDownButton.displayName;
386
+ var SelectContent = React11__namespace.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
387
+ SelectPrimitive__namespace.Content,
388
+ {
389
+ ref,
390
+ className: chunkVVVZO2LE_cjs.cn(
391
+ "fayz-glass-surface relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-card border bg-popover text-popover-foreground shadow-md",
392
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
393
+ className
394
+ ),
395
+ position,
396
+ ...props,
397
+ children: [
398
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
399
+ /* @__PURE__ */ jsxRuntime.jsx(
400
+ SelectPrimitive__namespace.Viewport,
401
+ {
402
+ className: chunkVVVZO2LE_cjs.cn(
403
+ "p-1",
404
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
405
+ ),
406
+ children
407
+ }
408
+ ),
409
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {})
410
+ ]
411
+ }
412
+ ) }));
413
+ SelectContent.displayName = SelectPrimitive__namespace.Content.displayName;
414
+ var SelectLabel = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
415
+ SelectPrimitive__namespace.Label,
416
+ {
417
+ ref,
418
+ className: chunkVVVZO2LE_cjs.cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
419
+ ...props
420
+ }
421
+ ));
422
+ SelectLabel.displayName = SelectPrimitive__namespace.Label.displayName;
423
+ var SelectItem = React11__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
424
+ SelectPrimitive__namespace.Item,
425
+ {
426
+ ref,
427
+ className: chunkVVVZO2LE_cjs.cn(
428
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-muted focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
429
+ className
430
+ ),
431
+ ...props,
432
+ children: [
433
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4" }) }) }),
434
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children })
435
+ ]
436
+ }
437
+ ));
438
+ SelectItem.displayName = SelectPrimitive__namespace.Item.displayName;
439
+ var SelectSeparator = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
440
+ SelectPrimitive__namespace.Separator,
441
+ {
442
+ ref,
443
+ className: chunkVVVZO2LE_cjs.cn("-mx-1 my-1 h-px bg-muted", className),
444
+ ...props
445
+ }
446
+ ));
447
+ SelectSeparator.displayName = SelectPrimitive__namespace.Separator.displayName;
448
+ function ToastProvider({
449
+ position = "bottom-center",
450
+ theme = "system"
451
+ }) {
452
+ const saveBarVisible = chunkW4XXXJRW_cjs.useSaveBarVisible();
453
+ const bottomOffset = position.startsWith("bottom") && saveBarVisible ? 84 : 24;
454
+ return /* @__PURE__ */ jsxRuntime.jsx(
455
+ sonner.Toaster,
456
+ {
457
+ position,
458
+ theme,
459
+ offset: bottomOffset,
460
+ closeButton: true,
461
+ richColors: true,
462
+ toastOptions: {
463
+ classNames: {
464
+ // Format harmonized with the SaveBar island: soft ring + xl shadow,
465
+ // generous rounded-2xl radius (full-pill looks wrong on multi-line
466
+ // toasts). Colors stay semantic (richColors).
467
+ toast: "group !gap-3 !rounded-3xl !border !px-4 !py-3 !shadow-xl !ring-1 !ring-black/5",
468
+ title: "!text-sm !font-semibold",
469
+ description: "!text-xs !mt-0.5",
470
+ closeButton: "!opacity-0 group-hover:!opacity-60 hover:!opacity-100 !transition-opacity"
471
+ }
472
+ }
473
+ }
474
+ );
475
+ }
476
+ var Tabs = TabsPrimitive__namespace.Root;
477
+ var TabsList = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
478
+ TabsPrimitive__namespace.List,
479
+ {
480
+ ref,
481
+ className: chunkVVVZO2LE_cjs.cn(
482
+ "inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",
483
+ className
484
+ ),
485
+ ...props
486
+ }
487
+ ));
488
+ TabsList.displayName = TabsPrimitive__namespace.List.displayName;
489
+ var TabsTrigger = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
490
+ TabsPrimitive__namespace.Trigger,
491
+ {
492
+ ref,
493
+ className: chunkVVVZO2LE_cjs.cn(
494
+ "inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
495
+ className
496
+ ),
497
+ ...props
498
+ }
499
+ ));
500
+ TabsTrigger.displayName = TabsPrimitive__namespace.Trigger.displayName;
501
+ var TabsContent = React11__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
502
+ TabsPrimitive__namespace.Content,
503
+ {
504
+ ref,
505
+ className: chunkVVVZO2LE_cjs.cn(
506
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
507
+ className
508
+ ),
509
+ ...props
510
+ }
511
+ ));
512
+ TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
513
+ var Separator2 = React11__namespace.forwardRef(
514
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
515
+ SeparatorPrimitive__namespace.Root,
516
+ {
517
+ ref,
518
+ decorative,
519
+ orientation,
520
+ className: chunkVVVZO2LE_cjs.cn(
521
+ "shrink-0 bg-border",
522
+ orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
523
+ className
524
+ ),
525
+ ...props
526
+ }
527
+ )
528
+ );
529
+ Separator2.displayName = SeparatorPrimitive__namespace.Root.displayName;
530
+ function Breadcrumb({ parent, current, onBack }) {
531
+ const { onBack: effectiveOnBack, parentLabel: effectiveParent } = chunkW4XXXJRW_cjs.useCrossModuleBack(onBack, parent);
532
+ chunkW4XXXJRW_cjs.useBackHandler(effectiveOnBack);
533
+ return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex items-center gap-1.5 text-sm text-muted-foreground", children: [
534
+ /* @__PURE__ */ jsxRuntime.jsxs(
535
+ "button",
536
+ {
537
+ type: "button",
538
+ onClick: effectiveOnBack,
539
+ className: "inline-flex items-center gap-1 hover:text-foreground transition-colors",
540
+ children: [
541
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "h-3.5 w-3.5" }),
542
+ effectiveParent
543
+ ]
544
+ }
545
+ ),
546
+ current !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
547
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "/" }),
548
+ current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground font-medium truncate max-w-[200px]", children: current }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block h-4 w-24 rounded bg-muted animate-pulse align-middle" })
549
+ ] })
550
+ ] });
551
+ }
552
+ var TooltipProvider = TooltipPrimitive__namespace.Provider;
553
+ var Tooltip = TooltipPrimitive__namespace.Root;
554
+ var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
555
+ var TooltipContent = React11__namespace.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
556
+ TooltipPrimitive__namespace.Content,
557
+ {
558
+ ref,
559
+ sideOffset,
560
+ className: chunkVVVZO2LE_cjs.cn(
561
+ "fayz-glass-surface z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
562
+ className
563
+ ),
564
+ ...props
565
+ }
566
+ ));
567
+ TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
568
+ function formatTime12(h, m) {
569
+ const period = h >= 12 ? "pm" : "am";
570
+ const h12 = h % 12 || 12;
571
+ return `${h12}:${String(m).padStart(2, "0")}${period}`;
572
+ }
573
+ function formatTime24(h, m) {
574
+ return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
575
+ }
576
+ function TimePicker({ value, onChange, interval = 15, min = "00:00", max = "23:45", use12h = false, readOnly, className, defaultOpen, onOpenChange }) {
577
+ const [open, setOpen] = React11.useState(defaultOpen ?? false);
578
+ const ref = React11.useRef(null);
579
+ const triggerRef = React11.useRef(null);
580
+ const listRef = React11.useRef(null);
581
+ const [pos, setPos] = React11.useState({ top: 0, left: 0, width: 0 });
582
+ React11.useEffect(() => {
583
+ if (!open || !triggerRef.current) return;
584
+ const rect = triggerRef.current.getBoundingClientRect();
585
+ setPos({ top: rect.bottom + 4, left: rect.left, width: Math.max(rect.width, 120) });
586
+ }, [open]);
587
+ React11.useEffect(() => {
588
+ if (!open) return;
589
+ const handler = (e) => {
590
+ const target = e.target;
591
+ if (ref.current?.contains(target)) return;
592
+ if (listRef.current?.contains(target)) return;
593
+ setOpen(false);
594
+ onOpenChange?.(false);
595
+ };
596
+ document.addEventListener("mousedown", handler);
597
+ return () => document.removeEventListener("mousedown", handler);
598
+ }, [open]);
599
+ React11.useEffect(() => {
600
+ if (!open || !listRef.current || !value) return;
601
+ const el = listRef.current.querySelector('[data-selected="true"]');
602
+ if (el) el.scrollIntoView({ block: "center" });
603
+ }, [open, value]);
604
+ const slots = React11.useMemo(() => {
605
+ const [minH, minM] = min.split(":").map(Number);
606
+ const [maxH, maxM] = max.split(":").map(Number);
607
+ const minTotal = minH * 60 + minM;
608
+ const maxTotal = maxH * 60 + maxM;
609
+ const result = [];
610
+ for (let t = minTotal; t <= maxTotal; t += interval) {
611
+ const h = Math.floor(t / 60);
612
+ const m = t % 60;
613
+ result.push({
614
+ value: formatTime24(h, m),
615
+ label: use12h ? formatTime12(h, m) : formatTime24(h, m)
616
+ });
617
+ }
618
+ return result;
619
+ }, [interval, min, max, use12h]);
620
+ const displayValue = React11.useMemo(() => {
621
+ if (!value) return "";
622
+ const [h, m] = value.split(":").map(Number);
623
+ return use12h ? formatTime12(h, m) : formatTime24(h, m);
624
+ }, [value, use12h]);
625
+ function handleKeyDown(e) {
626
+ if (readOnly) return;
627
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
628
+ e.preventDefault();
629
+ const idx = slots.findIndex((s) => s.value === value);
630
+ const next = e.key === "ArrowDown" ? Math.min(idx + 1, slots.length - 1) : Math.max(idx - 1, 0);
631
+ if (slots[next]) onChange(slots[next].value);
632
+ } else if (e.key === "Enter" || e.key === "Escape") {
633
+ setOpen(false);
634
+ }
635
+ }
636
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: `relative ${className ?? ""}`, children: [
637
+ /* @__PURE__ */ jsxRuntime.jsxs(
638
+ "button",
639
+ {
640
+ ref: triggerRef,
641
+ type: "button",
642
+ onClick: () => !readOnly && setOpen((p) => !p),
643
+ onKeyDown: handleKeyDown,
644
+ disabled: readOnly,
645
+ className: `flex items-center gap-2 rounded-lg border px-3 py-2 text-sm w-full text-left transition-colors ${readOnly ? "bg-muted/40 text-muted-foreground cursor-default" : "bg-background hover:bg-muted/30"}`,
646
+ children: [
647
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
648
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayValue || "--:--" })
649
+ ]
650
+ }
651
+ ),
652
+ open && !readOnly && reactDom.createPortal(
653
+ /* @__PURE__ */ jsxRuntime.jsx(
654
+ "div",
655
+ {
656
+ ref: listRef,
657
+ "data-modal-passthrough": true,
658
+ style: { position: "fixed", top: pos.top, left: pos.left, width: pos.width, zIndex: 9999, pointerEvents: "auto" },
659
+ className: "fayz-glass-surface min-w-[120px] max-h-48 overflow-y-auto rounded-xl border bg-popover shadow-xl py-1",
660
+ children: slots.map((slot) => {
661
+ const selected = slot.value === value;
662
+ return /* @__PURE__ */ jsxRuntime.jsx(
663
+ "button",
664
+ {
665
+ type: "button",
666
+ "data-selected": selected,
667
+ onClick: () => {
668
+ onChange(slot.value);
669
+ setOpen(false);
670
+ },
671
+ className: `block w-full px-3 py-1.5 text-sm text-left transition-colors ${selected ? "bg-primary/10 text-primary font-medium" : "hover:bg-muted/50"}`,
672
+ children: slot.label
673
+ },
674
+ slot.value
675
+ );
676
+ })
677
+ }
678
+ ),
679
+ document.body
680
+ )
681
+ ] });
682
+ }
683
+ function Skeleton({
684
+ className,
685
+ ...props
686
+ }) {
687
+ return /* @__PURE__ */ jsxRuntime.jsx(
688
+ "div",
689
+ {
690
+ className: chunkVVVZO2LE_cjs.cn("animate-pulse rounded-md bg-muted", className),
691
+ ...props
692
+ }
693
+ );
694
+ }
695
+ function TableSkeleton({ columns = 4, rows = 2 }) {
696
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border overflow-hidden", children: [
697
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b bg-muted/30 flex gap-4 px-4 py-2.5", children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 flex-1 rounded bg-muted-foreground/10" }, i)) }),
698
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: Array.from({ length: rows }).map((_, r) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4 px-4 py-3.5", children: Array.from({ length: columns }).map((_2, c) => /* @__PURE__ */ jsxRuntime.jsx(
699
+ Skeleton,
700
+ {
701
+ className: chunkVVVZO2LE_cjs.cn(
702
+ "h-3 rounded",
703
+ c === 0 ? "flex-[2]" : "flex-1"
704
+ )
705
+ },
706
+ c
707
+ )) }, r)) })
708
+ ] });
709
+ }
710
+ function ListView({
711
+ columns,
712
+ data,
713
+ loading = false,
714
+ searchPlaceholder = "Search...",
715
+ search: controlledSearch,
716
+ onSearchChange,
717
+ searchDebounce = 300,
718
+ tags,
719
+ allTagLabel = "All",
720
+ activeTag,
721
+ onTagChange,
722
+ newLabel,
723
+ onNew,
724
+ onRowClick,
725
+ emptyIcon: EmptyIcon,
726
+ emptyMessage = "No results found.",
727
+ emptyActionLabel,
728
+ onEmptyAction,
729
+ total,
730
+ page = 1,
731
+ pageSize = 25,
732
+ onPageChange,
733
+ toolbar,
734
+ className
735
+ }) {
736
+ const [internalSearch, setInternalSearch] = React11.useState(controlledSearch ?? "");
737
+ const debounceRef = React11.useRef();
738
+ React11.useEffect(() => {
739
+ if (controlledSearch !== void 0) setInternalSearch(controlledSearch);
740
+ }, [controlledSearch]);
741
+ const handleSearchChange = React11.useCallback((value) => {
742
+ setInternalSearch(value);
743
+ if (searchDebounce === 0) {
744
+ onSearchChange?.(value);
745
+ } else {
746
+ if (debounceRef.current) clearTimeout(debounceRef.current);
747
+ debounceRef.current = setTimeout(() => onSearchChange?.(value), searchDebounce);
748
+ }
749
+ }, [onSearchChange, searchDebounce]);
750
+ const totalItems = total ?? data.length;
751
+ const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
752
+ const showPagination = onPageChange && totalItems > pageSize;
753
+ const showSearch = !!onSearchChange;
754
+ const showTags = tags && tags.length > 0 && onTagChange;
755
+ const showToolbar = showSearch || onNew || showTags;
756
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkVVVZO2LE_cjs.cn("space-y-4", className), children: [
757
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-3 sm:items-center sm:justify-between", children: [
758
+ showSearch && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm", children: [
759
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }),
760
+ /* @__PURE__ */ jsxRuntime.jsx(
761
+ "input",
762
+ {
763
+ type: "text",
764
+ placeholder: searchPlaceholder,
765
+ value: internalSearch,
766
+ onChange: (e) => handleSearchChange(e.target.value),
767
+ className: "w-full rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] pl-8 pr-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring"
768
+ }
769
+ )
770
+ ] }),
771
+ onNew && newLabel && /* @__PURE__ */ jsxRuntime.jsxs(chunkD6SXPF4F_cjs.Button, { variant: "default", size: "default", onClick: onNew, className: "shrink-0", children: [
772
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
773
+ newLabel
774
+ ] })
775
+ ] }),
776
+ showTags && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-1.5 flex-wrap", children: [
777
+ /* @__PURE__ */ jsxRuntime.jsx(
778
+ "button",
779
+ {
780
+ onClick: () => onTagChange(void 0),
781
+ className: chunkVVVZO2LE_cjs.cn(
782
+ "rounded-full px-2.5 py-1 text-xs font-medium transition-colors",
783
+ !activeTag ? "bg-primary text-primary-foreground" : "bg-muted/50 text-muted-foreground hover:bg-muted"
784
+ ),
785
+ children: allTagLabel
786
+ }
787
+ ),
788
+ tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(
789
+ "button",
790
+ {
791
+ onClick: () => onTagChange(tag.value),
792
+ className: chunkVVVZO2LE_cjs.cn(
793
+ "rounded-full px-2.5 py-1 text-xs font-medium transition-colors",
794
+ activeTag === tag.value ? "bg-primary text-primary-foreground" : "bg-muted/50 text-muted-foreground hover:bg-muted"
795
+ ),
796
+ children: tag.label
797
+ },
798
+ tag.value
799
+ ))
800
+ ] }),
801
+ toolbar,
802
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(chunkD6SXPF4F_cjs.DataTable, { columns, data: [], loading: true, variant: "card" }) : data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-12 text-center rounded-lg border-2 border-dashed border-muted", children: [
803
+ EmptyIcon && /* @__PURE__ */ jsxRuntime.jsx(EmptyIcon, { className: "h-8 w-8 text-muted-foreground/30 mb-2" }),
804
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: emptyMessage }),
805
+ emptyActionLabel && onEmptyAction && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onEmptyAction, className: "text-xs text-primary hover:underline mt-1", children: emptyActionLabel })
806
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
807
+ chunkD6SXPF4F_cjs.DataTable,
808
+ {
809
+ columns,
810
+ data,
811
+ onRowClick,
812
+ variant: "card"
813
+ }
814
+ ),
815
+ showPagination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-1", children: [
816
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
817
+ (page - 1) * pageSize + 1,
818
+ "\u2013",
819
+ Math.min(page * pageSize, totalItems),
820
+ " of ",
821
+ totalItems
822
+ ] }),
823
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
824
+ /* @__PURE__ */ jsxRuntime.jsx(
825
+ "button",
826
+ {
827
+ onClick: () => onPageChange(page - 1),
828
+ disabled: page <= 1,
829
+ className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
830
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-3.5 w-3.5" })
831
+ }
832
+ ),
833
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground px-2", children: [
834
+ page,
835
+ " / ",
836
+ totalPages
837
+ ] }),
838
+ /* @__PURE__ */ jsxRuntime.jsx(
839
+ "button",
840
+ {
841
+ onClick: () => onPageChange(page + 1),
842
+ disabled: page >= totalPages,
843
+ className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
844
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-3.5 w-3.5" })
845
+ }
846
+ )
847
+ ] })
848
+ ] })
849
+ ] });
850
+ }
851
+ var DAY_LABELS = {
852
+ en: ["S", "M", "T", "W", "T", "F", "S"],
853
+ "pt-BR": ["D", "S", "T", "Q", "Q", "S", "S"]
854
+ };
855
+ function toDateLocale(locale) {
856
+ if (locale === "pt-BR") return "pt-BR";
857
+ return "en-US";
858
+ }
859
+ function isSameDay(a, b) {
860
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
861
+ }
862
+ function isToday(d) {
863
+ return isSameDay(d, /* @__PURE__ */ new Date());
864
+ }
865
+ function formatDate(date, locale) {
866
+ return date.toLocaleDateString(toDateLocale(locale), { month: "short", day: "numeric", year: "numeric" });
867
+ }
868
+ function toDateStr(d) {
869
+ return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
870
+ }
871
+ function parseDate(s) {
872
+ const [y, m, d] = s.split("-").map(Number);
873
+ return new Date(y, m - 1, d);
874
+ }
875
+ function DatePicker({ value, onChange, className, defaultOpen, onOpenChange }) {
876
+ const t = core.useTranslation();
877
+ const locale = core.getCurrentLocale();
878
+ const [open, setOpen] = React11.useState(defaultOpen ?? false);
879
+ const ref = React11.useRef(null);
880
+ const triggerRef = React11.useRef(null);
881
+ const dropdownRef = React11.useRef(null);
882
+ const selectedDate = value ? parseDate(value) : /* @__PURE__ */ new Date();
883
+ const [viewMonth, setViewMonth] = React11.useState(new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
884
+ const [pos, setPos] = React11.useState({ top: 0, left: 0 });
885
+ const dayLabels = DAY_LABELS[locale] ?? DAY_LABELS.en;
886
+ const dateLocale = toDateLocale(locale);
887
+ React11.useEffect(() => {
888
+ if (!open || !triggerRef.current) return;
889
+ const rect = triggerRef.current.getBoundingClientRect();
890
+ const dropW = 260;
891
+ let left = rect.left;
892
+ if (left + dropW > window.innerWidth - 12) left = window.innerWidth - dropW - 12;
893
+ if (left < 8) left = 8;
894
+ setPos({ top: rect.bottom + 4, left });
895
+ }, [open]);
896
+ React11.useEffect(() => {
897
+ if (!open) return;
898
+ const handler = (e) => {
899
+ const target = e.target;
900
+ if (ref.current?.contains(target)) return;
901
+ if (dropdownRef.current?.contains(target)) return;
902
+ setOpen(false);
903
+ onOpenChange?.(false);
904
+ };
905
+ document.addEventListener("mousedown", handler);
906
+ return () => document.removeEventListener("mousedown", handler);
907
+ }, [open, onOpenChange]);
908
+ React11.useEffect(() => {
909
+ if (value) {
910
+ const d = parseDate(value);
911
+ setViewMonth(new Date(d.getFullYear(), d.getMonth(), 1));
912
+ }
913
+ }, [value]);
914
+ const monthLabel = viewMonth.toLocaleDateString(dateLocale, { month: "long", year: "numeric" });
915
+ const weeks = React11.useMemo(() => {
916
+ const year = viewMonth.getFullYear();
917
+ const month = viewMonth.getMonth();
918
+ const firstDay = new Date(year, month, 1);
919
+ const startOffset = firstDay.getDay();
920
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
921
+ const prevMonthDays = new Date(year, month, 0).getDate();
922
+ const cells = [];
923
+ for (let i = startOffset - 1; i >= 0; i--) {
924
+ cells.push({ date: new Date(year, month - 1, prevMonthDays - i), inMonth: false });
925
+ }
926
+ for (let d = 1; d <= daysInMonth; d++) {
927
+ cells.push({ date: new Date(year, month, d), inMonth: true });
928
+ }
929
+ while (cells.length % 7 !== 0) {
930
+ cells.push({ date: new Date(year, month + 1, cells.length - startOffset - daysInMonth + 1), inMonth: false });
931
+ }
932
+ const rows = [];
933
+ for (let i = 0; i < cells.length; i += 7) rows.push(cells.slice(i, i + 7));
934
+ return rows;
935
+ }, [viewMonth]);
936
+ function handleSelect(date) {
937
+ onChange(toDateStr(date));
938
+ setOpen(false);
939
+ }
940
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: `relative ${className ?? ""}`, children: [
941
+ /* @__PURE__ */ jsxRuntime.jsxs(
942
+ "button",
943
+ {
944
+ ref: triggerRef,
945
+ type: "button",
946
+ onClick: () => setOpen((p) => !p),
947
+ className: "flex items-center gap-2 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-3 py-2 text-sm hover:bg-muted/30 transition-colors w-full text-left",
948
+ children: [
949
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
950
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: value ? formatDate(selectedDate, locale) : t("common.selectDate") })
951
+ ]
952
+ }
953
+ ),
954
+ open && reactDom.createPortal(
955
+ /* @__PURE__ */ jsxRuntime.jsxs(
956
+ "div",
957
+ {
958
+ ref: dropdownRef,
959
+ "data-modal-passthrough": true,
960
+ style: { position: "fixed", top: pos.top, left: pos.left, zIndex: 9999, pointerEvents: "auto" },
961
+ className: "fayz-glass-surface rounded-xl border bg-popover shadow-xl p-3 w-[260px]",
962
+ children: [
963
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
964
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium capitalize", children: monthLabel }),
965
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
966
+ /* @__PURE__ */ jsxRuntime.jsx(
967
+ "button",
968
+ {
969
+ type: "button",
970
+ onClick: () => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1)),
971
+ className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors",
972
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" })
973
+ }
974
+ ),
975
+ /* @__PURE__ */ jsxRuntime.jsx(
976
+ "button",
977
+ {
978
+ type: "button",
979
+ onClick: () => setViewMonth(new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1)),
980
+ className: "flex h-7 w-7 items-center justify-center rounded-full hover:bg-muted transition-colors",
981
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
982
+ }
983
+ )
984
+ ] })
985
+ ] }),
986
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 mb-1", children: dayLabels.map((l, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-8 items-center justify-center text-[11px] font-medium text-muted-foreground", children: l }, i)) }),
987
+ weeks.map((week, wi) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7", children: week.map(({ date, inMonth }, di) => {
988
+ const sel = value && isSameDay(date, selectedDate);
989
+ const today = isToday(date);
990
+ return /* @__PURE__ */ jsxRuntime.jsx(
991
+ "button",
992
+ {
993
+ type: "button",
994
+ onClick: () => handleSelect(date),
995
+ className: `flex h-8 w-8 items-center justify-center rounded-full text-xs mx-auto transition-colors ${sel ? "bg-primary text-primary-foreground font-semibold" : today ? "bg-primary/10 text-primary font-semibold" : inMonth ? "hover:bg-muted text-foreground" : "text-muted-foreground/40 hover:bg-muted/50"}`,
996
+ children: date.getDate()
997
+ },
998
+ di
999
+ );
1000
+ }) }, wi)),
1001
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 pt-2 border-t", children: /* @__PURE__ */ jsxRuntime.jsx(
1002
+ "button",
1003
+ {
1004
+ type: "button",
1005
+ onClick: () => {
1006
+ handleSelect(/* @__PURE__ */ new Date());
1007
+ },
1008
+ className: "text-xs text-primary font-medium hover:underline",
1009
+ children: t("agenda.calendar.today")
1010
+ }
1011
+ ) })
1012
+ ]
1013
+ }
1014
+ ),
1015
+ document.body
1016
+ )
1017
+ ] });
1018
+ }
1019
+ function SearchSelect({
1020
+ value,
1021
+ displayValue,
1022
+ onChange,
1023
+ onSearch,
1024
+ placeholder = "Search...",
1025
+ label,
1026
+ required,
1027
+ debounce = 250,
1028
+ minChars = 1,
1029
+ allowCreate,
1030
+ createLabel = "Add",
1031
+ onCreate,
1032
+ renderOption,
1033
+ loadOnOpen,
1034
+ className,
1035
+ disabled
1036
+ }) {
1037
+ const [open, setOpen] = React11__namespace.useState(false);
1038
+ const [query, setQuery] = React11__namespace.useState("");
1039
+ const [results, setResults] = React11__namespace.useState([]);
1040
+ const [loading, setLoading] = React11__namespace.useState(false);
1041
+ const [creating, setCreating] = React11__namespace.useState(false);
1042
+ const [selectedLabel, setSelectedLabel] = React11__namespace.useState(displayValue ?? "");
1043
+ const containerRef = React11__namespace.useRef(null);
1044
+ const inputRef = React11__namespace.useRef(null);
1045
+ const timerRef = React11__namespace.useRef();
1046
+ React11__namespace.useEffect(() => {
1047
+ function handler(e) {
1048
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
1049
+ setOpen(false);
1050
+ }
1051
+ }
1052
+ document.addEventListener("mousedown", handler);
1053
+ return () => document.removeEventListener("mousedown", handler);
1054
+ }, []);
1055
+ React11__namespace.useEffect(() => {
1056
+ if (displayValue !== void 0) setSelectedLabel(displayValue);
1057
+ }, [displayValue]);
1058
+ React11__namespace.useEffect(() => {
1059
+ if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
1060
+ setLoading(true);
1061
+ Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
1062
+ }
1063
+ }, [open, loadOnOpen]);
1064
+ function handleQueryChange(q) {
1065
+ setQuery(q);
1066
+ if (timerRef.current) clearTimeout(timerRef.current);
1067
+ if (q.length < minChars && !(loadOnOpen && q.length === 0)) {
1068
+ setResults([]);
1069
+ setLoading(false);
1070
+ return;
1071
+ }
1072
+ setLoading(true);
1073
+ timerRef.current = setTimeout(async () => {
1074
+ try {
1075
+ const res = await onSearch(q);
1076
+ setResults(res);
1077
+ } catch {
1078
+ setResults([]);
1079
+ }
1080
+ setLoading(false);
1081
+ }, debounce);
1082
+ }
1083
+ function handleSelect(option) {
1084
+ onChange(option.id, option);
1085
+ setSelectedLabel(option.label);
1086
+ setOpen(false);
1087
+ setQuery("");
1088
+ setResults([]);
1089
+ }
1090
+ function handleClear() {
1091
+ onChange("", null);
1092
+ setSelectedLabel("");
1093
+ setQuery("");
1094
+ setResults([]);
1095
+ }
1096
+ async function handleCreate(name) {
1097
+ if (!onCreate) return;
1098
+ setCreating(true);
1099
+ setSelectedLabel(name);
1100
+ setOpen(false);
1101
+ setQuery("");
1102
+ setResults([]);
1103
+ try {
1104
+ await onCreate(name);
1105
+ } finally {
1106
+ setCreating(false);
1107
+ }
1108
+ }
1109
+ function handleOpen() {
1110
+ if (disabled || creating) return;
1111
+ setOpen(true);
1112
+ setQuery("");
1113
+ setTimeout(() => inputRef.current?.focus(), 0);
1114
+ }
1115
+ const groups = React11__namespace.useMemo(() => {
1116
+ const map = /* @__PURE__ */ new Map();
1117
+ for (const opt of results) {
1118
+ const group = opt.group ?? "";
1119
+ if (!map.has(group)) map.set(group, []);
1120
+ map.get(group).push(opt);
1121
+ }
1122
+ return map;
1123
+ }, [results]);
1124
+ const hasValue = !!value && !!selectedLabel;
1125
+ const showDropdown = open && query.length >= minChars;
1126
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: chunkVVVZO2LE_cjs.cn("relative", className), children: [
1127
+ label && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "text-xs font-medium text-muted-foreground", children: [
1128
+ label,
1129
+ required && " *"
1130
+ ] }),
1131
+ /* @__PURE__ */ jsxRuntime.jsxs(
1132
+ "div",
1133
+ {
1134
+ className: chunkVVVZO2LE_cjs.cn(
1135
+ "mt-1 flex items-center gap-2 rounded-lg border bg-background transition-colors",
1136
+ open ? "ring-2 ring-primary/20" : "hover:bg-muted/30",
1137
+ disabled && "opacity-50 cursor-not-allowed"
1138
+ ),
1139
+ children: [
1140
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "h-3.5 w-3.5 text-muted-foreground ml-3 shrink-0" }),
1141
+ open ? /* @__PURE__ */ jsxRuntime.jsx(
1142
+ "input",
1143
+ {
1144
+ ref: inputRef,
1145
+ type: "text",
1146
+ value: query,
1147
+ onChange: (e) => handleQueryChange(e.target.value),
1148
+ placeholder,
1149
+ className: "flex-1 bg-transparent py-2 pr-3 text-sm outline-none",
1150
+ onKeyDown: (e) => {
1151
+ if (e.key === "Escape") setOpen(false);
1152
+ }
1153
+ }
1154
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1155
+ "button",
1156
+ {
1157
+ type: "button",
1158
+ onClick: handleOpen,
1159
+ className: "flex-1 text-left py-2 pr-3 text-sm outline-none",
1160
+ disabled: disabled || creating,
1161
+ children: creating ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
1162
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3 w-3 animate-spin" }),
1163
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: selectedLabel })
1164
+ ] }) : hasValue ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: selectedLabel }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: placeholder })
1165
+ }
1166
+ ),
1167
+ hasValue && !open && /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleClear, className: "pr-3 text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3 w-3" }) }),
1168
+ !hasValue && !open && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 text-muted-foreground mr-3 shrink-0" })
1169
+ ]
1170
+ }
1171
+ ),
1172
+ showDropdown && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fayz-glass-surface absolute top-full left-0 right-0 z-50 mt-1 rounded-lg border bg-popover shadow-lg overflow-hidden", children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 px-4 py-6 text-xs text-muted-foreground", children: [
1173
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
1174
+ " Searching..."
1175
+ ] }) : results.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-4 text-center", children: [
1176
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground", children: [
1177
+ 'No results for "',
1178
+ query,
1179
+ '"'
1180
+ ] }),
1181
+ allowCreate && onCreate && /* @__PURE__ */ jsxRuntime.jsxs(
1182
+ "button",
1183
+ {
1184
+ onClick: () => handleCreate(query),
1185
+ className: "mt-2 text-xs text-primary hover:underline",
1186
+ children: [
1187
+ "+ ",
1188
+ createLabel,
1189
+ ' "',
1190
+ query,
1191
+ '"'
1192
+ ]
1193
+ }
1194
+ )
1195
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-h-64 overflow-auto py-1", children: [
1196
+ [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxRuntime.jsxs(React11__namespace.Fragment, { children: [
1197
+ group && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
1198
+ options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
1199
+ "button",
1200
+ {
1201
+ onClick: () => handleSelect(opt),
1202
+ disabled: opt.disabled,
1203
+ className: chunkVVVZO2LE_cjs.cn(
1204
+ "w-full text-left px-3 py-2 hover:bg-muted/50 transition-colors flex items-center gap-2.5",
1205
+ opt.disabled && "opacity-40 cursor-not-allowed",
1206
+ opt.id === value && "bg-muted/30"
1207
+ ),
1208
+ children: renderOption ? renderOption(opt) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1209
+ opt.icon,
1210
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
1211
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm truncate", children: opt.label }),
1212
+ opt.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[10px] text-muted-foreground truncate", children: opt.subtitle })
1213
+ ] })
1214
+ ] })
1215
+ },
1216
+ opt.id
1217
+ ))
1218
+ ] }, group)),
1219
+ allowCreate && onCreate && /* @__PURE__ */ jsxRuntime.jsxs(
1220
+ "button",
1221
+ {
1222
+ onClick: () => handleCreate(query),
1223
+ className: "w-full text-left px-3 py-2 text-xs text-primary hover:bg-muted/50 transition-colors border-t",
1224
+ children: [
1225
+ "+ ",
1226
+ createLabel,
1227
+ ' "',
1228
+ query,
1229
+ '"'
1230
+ ]
1231
+ }
1232
+ )
1233
+ ] }) })
1234
+ ] });
1235
+ }
1236
+ function CurrencyInput({
1237
+ value,
1238
+ onChange,
1239
+ symbol = "R$",
1240
+ locale = "pt-BR",
1241
+ currencyCode = "BRL",
1242
+ label,
1243
+ placeholder,
1244
+ className,
1245
+ disabled
1246
+ }) {
1247
+ const inputRef = React11__namespace.useRef(null);
1248
+ const [focused, setFocused] = React11__namespace.useState(false);
1249
+ const format = React11__namespace.useCallback((v) => {
1250
+ return new Intl.NumberFormat(locale, {
1251
+ minimumFractionDigits: 2,
1252
+ maximumFractionDigits: 2
1253
+ }).format(v);
1254
+ }, [locale]);
1255
+ const displayValue = format(value);
1256
+ function handleKeyDown(e) {
1257
+ if (disabled) return;
1258
+ if (["Tab", "Escape", "ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
1259
+ e.preventDefault();
1260
+ if (e.key === "Backspace" || e.key === "Delete") {
1261
+ const cents = Math.floor(Math.round(value * 100) / 10);
1262
+ onChange(cents / 100);
1263
+ return;
1264
+ }
1265
+ if (!/^\d$/.test(e.key)) return;
1266
+ const currentCents = Math.round(value * 100);
1267
+ const newCents = currentCents * 10 + parseInt(e.key, 10);
1268
+ if (newCents > 99999999999) return;
1269
+ onChange(newCents / 100);
1270
+ }
1271
+ function handlePaste(e) {
1272
+ e.preventDefault();
1273
+ const text = e.clipboardData.getData("text");
1274
+ const cleaned = text.replace(/[^\d.,]/g, "");
1275
+ const normalized = cleaned.replace(",", ".");
1276
+ const parsed = parseFloat(normalized);
1277
+ if (!isNaN(parsed)) {
1278
+ onChange(Math.round(parsed * 100) / 100);
1279
+ }
1280
+ }
1281
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
1282
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-xs font-medium text-muted-foreground", children: label }),
1283
+ /* @__PURE__ */ jsxRuntime.jsxs(
1284
+ "div",
1285
+ {
1286
+ className: chunkVVVZO2LE_cjs.cn(
1287
+ "flex items-center rounded-lg border border-input bg-background ring-offset-background transition-colors cursor-text",
1288
+ label && "mt-1",
1289
+ focused && "border-ring ring-2 ring-ring ring-offset-2",
1290
+ disabled && "opacity-50 cursor-not-allowed"
1291
+ ),
1292
+ onClick: () => inputRef.current?.focus(),
1293
+ children: [
1294
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pl-3 pr-1 text-sm font-medium text-muted-foreground select-none", children: symbol }),
1295
+ /* @__PURE__ */ jsxRuntime.jsx(
1296
+ "input",
1297
+ {
1298
+ ref: inputRef,
1299
+ type: "text",
1300
+ inputMode: "numeric",
1301
+ value: displayValue,
1302
+ onKeyDown: handleKeyDown,
1303
+ onPaste: handlePaste,
1304
+ onFocus: () => setFocused(true),
1305
+ onBlur: () => setFocused(false),
1306
+ placeholder: placeholder ?? format(0),
1307
+ disabled,
1308
+ readOnly: false,
1309
+ className: "flex-1 bg-transparent px-2 py-2 text-sm outline-none text-right tabular-nums caret-primary selection:bg-primary/20",
1310
+ onChange: () => {
1311
+ }
1312
+ }
1313
+ )
1314
+ ]
1315
+ }
1316
+ )
1317
+ ] });
1318
+ }
1319
+ var VARIANT_CONFIG = {
1320
+ default: {
1321
+ icon: lucideReact.Info,
1322
+ iconBg: "bg-info/10",
1323
+ iconColor: "text-info",
1324
+ buttonVariant: "default"
1325
+ },
1326
+ destructive: {
1327
+ icon: lucideReact.XCircle,
1328
+ iconBg: "bg-destructive/10",
1329
+ iconColor: "text-destructive",
1330
+ buttonVariant: "destructive"
1331
+ },
1332
+ warning: {
1333
+ icon: lucideReact.AlertTriangle,
1334
+ iconBg: "bg-warning/10",
1335
+ iconColor: "text-warning",
1336
+ buttonVariant: "destructive"
1337
+ },
1338
+ success: {
1339
+ icon: lucideReact.CheckCircle2,
1340
+ iconBg: "bg-success/10",
1341
+ iconColor: "text-success",
1342
+ buttonVariant: "default"
1343
+ }
1344
+ };
1345
+ function ConfirmDialog({
1346
+ open,
1347
+ onConfirm,
1348
+ onCancel,
1349
+ title,
1350
+ description,
1351
+ confirmLabel = "Confirm",
1352
+ cancelLabel = "Cancel",
1353
+ variant = "default",
1354
+ loading = false
1355
+ }) {
1356
+ const config = VARIANT_CONFIG[variant];
1357
+ const Icon2 = config.icon;
1358
+ React11__namespace.useEffect(() => {
1359
+ if (!open) return;
1360
+ function handleKey(e) {
1361
+ if (e.key === "Escape") onCancel();
1362
+ }
1363
+ document.addEventListener("keydown", handleKey);
1364
+ return () => document.removeEventListener("keydown", handleKey);
1365
+ }, [open, onCancel]);
1366
+ if (!open) return null;
1367
+ return reactDom.createPortal(
1368
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed inset-0 z-[60] flex items-center justify-center", children: [
1369
+ /* @__PURE__ */ jsxRuntime.jsx(
1370
+ "div",
1371
+ {
1372
+ className: "absolute inset-0 bg-black/50 backdrop-blur-[2px] animate-fade-in",
1373
+ onClick: onCancel
1374
+ }
1375
+ ),
1376
+ /* @__PURE__ */ jsxRuntime.jsx(
1377
+ "div",
1378
+ {
1379
+ className: "relative z-10 w-full max-w-sm mx-4 rounded-modal border border-border bg-card shadow-lg animate-zoom-in",
1380
+ role: "alertdialog",
1381
+ "aria-modal": "true",
1382
+ "aria-labelledby": "confirm-title",
1383
+ "aria-describedby": description ? "confirm-desc" : void 0,
1384
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
1385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4", children: [
1386
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: chunkVVVZO2LE_cjs.cn("flex h-10 w-10 items-center justify-center rounded-full shrink-0", config.iconBg), children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: chunkVVVZO2LE_cjs.cn("h-5 w-5", config.iconColor) }) }),
1387
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 pt-0.5", children: [
1388
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { id: "confirm-title", className: "text-sm font-semibold text-foreground", children: title }),
1389
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "confirm-desc", className: "text-xs text-muted-foreground mt-1 leading-relaxed", children: description })
1390
+ ] })
1391
+ ] }),
1392
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 mt-5", children: [
1393
+ /* @__PURE__ */ jsxRuntime.jsx(chunkD6SXPF4F_cjs.Button, { variant: "outline", size: "sm", onClick: onCancel, disabled: loading, children: cancelLabel }),
1394
+ /* @__PURE__ */ jsxRuntime.jsx(chunkD6SXPF4F_cjs.Button, { variant: config.buttonVariant, size: "sm", onClick: onConfirm, disabled: loading, children: loading ? "Processing..." : confirmLabel })
1395
+ ] })
1396
+ ] })
1397
+ }
1398
+ )
1399
+ ] }),
1400
+ document.body
1401
+ );
1402
+ }
1403
+ var Popover = PopoverPrimitive__namespace.Root;
1404
+ var PopoverTrigger = PopoverPrimitive__namespace.Trigger;
1405
+ var PopoverContent = React11__namespace.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1406
+ PopoverPrimitive__namespace.Content,
1407
+ {
1408
+ ref,
1409
+ align,
1410
+ sideOffset,
1411
+ className: chunkVVVZO2LE_cjs.cn(
1412
+ "fayz-glass-surface z-[110] w-72 rounded-xl border bg-popover p-0 text-popover-foreground shadow-lg outline-none",
1413
+ "data-[state=open]:animate-zoom-in data-[state=closed]:animate-zoom-out",
1414
+ className
1415
+ ),
1416
+ ...props
1417
+ }
1418
+ ) }));
1419
+ PopoverContent.displayName = PopoverPrimitive__namespace.Content.displayName;
1420
+
1421
+ Object.defineProperty(exports, "toast", {
1422
+ enumerable: true,
1423
+ get: function () { return sonner.toast; }
1424
+ });
1425
+ exports.Badge = Badge;
1426
+ exports.Breadcrumb = Breadcrumb;
1427
+ exports.Checkbox = Checkbox;
1428
+ exports.ConfirmDialog = ConfirmDialog;
1429
+ exports.CurrencyInput = CurrencyInput;
1430
+ exports.DatePicker = DatePicker;
1431
+ exports.Input = Input;
1432
+ exports.ListView = ListView;
1433
+ exports.Modal = Modal;
1434
+ exports.ModalBody = ModalBody;
1435
+ exports.ModalClose = ModalClose;
1436
+ exports.ModalContent = ModalContent;
1437
+ exports.ModalDescription = ModalDescription;
1438
+ exports.ModalFooter = ModalFooter;
1439
+ exports.ModalHeader = ModalHeader;
1440
+ exports.ModalOverlay = ModalOverlay;
1441
+ exports.ModalPortal = ModalPortal;
1442
+ exports.ModalTitle = ModalTitle;
1443
+ exports.ModalTrigger = ModalTrigger;
1444
+ exports.Popover = Popover;
1445
+ exports.PopoverContent = PopoverContent;
1446
+ exports.PopoverTrigger = PopoverTrigger;
1447
+ exports.SearchSelect = SearchSelect;
1448
+ exports.Select = Select;
1449
+ exports.SelectContent = SelectContent;
1450
+ exports.SelectGroup = SelectGroup;
1451
+ exports.SelectItem = SelectItem;
1452
+ exports.SelectLabel = SelectLabel;
1453
+ exports.SelectScrollDownButton = SelectScrollDownButton;
1454
+ exports.SelectScrollUpButton = SelectScrollUpButton;
1455
+ exports.SelectSeparator = SelectSeparator;
1456
+ exports.SelectTrigger = SelectTrigger;
1457
+ exports.SelectValue = SelectValue;
1458
+ exports.Separator = Separator2;
1459
+ exports.Sheet = Sheet;
1460
+ exports.SheetBody = SheetBody;
1461
+ exports.SheetClose = SheetClose;
1462
+ exports.SheetContent = SheetContent;
1463
+ exports.SheetDescription = SheetDescription;
1464
+ exports.SheetFooter = SheetFooter;
1465
+ exports.SheetHeader = SheetHeader;
1466
+ exports.SheetOverlay = SheetOverlay;
1467
+ exports.SheetPortal = SheetPortal;
1468
+ exports.SheetTitle = SheetTitle;
1469
+ exports.SheetTrigger = SheetTrigger;
1470
+ exports.Skeleton = Skeleton;
1471
+ exports.TableSkeleton = TableSkeleton;
1472
+ exports.Tabs = Tabs;
1473
+ exports.TabsContent = TabsContent;
1474
+ exports.TabsList = TabsList;
1475
+ exports.TabsTrigger = TabsTrigger;
1476
+ exports.TimePicker = TimePicker;
1477
+ exports.ToastProvider = ToastProvider;
1478
+ exports.Tooltip = Tooltip;
1479
+ exports.TooltipContent = TooltipContent;
1480
+ exports.TooltipProvider = TooltipProvider;
1481
+ exports.TooltipTrigger = TooltipTrigger;
1482
+ exports.badgeVariants = badgeVariants;
1483
+ //# sourceMappingURL=chunk-YB5ZJKNG.cjs.map
1484
+ //# sourceMappingURL=chunk-YB5ZJKNG.cjs.map