@greatapps/common 1.1.1 → 1.1.3

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,23 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { cn } from "../../infra/utils/clsx";
4
+ function NavBarItem({ icon, label, onClick, className, labelClassName }) {
5
+ return /* @__PURE__ */ jsxs(
6
+ "div",
7
+ {
8
+ className: cn(
9
+ "rounded-lg flex items-center gap-2 px-2 py-2 h-10 cursor-pointer transition-colors bg-white hover:bg-gray-100 active:bg-gray-50",
10
+ className
11
+ ),
12
+ onClick,
13
+ children: [
14
+ icon,
15
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium text-gray-950", labelClassName), children: label })
16
+ ]
17
+ }
18
+ );
19
+ }
20
+ export {
21
+ NavBarItem
22
+ };
23
+ //# sourceMappingURL=NavBarItem.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/layouts/NavBarItem.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { cn } from '../../infra/utils/clsx';\r\n\r\ntype NavBarItemProps = {\r\n icon?: React.ReactNode;\r\n label: string;\r\n onClick: () => void;\r\n className?: string;\r\n labelClassName?: string;\r\n}\r\n\r\nfunction NavBarItem({ icon, label, onClick, className, labelClassName }: NavBarItemProps) {\r\n return (\r\n <div\r\n className={cn(\r\n 'rounded-lg flex items-center gap-2 px-2 py-2 h-10 cursor-pointer transition-colors bg-white hover:bg-gray-100 active:bg-gray-50',\r\n className\r\n )}\r\n onClick={onClick}\r\n >\r\n {icon}\r\n <span className={cn('text-sm font-medium text-gray-950', labelClassName)}>{label}</span>\r\n </div>\r\n );\r\n}\r\n\r\nexport { NavBarItem };\r\nexport type { NavBarItemProps };\r\n"],"mappings":";AAcI,SAQE,KARF;AAZJ,SAAS,UAAU;AAUnB,SAAS,WAAW,EAAE,MAAM,OAAO,SAAS,WAAW,eAAe,GAAoB;AACxF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,QACD,oBAAC,UAAK,WAAW,GAAG,qCAAqC,cAAc,GAAI,iBAAM;AAAA;AAAA;AAAA,EACnF;AAEJ;","names":[]}
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { Bell } from "lucide-react";
5
+ import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
6
+ import { Button } from "../ui/buttons/Button";
7
+ import { NotificationItem } from "./NotificationItem";
8
+ import { cn } from "../../infra/utils/clsx";
9
+ function NotificationsPopover({
10
+ notifications = [],
11
+ onViewAll,
12
+ side,
13
+ align,
14
+ contentClassName,
15
+ badgeClassName = "bg-pages-400"
16
+ }) {
17
+ const [open, setOpen] = useState(false);
18
+ const [hasNewNotifications, setHasNewNotifications] = useState(true);
19
+ const handleOpenChange = (isOpen) => {
20
+ setOpen(isOpen);
21
+ if (isOpen) setHasNewNotifications(false);
22
+ };
23
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
24
+ /* @__PURE__ */ jsx(PopoverTrigger, { className: "cursor-pointer", children: /* @__PURE__ */ jsxs(
25
+ "div",
26
+ {
27
+ className: `relative rounded-full p-2.5 ${open ? "bg-gray-100" : "hover:bg-gray-100"}`,
28
+ children: [
29
+ /* @__PURE__ */ jsx(Bell, { size: 20, className: "text-gray-500" }),
30
+ hasNewNotifications && /* @__PURE__ */ jsx("span", { className: cn("absolute top-2 right-2 size-2.5 rounded-full", badgeClassName) })
31
+ ]
32
+ }
33
+ ) }),
34
+ /* @__PURE__ */ jsxs(
35
+ PopoverContent,
36
+ {
37
+ className: cn(
38
+ "absolute bottom-2 left-[26px] w-[308px] p-0 pt-4 bg-white rounded-2xl shadow-md border border-gray-200",
39
+ contentClassName
40
+ ),
41
+ side,
42
+ align,
43
+ sideOffset: 8,
44
+ children: [
45
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-gray-950 px-4", children: "\xDAltimas notifica\xE7\xF5es" }),
46
+ notifications.length > 0 ? notifications.map((notification, index) => /* @__PURE__ */ jsx(
47
+ NotificationItem,
48
+ {
49
+ icon: notification.icon,
50
+ iconBgColor: notification.iconBgColor,
51
+ title: notification.title,
52
+ time: notification.time,
53
+ showBorder: index < notifications.length - 1
54
+ },
55
+ index
56
+ )) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 pt-[41.5px] pb-[33.5px]", children: [
57
+ /* @__PURE__ */ jsx("div", { className: "bg-gray-50 rounded-md p-2.5", children: /* @__PURE__ */ jsx(Bell, { size: 20, color: "var(--color-gray-950)" }) }),
58
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-medium text-gray-950", children: "Sem notifica\xE7\xF5es por enquanto" })
59
+ ] }),
60
+ onViewAll && /* @__PURE__ */ jsx(
61
+ Button,
62
+ {
63
+ variant: "secondary",
64
+ className: "h-8! mt-2 mb-4 mx-4 paragraph-small-semibold",
65
+ onClick: onViewAll,
66
+ children: "Todas as notifica\xE7\xF5es"
67
+ }
68
+ )
69
+ ]
70
+ }
71
+ )
72
+ ] });
73
+ }
74
+ export {
75
+ NotificationsPopover
76
+ };
77
+ //# sourceMappingURL=NotificationsPopover.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/layouts/NotificationsPopover.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { ReactNode, useState } from 'react';\r\nimport { Bell } from 'lucide-react';\r\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';\r\nimport { Button } from '../ui/buttons/Button';\r\nimport { NotificationItem } from './NotificationItem';\r\nimport { cn } from '../../infra/utils/clsx';\r\n\r\nexport interface NotificationData {\r\n icon: ReactNode;\r\n iconBgColor: string;\r\n title: string;\r\n time: string;\r\n}\r\n\r\nexport interface NotificationsPopoverProps {\r\n notifications?: NotificationData[];\r\n onViewAll?: () => void;\r\n side?: 'top' | 'bottom' | 'left' | 'right';\r\n align?: 'start' | 'center' | 'end';\r\n contentClassName?: string;\r\n badgeClassName?: string;\r\n}\r\n\r\nfunction NotificationsPopover({\r\n notifications = [],\r\n onViewAll,\r\n side,\r\n align,\r\n contentClassName,\r\n badgeClassName = 'bg-pages-400',\r\n}: NotificationsPopoverProps) {\r\n const [open, setOpen] = useState(false);\r\n const [hasNewNotifications, setHasNewNotifications] = useState(true);\r\n\r\n const handleOpenChange = (isOpen: boolean) => {\r\n setOpen(isOpen);\r\n if (isOpen) setHasNewNotifications(false);\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={handleOpenChange}>\r\n <PopoverTrigger className=\"cursor-pointer\">\r\n <div\r\n className={`relative rounded-full p-2.5 ${open ? 'bg-gray-100' : 'hover:bg-gray-100'}`}\r\n >\r\n <Bell size={20} className=\"text-gray-500\" />\r\n {hasNewNotifications && (\r\n <span className={cn('absolute top-2 right-2 size-2.5 rounded-full', badgeClassName)} />\r\n )}\r\n </div>\r\n </PopoverTrigger>\r\n <PopoverContent\r\n className={cn(\r\n 'absolute bottom-2 left-[26px] w-[308px] p-0 pt-4 bg-white rounded-2xl shadow-md border border-gray-200',\r\n contentClassName\r\n )}\r\n side={side}\r\n align={align}\r\n sideOffset={8}\r\n >\r\n <span className=\"paragraph-small-semibold text-gray-950 px-4\">Últimas notificações</span>\r\n\r\n {notifications.length > 0 ? (\r\n notifications.map((notification, index) => (\r\n <NotificationItem\r\n key={index}\r\n icon={notification.icon}\r\n iconBgColor={notification.iconBgColor}\r\n title={notification.title}\r\n time={notification.time}\r\n showBorder={index < notifications.length - 1}\r\n />\r\n ))\r\n ) : (\r\n <div className=\"flex flex-col items-center gap-4 pt-[41.5px] pb-[33.5px]\">\r\n <div className=\"bg-gray-50 rounded-md p-2.5\">\r\n <Bell size={20} color=\"var(--color-gray-950)\" />\r\n </div>\r\n <span className=\"paragraph-small-medium text-gray-950\">Sem notificações por enquanto</span>\r\n </div>\r\n )}\r\n\r\n {onViewAll && (\r\n <Button\r\n variant=\"secondary\"\r\n className=\"h-8! mt-2 mb-4 mx-4 paragraph-small-semibold\"\r\n onClick={onViewAll}\r\n >\r\n Todas as notificações\r\n </Button>\r\n )}\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n\r\nexport { NotificationsPopover };\r\n"],"mappings":";AA4CQ,SAGE,KAHF;AA1CR,SAAoB,gBAAgB;AACpC,SAAS,YAAY;AACrB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,cAAc;AACvB,SAAS,wBAAwB;AACjC,SAAS,UAAU;AAkBnB,SAAS,qBAAqB;AAAA,EAC5B,gBAAgB,CAAC;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AACnB,GAA8B;AAC5B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,SAAS,IAAI;AAEnE,QAAM,mBAAmB,CAAC,WAAoB;AAC5C,YAAQ,MAAM;AACd,QAAI,OAAQ,wBAAuB,KAAK;AAAA,EAC1C;AAEA,SACE,qBAAC,WAAQ,MAAY,cAAc,kBACjC;AAAA,wBAAC,kBAAe,WAAU,kBACxB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,+BAA+B,OAAO,gBAAgB,mBAAmB;AAAA,QAEpF;AAAA,8BAAC,QAAK,MAAM,IAAI,WAAU,iBAAgB;AAAA,UACzC,uBACC,oBAAC,UAAK,WAAW,GAAG,gDAAgD,cAAc,GAAG;AAAA;AAAA;AAAA,IAEzF,GACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QAEZ;AAAA,8BAAC,UAAK,WAAU,+CAA8C,2CAAoB;AAAA,UAEjF,cAAc,SAAS,IACtB,cAAc,IAAI,CAAC,cAAc,UAC/B;AAAA,YAAC;AAAA;AAAA,cAEC,MAAM,aAAa;AAAA,cACnB,aAAa,aAAa;AAAA,cAC1B,OAAO,aAAa;AAAA,cACpB,MAAM,aAAa;AAAA,cACnB,YAAY,QAAQ,cAAc,SAAS;AAAA;AAAA,YALtC;AAAA,UAMP,CACD,IAED,qBAAC,SAAI,WAAU,4DACb;AAAA,gCAAC,SAAI,WAAU,+BACb,8BAAC,QAAK,MAAM,IAAI,OAAM,yBAAwB,GAChD;AAAA,YACA,oBAAC,UAAK,WAAU,wCAAuC,iDAA6B;AAAA,aACtF;AAAA,UAGD,aACC;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,WAAU;AAAA,cACV,SAAS;AAAA,cACV;AAAA;AAAA,UAED;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,141 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { useRouter } from "next/navigation";
5
+ import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
6
+ import { Button } from "../ui/buttons/Button";
7
+ import { Progress } from "../ui/feedback/Progress";
8
+ import { Separator } from "../ui/data-display/Separator";
9
+ import { NavBarItem } from "./NavBarItem";
10
+ import { UserAvatar } from "../ui/data-display/UserAvatar";
11
+ import { useAuth } from "../../providers/auth.provider";
12
+ import { cn } from "../../infra/utils/clsx";
13
+ function ProfilePopover({
14
+ side = "top",
15
+ align = "start",
16
+ contentClassName,
17
+ onEditProfile,
18
+ credits,
19
+ onCreditsClick,
20
+ menuItems = [],
21
+ logoutRedirect = "/login",
22
+ storageUrl,
23
+ logoutOverlay
24
+ }) {
25
+ const router = useRouter();
26
+ const { user, logout } = useAuth();
27
+ const [isLoggingOut, setIsLoggingOut] = useState(false);
28
+ const handleLogout = async () => {
29
+ try {
30
+ setIsLoggingOut(true);
31
+ await logout();
32
+ router.push(logoutRedirect);
33
+ } catch (error) {
34
+ console.error("Erro ao fazer logout:", error);
35
+ } finally {
36
+ setIsLoggingOut(false);
37
+ }
38
+ };
39
+ const creditsPercentage = credits && credits.total > 0 ? credits.used / credits.total * 100 : 0;
40
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
41
+ isLoggingOut && logoutOverlay,
42
+ /* @__PURE__ */ jsxs(Popover, { children: [
43
+ /* @__PURE__ */ jsx(PopoverTrigger, { className: "cursor-pointer", children: user && /* @__PURE__ */ jsx(
44
+ UserAvatar,
45
+ {
46
+ photo: user.photo,
47
+ name: user.name,
48
+ size: 40,
49
+ storageUrl
50
+ },
51
+ user.id
52
+ ) }),
53
+ /* @__PURE__ */ jsxs(
54
+ PopoverContent,
55
+ {
56
+ className: cn(
57
+ "w-64.75 p-0 bg-white rounded-2xl shadow-md border border-gray-200 z-99",
58
+ contentClassName
59
+ ),
60
+ side,
61
+ align,
62
+ sideOffset: 8,
63
+ children: [
64
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[32px_1fr_auto] items-center gap-3 p-3 w-full", children: [
65
+ user && /* @__PURE__ */ jsx(
66
+ UserAvatar,
67
+ {
68
+ photo: user.photo,
69
+ name: user.name,
70
+ size: 32,
71
+ storageUrl
72
+ },
73
+ user.id
74
+ ),
75
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
76
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold text-gray-950 truncate", children: user?.name || "" }),
77
+ /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-medium text-gray-500 truncate", children: user?.email || "" })
78
+ ] }),
79
+ onEditProfile && /* @__PURE__ */ jsx(
80
+ Button,
81
+ {
82
+ variant: "secondary",
83
+ className: "paragraph-small-semibold h-8! whitespace-nowrap px-3 w-fit",
84
+ onClick: onEditProfile,
85
+ children: "Editar Perfil"
86
+ }
87
+ )
88
+ ] }),
89
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-gray-200 rounded-2xl p-1.5", children: [
90
+ credits && /* @__PURE__ */ jsxs(
91
+ "div",
92
+ {
93
+ className: cn(
94
+ "flex flex-col bg-gray-950 rounded-lg gap-4 w-full p-4 transition-colors",
95
+ onCreditsClick && "cursor-pointer hover:bg-gray-900"
96
+ ),
97
+ onClick: onCreditsClick,
98
+ children: [
99
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
100
+ /* @__PURE__ */ jsx("span", { className: "paragraph-xsmall-semibold text-white truncate", children: "Cr\xE9ditos usados" }),
101
+ /* @__PURE__ */ jsxs("span", { className: "paragraph-xsmall-medium text-white/50", children: [
102
+ credits.used.toLocaleString("pt-BR"),
103
+ "/",
104
+ credits.total.toLocaleString("pt-BR")
105
+ ] })
106
+ ] }),
107
+ /* @__PURE__ */ jsx(
108
+ Progress,
109
+ {
110
+ className: "bg-white/10",
111
+ indicatorColor: "bg-white",
112
+ value: creditsPercentage
113
+ }
114
+ )
115
+ ]
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
119
+ menuItems.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: menuItems.map((item, index) => /* @__PURE__ */ jsx(
120
+ NavBarItem,
121
+ {
122
+ icon: item.icon,
123
+ label: item.label,
124
+ onClick: item.onClick
125
+ },
126
+ index
127
+ )) }),
128
+ /* @__PURE__ */ jsx(Separator, {}),
129
+ /* @__PURE__ */ jsx(NavBarItem, { label: "Sair", onClick: handleLogout })
130
+ ] })
131
+ ] })
132
+ ]
133
+ }
134
+ )
135
+ ] })
136
+ ] });
137
+ }
138
+ export {
139
+ ProfilePopover
140
+ };
141
+ //# sourceMappingURL=ProfilePopover.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/layouts/ProfilePopover.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { useState } from 'react';\r\nimport { useRouter } from 'next/navigation';\r\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';\r\nimport { Button } from '../ui/buttons/Button';\r\nimport { Progress } from '../ui/feedback/Progress';\r\nimport { Separator } from '../ui/data-display/Separator';\r\nimport { NavBarItem } from './NavBarItem';\r\nimport { UserAvatar } from '../ui/data-display/UserAvatar';\r\nimport { useAuth } from '../../providers/auth.provider';\r\nimport { cn } from '../../infra/utils/clsx';\r\n\r\nexport interface ProfileMenuItem {\r\n icon?: React.ReactNode;\r\n label: string;\r\n onClick: () => void;\r\n}\r\n\r\nexport interface ProfilePopoverProps {\r\n side?: 'top' | 'bottom' | 'left' | 'right';\r\n align?: 'start' | 'center' | 'end';\r\n contentClassName?: string;\r\n onEditProfile?: () => void;\r\n credits?: { used: number; total: number };\r\n onCreditsClick?: () => void;\r\n menuItems?: ProfileMenuItem[];\r\n logoutRedirect?: string;\r\n storageUrl?: string;\r\n logoutOverlay?: React.ReactNode;\r\n}\r\n\r\nfunction ProfilePopover({\r\n side = 'top',\r\n align = 'start',\r\n contentClassName,\r\n onEditProfile,\r\n credits,\r\n onCreditsClick,\r\n menuItems = [],\r\n logoutRedirect = '/login',\r\n storageUrl,\r\n logoutOverlay,\r\n}: ProfilePopoverProps) {\r\n const router = useRouter();\r\n const { user, logout } = useAuth();\r\n const [isLoggingOut, setIsLoggingOut] = useState(false);\r\n\r\n const handleLogout = async () => {\r\n try {\r\n setIsLoggingOut(true);\r\n await logout();\r\n router.push(logoutRedirect);\r\n } catch (error) {\r\n console.error('Erro ao fazer logout:', error);\r\n } finally {\r\n setIsLoggingOut(false);\r\n }\r\n };\r\n\r\n const creditsPercentage =\r\n credits && credits.total > 0\r\n ? (credits.used / credits.total) * 100\r\n : 0;\r\n\r\n return (\r\n <>\r\n {isLoggingOut && logoutOverlay}\r\n <Popover>\r\n <PopoverTrigger className=\"cursor-pointer\">\r\n {user && (\r\n <UserAvatar\r\n key={user.id}\r\n photo={user.photo}\r\n name={user.name}\r\n size={40}\r\n storageUrl={storageUrl}\r\n />\r\n )}\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className={cn(\r\n 'w-64.75 p-0 bg-white rounded-2xl shadow-md border border-gray-200 z-99',\r\n contentClassName\r\n )}\r\n side={side}\r\n align={align}\r\n sideOffset={8}\r\n >\r\n <div className=\"grid grid-cols-[32px_1fr_auto] items-center gap-3 p-3 w-full\">\r\n {user && (\r\n <UserAvatar\r\n key={user.id}\r\n photo={user.photo}\r\n name={user.name}\r\n size={32}\r\n storageUrl={storageUrl}\r\n />\r\n )}\r\n\r\n <div className=\"flex flex-col gap-0.5 min-w-0\">\r\n <span className=\"paragraph-small-semibold text-gray-950 truncate\">\r\n {user?.name || ''}\r\n </span>\r\n <span className=\"paragraph-xsmall-medium text-gray-500 truncate\">\r\n {user?.email || ''}\r\n </span>\r\n </div>\r\n\r\n {onEditProfile && (\r\n <Button\r\n variant=\"secondary\"\r\n className=\"paragraph-small-semibold h-8! whitespace-nowrap px-3 w-fit\"\r\n onClick={onEditProfile}\r\n >\r\n Editar Perfil\r\n </Button>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex flex-col gap-2 border-t border-gray-200 rounded-2xl p-1.5\">\r\n {credits && (\r\n <div\r\n className={cn(\r\n 'flex flex-col bg-gray-950 rounded-lg gap-4 w-full p-4 transition-colors',\r\n onCreditsClick && 'cursor-pointer hover:bg-gray-900'\r\n )}\r\n onClick={onCreditsClick}\r\n >\r\n <div className=\"flex items-center justify-between gap-2\">\r\n <span className=\"paragraph-xsmall-semibold text-white truncate\">\r\n Créditos usados\r\n </span>\r\n <span className=\"paragraph-xsmall-medium text-white/50\">\r\n {credits.used.toLocaleString('pt-BR')}/\r\n {credits.total.toLocaleString('pt-BR')}\r\n </span>\r\n </div>\r\n <Progress\r\n className=\"bg-white/10\"\r\n indicatorColor=\"bg-white\"\r\n value={creditsPercentage}\r\n />\r\n </div>\r\n )}\r\n\r\n <div className=\"flex flex-col gap-2\">\r\n {menuItems.length > 0 && (\r\n <div className=\"flex flex-col\">\r\n {menuItems.map((item, index) => (\r\n <NavBarItem\r\n key={index}\r\n icon={item.icon}\r\n label={item.label}\r\n onClick={item.onClick}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n <Separator />\r\n <NavBarItem label=\"Sair\" onClick={handleLogout} />\r\n </div>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n </>\r\n );\r\n}\r\n\r\nexport { ProfilePopover };\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,142 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { Plus, Settings, User } from "lucide-react";
5
+ import Image from "next/image";
6
+ import { useRouter } from "next/navigation";
7
+ import { Popover, PopoverContent, PopoverTrigger } from "../ui/overlay/Popover";
8
+ import { Button } from "../ui/buttons/Button";
9
+ import { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from "../ui/overlay/Command";
10
+ import { Checkbox } from "../ui/form/Checkbox";
11
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip";
12
+ import { cn } from "../../infra/utils/clsx";
13
+ function UsersSelectorPopover({
14
+ users: externalUsers,
15
+ onToggleUser,
16
+ addRoute = "/my-teams?createNew=true",
17
+ manageRoute = "/my-teams",
18
+ userCount = 5,
19
+ side,
20
+ align,
21
+ contentClassName
22
+ }) {
23
+ const route = useRouter();
24
+ const [open, setOpen] = useState(false);
25
+ const [internalUsers, setInternalUsers] = useState(externalUsers ?? []);
26
+ const [hoveredId, setHoveredId] = useState(null);
27
+ const users = externalUsers ?? internalUsers;
28
+ const toggleUser = (id) => {
29
+ if (onToggleUser) {
30
+ onToggleUser(id);
31
+ } else {
32
+ setInternalUsers(
33
+ (prev) => prev.map((u) => u.id === id ? { ...u, checked: !u.checked } : u)
34
+ );
35
+ }
36
+ };
37
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
38
+ /* @__PURE__ */ jsx(PopoverTrigger, { className: "cursor-pointer", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-gray-950 px-3 py-2 border border-gray-200 rounded-full hover:border-gray-950", children: [
39
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold", children: userCount }),
40
+ /* @__PURE__ */ jsx(User, { size: 16 })
41
+ ] }) }),
42
+ /* @__PURE__ */ jsx(
43
+ PopoverContent,
44
+ {
45
+ className: cn(
46
+ "absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200",
47
+ contentClassName
48
+ ),
49
+ side,
50
+ align,
51
+ sideOffset: 8,
52
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col p-3 gap-2", children: [
53
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
54
+ /* @__PURE__ */ jsx("span", { className: "paragraph-small-semibold", children: "Usu\xE1rios" }),
55
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
56
+ /* @__PURE__ */ jsxs(
57
+ Button,
58
+ {
59
+ variant: "secondary",
60
+ className: "h-8 paragraph-small-semibold text-gray-950",
61
+ onClick: () => route.push(addRoute),
62
+ children: [
63
+ /* @__PURE__ */ jsx(Plus, { size: 16 }),
64
+ "Adicionar"
65
+ ]
66
+ }
67
+ ),
68
+ /* @__PURE__ */ jsxs(Tooltip, { children: [
69
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
70
+ Button,
71
+ {
72
+ variant: "secondary",
73
+ className: "p-0 size-8",
74
+ onClick: () => route.push(manageRoute),
75
+ children: /* @__PURE__ */ jsx(Settings, { size: 18 })
76
+ }
77
+ ) }),
78
+ /* @__PURE__ */ jsx(TooltipContent, { children: "Visualizar todos usu\xE1rios" })
79
+ ] })
80
+ ] })
81
+ ] }),
82
+ /* @__PURE__ */ jsxs(Command, { className: "gap-2", value: "", children: [
83
+ /* @__PURE__ */ jsx(CommandInput, { placeholder: "Busque aqui" }),
84
+ /* @__PURE__ */ jsxs(CommandList, { className: "custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]", children: [
85
+ /* @__PURE__ */ jsx(CommandEmpty, { children: "No results found." }),
86
+ users.map((user) => /* @__PURE__ */ jsx(
87
+ CommandItem,
88
+ {
89
+ autoFocus: false,
90
+ onPointerEnter: () => setHoveredId(user.id),
91
+ onPointerLeave: () => setHoveredId(null),
92
+ onFocus: () => setHoveredId(user.id),
93
+ onBlur: () => setHoveredId(null),
94
+ onSelect: () => toggleUser(user.id),
95
+ className: "cursor-pointer",
96
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
97
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
98
+ /* @__PURE__ */ jsx(
99
+ Image,
100
+ {
101
+ alt: "Avatar",
102
+ src: user.avatar,
103
+ width: 32,
104
+ height: 32,
105
+ className: "rounded-full"
106
+ }
107
+ ),
108
+ user.name
109
+ ] }),
110
+ /* @__PURE__ */ jsxs(Tooltip, { open: hoveredId === user.id, children: [
111
+ /* @__PURE__ */ jsx(
112
+ TooltipTrigger,
113
+ {
114
+ onClick: (e) => e.stopPropagation(),
115
+ onPointerDown: (e) => e.stopPropagation(),
116
+ children: /* @__PURE__ */ jsx(
117
+ Checkbox,
118
+ {
119
+ checked: user.checked,
120
+ onCheckedChange: () => toggleUser(user.id),
121
+ className: hoveredId === user.id ? "border-gray-950" : ""
122
+ }
123
+ )
124
+ }
125
+ ),
126
+ /* @__PURE__ */ jsx(TooltipContent, { children: user.checked ? "Remover do projeto" : "Adicionar ao projeto" })
127
+ ] })
128
+ ] })
129
+ },
130
+ user.id
131
+ ))
132
+ ] })
133
+ ] })
134
+ ] })
135
+ }
136
+ )
137
+ ] });
138
+ }
139
+ export {
140
+ UsersSelectorPopover
141
+ };
142
+ //# sourceMappingURL=UsersSelectorPopover.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/layouts/UsersSelectorPopover.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport { useState } from 'react';\r\nimport { Plus, Settings, User } from 'lucide-react';\r\nimport Image from 'next/image';\r\nimport { useRouter } from 'next/navigation';\r\nimport { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';\r\nimport { Button } from '../ui/buttons/Button';\r\nimport { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '../ui/overlay/Command';\r\nimport { Checkbox } from '../ui/form/Checkbox';\r\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../ui/overlay/Tooltip';\r\nimport { cn } from '../../infra/utils/clsx';\r\n\r\nexport interface UserSelectorItem {\r\n id: number;\r\n name: string;\r\n avatar: string;\r\n checked: boolean;\r\n}\r\n\r\nexport interface UsersSelectorPopoverProps {\r\n users?: UserSelectorItem[];\r\n onToggleUser?: (id: number) => void;\r\n addRoute?: string;\r\n manageRoute?: string;\r\n userCount?: number;\r\n side?: 'top' | 'bottom' | 'left' | 'right';\r\n align?: 'start' | 'center' | 'end';\r\n contentClassName?: string;\r\n}\r\n\r\nfunction UsersSelectorPopover({\r\n users: externalUsers,\r\n onToggleUser,\r\n addRoute = '/my-teams?createNew=true',\r\n manageRoute = '/my-teams',\r\n userCount = 5,\r\n side,\r\n align,\r\n contentClassName,\r\n}: UsersSelectorPopoverProps) {\r\n const route = useRouter();\r\n const [open, setOpen] = useState(false);\r\n const [internalUsers, setInternalUsers] = useState<UserSelectorItem[]>(externalUsers ?? []);\r\n const [hoveredId, setHoveredId] = useState<number | null>(null);\r\n\r\n const users = externalUsers ?? internalUsers;\r\n\r\n const toggleUser = (id: number) => {\r\n if (onToggleUser) {\r\n onToggleUser(id);\r\n } else {\r\n setInternalUsers((prev) =>\r\n prev.map((u) => (u.id === id ? { ...u, checked: !u.checked } : u))\r\n );\r\n }\r\n };\r\n\r\n return (\r\n <Popover open={open} onOpenChange={setOpen}>\r\n <PopoverTrigger className=\"cursor-pointer\">\r\n <div className=\"flex items-center gap-2 text-gray-950 px-3 py-2 border border-gray-200 rounded-full hover:border-gray-950\">\r\n <span className=\"paragraph-small-semibold\">{userCount}</span>\r\n <User size={16} />\r\n </div>\r\n </PopoverTrigger>\r\n\r\n <PopoverContent\r\n className={cn(\r\n 'absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200',\r\n contentClassName\r\n )}\r\n side={side}\r\n align={align}\r\n sideOffset={8}\r\n >\r\n <div className=\"flex flex-col p-3 gap-2\">\r\n <div className=\"flex items-center justify-between\">\r\n <span className=\"paragraph-small-semibold\">Usuários</span>\r\n <div className=\"flex items-center gap-1.5\">\r\n <Button\r\n variant=\"secondary\"\r\n className=\"h-8 paragraph-small-semibold text-gray-950\"\r\n onClick={() => route.push(addRoute)}\r\n >\r\n <Plus size={16} />\r\n Adicionar\r\n </Button>\r\n\r\n <Tooltip>\r\n <TooltipTrigger asChild>\r\n <Button\r\n variant=\"secondary\"\r\n className=\"p-0 size-8\"\r\n onClick={() => route.push(manageRoute)}\r\n >\r\n <Settings size={18} />\r\n </Button>\r\n </TooltipTrigger>\r\n <TooltipContent>Visualizar todos usuários</TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n\r\n <Command className=\"gap-2\" value=\"\">\r\n <CommandInput placeholder=\"Busque aqui\" />\r\n <CommandList className=\"custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]\">\r\n <CommandEmpty>No results found.</CommandEmpty>\r\n {users.map((user) => (\r\n <CommandItem\r\n key={user.id}\r\n autoFocus={false}\r\n onPointerEnter={() => setHoveredId(user.id)}\r\n onPointerLeave={() => setHoveredId(null)}\r\n onFocus={() => setHoveredId(user.id)}\r\n onBlur={() => setHoveredId(null)}\r\n onSelect={() => toggleUser(user.id)}\r\n className=\"cursor-pointer\"\r\n >\r\n <div className=\"flex items-center justify-between w-full\">\r\n <div className=\"flex items-center gap-2\">\r\n <Image\r\n alt=\"Avatar\"\r\n src={user.avatar}\r\n width={32}\r\n height={32}\r\n className=\"rounded-full\"\r\n />\r\n {user.name}\r\n </div>\r\n\r\n <Tooltip open={hoveredId === user.id}>\r\n <TooltipTrigger\r\n onClick={(e) => e.stopPropagation()}\r\n onPointerDown={(e) => e.stopPropagation()}\r\n >\r\n <Checkbox\r\n checked={user.checked}\r\n onCheckedChange={() => toggleUser(user.id)}\r\n className={hoveredId === user.id ? 'border-gray-950' : ''}\r\n />\r\n </TooltipTrigger>\r\n <TooltipContent>\r\n {user.checked ? 'Remover do projeto' : 'Adicionar ao projeto'}\r\n </TooltipContent>\r\n </Tooltip>\r\n </div>\r\n </CommandItem>\r\n ))}\r\n </CommandList>\r\n </Command>\r\n </div>\r\n </PopoverContent>\r\n </Popover>\r\n );\r\n}\r\n\r\nexport { UsersSelectorPopover };\r\n"],"mappings":";AA6DQ,SACE,KADF;AA3DR,SAAS,gBAAgB;AACzB,SAAS,MAAM,UAAU,YAAY;AACrC,OAAO,WAAW;AAClB,SAAS,iBAAiB;AAC1B,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,cAAc;AACvB,SAAS,SAAS,cAAc,cAAc,aAAa,mBAAmB;AAC9E,SAAS,gBAAgB;AACzB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,UAAU;AAoBnB,SAAS,qBAAqB;AAAA,EAC5B,OAAO;AAAA,EACP;AAAA,EACA,WAAW;AAAA,EACX,cAAc;AAAA,EACd,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AACF,GAA8B;AAC5B,QAAM,QAAQ,UAAU;AACxB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAA6B,iBAAiB,CAAC,CAAC;AAC1F,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAE9D,QAAM,QAAQ,iBAAiB;AAE/B,QAAM,aAAa,CAAC,OAAe;AACjC,QAAI,cAAc;AAChB,mBAAa,EAAE;AAAA,IACjB,OAAO;AACL;AAAA,QAAiB,CAAC,SAChB,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,EAAE,GAAG,GAAG,SAAS,CAAC,EAAE,QAAQ,IAAI,CAAE;AAAA,MACnE;AAAA,IACF;AAAA,EACF;AAEA,SACE,qBAAC,WAAQ,MAAY,cAAc,SACjC;AAAA,wBAAC,kBAAe,WAAU,kBACxB,+BAAC,SAAI,WAAU,6GACb;AAAA,0BAAC,UAAK,WAAU,4BAA4B,qBAAU;AAAA,MACtD,oBAAC,QAAK,MAAM,IAAI;AAAA,OAClB,GACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QAEZ,+BAAC,SAAI,WAAU,2BACb;AAAA,+BAAC,SAAI,WAAU,qCACb;AAAA,gCAAC,UAAK,WAAU,4BAA2B,yBAAQ;AAAA,YACnD,qBAAC,SAAI,WAAU,6BACb;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,SAAQ;AAAA,kBACR,WAAU;AAAA,kBACV,SAAS,MAAM,MAAM,KAAK,QAAQ;AAAA,kBAElC;AAAA,wCAAC,QAAK,MAAM,IAAI;AAAA,oBAAE;AAAA;AAAA;AAAA,cAEpB;AAAA,cAEA,qBAAC,WACC;AAAA,oCAAC,kBAAe,SAAO,MACrB;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,WAAU;AAAA,oBACV,SAAS,MAAM,MAAM,KAAK,WAAW;AAAA,oBAErC,8BAAC,YAAS,MAAM,IAAI;AAAA;AAAA,gBACtB,GACF;AAAA,gBACA,oBAAC,kBAAe,0CAAyB;AAAA,iBAC3C;AAAA,eACF;AAAA,aACF;AAAA,UAEA,qBAAC,WAAQ,WAAU,SAAQ,OAAM,IAC/B;AAAA,gCAAC,gBAAa,aAAY,eAAc;AAAA,YACxC,qBAAC,eAAY,WAAU,mEACrB;AAAA,kCAAC,gBAAa,+BAAiB;AAAA,cAC9B,MAAM,IAAI,CAAC,SACV;AAAA,gBAAC;AAAA;AAAA,kBAEC,WAAW;AAAA,kBACX,gBAAgB,MAAM,aAAa,KAAK,EAAE;AAAA,kBAC1C,gBAAgB,MAAM,aAAa,IAAI;AAAA,kBACvC,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,kBACnC,QAAQ,MAAM,aAAa,IAAI;AAAA,kBAC/B,UAAU,MAAM,WAAW,KAAK,EAAE;AAAA,kBAClC,WAAU;AAAA,kBAEV,+BAAC,SAAI,WAAU,4CACb;AAAA,yCAAC,SAAI,WAAU,2BACb;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,KAAI;AAAA,0BACJ,KAAK,KAAK;AAAA,0BACV,OAAO;AAAA,0BACP,QAAQ;AAAA,0BACR,WAAU;AAAA;AAAA,sBACZ;AAAA,sBACC,KAAK;AAAA,uBACR;AAAA,oBAEA,qBAAC,WAAQ,MAAM,cAAc,KAAK,IAChC;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BAClC,eAAe,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BAExC;AAAA,4BAAC;AAAA;AAAA,8BACC,SAAS,KAAK;AAAA,8BACd,iBAAiB,MAAM,WAAW,KAAK,EAAE;AAAA,8BACzC,WAAW,cAAc,KAAK,KAAK,oBAAoB;AAAA;AAAA,0BACzD;AAAA;AAAA,sBACF;AAAA,sBACA,oBAAC,kBACE,eAAK,UAAU,uBAAuB,wBACzC;AAAA,uBACF;AAAA,qBACF;AAAA;AAAA,gBApCK,KAAK;AAAA,cAqCZ,CACD;AAAA,eACH;AAAA,aACF;AAAA,WACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import Image from "next/image";
4
+ import { cn } from "../../../infra/utils/clsx";
5
+ function getInitials(name, maxLength = 2) {
6
+ return name.split(" ").map((n) => n[0]).join("").slice(0, maxLength).toUpperCase();
7
+ }
8
+ function UserAvatar({
9
+ photo,
10
+ name,
11
+ initials,
12
+ size = 32,
13
+ shape = "circle",
14
+ className,
15
+ storageUrl
16
+ }) {
17
+ const shapeClass = shape === "circle" ? "rounded-full" : "rounded-lg";
18
+ const displayInitials = initials || (name ? getInitials(name) : "?");
19
+ const photoUrl = storageUrl && photo ? `${storageUrl}/${photo}` : photo;
20
+ if (photoUrl) {
21
+ return /* @__PURE__ */ jsx(
22
+ Image,
23
+ {
24
+ alt: name || "imagem do usuario",
25
+ src: photoUrl,
26
+ width: size,
27
+ height: size,
28
+ className: cn("object-cover shrink-0", shapeClass, className),
29
+ style: { width: size, height: size }
30
+ }
31
+ );
32
+ }
33
+ return /* @__PURE__ */ jsx(
34
+ "div",
35
+ {
36
+ className: cn(
37
+ "flex items-center justify-center shrink-0 bg-gray-100",
38
+ shapeClass,
39
+ className
40
+ ),
41
+ style: { width: size, height: size },
42
+ children: /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-gray-700", children: displayInitials })
43
+ }
44
+ );
45
+ }
46
+ export {
47
+ UserAvatar
48
+ };
49
+ //# sourceMappingURL=UserAvatar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/components/ui/data-display/UserAvatar.tsx"],"sourcesContent":["\"use client\"\r\n\r\nimport Image from 'next/image';\r\nimport { cn } from '../../../infra/utils/clsx';\r\n\r\nfunction getInitials(name: string, maxLength: number = 2): string {\r\n return name\r\n .split(' ')\r\n .map((n) => n[0])\r\n .join('')\r\n .slice(0, maxLength)\r\n .toUpperCase();\r\n}\r\n\r\ninterface UserAvatarProps {\r\n photo?: string | null;\r\n name?: string;\r\n initials?: string;\r\n size?: number;\r\n shape?: 'circle' | 'square';\r\n className?: string;\r\n storageUrl?: string;\r\n}\r\n\r\nfunction UserAvatar({\r\n photo,\r\n name,\r\n initials,\r\n size = 32,\r\n shape = 'circle',\r\n className,\r\n storageUrl,\r\n}: UserAvatarProps) {\r\n const shapeClass = shape === 'circle' ? 'rounded-full' : 'rounded-lg';\r\n const displayInitials = initials || (name ? getInitials(name) : '?');\r\n\r\n const photoUrl = storageUrl && photo ? `${storageUrl}/${photo}` : photo;\r\n\r\n if (photoUrl) {\r\n return (\r\n <Image\r\n alt={name || 'imagem do usuario'}\r\n src={photoUrl}\r\n width={size}\r\n height={size}\r\n className={cn('object-cover shrink-0', shapeClass, className)}\r\n style={{ width: size, height: size }}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <div\r\n className={cn(\r\n 'flex items-center justify-center shrink-0 bg-gray-100',\r\n shapeClass,\r\n className\r\n )}\r\n style={{ width: size, height: size }}\r\n >\r\n <span className=\"text-xs font-semibold text-gray-700\">{displayInitials}</span>\r\n </div>\r\n );\r\n}\r\n\r\nexport { UserAvatar };\r\nexport type { UserAvatarProps };\r\n"],"mappings":";AAwCM;AAtCN,OAAO,WAAW;AAClB,SAAS,UAAU;AAEnB,SAAS,YAAY,MAAc,YAAoB,GAAW;AAChE,SAAO,KACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,EACP,MAAM,GAAG,SAAS,EAClB,YAAY;AACjB;AAYA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,aAAa,UAAU,WAAW,iBAAiB;AACzD,QAAM,kBAAkB,aAAa,OAAO,YAAY,IAAI,IAAI;AAEhE,QAAM,WAAW,cAAc,QAAQ,GAAG,UAAU,IAAI,KAAK,KAAK;AAElE,MAAI,UAAU;AACZ,WACE;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,QAAQ;AAAA,QACb,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,WAAW,GAAG,yBAAyB,YAAY,SAAS;AAAA,QAC5D,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA;AAAA,IACrC;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MAEnC,8BAAC,UAAK,WAAU,uCAAuC,2BAAgB;AAAA;AAAA,EACzE;AAEJ;","names":[]}
package/dist/index.mjs CHANGED
@@ -17,24 +17,168 @@ import { NavBar } from "./components/layouts/NavBar";
17
17
  import { SideBarNavigation } from "./components/layouts/SideBarNavigation";
