analytica-frontend-lib 1.1.21 → 1.1.23

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.
@@ -0,0 +1,786 @@
1
+ // src/components/NotificationCard/NotificationCard.tsx
2
+ import { DotsThreeVertical } from "phosphor-react";
3
+
4
+ // src/utils/utils.ts
5
+ import { clsx } from "clsx";
6
+ import { twMerge } from "tailwind-merge";
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+
11
+ // src/assets/img/no-notification-result.png
12
+ var no_notification_result_default = "../no-notification-result-7Y3ACV6V.png";
13
+
14
+ // src/components/DropdownMenu/DropdownMenu.tsx
15
+ import { SignOut, User } from "phosphor-react";
16
+ import {
17
+ forwardRef,
18
+ useEffect,
19
+ useRef,
20
+ isValidElement,
21
+ Children,
22
+ cloneElement,
23
+ useState
24
+ } from "react";
25
+ import { create, useStore } from "zustand";
26
+
27
+ // src/components/Button/Button.tsx
28
+ import { jsx, jsxs } from "react/jsx-runtime";
29
+ var VARIANT_ACTION_CLASSES = {
30
+ solid: {
31
+ primary: "bg-primary-950 text-text border border-primary-950 hover:bg-primary-800 hover:border-primary-800 focus-visible:outline-none focus-visible:bg-primary-950 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-primary-700 active:border-primary-700 disabled:bg-primary-500 disabled:border-primary-500 disabled:opacity-40 disabled:cursor-not-allowed",
32
+ positive: "bg-success-500 text-text border border-success-500 hover:bg-success-600 hover:border-success-600 focus-visible:outline-none focus-visible:bg-success-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-success-700 active:border-success-700 disabled:bg-success-500 disabled:border-success-500 disabled:opacity-40 disabled:cursor-not-allowed",
33
+ negative: "bg-error-500 text-text border border-error-500 hover:bg-error-600 hover:border-error-600 focus-visible:outline-none focus-visible:bg-error-500 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:bg-error-700 active:border-error-700 disabled:bg-error-500 disabled:border-error-500 disabled:opacity-40 disabled:cursor-not-allowed"
34
+ },
35
+ outline: {
36
+ primary: "bg-transparent text-primary-950 border border-primary-950 hover:bg-background-50 hover:text-primary-400 hover:border-primary-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 active:border-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
37
+ positive: "bg-transparent text-success-500 border border-success-300 hover:bg-background-50 hover:text-success-400 hover:border-success-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 active:border-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
38
+ negative: "bg-transparent text-error-500 border border-error-300 hover:bg-background-50 hover:text-error-400 hover:border-error-400 focus-visible:border-0 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 active:border-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
39
+ },
40
+ link: {
41
+ primary: "bg-transparent text-primary-950 hover:text-primary-400 focus-visible:outline-none focus-visible:text-primary-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-primary-700 disabled:opacity-40 disabled:cursor-not-allowed",
42
+ positive: "bg-transparent text-success-500 hover:text-success-400 focus-visible:outline-none focus-visible:text-success-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-success-700 disabled:opacity-40 disabled:cursor-not-allowed",
43
+ negative: "bg-transparent text-error-500 hover:text-error-400 focus-visible:outline-none focus-visible:text-error-600 focus-visible:ring-2 focus-visible:ring-offset-0 focus-visible:ring-indicator-info active:text-error-700 disabled:opacity-40 disabled:cursor-not-allowed"
44
+ }
45
+ };
46
+ var SIZE_CLASSES = {
47
+ "extra-small": "text-xs px-3.5 py-2",
48
+ small: "text-sm px-4 py-2.5",
49
+ medium: "text-md px-5 py-2.5",
50
+ large: "text-lg px-6 py-3",
51
+ "extra-large": "text-lg px-7 py-3.5"
52
+ };
53
+ var Button = ({
54
+ children,
55
+ iconLeft,
56
+ iconRight,
57
+ size = "medium",
58
+ variant = "solid",
59
+ action = "primary",
60
+ className = "",
61
+ disabled,
62
+ type = "button",
63
+ ...props
64
+ }) => {
65
+ const sizeClasses = SIZE_CLASSES[size];
66
+ const variantClasses = VARIANT_ACTION_CLASSES[variant][action];
67
+ const baseClasses = "inline-flex items-center justify-center rounded-full cursor-pointer font-medium";
68
+ return /* @__PURE__ */ jsxs(
69
+ "button",
70
+ {
71
+ className: cn(baseClasses, variantClasses, sizeClasses, className),
72
+ disabled,
73
+ type,
74
+ ...props,
75
+ children: [
76
+ iconLeft && /* @__PURE__ */ jsx("span", { className: "mr-2 flex items-center", children: iconLeft }),
77
+ children,
78
+ iconRight && /* @__PURE__ */ jsx("span", { className: "ml-2 flex items-center", children: iconRight })
79
+ ]
80
+ }
81
+ );
82
+ };
83
+ var Button_default = Button;
84
+
85
+ // src/components/DropdownMenu/DropdownMenu.tsx
86
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
87
+ function createDropdownStore() {
88
+ return create((set) => ({
89
+ open: false,
90
+ setOpen: (open) => set({ open })
91
+ }));
92
+ }
93
+ var useDropdownStore = (externalStore) => {
94
+ if (!externalStore) {
95
+ throw new Error(
96
+ "Component must be used within a DropdownMenu (store is missing)"
97
+ );
98
+ }
99
+ return externalStore;
100
+ };
101
+ var injectStore = (children, store) => {
102
+ return Children.map(children, (child) => {
103
+ if (isValidElement(child)) {
104
+ const typedChild = child;
105
+ const newProps = {
106
+ store
107
+ };
108
+ if (typedChild.props.children) {
109
+ newProps.children = injectStore(typedChild.props.children, store);
110
+ }
111
+ return cloneElement(typedChild, newProps);
112
+ }
113
+ return child;
114
+ });
115
+ };
116
+ var DropdownMenu = ({
117
+ children,
118
+ open: propOpen,
119
+ onOpenChange
120
+ }) => {
121
+ const storeRef = useRef(null);
122
+ storeRef.current ??= createDropdownStore();
123
+ const store = storeRef.current;
124
+ const { open, setOpen: storeSetOpen } = useStore(store, (s) => s);
125
+ const setOpen = (newOpen) => {
126
+ storeSetOpen(newOpen);
127
+ };
128
+ const menuRef = useRef(null);
129
+ const handleArrowDownOrArrowUp = (event) => {
130
+ const menuContent = menuRef.current?.querySelector('[role="menu"]');
131
+ if (menuContent) {
132
+ event.preventDefault();
133
+ const items = Array.from(
134
+ menuContent.querySelectorAll(
135
+ '[role="menuitem"]:not([aria-disabled="true"])'
136
+ )
137
+ ).filter((el) => el instanceof HTMLElement);
138
+ if (items.length === 0) return;
139
+ const focusedItem = document.activeElement;
140
+ const currentIndex = items.findIndex((item) => item === focusedItem);
141
+ let nextIndex;
142
+ if (event.key === "ArrowDown") {
143
+ nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;
144
+ } else {
145
+ nextIndex = currentIndex === -1 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;
146
+ }
147
+ items[nextIndex]?.focus();
148
+ }
149
+ };
150
+ const handleDownkey = (event) => {
151
+ if (event.key === "Escape") {
152
+ setOpen(false);
153
+ } else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
154
+ handleArrowDownOrArrowUp(event);
155
+ }
156
+ };
157
+ const handleClickOutside = (event) => {
158
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
159
+ setOpen(false);
160
+ }
161
+ };
162
+ useEffect(() => {
163
+ if (open) {
164
+ document.addEventListener("mousedown", handleClickOutside);
165
+ document.addEventListener("keydown", handleDownkey);
166
+ }
167
+ return () => {
168
+ document.removeEventListener("mousedown", handleClickOutside);
169
+ document.removeEventListener("keydown", handleDownkey);
170
+ };
171
+ }, [open]);
172
+ useEffect(() => {
173
+ setOpen(open);
174
+ onOpenChange?.(open);
175
+ }, [open, onOpenChange]);
176
+ useEffect(() => {
177
+ if (propOpen) {
178
+ setOpen(propOpen);
179
+ }
180
+ }, [propOpen]);
181
+ return /* @__PURE__ */ jsx2("div", { className: "relative", ref: menuRef, children: injectStore(children, store) });
182
+ };
183
+ var DropdownMenuTrigger = ({
184
+ className,
185
+ children,
186
+ onClick,
187
+ store: externalStore,
188
+ ...props
189
+ }) => {
190
+ const store = useDropdownStore(externalStore);
191
+ const open = useStore(store, (s) => s.open);
192
+ const toggleOpen = () => store.setState({ open: !open });
193
+ return /* @__PURE__ */ jsx2(
194
+ "button",
195
+ {
196
+ onClick: (e) => {
197
+ e.stopPropagation();
198
+ toggleOpen();
199
+ if (onClick) onClick(e);
200
+ },
201
+ "aria-expanded": open,
202
+ className: cn(className),
203
+ ...props,
204
+ children
205
+ }
206
+ );
207
+ };
208
+ DropdownMenuTrigger.displayName = "DropdownMenuTrigger";
209
+ var ITEM_SIZE_CLASSES = {
210
+ small: "text-sm",
211
+ medium: "text-md"
212
+ };
213
+ var SIDE_CLASSES = {
214
+ top: "bottom-full",
215
+ right: "top-full",
216
+ bottom: "top-full",
217
+ left: "top-full"
218
+ };
219
+ var ALIGN_CLASSES = {
220
+ start: "left-0",
221
+ center: "left-1/2 -translate-x-1/2",
222
+ end: "right-0"
223
+ };
224
+ var MENUCONTENT_VARIANT_CLASSES = {
225
+ menu: "p-1",
226
+ profile: "p-6"
227
+ };
228
+ var MenuLabel = forwardRef(({ className, inset, store: _store, ...props }, ref) => {
229
+ return /* @__PURE__ */ jsx2(
230
+ "div",
231
+ {
232
+ ref,
233
+ className: cn("text-sm w-full", inset ? "pl-8" : "", className),
234
+ ...props
235
+ }
236
+ );
237
+ });
238
+ MenuLabel.displayName = "MenuLabel";
239
+ var DropdownMenuContent = forwardRef(
240
+ ({
241
+ className,
242
+ align = "start",
243
+ side = "bottom",
244
+ variant = "menu",
245
+ sideOffset = 4,
246
+ children,
247
+ store: externalStore,
248
+ ...props
249
+ }, ref) => {
250
+ const store = useDropdownStore(externalStore);
251
+ const open = useStore(store, (s) => s.open);
252
+ const [isVisible, setIsVisible] = useState(open);
253
+ useEffect(() => {
254
+ if (open) {
255
+ setIsVisible(true);
256
+ } else {
257
+ const timer = setTimeout(() => setIsVisible(false), 200);
258
+ return () => clearTimeout(timer);
259
+ }
260
+ }, [open]);
261
+ if (!isVisible) return null;
262
+ const getPositionClasses = () => {
263
+ const vertical = SIDE_CLASSES[side];
264
+ const horizontal = ALIGN_CLASSES[align];
265
+ return `absolute ${vertical} ${horizontal}`;
266
+ };
267
+ const variantClasses = MENUCONTENT_VARIANT_CLASSES[variant];
268
+ return /* @__PURE__ */ jsx2(
269
+ "div",
270
+ {
271
+ ref,
272
+ role: "menu",
273
+ className: `
274
+ bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md border-border-100
275
+ ${open ? "animate-in fade-in-0 zoom-in-95" : "animate-out fade-out-0 zoom-out-95"}
276
+ ${getPositionClasses()}
277
+ ${variantClasses}
278
+ ${className}
279
+ `,
280
+ style: {
281
+ marginTop: side === "bottom" ? sideOffset : void 0,
282
+ marginBottom: side === "top" ? sideOffset : void 0,
283
+ marginLeft: side === "right" ? sideOffset : void 0,
284
+ marginRight: side === "left" ? sideOffset : void 0
285
+ },
286
+ ...props,
287
+ children
288
+ }
289
+ );
290
+ }
291
+ );
292
+ DropdownMenuContent.displayName = "DropdownMenuContent";
293
+ var DropdownMenuItem = forwardRef(
294
+ ({
295
+ className,
296
+ size = "small",
297
+ children,
298
+ iconRight,
299
+ iconLeft,
300
+ disabled = false,
301
+ onClick,
302
+ variant = "menu",
303
+ store: externalStore,
304
+ ...props
305
+ }, ref) => {
306
+ const store = useDropdownStore(externalStore);
307
+ const setOpen = useStore(store, (s) => s.setOpen);
308
+ const sizeClasses = ITEM_SIZE_CLASSES[size];
309
+ const handleClick = (e) => {
310
+ if (disabled) {
311
+ e.preventDefault();
312
+ e.stopPropagation();
313
+ return;
314
+ }
315
+ onClick?.(e);
316
+ setOpen(false);
317
+ };
318
+ const getVariantClasses = () => {
319
+ if (variant === "profile") {
320
+ return "relative flex flex-row justify-between select-none items-center gap-2 rounded-sm p-4 text-sm outline-none transition-colors [&>svg]:size-6 [&>svg]:shrink-0";
321
+ }
322
+ return "relative flex select-none items-center gap-2 rounded-sm p-3 text-sm outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0";
323
+ };
324
+ const getVariantProps = () => {
325
+ return variant === "profile" ? { "data-variant": "profile" } : {};
326
+ };
327
+ return /* @__PURE__ */ jsxs2(
328
+ "div",
329
+ {
330
+ ref,
331
+ role: "menuitem",
332
+ ...getVariantProps(),
333
+ "aria-disabled": disabled,
334
+ className: `
335
+ focus-visible:bg-background-50
336
+ ${getVariantClasses()}
337
+ ${sizeClasses}
338
+ ${className}
339
+ ${disabled ? "cursor-not-allowed text-text-400" : "cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground"}
340
+ `,
341
+ onClick: handleClick,
342
+ onKeyDown: (e) => {
343
+ if (e.key === "Enter" || e.key === " ") handleClick(e);
344
+ },
345
+ tabIndex: disabled ? -1 : 0,
346
+ ...props,
347
+ children: [
348
+ iconLeft,
349
+ /* @__PURE__ */ jsx2("span", { className: "w-full text-md", children }),
350
+ iconRight
351
+ ]
352
+ }
353
+ );
354
+ }
355
+ );
356
+ DropdownMenuItem.displayName = "DropdownMenuItem";
357
+ var DropdownMenuSeparator = forwardRef(({ className, store: _store, ...props }, ref) => /* @__PURE__ */ jsx2(
358
+ "div",
359
+ {
360
+ ref,
361
+ className: cn("my-1 h-px bg-border-200", className),
362
+ ...props
363
+ }
364
+ ));
365
+ DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
366
+ var ProfileMenuTrigger = forwardRef(({ className, onClick, store: externalStore, ...props }, ref) => {
367
+ const store = useDropdownStore(externalStore);
368
+ const open = useStore(store, (s) => s.open);
369
+ const toggleOpen = () => store.setState({ open: !open });
370
+ return /* @__PURE__ */ jsx2(
371
+ "button",
372
+ {
373
+ ref,
374
+ className: cn(
375
+ "rounded-lg size-10 bg-primary-50 flex items-center justify-center cursor-pointer",
376
+ className
377
+ ),
378
+ onClick: (e) => {
379
+ e.stopPropagation();
380
+ toggleOpen();
381
+ onClick?.(e);
382
+ },
383
+ "aria-expanded": open,
384
+ ...props,
385
+ children: /* @__PURE__ */ jsx2("span", { className: "size-6 rounded-full bg-primary-100 flex items-center justify-center", children: /* @__PURE__ */ jsx2(User, { className: "text-primary-950", size: 18 }) })
386
+ }
387
+ );
388
+ });
389
+ ProfileMenuTrigger.displayName = "ProfileMenuTrigger";
390
+ var ProfileMenuHeader = forwardRef(({ className, name, email, store: _store, ...props }, ref) => {
391
+ return /* @__PURE__ */ jsxs2(
392
+ "div",
393
+ {
394
+ ref,
395
+ "data-component": "ProfileMenuHeader",
396
+ className: cn("flex flex-row gap-4 items-center", className),
397
+ ...props,
398
+ children: [
399
+ /* @__PURE__ */ jsx2("span", { className: "size-16 bg-primary-100 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx2(User, { size: 34, className: "text-primary-950" }) }),
400
+ /* @__PURE__ */ jsxs2("div", { className: "flex flex-col ", children: [
401
+ /* @__PURE__ */ jsx2("p", { className: "text-xl font-bold text-text-950", children: name }),
402
+ /* @__PURE__ */ jsx2("p", { className: "text-md text-text-600", children: email })
403
+ ] })
404
+ ]
405
+ }
406
+ );
407
+ });
408
+ ProfileMenuHeader.displayName = "ProfileMenuHeader";
409
+ var ProfileMenuSection = forwardRef(({ className, children, store: _store, ...props }, ref) => {
410
+ return /* @__PURE__ */ jsx2("div", { ref, className: cn("flex flex-col p-2", className), ...props, children });
411
+ });
412
+ ProfileMenuSection.displayName = "ProfileMenuSection";
413
+ var ProfileMenuFooter = ({
414
+ className,
415
+ disabled = false,
416
+ onClick,
417
+ store: externalStore,
418
+ ...props
419
+ }) => {
420
+ const store = useDropdownStore(externalStore);
421
+ const setOpen = useStore(store, (s) => s.setOpen);
422
+ return /* @__PURE__ */ jsxs2(
423
+ Button_default,
424
+ {
425
+ variant: "outline",
426
+ className: cn("w-full", className),
427
+ disabled,
428
+ onClick: (e) => {
429
+ setOpen(false);
430
+ onClick?.(e);
431
+ },
432
+ ...props,
433
+ children: [
434
+ /* @__PURE__ */ jsx2("span", { className: "mr-2 flex items-center", children: /* @__PURE__ */ jsx2(SignOut, {}) }),
435
+ /* @__PURE__ */ jsx2("span", { children: "Sair" })
436
+ ]
437
+ }
438
+ );
439
+ };
440
+ ProfileMenuFooter.displayName = "ProfileMenuFooter";
441
+ var DropdownMenu_default = DropdownMenu;
442
+
443
+ // src/components/Skeleton/Skeleton.tsx
444
+ import { forwardRef as forwardRef2 } from "react";
445
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
446
+ var SKELETON_ANIMATION_CLASSES = {
447
+ pulse: "animate-pulse",
448
+ none: ""
449
+ };
450
+ var SKELETON_VARIANT_CLASSES = {
451
+ text: "h-4 bg-background-200 rounded",
452
+ circular: "bg-background-200 rounded-full",
453
+ rectangular: "bg-background-200",
454
+ rounded: "bg-background-200 rounded-lg"
455
+ };
456
+ var SPACING_CLASSES = {
457
+ none: "",
458
+ small: "space-y-1",
459
+ medium: "space-y-2",
460
+ large: "space-y-3"
461
+ };
462
+ var Skeleton = forwardRef2(
463
+ ({
464
+ variant = "text",
465
+ width,
466
+ height,
467
+ animation = "pulse",
468
+ lines = 1,
469
+ spacing = "none",
470
+ className = "",
471
+ children,
472
+ ...props
473
+ }, ref) => {
474
+ const animationClass = SKELETON_ANIMATION_CLASSES[animation];
475
+ const variantClass = SKELETON_VARIANT_CLASSES[variant];
476
+ const spacingClass = SPACING_CLASSES[spacing];
477
+ const style = {
478
+ width: typeof width === "number" ? `${width}px` : width,
479
+ height: typeof height === "number" ? `${height}px` : height
480
+ };
481
+ if (variant === "text" && lines > 1) {
482
+ return /* @__PURE__ */ jsx3(
483
+ "div",
484
+ {
485
+ ref,
486
+ className: cn("flex flex-col", spacingClass, className),
487
+ ...props,
488
+ children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx3(
489
+ "div",
490
+ {
491
+ className: cn(variantClass, animationClass),
492
+ style: index === lines - 1 ? { width: "60%" } : void 0
493
+ },
494
+ index
495
+ ))
496
+ }
497
+ );
498
+ }
499
+ return /* @__PURE__ */ jsx3(
500
+ "div",
501
+ {
502
+ ref,
503
+ className: cn(variantClass, animationClass, className),
504
+ style,
505
+ ...props,
506
+ children
507
+ }
508
+ );
509
+ }
510
+ );
511
+ var SkeletonText = forwardRef2(
512
+ (props, ref) => /* @__PURE__ */ jsx3(Skeleton, { ref, variant: "text", ...props })
513
+ );
514
+ var SkeletonCircle = forwardRef2((props, ref) => /* @__PURE__ */ jsx3(Skeleton, { ref, variant: "circular", ...props }));
515
+ var SkeletonRectangle = forwardRef2((props, ref) => /* @__PURE__ */ jsx3(Skeleton, { ref, variant: "rectangular", ...props }));
516
+ var SkeletonRounded = forwardRef2((props, ref) => /* @__PURE__ */ jsx3(Skeleton, { ref, variant: "rounded", ...props }));
517
+ var SkeletonCard = forwardRef2(
518
+ ({
519
+ showAvatar = true,
520
+ showTitle = true,
521
+ showDescription = true,
522
+ showActions = true,
523
+ lines = 2,
524
+ className = "",
525
+ ...props
526
+ }, ref) => {
527
+ return /* @__PURE__ */ jsxs3(
528
+ "div",
529
+ {
530
+ ref,
531
+ className: cn(
532
+ "w-full p-4 bg-background border border-border-200 rounded-lg",
533
+ className
534
+ ),
535
+ ...props,
536
+ children: [
537
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-start space-x-3", children: [
538
+ showAvatar && /* @__PURE__ */ jsx3(SkeletonCircle, { width: 40, height: 40 }),
539
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
540
+ showTitle && /* @__PURE__ */ jsx3(SkeletonText, { width: "60%", height: 20 }),
541
+ showDescription && /* @__PURE__ */ jsx3(SkeletonText, { lines, spacing: "small" })
542
+ ] })
543
+ ] }),
544
+ showActions && /* @__PURE__ */ jsxs3("div", { className: "flex justify-end space-x-2 mt-4", children: [
545
+ /* @__PURE__ */ jsx3(SkeletonRectangle, { width: 80, height: 32 }),
546
+ /* @__PURE__ */ jsx3(SkeletonRectangle, { width: 80, height: 32 })
547
+ ] })
548
+ ]
549
+ }
550
+ );
551
+ }
552
+ );
553
+ var SkeletonList = forwardRef2(
554
+ ({
555
+ items = 3,
556
+ showAvatar = true,
557
+ showTitle = true,
558
+ showDescription = true,
559
+ lines = 1,
560
+ className = "",
561
+ ...props
562
+ }, ref) => {
563
+ return /* @__PURE__ */ jsx3("div", { ref, className: cn("space-y-3", className), ...props, children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs3("div", { className: "flex items-start space-x-3 p-3", children: [
564
+ showAvatar && /* @__PURE__ */ jsx3(SkeletonCircle, { width: 32, height: 32 }),
565
+ /* @__PURE__ */ jsxs3("div", { className: "flex-1 space-y-2", children: [
566
+ showTitle && /* @__PURE__ */ jsx3(SkeletonText, { width: "40%", height: 16 }),
567
+ showDescription && /* @__PURE__ */ jsx3(SkeletonText, { lines, spacing: "small" })
568
+ ] })
569
+ ] }, index)) });
570
+ }
571
+ );
572
+ var SkeletonTable = forwardRef2(
573
+ ({ rows = 5, columns = 4, showHeader = true, className = "", ...props }, ref) => {
574
+ return /* @__PURE__ */ jsxs3("div", { ref, className: cn("w-full", className), ...props, children: [
575
+ showHeader && /* @__PURE__ */ jsx3("div", { className: "flex space-x-2 mb-3", children: Array.from({ length: columns }, (_, index) => /* @__PURE__ */ jsx3(
576
+ SkeletonText,
577
+ {
578
+ width: `${100 / columns}%`,
579
+ height: 20
580
+ },
581
+ index
582
+ )) }),
583
+ /* @__PURE__ */ jsx3("div", { className: "space-y-2", children: Array.from({ length: rows }, (_, rowIndex) => /* @__PURE__ */ jsx3("div", { className: "flex space-x-2", children: Array.from({ length: columns }, (_2, colIndex) => /* @__PURE__ */ jsx3(
584
+ SkeletonText,
585
+ {
586
+ width: `${100 / columns}%`,
587
+ height: 16
588
+ },
589
+ colIndex
590
+ )) }, rowIndex)) })
591
+ ] });
592
+ }
593
+ );
594
+
595
+ // src/components/NotificationCard/NotificationCard.tsx
596
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
597
+ var SingleNotificationCard = ({
598
+ title,
599
+ message,
600
+ time,
601
+ isRead,
602
+ onMarkAsRead,
603
+ onDelete,
604
+ onNavigate,
605
+ actionLabel,
606
+ className
607
+ }) => {
608
+ const handleMarkAsRead = (e) => {
609
+ e.preventDefault();
610
+ e.stopPropagation();
611
+ if (!isRead) {
612
+ onMarkAsRead();
613
+ }
614
+ };
615
+ const handleDelete = (e) => {
616
+ e.preventDefault();
617
+ e.stopPropagation();
618
+ onDelete();
619
+ };
620
+ const handleNavigate = (e) => {
621
+ e.stopPropagation();
622
+ if (onNavigate) {
623
+ onNavigate();
624
+ }
625
+ };
626
+ return /* @__PURE__ */ jsxs4(
627
+ "div",
628
+ {
629
+ className: cn(
630
+ "flex flex-col justify-center items-start p-4 gap-2 w-full bg-background border-b border-border-200",
631
+ "last:border-b-0",
632
+ className
633
+ ),
634
+ children: [
635
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 w-full", children: [
636
+ !isRead && /* @__PURE__ */ jsx4("div", { className: "w-[7px] h-[7px] bg-info-300 rounded-full flex-shrink-0" }),
637
+ /* @__PURE__ */ jsx4("h3", { className: "font-bold text-sm leading-4 text-text-950 flex-grow", children: title }),
638
+ /* @__PURE__ */ jsxs4(DropdownMenu_default, { children: [
639
+ /* @__PURE__ */ jsx4(
640
+ DropdownMenuTrigger,
641
+ {
642
+ className: "flex-shrink-0 inline-flex items-center justify-center font-medium bg-transparent text-text-950 cursor-pointer hover:bg-info-50 w-6 h-6 rounded-lg",
643
+ "aria-label": "Menu de a\xE7\xF5es",
644
+ children: /* @__PURE__ */ jsx4(DotsThreeVertical, { size: 24 })
645
+ }
646
+ ),
647
+ /* @__PURE__ */ jsxs4(DropdownMenuContent, { align: "end", className: "min-w-[160px]", children: [
648
+ !isRead && /* @__PURE__ */ jsx4(
649
+ DropdownMenuItem,
650
+ {
651
+ onClick: handleMarkAsRead,
652
+ className: "text-text-950",
653
+ children: "Marcar como lida"
654
+ }
655
+ ),
656
+ /* @__PURE__ */ jsx4(DropdownMenuItem, { onClick: handleDelete, className: "text-error-600", children: "Deletar" })
657
+ ] })
658
+ ] })
659
+ ] }),
660
+ /* @__PURE__ */ jsx4("p", { className: "text-sm leading-[21px] text-text-800 w-full", children: message }),
661
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between w-full", children: [
662
+ /* @__PURE__ */ jsx4("span", { className: "text-sm font-medium text-text-400", children: time }),
663
+ onNavigate && actionLabel && /* @__PURE__ */ jsx4(
664
+ "button",
665
+ {
666
+ type: "button",
667
+ onClick: handleNavigate,
668
+ className: "text-sm font-medium text-info-600 hover:text-info-700 cursor-pointer",
669
+ children: actionLabel
670
+ }
671
+ )
672
+ ] })
673
+ ]
674
+ }
675
+ );
676
+ };
677
+ var NotificationEmpty = () => {
678
+ return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center justify-center gap-4 p-6 w-full", children: [
679
+ /* @__PURE__ */ jsx4("div", { className: "w-20 h-20 flex items-center justify-center", children: /* @__PURE__ */ jsx4(
680
+ "img",
681
+ {
682
+ src: no_notification_result_default,
683
+ alt: "Sem notifica\xE7\xF5es",
684
+ width: 82,
685
+ height: 82,
686
+ className: "object-contain"
687
+ }
688
+ ) }),
689
+ /* @__PURE__ */ jsx4("h3", { className: "text-xl font-semibold text-text-950 text-center leading-[23px]", children: "Nenhuma notifica\xE7\xE3o no momento" }),
690
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-normal text-text-400 text-center max-w-[316px] leading-[21px]", children: "Voc\xEA est\xE1 em dia com todas as novidades. Volte depois para conferir atualiza\xE7\xF5es!" })
691
+ ] });
692
+ };
693
+ var NotificationList = ({
694
+ groupedNotifications = [],
695
+ loading = false,
696
+ error = null,
697
+ onRetry,
698
+ onMarkAsReadById,
699
+ onDeleteById,
700
+ onNavigateById,
701
+ getActionLabel,
702
+ renderEmpty,
703
+ className
704
+ }) => {
705
+ if (error) {
706
+ return /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: [
707
+ /* @__PURE__ */ jsx4("p", { className: "text-sm text-error-600", children: error }),
708
+ onRetry && /* @__PURE__ */ jsx4(
709
+ "button",
710
+ {
711
+ type: "button",
712
+ onClick: onRetry,
713
+ className: "text-sm text-info-600 hover:text-info-700",
714
+ children: "Tentar novamente"
715
+ }
716
+ )
717
+ ] });
718
+ }
719
+ if (loading) {
720
+ return /* @__PURE__ */ jsx4("div", { className: "flex flex-col gap-0 w-full", children: ["skeleton-first", "skeleton-second", "skeleton-third"].map(
721
+ (skeletonId) => /* @__PURE__ */ jsx4(
722
+ SkeletonCard,
723
+ {
724
+ className: "p-4 border-b border-border-200"
725
+ },
726
+ skeletonId
727
+ )
728
+ ) });
729
+ }
730
+ if (!groupedNotifications || groupedNotifications.length === 0) {
731
+ return renderEmpty ? /* @__PURE__ */ jsx4("div", { className: "w-full", children: renderEmpty() }) : /* @__PURE__ */ jsx4(NotificationEmpty, {});
732
+ }
733
+ return /* @__PURE__ */ jsx4("div", { className: cn("flex flex-col gap-0 w-full", className), children: groupedNotifications.map((group, idx) => /* @__PURE__ */ jsxs4("div", { className: "flex flex-col", children: [
734
+ /* @__PURE__ */ jsx4("div", { className: "flex items-end px-4 py-6 pb-4", children: /* @__PURE__ */ jsx4("h4", { className: "text-lg font-bold text-text-500 flex-grow", children: group.label }) }),
735
+ group.notifications.map((notification) => /* @__PURE__ */ jsx4(
736
+ SingleNotificationCard,
737
+ {
738
+ title: notification.title,
739
+ message: notification.message,
740
+ time: notification.time,
741
+ isRead: notification.isRead,
742
+ onMarkAsRead: () => onMarkAsReadById?.(notification.id),
743
+ onDelete: () => onDeleteById?.(notification.id),
744
+ onNavigate: notification.entityType && notification.entityId && onNavigateById ? () => onNavigateById(
745
+ notification.entityType,
746
+ notification.entityId
747
+ ) : void 0,
748
+ actionLabel: getActionLabel?.(notification.entityType)
749
+ },
750
+ notification.id
751
+ ))
752
+ ] }, `${group.label}-${idx}`)) });
753
+ };
754
+ var NotificationCard = (props) => {
755
+ if (props.groupedNotifications !== void 0 || props.notifications !== void 0 || props.loading || props.error) {
756
+ return /* @__PURE__ */ jsx4(
757
+ NotificationList,
758
+ {
759
+ ...props,
760
+ groupedNotifications: props.groupedNotifications ?? (props.notifications ? [{ label: "Notifica\xE7\xF5es", notifications: props.notifications }] : [])
761
+ }
762
+ );
763
+ }
764
+ if (props.title !== void 0 && props.message !== void 0 && props.time !== void 0 && props.isRead !== void 0 && props.onMarkAsRead && props.onDelete) {
765
+ return /* @__PURE__ */ jsx4(
766
+ SingleNotificationCard,
767
+ {
768
+ title: props.title,
769
+ message: props.message,
770
+ time: props.time,
771
+ isRead: props.isRead,
772
+ onMarkAsRead: props.onMarkAsRead,
773
+ onDelete: props.onDelete,
774
+ onNavigate: props.onNavigate,
775
+ actionLabel: props.actionLabel,
776
+ className: props.className
777
+ }
778
+ );
779
+ }
780
+ return /* @__PURE__ */ jsx4("div", { className: "flex flex-col items-center gap-4 p-6 w-full", children: /* @__PURE__ */ jsx4("p", { className: "text-sm text-text-600", children: "Nenhuma notifica\xE7\xE3o configurada" }) });
781
+ };
782
+ var NotificationCard_default = NotificationCard;
783
+ export {
784
+ NotificationCard_default as default
785
+ };
786
+ //# sourceMappingURL=index.mjs.map