18
18
  import { MdSideBarNavigation } from "./components/layouts/MdSideBarNavigation";
19
19
  import { NotificationItem } from "./components/layouts/NotificationItem";
20
+ import { NotificationsPopover } from "./components/layouts/NotificationsPopover";
21
+ import { UsersSelectorPopover } from "./components/layouts/UsersSelectorPopover";
22
+ import { ProfilePopover } from "./components/layouts/ProfilePopover";
23
+ import { NavBarItem } from "./components/layouts/NavBarItem";
24
+ import { Button, buttonVariants } from "./components/ui/buttons/Button";
25
+ import { CopyButton } from "./components/ui/buttons/CopyButton";
26
+ import { default as default2 } from "./components/ui/buttons/CancelButton";
27
+ import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from "./components/ui/data-display/Accordion";
28
+ import { Badge, badgeVariants } from "./components/ui/data-display/Badge";
29
+ import { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent } from "./components/ui/data-display/Card";
30
+ import { Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis } from "./components/ui/data-display/Pagination";
31
+ import { ScrollArea, ScrollBar } from "./components/ui/data-display/ScrollArea";
32
+ import { Separator } from "./components/ui/data-display/Separator";
33
+ import { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from "./components/ui/data-display/Table";
34
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "./components/ui/data-display/Tabs";
35
+ import { UserAvatar } from "./components/ui/data-display/UserAvatar";
36
+ import { default as default3 } from "./components/ui/feedback/CircularProgress";
37
+ import { default as default4 } from "./components/ui/feedback/DefaultCircularProgress";
38
+ import { Progress } from "./components/ui/feedback/Progress";
39
+ import { Toast, toastVariants, toastIconContainerVariants } from "./components/ui/feedback/Toast";
40
+ import { Calendar, CalendarDayButton } from "./components/ui/form/Calendar";
41
+ import { Checkbox } from "./components/ui/form/Checkbox";
42
+ import { DatePicker } from "./components/ui/form/DatePicker";
43
+ import { DateRangePicker } from "./components/ui/form/DateRangePicker";
44
+ import { Input } from "./components/ui/form/Input";
45
+ import { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from "./components/ui/form/InputOtp";
46
+ import { RadioGroup, RadioGroupItem } from "./components/ui/form/RadioGroup";
47
+ import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from "./components/ui/form/Select";
48
+ import { Switch } from "./components/ui/form/Switch";
49
+ import { Textarea } from "./components/ui/form/Textarea";
50
+ import { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator } from "./components/ui/overlay/Command";
51
+ import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from "./components/ui/overlay/Dialog";
52
+ import { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from "./components/ui/overlay/Popover";
53
+ import { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from "./components/ui/overlay/Sheet";
54
+ import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "./components/ui/overlay/Tooltip";
20
55
  import { useMdSidebarStore } from "./store/useMdSidebarStore";
21
56
  export {
57
+ Accordion,
58
+ AccordionContent,
59
+ AccordionItem,
60
+ AccordionTrigger,
61
+ Badge,
62
+ Button,
63
+ Calendar,
64
+ CalendarDayButton,
65
+ default2 as CancelButton,
66
+ Card,
67
+ CardAction,
68
+ CardContent,
69
+ CardDescription,
70
+ CardFooter,
71
+ CardHeader,
72
+ CardTitle,
73
+ Checkbox,
74
+ default3 as CircularProgress,
75
+ Command,
76
+ CommandDialog,
77
+ CommandEmpty,
78
+ CommandGroup,
79
+ CommandInput,
80
+ CommandItem,
81
+ CommandList,
82
+ CommandSeparator,
83
+ CommandShortcut,
84
+ CopyButton,
85
+ DatePicker,
86
+ DateRangePicker,
87
+ default4 as DefaultCircularProgress,
88
+ Dialog,
89
+ DialogClose,
90
+ DialogContent,
91
+ DialogDescription,
92
+ DialogFooter,
93
+ DialogHeader,
94
+ DialogOverlay,
95
+ DialogPortal,
96
+ DialogTitle,
97
+ DialogTrigger,
98
+ Input,
99
+ InputOTP,
100
+ InputOTPGroup,
101
+ InputOTPSeparator,
102
+ InputOTPSlot,
22
103
  MainLayout,
23
104
  MainLayoutContent,
24
105
  MainLayoutMain,
25
106
  MainLayoutSpacer,
26
107
  MdSideBarNavigation,
27
108
  NavBar,
109
+ NavBarItem,
28
110
  NotificationItem,
111
+ NotificationsPopover,
112
+ Pagination,
113
+ PaginationContent,
114
+ PaginationEllipsis,
115
+ PaginationItem,
116
+ PaginationLink,
117
+ PaginationNext,
118
+ PaginationPrevious,
119
+ Popover,
120
+ PopoverAnchor,
121
+ PopoverContent,
122
+ PopoverTrigger,
123
+ ProfilePopover,
124
+ Progress,
29
125
  QueryProvider,
126
+ RadioGroup,
127
+ RadioGroupItem,
128
+ ScrollArea,
129
+ ScrollBar,
130
+ Select,
131
+ SelectContent,
132
+ SelectGroup,
133
+ SelectItem,
134
+ SelectLabel,
135
+ SelectScrollDownButton,
136
+ SelectScrollUpButton,
137
+ SelectSeparator,
138
+ SelectTrigger,
139
+ SelectValue,
140
+ Separator,
141
+ Sheet,
142
+ SheetClose,
143
+ SheetContent,
144
+ SheetDescription,
145
+ SheetFooter,
146
+ SheetHeader,
147
+ SheetTitle,
148
+ SheetTrigger,
30
149
  SideBarNavigation,
150
+ Switch,
151
+ Table,
152
+ TableBody,
153
+ TableCaption,
154
+ TableCell,
155
+ TableFooter,
156
+ TableHead,
157
+ TableHeader,
158
+ TableRow,
159
+ Tabs,
160
+ TabsContent,
161
+ TabsList,
162
+ TabsTrigger,
163
+ Textarea,
164
+ Toast,
165
+ Tooltip,
166
+ TooltipContent,
167
+ TooltipProvider,
168
+ TooltipTrigger,
31
169
  USER_QUERY_KEY,
170
+ UserAvatar,
171
+ UsersSelectorPopover,
172
+ badgeVariants,
32
173
  buildQueryParams,
174
+ buttonVariants,
33
175
  cn,
34
176
  continueChain,
35
177
  createAuthMiddleware,
36
178
  createMiddlewareChain,
37
179
  stopChain,
180
+ toastIconContainerVariants,
181
+ toastVariants,
38
182
  useInvalidateUser,
39
183
  useMdSidebarStore,
40
184
  useSetUserData,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from './modules/auth/schema';\nexport * from './modules/users/schema';\nexport * from './modules/whitelabel/schema';\nexport * from './infra/api/types';\n\n// Contexts\nexport * from './providers/query.provider';\nexport * from './providers/auth.provider';\nexport * from './providers/whitelabel.provider';\n\n// Hooks\nexport { useUserQuery, useUserValidateSession, useInvalidateUser, useSetUserData, USER_QUERY_KEY } from './modules/auth/hooks/useUserQuery';\n\n// Providers\nexport { QueryProvider } from './providers/query.provider';\n\n// Middleware\nexport { createAuthMiddleware } from './middlewares/create-auth-middleware';\nexport { createMiddlewareChain } from './middlewares/chain';\nexport { continueChain, stopChain } from './middlewares/types';\nexport type { MiddlewareFunction, MiddlewareConfig, MiddlewareResult } from './middlewares/types';\n\n// Utils\nexport { cn } from './infra/utils/clsx';\nexport { buildQueryParams } from './infra/utils/params';\n\n// Layout\nexport { MainLayout, MainLayoutContent, MainLayoutSpacer, MainLayoutMain } from './components/layouts/MainLayout';\nexport { NavBar } from './components/layouts/NavBar';\nexport type { NavBarProps } from './components/layouts/NavBar';\nexport { SideBarNavigation } from './components/layouts/SideBarNavigation';\nexport { MdSideBarNavigation } from './components/layouts/MdSideBarNavigation';\nexport { NotificationItem } from './components/layouts/NotificationItem';\nexport type { NotificationItemProps } from './components/layouts/NotificationItem';\n\n// Store\nexport { useMdSidebarStore } from './store/useMdSidebarStore';\n"],"mappings":"AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,SAAS,cAAc,wBAAwB,mBAAmB,gBAAgB,sBAAsB;AAGxG,SAAS,qBAAqB;AAG9B,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,eAAe,iBAAiB;AAIzC,SAAS,UAAU;AACnB,SAAS,wBAAwB;AAGjC,SAAS,YAAY,mBAAmB,kBAAkB,sBAAsB;AAChF,SAAS,cAAc;AAEvB,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAIjC,SAAS,yBAAyB;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from './modules/auth/schema';\nexport * from './modules/users/schema';\nexport * from './modules/whitelabel/schema';\nexport * from './infra/api/types';\n\n// Contexts\nexport * from './providers/query.provider';\nexport * from './providers/auth.provider';\nexport * from './providers/whitelabel.provider';\n\n// Hooks\nexport { useUserQuery, useUserValidateSession, useInvalidateUser, useSetUserData, USER_QUERY_KEY } from './modules/auth/hooks/useUserQuery';\n\n// Providers\nexport { QueryProvider } from './providers/query.provider';\n\n// Middleware\nexport { createAuthMiddleware } from './middlewares/create-auth-middleware';\nexport { createMiddlewareChain } from './middlewares/chain';\nexport { continueChain, stopChain } from './middlewares/types';\nexport type { MiddlewareFunction, MiddlewareConfig, MiddlewareResult } from './middlewares/types';\n\n// Utils\nexport { cn } from './infra/utils/clsx';\nexport { buildQueryParams } from './infra/utils/params';\n\n// Layout\nexport { MainLayout, MainLayoutContent, MainLayoutSpacer, MainLayoutMain } from './components/layouts/MainLayout';\nexport { NavBar } from './components/layouts/NavBar';\nexport type { NavBarProps } from './components/layouts/NavBar';\nexport { SideBarNavigation } from './components/layouts/SideBarNavigation';\nexport { MdSideBarNavigation } from './components/layouts/MdSideBarNavigation';\nexport { NotificationItem } from './components/layouts/NotificationItem';\nexport type { NotificationItemProps } from './components/layouts/NotificationItem';\nexport { NotificationsPopover } from './components/layouts/NotificationsPopover';\nexport type { NotificationsPopoverProps, NotificationData } from './components/layouts/NotificationsPopover';\nexport { UsersSelectorPopover } from './components/layouts/UsersSelectorPopover';\nexport type { UsersSelectorPopoverProps, UserSelectorItem } from './components/layouts/UsersSelectorPopover';\nexport { ProfilePopover } from './components/layouts/ProfilePopover';\nexport type { ProfilePopoverProps, ProfileMenuItem } from './components/layouts/ProfilePopover';\nexport { NavBarItem } from './components/layouts/NavBarItem';\nexport type { NavBarItemProps } from './components/layouts/NavBarItem';\n\n// UI - Buttons\nexport { Button, buttonVariants } from './components/ui/buttons/Button';\nexport { CopyButton } from './components/ui/buttons/CopyButton';\nexport { default as CancelButton } from './components/ui/buttons/CancelButton';\n\n// UI - Data Display\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './components/ui/data-display/Accordion';\nexport { Badge, badgeVariants } from './components/ui/data-display/Badge';\nexport { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent } from './components/ui/data-display/Card';\nexport { Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis } from './components/ui/data-display/Pagination';\nexport { ScrollArea, ScrollBar } from './components/ui/data-display/ScrollArea';\nexport { Separator } from './components/ui/data-display/Separator';\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from './components/ui/data-display/Table';\nexport { Tabs, TabsList, TabsTrigger, TabsContent } from './components/ui/data-display/Tabs';\nexport { UserAvatar } from './components/ui/data-display/UserAvatar';\nexport type { UserAvatarProps } from './components/ui/data-display/UserAvatar';\n\n// UI - Feedback\nexport { default as CircularProgress } from './components/ui/feedback/CircularProgress';\nexport { default as DefaultCircularProgress } from './components/ui/feedback/DefaultCircularProgress';\nexport { Progress } from './components/ui/feedback/Progress';\nexport { Toast, toastVariants, toastIconContainerVariants } from './components/ui/feedback/Toast';\nexport type { ToastProps } from './components/ui/feedback/Toast';\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from './components/ui/form/Calendar';\nexport { Checkbox } from './components/ui/form/Checkbox';\nexport { DatePicker } from './components/ui/form/DatePicker';\nexport { DateRangePicker } from './components/ui/form/DateRangePicker';\nexport { Input } from './components/ui/form/Input';\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './components/ui/form/InputOtp';\nexport { RadioGroup, RadioGroupItem } from './components/ui/form/RadioGroup';\nexport { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './components/ui/form/Select';\nexport { Switch } from './components/ui/form/Switch';\nexport { Textarea } from './components/ui/form/Textarea';\n\n// UI - Overlay\nexport { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator } from './components/ui/overlay/Command';\nexport { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './components/ui/overlay/Dialog';\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from './components/ui/overlay/Popover';\nexport { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from './components/ui/overlay/Sheet';\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './components/ui/overlay/Tooltip';\n\n// Store\nexport { useMdSidebarStore } from './store/useMdSidebarStore';\n"],"mappings":"AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,SAAS,cAAc,wBAAwB,mBAAmB,gBAAgB,sBAAsB;AAGxG,SAAS,qBAAqB;AAG9B,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,eAAe,iBAAiB;AAIzC,SAAS,UAAU;AACnB,SAAS,wBAAwB;AAGjC,SAAS,YAAY,mBAAmB,kBAAkB,sBAAsB;AAChF,SAAS,cAAc;AAEvB,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAEjC,SAAS,4BAA4B;AAErC,SAAS,4BAA4B;AAErC,SAAS,sBAAsB;AAE/B,SAAS,kBAAkB;AAI3B,SAAS,QAAQ,sBAAsB;AACvC,SAAS,kBAAkB;AAC3B,SAAoB,WAAXA,gBAA+B;AAGxC,SAAS,WAAW,eAAe,kBAAkB,wBAAwB;AAC7E,SAAS,OAAO,qBAAqB;AACrC,SAAS,MAAM,YAAY,YAAY,WAAW,YAAY,iBAAiB,mBAAmB;AAClG,SAAS,YAAY,mBAAmB,gBAAgB,gBAAgB,oBAAoB,gBAAgB,0BAA0B;AACtI,SAAS,YAAY,iBAAiB;AACtC,SAAS,iBAAiB;AAC1B,SAAS,OAAO,aAAa,WAAW,aAAa,WAAW,UAAU,WAAW,oBAAoB;AACzG,SAAS,MAAM,UAAU,aAAa,mBAAmB;AACzD,SAAS,kBAAkB;AAI3B,SAAoB,WAAXA,gBAAmC;AAC5C,SAAoB,WAAXA,gBAA0C;AACnD,SAAS,gBAAgB;AACzB,SAAS,OAAO,eAAe,kCAAkC;AAIjE,SAAS,UAAU,yBAAyB;AAC5C,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAChC,SAAS,aAAa;AACtB,SAAS,UAAU,eAAe,cAAc,yBAAyB;AACzE,SAAS,YAAY,sBAAsB;AAC3C,SAAS,QAAQ,eAAe,aAAa,YAAY,aAAa,wBAAwB,sBAAsB,iBAAiB,eAAe,mBAAmB;AACvK,SAAS,cAAc;AACvB,SAAS,gBAAgB;AAGzB,SAAS,SAAS,eAAe,cAAc,aAAa,cAAc,cAAc,aAAa,iBAAiB,wBAAwB;AAC9I,SAAS,QAAQ,aAAa,eAAe,mBAAmB,cAAc,cAAc,eAAe,cAAc,aAAa,qBAAqB;AAC3J,SAAS,SAAS,gBAAgB,gBAAgB,qBAAqB;AACvE,SAAS,OAAO,cAAc,YAAY,cAAc,aAAa,aAAa,YAAY,wBAAwB;AACtH,SAAS,SAAS,gBAAgB,gBAAgB,uBAAuB;AAGzE,SAAS,yBAAyB;","names":["default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -0,0 +1,29 @@
1
+ "use client"
2
+
3
+ import { cn } from '../../infra/utils/clsx';
4
+
5
+ type NavBarItemProps = {
6
+ icon?: React.ReactNode;
7
+ label: string;
8
+ onClick: () => void;
9
+ className?: string;
10
+ labelClassName?: string;
11
+ }
12
+
13
+ function NavBarItem({ icon, label, onClick, className, labelClassName }: NavBarItemProps) {
14
+ return (
15
+ <div
16
+ className={cn(
17
+ 'rounded-lg flex items-center gap-2 px-2 py-2 h-10 cursor-pointer transition-colors bg-white hover:bg-gray-100 active:bg-gray-50',
18
+ className
19
+ )}
20
+ onClick={onClick}
21
+ >
22
+ {icon}
23
+ <span className={cn('text-sm font-medium text-gray-950', labelClassName)}>{label}</span>
24
+ </div>
25
+ );
26
+ }
27
+
28
+ export { NavBarItem };
29
+ export type { NavBarItemProps };
@@ -0,0 +1,99 @@
1
+ "use client"
2
+
3
+ import { ReactNode, useState } from 'react';
4
+ import { Bell } from 'lucide-react';
5
+ import { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';
6
+ import { Button } from '../ui/buttons/Button';
7
+ import { NotificationItem } from './NotificationItem';
8
+ import { cn } from '../../infra/utils/clsx';
9
+
10
+ export interface NotificationData {
11
+ icon: ReactNode;
12
+ iconBgColor: string;
13
+ title: string;
14
+ time: string;
15
+ }
16
+
17
+ export interface NotificationsPopoverProps {
18
+ notifications?: NotificationData[];
19
+ onViewAll?: () => void;
20
+ side?: 'top' | 'bottom' | 'left' | 'right';
21
+ align?: 'start' | 'center' | 'end';
22
+ contentClassName?: string;
23
+ badgeClassName?: string;
24
+ }
25
+
26
+ function NotificationsPopover({
27
+ notifications = [],
28
+ onViewAll,
29
+ side,
30
+ align,
31
+ contentClassName,
32
+ badgeClassName = 'bg-pages-400',
33
+ }: NotificationsPopoverProps) {
34
+ const [open, setOpen] = useState(false);
35
+ const [hasNewNotifications, setHasNewNotifications] = useState(true);
36
+
37
+ const handleOpenChange = (isOpen: boolean) => {
38
+ setOpen(isOpen);
39
+ if (isOpen) setHasNewNotifications(false);
40
+ };
41
+
42
+ return (
43
+ <Popover open={open} onOpenChange={handleOpenChange}>
44
+ <PopoverTrigger className="cursor-pointer">
45
+ <div
46
+ className={`relative rounded-full p-2.5 ${open ? 'bg-gray-100' : 'hover:bg-gray-100'}`}
47
+ >
48
+ <Bell size={20} className="text-gray-500" />
49
+ {hasNewNotifications && (
50
+ <span className={cn('absolute top-2 right-2 size-2.5 rounded-full', badgeClassName)} />
51
+ )}
52
+ </div>
53
+ </PopoverTrigger>
54
+ <PopoverContent
55
+ className={cn(
56
+ 'absolute bottom-2 left-[26px] w-[308px] p-0 pt-4 bg-white rounded-2xl shadow-md border border-gray-200',
57
+ contentClassName
58
+ )}
59
+ side={side}
60
+ align={align}
61
+ sideOffset={8}
62
+ >
63
+ <span className="paragraph-small-semibold text-gray-950 px-4">Últimas notificações</span>
64
+
65
+ {notifications.length > 0 ? (
66
+ notifications.map((notification, index) => (
67
+ <NotificationItem
68
+ key={index}
69
+ icon={notification.icon}
70
+ iconBgColor={notification.iconBgColor}
71
+ title={notification.title}
72
+ time={notification.time}
73
+ showBorder={index < notifications.length - 1}
74
+ />
75
+ ))
76
+ ) : (
77
+ <div className="flex flex-col items-center gap-4 pt-[41.5px] pb-[33.5px]">
78
+ <div className="bg-gray-50 rounded-md p-2.5">
79
+ <Bell size={20} color="var(--color-gray-950)" />
80
+ </div>
81
+ <span className="paragraph-small-medium text-gray-950">Sem notificações por enquanto</span>
82
+ </div>
83
+ )}
84
+
85
+ {onViewAll && (
86
+ <Button
87
+ variant="secondary"
88
+ className="h-8! mt-2 mb-4 mx-4 paragraph-small-semibold"
89
+ onClick={onViewAll}
90
+ >
91
+ Todas as notificações
92
+ </Button>
93
+ )}
94
+ </PopoverContent>
95
+ </Popover>
96
+ );
97
+ }
98
+
99
+ export { NotificationsPopover };
@@ -0,0 +1,171 @@
1
+ "use client"
2
+
3
+ import { useState } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';
6
+ import { Button } from '../ui/buttons/Button';
7
+ import { Progress } from '../ui/feedback/Progress';
8
+ import { Separator } from '../ui/data-display/Separator';
9
+ import { NavBarItem } from './NavBarItem';
10
+ import { UserAvatar } from '../ui/data-display/UserAvatar';
11
+ import { useAuth } from '../../providers/auth.provider';
12
+ import { cn } from '../../infra/utils/clsx';
13
+
14
+ export interface ProfileMenuItem {
15
+ icon?: React.ReactNode;
16
+ label: string;
17
+ onClick: () => void;
18
+ }
19
+
20
+ export interface ProfilePopoverProps {
21
+ side?: 'top' | 'bottom' | 'left' | 'right';
22
+ align?: 'start' | 'center' | 'end';
23
+ contentClassName?: string;
24
+ onEditProfile?: () => void;
25
+ credits?: { used: number; total: number };
26
+ onCreditsClick?: () => void;
27
+ menuItems?: ProfileMenuItem[];
28
+ logoutRedirect?: string;
29
+ storageUrl?: string;
30
+ logoutOverlay?: React.ReactNode;
31
+ }
32
+
33
+ function ProfilePopover({
34
+ side = 'top',
35
+ align = 'start',
36
+ contentClassName,
37
+ onEditProfile,
38
+ credits,
39
+ onCreditsClick,
40
+ menuItems = [],
41
+ logoutRedirect = '/login',
42
+ storageUrl,
43
+ logoutOverlay,
44
+ }: ProfilePopoverProps) {
45
+ const router = useRouter();
46
+ const { user, logout } = useAuth();
47
+ const [isLoggingOut, setIsLoggingOut] = useState(false);
48
+
49
+ const handleLogout = async () => {
50
+ try {
51
+ setIsLoggingOut(true);
52
+ await logout();
53
+ router.push(logoutRedirect);
54
+ } catch (error) {
55
+ console.error('Erro ao fazer logout:', error);
56
+ } finally {
57
+ setIsLoggingOut(false);
58
+ }
59
+ };
60
+
61
+ const creditsPercentage =
62
+ credits && credits.total > 0
63
+ ? (credits.used / credits.total) * 100
64
+ : 0;
65
+
66
+ return (
67
+ <>
68
+ {isLoggingOut && logoutOverlay}
69
+ <Popover>
70
+ <PopoverTrigger className="cursor-pointer">
71
+ {user && (
72
+ <UserAvatar
73
+ key={user.id}
74
+ photo={user.photo}
75
+ name={user.name}
76
+ size={40}
77
+ storageUrl={storageUrl}
78
+ />
79
+ )}
80
+ </PopoverTrigger>
81
+
82
+ <PopoverContent
83
+ className={cn(
84
+ 'w-64.75 p-0 bg-white rounded-2xl shadow-md border border-gray-200 z-99',
85
+ contentClassName
86
+ )}
87
+ side={side}
88
+ align={align}
89
+ sideOffset={8}
90
+ >
91
+ <div className="grid grid-cols-[32px_1fr_auto] items-center gap-3 p-3 w-full">
92
+ {user && (
93
+ <UserAvatar
94
+ key={user.id}
95
+ photo={user.photo}
96
+ name={user.name}
97
+ size={32}
98
+ storageUrl={storageUrl}
99
+ />
100
+ )}
101
+
102
+ <div className="flex flex-col gap-0.5 min-w-0">
103
+ <span className="paragraph-small-semibold text-gray-950 truncate">
104
+ {user?.name || ''}
105
+ </span>
106
+ <span className="paragraph-xsmall-medium text-gray-500 truncate">
107
+ {user?.email || ''}
108
+ </span>
109
+ </div>
110
+
111
+ {onEditProfile && (
112
+ <Button
113
+ variant="secondary"
114
+ className="paragraph-small-semibold h-8! whitespace-nowrap px-3 w-fit"
115
+ onClick={onEditProfile}
116
+ >
117
+ Editar Perfil
118
+ </Button>
119
+ )}
120
+ </div>
121
+
122
+ <div className="flex flex-col gap-2 border-t border-gray-200 rounded-2xl p-1.5">
123
+ {credits && (
124
+ <div
125
+ className={cn(
126
+ 'flex flex-col bg-gray-950 rounded-lg gap-4 w-full p-4 transition-colors',
127
+ onCreditsClick && 'cursor-pointer hover:bg-gray-900'
128
+ )}
129
+ onClick={onCreditsClick}
130
+ >
131
+ <div className="flex items-center justify-between gap-2">
132
+ <span className="paragraph-xsmall-semibold text-white truncate">
133
+ Créditos usados
134
+ </span>
135
+ <span className="paragraph-xsmall-medium text-white/50">
136
+ {credits.used.toLocaleString('pt-BR')}/
137
+ {credits.total.toLocaleString('pt-BR')}
138
+ </span>
139
+ </div>
140
+ <Progress
141
+ className="bg-white/10"
142
+ indicatorColor="bg-white"
143
+ value={creditsPercentage}
144
+ />
145
+ </div>
146
+ )}
147
+
148
+ <div className="flex flex-col gap-2">
149
+ {menuItems.length > 0 && (
150
+ <div className="flex flex-col">
151
+ {menuItems.map((item, index) => (
152
+ <NavBarItem
153
+ key={index}
154
+ icon={item.icon}
155
+ label={item.label}
156
+ onClick={item.onClick}
157
+ />
158
+ ))}
159
+ </div>
160
+ )}
161
+ <Separator />
162
+ <NavBarItem label="Sair" onClick={handleLogout} />
163
+ </div>
164
+ </div>
165
+ </PopoverContent>
166
+ </Popover>
167
+ </>
168
+ );
169
+ }
170
+
171
+ export { ProfilePopover };
@@ -0,0 +1,158 @@
1
+ "use client"
2
+
3
+ import { useState } from 'react';
4
+ import { Plus, Settings, User } from 'lucide-react';
5
+ import Image from 'next/image';
6
+ import { useRouter } from 'next/navigation';
7
+ import { Popover, PopoverContent, PopoverTrigger } from '../ui/overlay/Popover';
8
+ import { Button } from '../ui/buttons/Button';
9
+ import { Command, CommandEmpty, CommandInput, CommandItem, CommandList } from '../ui/overlay/Command';
10
+ import { Checkbox } from '../ui/form/Checkbox';
11
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/overlay/Tooltip';
12
+ import { cn } from '../../infra/utils/clsx';
13
+
14
+ export interface UserSelectorItem {
15
+ id: number;
16
+ name: string;
17
+ avatar: string;
18
+ checked: boolean;
19
+ }
20
+
21
+ export interface UsersSelectorPopoverProps {
22
+ users?: UserSelectorItem[];
23
+ onToggleUser?: (id: number) => void;
24
+ addRoute?: string;
25
+ manageRoute?: string;
26
+ userCount?: number;
27
+ side?: 'top' | 'bottom' | 'left' | 'right';
28
+ align?: 'start' | 'center' | 'end';
29
+ contentClassName?: string;
30
+ }
31
+
32
+ function UsersSelectorPopover({
33
+ users: externalUsers,
34
+ onToggleUser,
35
+ addRoute = '/my-teams?createNew=true',
36
+ manageRoute = '/my-teams',
37
+ userCount = 5,
38
+ side,
39
+ align,
40
+ contentClassName,
41
+ }: UsersSelectorPopoverProps) {
42
+ const route = useRouter();
43
+ const [open, setOpen] = useState(false);
44
+ const [internalUsers, setInternalUsers] = useState<UserSelectorItem[]>(externalUsers ?? []);
45
+ const [hoveredId, setHoveredId] = useState<number | null>(null);
46
+
47
+ const users = externalUsers ?? internalUsers;
48
+
49
+ const toggleUser = (id: number) => {
50
+ if (onToggleUser) {
51
+ onToggleUser(id);
52
+ } else {
53
+ setInternalUsers((prev) =>
54
+ prev.map((u) => (u.id === id ? { ...u, checked: !u.checked } : u))
55
+ );
56
+ }
57
+ };
58
+
59
+ return (
60
+ <Popover open={open} onOpenChange={setOpen}>
61
+ <PopoverTrigger className="cursor-pointer">
62
+ <div className="flex items-center gap-2 text-gray-950 px-3 py-2 border border-gray-200 rounded-full hover:border-gray-950">
63
+ <span className="paragraph-small-semibold">{userCount}</span>
64
+ <User size={16} />
65
+ </div>
66
+ </PopoverTrigger>
67
+
68
+ <PopoverContent
69
+ className={cn(
70
+ 'absolute right-[-88px] w-[273px] p-0 bg-white rounded-2xl shadow-md border border-gray-200',
71
+ contentClassName
72
+ )}
73
+ side={side}
74
+ align={align}
75
+ sideOffset={8}
76
+ >
77
+ <div className="flex flex-col p-3 gap-2">
78
+ <div className="flex items-center justify-between">
79
+ <span className="paragraph-small-semibold">Usuários</span>
80
+ <div className="flex items-center gap-1.5">
81
+ <Button
82
+ variant="secondary"
83
+ className="h-8 paragraph-small-semibold text-gray-950"
84
+ onClick={() => route.push(addRoute)}
85
+ >
86
+ <Plus size={16} />
87
+ Adicionar
88
+ </Button>
89
+
90
+ <Tooltip>
91
+ <TooltipTrigger asChild>
92
+ <Button
93
+ variant="secondary"
94
+ className="p-0 size-8"
95
+ onClick={() => route.push(manageRoute)}
96
+ >
97
+ <Settings size={18} />
98
+ </Button>
99
+ </TooltipTrigger>
100
+ <TooltipContent>Visualizar todos usuários</TooltipContent>
101
+ </Tooltip>
102
+ </div>
103
+ </div>
104
+
105
+ <Command className="gap-2" value="">
106
+ <CommandInput placeholder="Busque aqui" />
107
+ <CommandList className="custom-scrollbar paragraph-small-medium text-gray-600 h-[162px]">
108
+ <CommandEmpty>No results found.</CommandEmpty>
109
+ {users.map((user) => (
110
+ <CommandItem
111
+ key={user.id}
112
+ autoFocus={false}
113
+ onPointerEnter={() => setHoveredId(user.id)}
114
+ onPointerLeave={() => setHoveredId(null)}
115
+ onFocus={() => setHoveredId(user.id)}
116
+ onBlur={() => setHoveredId(null)}
117
+ onSelect={() => toggleUser(user.id)}
118
+ className="cursor-pointer"
119
+ >
120
+ <div className="flex items-center justify-between w-full">
121
+ <div className="flex items-center gap-2">
122
+ <Image
123
+ alt="Avatar"
124
+ src={user.avatar}
125
+ width={32}
126
+ height={32}
127
+ className="rounded-full"
128
+ />
129
+ {user.name}
130
+ </div>
131
+
132
+ <Tooltip open={hoveredId === user.id}>
133
+ <TooltipTrigger
134
+ onClick={(e) => e.stopPropagation()}
135
+ onPointerDown={(e) => e.stopPropagation()}
136
+ >
137
+ <Checkbox
138
+ checked={user.checked}
139
+ onCheckedChange={() => toggleUser(user.id)}
140
+ className={hoveredId === user.id ? 'border-gray-950' : ''}
141
+ />
142
+ </TooltipTrigger>
143
+ <TooltipContent>
144
+ {user.checked ? 'Remover do projeto' : 'Adicionar ao projeto'}
145
+ </TooltipContent>
146
+ </Tooltip>
147
+ </div>
148
+ </CommandItem>
149
+ ))}
150
+ </CommandList>
151
+ </Command>
152
+ </div>
153
+ </PopoverContent>
154
+ </Popover>
155
+ );
156
+ }
157
+
158
+ export { UsersSelectorPopover };
@@ -0,0 +1,67 @@
1
+ "use client"
2
+
3
+ import Image from 'next/image';
4
+ import { cn } from '../../../infra/utils/clsx';
5
+
6
+ function getInitials(name: string, maxLength: number = 2): string {
7
+ return name
8
+ .split(' ')
9
+ .map((n) => n[0])
10
+ .join('')
11
+ .slice(0, maxLength)
12
+ .toUpperCase();
13
+ }
14
+
15
+ interface UserAvatarProps {
16
+ photo?: string | null;
17
+ name?: string;
18
+ initials?: string;
19
+ size?: number;
20
+ shape?: 'circle' | 'square';
21
+ className?: string;
22
+ storageUrl?: string;
23
+ }
24
+
25
+ function UserAvatar({
26
+ photo,
27
+ name,
28
+ initials,
29
+ size = 32,
30
+ shape = 'circle',
31
+ className,
32
+ storageUrl,
33
+ }: UserAvatarProps) {
34
+ const shapeClass = shape === 'circle' ? 'rounded-full' : 'rounded-lg';
35
+ const displayInitials = initials || (name ? getInitials(name) : '?');
36
+
37
+ const photoUrl = storageUrl && photo ? `${storageUrl}/${photo}` : photo;
38
+
39
+ if (photoUrl) {
40
+ return (
41
+ <Image
42
+ alt={name || 'imagem do usuario'}
43
+ src={photoUrl}
44
+ width={size}
45
+ height={size}
46
+ className={cn('object-cover shrink-0', shapeClass, className)}
47
+ style={{ width: size, height: size }}
48
+ />
49
+ );
50
+ }
51
+
52
+ return (
53
+ <div
54
+ className={cn(
55
+ 'flex items-center justify-center shrink-0 bg-gray-100',
56
+ shapeClass,
57
+ className
58
+ )}
59
+ style={{ width: size, height: size }}
60
+ >
61
+ <span className="text-xs font-semibold text-gray-700">{displayInitials}</span>
62
+ </div>
63
+ );
64
+ }
65
+
66
+ export { UserAvatar };
67
+ export type { UserAvatarProps };
package/src/index.ts CHANGED
@@ -33,6 +33,57 @@ export { SideBarNavigation } from './components/layouts/SideBarNavigation';
33
33
  export { MdSideBarNavigation } from './components/layouts/MdSideBarNavigation';
34
34
  export { NotificationItem } from './components/layouts/NotificationItem';
35
35
  export type { NotificationItemProps } from './components/layouts/NotificationItem';
36
+ export { NotificationsPopover } from './components/layouts/NotificationsPopover';
37
+ export type { NotificationsPopoverProps, NotificationData } from './components/layouts/NotificationsPopover';
38
+ export { UsersSelectorPopover } from './components/layouts/UsersSelectorPopover';
39
+ export type { UsersSelectorPopoverProps, UserSelectorItem } from './components/layouts/UsersSelectorPopover';
40
+ export { ProfilePopover } from './components/layouts/ProfilePopover';
41
+ export type { ProfilePopoverProps, ProfileMenuItem } from './components/layouts/ProfilePopover';
42
+ export { NavBarItem } from './components/layouts/NavBarItem';
43
+ export type { NavBarItemProps } from './components/layouts/NavBarItem';
44
+
45
+ // UI - Buttons
46
+ export { Button, buttonVariants } from './components/ui/buttons/Button';
47
+ export { CopyButton } from './components/ui/buttons/CopyButton';
48
+ export { default as CancelButton } from './components/ui/buttons/CancelButton';
49
+
50
+ // UI - Data Display
51
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './components/ui/data-display/Accordion';
52
+ export { Badge, badgeVariants } from './components/ui/data-display/Badge';
53
+ export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent } from './components/ui/data-display/Card';
54
+ export { Pagination, PaginationContent, PaginationLink, PaginationItem, PaginationPrevious, PaginationNext, PaginationEllipsis } from './components/ui/data-display/Pagination';
55
+ export { ScrollArea, ScrollBar } from './components/ui/data-display/ScrollArea';
56
+ export { Separator } from './components/ui/data-display/Separator';
57
+ export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption } from './components/ui/data-display/Table';
58
+ export { Tabs, TabsList, TabsTrigger, TabsContent } from './components/ui/data-display/Tabs';
59
+ export { UserAvatar } from './components/ui/data-display/UserAvatar';
60
+ export type { UserAvatarProps } from './components/ui/data-display/UserAvatar';
61
+
62
+ // UI - Feedback
63
+ export { default as CircularProgress } from './components/ui/feedback/CircularProgress';
64
+ export { default as DefaultCircularProgress } from './components/ui/feedback/DefaultCircularProgress';
65
+ export { Progress } from './components/ui/feedback/Progress';
66
+ export { Toast, toastVariants, toastIconContainerVariants } from './components/ui/feedback/Toast';
67
+ export type { ToastProps } from './components/ui/feedback/Toast';
68
+
69
+ // UI - Form
70
+ export { Calendar, CalendarDayButton } from './components/ui/form/Calendar';
71
+ export { Checkbox } from './components/ui/form/Checkbox';
72
+ export { DatePicker } from './components/ui/form/DatePicker';
73
+ export { DateRangePicker } from './components/ui/form/DateRangePicker';
74
+ export { Input } from './components/ui/form/Input';
75
+ export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator } from './components/ui/form/InputOtp';
76
+ export { RadioGroup, RadioGroupItem } from './components/ui/form/RadioGroup';
77
+ export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './components/ui/form/Select';
78
+ export { Switch } from './components/ui/form/Switch';
79
+ export { Textarea } from './components/ui/form/Textarea';
80
+
81
+ // UI - Overlay
82
+ export { Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator } from './components/ui/overlay/Command';
83
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './components/ui/overlay/Dialog';
84
+ export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } from './components/ui/overlay/Popover';
85
+ export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription } from './components/ui/overlay/Sheet';
86
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './components/ui/overlay/Tooltip';
36
87
 
37
88
  // Store
38
89
  export { useMdSidebarStore } from './store/useMdSidebarStore';