@greatapps/common 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/components/handlers/SearchParamsHandler.mjs +23 -0
  2. package/dist/components/handlers/SearchParamsHandler.mjs.map +1 -0
  3. package/dist/components/layouts/MainLayout.mjs +60 -0
  4. package/dist/components/layouts/MainLayout.mjs.map +1 -0
  5. package/dist/components/layouts/MdSideBarNavigation.mjs +36 -0
  6. package/dist/components/layouts/MdSideBarNavigation.mjs.map +1 -0
  7. package/dist/components/layouts/NavBar.mjs +45 -0
  8. package/dist/components/layouts/NavBar.mjs.map +1 -0
  9. package/dist/components/layouts/NotificationItem.mjs +7 -0
  10. package/dist/components/layouts/NotificationItem.mjs.map +1 -0
  11. package/dist/components/layouts/SideBarNavigation.mjs +22 -0
  12. package/dist/components/layouts/SideBarNavigation.mjs.map +1 -0
  13. package/dist/components/ui/buttons/Button.mjs +51 -0
  14. package/dist/components/ui/buttons/Button.mjs.map +1 -0
  15. package/dist/components/ui/buttons/CancelButton.mjs +16 -0
  16. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -0
  17. package/dist/components/ui/buttons/CopyButton.mjs +34 -0
  18. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -0
  19. package/dist/components/ui/data-display/Accordion.mjs +73 -0
  20. package/dist/components/ui/data-display/Accordion.mjs.map +1 -0
  21. package/dist/components/ui/data-display/Badge.mjs +41 -0
  22. package/dist/components/ui/data-display/Badge.mjs.map +1 -0
  23. package/dist/components/ui/data-display/Card.mjs +91 -0
  24. package/dist/components/ui/data-display/Card.mjs.map +1 -0
  25. package/dist/components/ui/data-display/Pagination.mjs +115 -0
  26. package/dist/components/ui/data-display/Pagination.mjs.map +1 -0
  27. package/dist/components/ui/data-display/ScrollArea.mjs +60 -0
  28. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -0
  29. package/dist/components/ui/data-display/Separator.mjs +28 -0
  30. package/dist/components/ui/data-display/Separator.mjs.map +1 -0
  31. package/dist/components/ui/data-display/Table.mjs +116 -0
  32. package/dist/components/ui/data-display/Table.mjs.map +1 -0
  33. package/dist/components/ui/data-display/Tabs.mjs +69 -0
  34. package/dist/components/ui/data-display/Tabs.mjs.map +1 -0
  35. package/dist/components/ui/feedback/CircularProgress.mjs +61 -0
  36. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -0
  37. package/dist/components/ui/feedback/DefaultCircularProgress.mjs +49 -0
  38. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -0
  39. package/dist/components/ui/feedback/Progress.mjs +37 -0
  40. package/dist/components/ui/feedback/Progress.mjs.map +1 -0
  41. package/dist/components/ui/feedback/Toast.mjs +73 -0
  42. package/dist/components/ui/feedback/Toast.mjs.map +1 -0
  43. package/dist/components/ui/form/Calendar.mjs +203 -0
  44. package/dist/components/ui/form/Calendar.mjs.map +1 -0
  45. package/dist/components/ui/form/Checkbox.mjs +33 -0
  46. package/dist/components/ui/form/Checkbox.mjs.map +1 -0
  47. package/dist/components/ui/form/DatePicker.mjs +78 -0
  48. package/dist/components/ui/form/DatePicker.mjs.map +1 -0
  49. package/dist/components/ui/form/DateRangePicker.mjs +86 -0
  50. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -0
  51. package/dist/components/ui/form/Input.mjs +20 -0
  52. package/dist/components/ui/form/Input.mjs.map +1 -0
  53. package/dist/components/ui/form/InputOtp.mjs +67 -0
  54. package/dist/components/ui/form/InputOtp.mjs.map +1 -0
  55. package/dist/components/ui/form/RadioGroup.mjs +36 -0
  56. package/dist/components/ui/form/RadioGroup.mjs.map +1 -0
  57. package/dist/components/ui/form/Select.mjs +172 -0
  58. package/dist/components/ui/form/Select.mjs.map +1 -0
  59. package/dist/components/ui/form/Switch.mjs +33 -0
  60. package/dist/components/ui/form/Switch.mjs.map +1 -0
  61. package/dist/components/ui/form/Textarea.mjs +19 -0
  62. package/dist/components/ui/form/Textarea.mjs.map +1 -0
  63. package/dist/components/ui/overlay/Command.mjs +170 -0
  64. package/dist/components/ui/overlay/Command.mjs.map +1 -0
  65. package/dist/components/ui/overlay/Dialog.mjs +131 -0
  66. package/dist/components/ui/overlay/Dialog.mjs.map +1 -0
  67. package/dist/components/ui/overlay/Popover.mjs +46 -0
  68. package/dist/components/ui/overlay/Popover.mjs.map +1 -0
  69. package/dist/components/ui/overlay/Sheet.mjs +129 -0
  70. package/dist/components/ui/overlay/Sheet.mjs.map +1 -0
  71. package/dist/components/ui/overlay/Tooltip.mjs +55 -0
  72. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -0
  73. package/dist/hooks/copy-to-clipboard.hook.mjs +39 -0
  74. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -0
  75. package/dist/index.mjs +57 -0
  76. package/dist/index.mjs.map +1 -0
  77. package/dist/infra/api/client.mjs +115 -0
  78. package/dist/infra/api/client.mjs.map +1 -0
  79. package/dist/infra/api/types.mjs +31 -0
  80. package/dist/infra/api/types.mjs.map +1 -0
  81. package/dist/infra/utils/client-info.mjs +27 -0
  82. package/dist/infra/utils/client-info.mjs.map +1 -0
  83. package/dist/infra/utils/clsx.mjs +9 -0
  84. package/dist/infra/utils/clsx.mjs.map +1 -0
  85. package/dist/infra/utils/params.mjs +21 -0
  86. package/dist/infra/utils/params.mjs.map +1 -0
  87. package/dist/infra/utils/percentage.mjs +20 -0
  88. package/dist/infra/utils/percentage.mjs.map +1 -0
  89. package/dist/middlewares/chain.mjs +37 -0
  90. package/dist/middlewares/chain.mjs.map +1 -0
  91. package/dist/middlewares/create-auth-middleware.mjs +28 -0
  92. package/dist/middlewares/create-auth-middleware.mjs.map +1 -0
  93. package/dist/middlewares/types.mjs +11 -0
  94. package/dist/middlewares/types.mjs.map +1 -0
  95. package/dist/middlewares/validate-session.mjs +92 -0
  96. package/dist/middlewares/validate-session.mjs.map +1 -0
  97. package/dist/modules/auth/actions/login.action.mjs +11 -0
  98. package/dist/modules/auth/actions/login.action.mjs.map +1 -0
  99. package/dist/modules/auth/actions/logout.action.mjs +11 -0
  100. package/dist/modules/auth/actions/logout.action.mjs.map +1 -0
  101. package/dist/modules/auth/actions/register.action.mjs +9 -0
  102. package/dist/modules/auth/actions/register.action.mjs.map +1 -0
  103. package/dist/modules/auth/actions/validate-session.action.mjs +44 -0
  104. package/dist/modules/auth/actions/validate-session.action.mjs.map +1 -0
  105. package/dist/modules/auth/hooks/login.hook.mjs +12 -0
  106. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -0
  107. package/dist/modules/auth/hooks/logout.hook.mjs +12 -0
  108. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -0
  109. package/dist/modules/auth/hooks/register.hook.mjs +12 -0
  110. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -0
  111. package/dist/modules/auth/hooks/useUserQuery.mjs +48 -0
  112. package/dist/modules/auth/hooks/useUserQuery.mjs.map +1 -0
  113. package/dist/modules/auth/schema.mjs +1 -0
  114. package/dist/modules/auth/schema.mjs.map +1 -0
  115. package/dist/modules/auth/services/auth.service.mjs +163 -0
  116. package/dist/modules/auth/services/auth.service.mjs.map +1 -0
  117. package/dist/modules/users/action/find-user-by-id.action.mjs +21 -0
  118. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -0
  119. package/dist/modules/users/schema.mjs +11 -0
  120. package/dist/modules/users/schema.mjs.map +1 -0
  121. package/dist/modules/users/services/user.service.mjs +50 -0
  122. package/dist/modules/users/services/user.service.mjs.map +1 -0
  123. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs +19 -0
  124. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -0
  125. package/dist/modules/whitelabel/schema.mjs +1 -0
  126. package/dist/modules/whitelabel/schema.mjs.map +1 -0
  127. package/dist/modules/whitelabel/services/whitelabel.service.mjs +62 -0
  128. package/dist/modules/whitelabel/services/whitelabel.service.mjs.map +1 -0
  129. package/dist/providers/auth.provider.mjs +84 -0
  130. package/dist/providers/auth.provider.mjs.map +1 -0
  131. package/dist/providers/query.provider.mjs +37 -0
  132. package/dist/providers/query.provider.mjs.map +1 -0
  133. package/dist/providers/whitelabel.provider.mjs +33 -0
  134. package/dist/providers/whitelabel.provider.mjs.map +1 -0
  135. package/dist/store/useMdSidebarStore.mjs +11 -0
  136. package/dist/store/useMdSidebarStore.mjs.map +1 -0
  137. package/package.json +68 -0
  138. package/src/components/handlers/SearchParamsHandler.tsx +61 -0
  139. package/src/components/layouts/MainLayout.tsx +59 -0
  140. package/src/components/layouts/MdSideBarNavigation.tsx +39 -0
  141. package/src/components/layouts/NavBar.tsx +79 -0
  142. package/src/components/layouts/NotificationItem.tsx +26 -0
  143. package/src/components/layouts/SideBarNavigation.tsx +22 -0
  144. package/src/components/ui/buttons/Button.tsx +55 -0
  145. package/src/components/ui/buttons/CancelButton.tsx +12 -0
  146. package/src/components/ui/buttons/CopyButton.tsx +47 -0
  147. package/src/components/ui/data-display/Accordion.tsx +79 -0
  148. package/src/components/ui/data-display/Badge.tsx +45 -0
  149. package/src/components/ui/data-display/Card.tsx +91 -0
  150. package/src/components/ui/data-display/Pagination.tsx +124 -0
  151. package/src/components/ui/data-display/ScrollArea.tsx +57 -0
  152. package/src/components/ui/data-display/Separator.tsx +27 -0
  153. package/src/components/ui/data-display/Table.tsx +115 -0
  154. package/src/components/ui/data-display/Tabs.tsx +65 -0
  155. package/src/components/ui/feedback/CircularProgress.tsx +75 -0
  156. package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -0
  157. package/src/components/ui/feedback/Progress.tsx +38 -0
  158. package/src/components/ui/feedback/Toast.tsx +99 -0
  159. package/src/components/ui/form/Calendar.tsx +226 -0
  160. package/src/components/ui/form/Checkbox.tsx +31 -0
  161. package/src/components/ui/form/DatePicker.tsx +97 -0
  162. package/src/components/ui/form/DateRangePicker.tsx +108 -0
  163. package/src/components/ui/form/Input.tsx +18 -0
  164. package/src/components/ui/form/InputOtp.tsx +78 -0
  165. package/src/components/ui/form/RadioGroup.tsx +43 -0
  166. package/src/components/ui/form/Select.tsx +195 -0
  167. package/src/components/ui/form/Switch.tsx +30 -0
  168. package/src/components/ui/form/Textarea.tsx +17 -0
  169. package/src/components/ui/overlay/Command.tsx +183 -0
  170. package/src/components/ui/overlay/Dialog.tsx +146 -0
  171. package/src/components/ui/overlay/Popover.tsx +47 -0
  172. package/src/components/ui/overlay/Sheet.tsx +145 -0
  173. package/src/components/ui/overlay/Tooltip.tsx +60 -0
  174. package/src/hooks/copy-to-clipboard.hook.tsx +52 -0
  175. package/src/index.ts +50 -0
  176. package/src/infra/api/client.ts +142 -0
  177. package/src/infra/api/types.ts +79 -0
  178. package/src/infra/utils/client-info.ts +35 -0
  179. package/src/infra/utils/clsx.ts +6 -0
  180. package/src/infra/utils/params.ts +27 -0
  181. package/src/infra/utils/percentage.ts +42 -0
  182. package/src/middlewares/chain.ts +45 -0
  183. package/src/middlewares/create-auth-middleware.ts +38 -0
  184. package/src/middlewares/types.ts +24 -0
  185. package/src/middlewares/validate-session.ts +116 -0
  186. package/src/modules/auth/actions/login.action.ts +11 -0
  187. package/src/modules/auth/actions/logout.action.ts +11 -0
  188. package/src/modules/auth/actions/register.action.ts +8 -0
  189. package/src/modules/auth/actions/validate-session.action.ts +51 -0
  190. package/src/modules/auth/hooks/login.hook.tsx +10 -0
  191. package/src/modules/auth/hooks/logout.hook.tsx +10 -0
  192. package/src/modules/auth/hooks/register.hook.tsx +10 -0
  193. package/src/modules/auth/hooks/useUserQuery.ts +49 -0
  194. package/src/modules/auth/schema.ts +220 -0
  195. package/src/modules/auth/services/auth.service.ts +225 -0
  196. package/src/modules/users/action/find-user-by-id.action.ts +25 -0
  197. package/src/modules/users/schema.ts +79 -0
  198. package/src/modules/users/services/user.service.ts +63 -0
  199. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +20 -0
  200. package/src/modules/whitelabel/schema.ts +49 -0
  201. package/src/modules/whitelabel/services/whitelabel.service.ts +77 -0
  202. package/src/providers/auth.provider.tsx +113 -0
  203. package/src/providers/query.provider.tsx +52 -0
  204. package/src/providers/whitelabel.provider.tsx +44 -0
  205. package/src/store/useMdSidebarStore.ts +15 -0
@@ -0,0 +1,79 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import Image from "next/image"
5
+ import { ChevronRight } from "lucide-react"
6
+ import { Separator } from "../ui/data-display/Separator"
7
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/overlay/Tooltip"
8
+ import { cn } from "../../infra/utils/clsx"
9
+
10
+ type NavBarProps = {
11
+ onLogoClick: () => void;
12
+ logoIndicatorClassName?: string;
13
+ showExpandButton?: boolean;
14
+ onExpandClick?: () => void;
15
+ appIconSlot: React.ReactNode;
16
+ children?: React.ReactNode;
17
+ className?: string;
18
+ }
19
+
20
+ function NavBar({
21
+ onLogoClick,
22
+ logoIndicatorClassName,
23
+ showExpandButton = false,
24
+ onExpandClick,
25
+ appIconSlot,
26
+ children,
27
+ className,
28
+ }: NavBarProps) {
29
+ return (
30
+ <div className={cn("hidden md:flex flex-col justify-between h-screen p-4 border-r border-gray-200 overflow-visible z-40 bg-white", className)}>
31
+ <div className="flex flex-col gap-4 items-center mt-[6.5px]">
32
+ <div className="relative">
33
+ <Tooltip>
34
+ <TooltipTrigger className="cursor-pointer" asChild onClick={onLogoClick}>
35
+ <Image
36
+ src="/icons/great-icon.svg"
37
+ alt="Great Icon"
38
+ width={28}
39
+ height={28}
40
+ />
41
+ </TooltipTrigger>
42
+ <TooltipContent side="right">GreatApps</TooltipContent>
43
+ </Tooltip>
44
+ <div
45
+ className={cn(
46
+ "absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 bg-gray-950 rounded-r-xl transition-opacity duration-300",
47
+ logoIndicatorClassName
48
+ )}
49
+ />
50
+ </div>
51
+ <div className="relative w-full mt-[7.5px]">
52
+ <Separator />
53
+ {showExpandButton && (
54
+ <Tooltip>
55
+ <TooltipTrigger asChild>
56
+ <button
57
+ onClick={onExpandClick}
58
+ className="lg:hidden absolute top-1/2 -translate-y-1/2 right-0 translate-x-[calc(50%+1rem)] size-8 flex items-center justify-center rounded-full border border-gray-200 bg-white hover:bg-gray-100 cursor-pointer transition-colors z-10"
59
+ >
60
+ <ChevronRight size={16} className="text-gray-500" />
61
+ </button>
62
+ </TooltipTrigger>
63
+ <TooltipContent side="right">Expandir menu</TooltipContent>
64
+ </Tooltip>
65
+ )}
66
+ </div>
67
+ <div className="flex flex-col gap-2">
68
+ {appIconSlot}
69
+ </div>
70
+ </div>
71
+ <div className="flex flex-col items-center gap-2">
72
+ {children}
73
+ </div>
74
+ </div>
75
+ )
76
+ }
77
+
78
+ export { NavBar };
79
+ export type { NavBarProps };
@@ -0,0 +1,26 @@
1
+ import { ReactNode } from "react";
2
+
3
+ type NotificationItemProps = {
4
+ icon: ReactNode;
5
+ iconBgColor: string;
6
+ title: string;
7
+ time: string;
8
+ showBorder?: boolean;
9
+ }
10
+
11
+ function NotificationItem({ icon, iconBgColor, title, time, showBorder = true }: NotificationItemProps) {
12
+ return (
13
+ <div className={`flex items-center gap-3 px-4 py-5 ${showBorder ? 'border-b border-gray-200' : ''}`}>
14
+ <div className={`flex items-center justify-center rounded-full ${iconBgColor} size-10`}>
15
+ {icon}
16
+ </div>
17
+ <div className="flex flex-col gap-1.5">
18
+ <span className="paragraph-small-semibold text-gray-950">{title}</span>
19
+ <span className="paragraph-xsmall-medium text-gray-500">{time}</span>
20
+ </div>
21
+ </div>
22
+ );
23
+ }
24
+
25
+ export { NotificationItem };
26
+ export type { NotificationItemProps };
@@ -0,0 +1,22 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "../../infra/utils/clsx"
5
+
6
+ function SideBarNavigation({
7
+ className,
8
+ children,
9
+ ...props
10
+ }: React.ComponentProps<"div">) {
11
+ return (
12
+ <div
13
+ data-slot="sidebar-navigation"
14
+ className={cn("hidden lg:flex flex-col h-screen p-4 border-r w-[273px] border-gray-200", className)}
15
+ {...props}
16
+ >
17
+ {children}
18
+ </div>
19
+ )
20
+ }
21
+
22
+ export { SideBarNavigation };
@@ -0,0 +1,55 @@
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+ import { cn } from "../../../infra/utils/clsx"
5
+
6
+ const buttonVariants = cva(
7
+ "paragraph-small-semibold cursor-pointer flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: " bg-gray-950 text-white hover:bg-gray-950/90",
12
+ secondary:
13
+ "bg-white text-gray-950 border-gray-200 hover:border-gray-400 border",
14
+ ghost:
15
+ "text-gray-600 hover:bg-accent hover:text-gray-950 dark:hover:bg-accent/50",
16
+ brand: "bg-pages-300 hover:bg-pages-200 text-gray-950",
17
+ },
18
+ size: {
19
+ default: "h-12 px-4 py-2 has-[>svg]:px-3",
20
+ sm: "rounded-md gap-1.5 px-2 py-2 has-[>svg]:px-2.5",
21
+ lg: "rounded-md px-6 has-[>svg]:px-4",
22
+ icon: "size-9",
23
+ "icon-sm": "size-8",
24
+ "icon-lg": "size-10",
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: "default",
29
+ size: "default",
30
+ },
31
+ }
32
+ )
33
+
34
+ function Button({
35
+ className,
36
+ variant,
37
+ size,
38
+ asChild = false,
39
+ ...props
40
+ }: React.ComponentProps<"button"> &
41
+ VariantProps<typeof buttonVariants> & {
42
+ asChild?: boolean
43
+ }) {
44
+ const Comp = asChild ? Slot : "button"
45
+
46
+ return (
47
+ <Comp
48
+ data-slot="button"
49
+ className={cn(buttonVariants({ variant, size, className }))}
50
+ {...props}
51
+ />
52
+ )
53
+ }
54
+
55
+ export { Button, buttonVariants }
@@ -0,0 +1,12 @@
1
+ import * as React from "react";
2
+
3
+ export default function CancelButton({
4
+ ...props
5
+ }: React.ComponentProps<"button">) {
6
+ return (
7
+ <button
8
+ className="flex h-8 px-2 justify-center items-center rounded-lg bg-red-50 text-red-600 font-semibold text-sm px-3 cursor-pointer hover:bg-red-100"
9
+ {...props}
10
+ />
11
+ );
12
+ }
@@ -0,0 +1,47 @@
1
+ import { Check, Copy } from "lucide-react";
2
+ import { toast } from "sonner";
3
+ import { Toast } from "../feedback/Toast";
4
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../overlay/Tooltip";
5
+ import useCopyToClipboard from "../../../hooks/copy-to-clipboard.hook";
6
+ import { cn } from "../../../infra/utils/clsx";
7
+
8
+ interface CopyButtonProps {
9
+ textToCopy: string;
10
+ size?: number;
11
+ className?: string;
12
+ tooltipText?: string;
13
+ successMessage?: string;
14
+ }
15
+
16
+ export function CopyButton({
17
+ textToCopy,
18
+ size = 14,
19
+ className,
20
+ tooltipText = "Copiar link",
21
+ successMessage = "Link copiado",
22
+ }: CopyButtonProps) {
23
+ const { isCopied, copy } = useCopyToClipboard({
24
+ onSuccess: () => {
25
+ toast.custom((t) => (
26
+ <Toast variant="success" message={successMessage} toastId={t} />
27
+ ));
28
+ },
29
+ });
30
+
31
+ return (
32
+ <Tooltip>
33
+ <TooltipTrigger
34
+ asChild
35
+ onClick={(e: React.MouseEvent) => {
36
+ e.stopPropagation();
37
+ copy(textToCopy);
38
+ }}
39
+ >
40
+ <span className={cn("cursor-pointer text-gray-500", className)}>
41
+ {isCopied ? <Check size={size} /> : <Copy size={size} />}
42
+ </span>
43
+ </TooltipTrigger>
44
+ <TooltipContent>{isCopied ? "Copiado!" : tooltipText}</TooltipContent>
45
+ </Tooltip>
46
+ );
47
+ }
@@ -0,0 +1,79 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as AccordionPrimitive from "@radix-ui/react-accordion"
5
+ import { ChevronDownIcon } from "lucide-react"
6
+ import { cn } from "../../../infra/utils/clsx"
7
+
8
+ function Accordion({
9
+ ...props
10
+ }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
11
+ return <AccordionPrimitive.Root data-slot="accordion" {...props} />
12
+ }
13
+
14
+ function AccordionItem({
15
+ className,
16
+ children,
17
+ ...props
18
+ }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
19
+ const itemRef = React.useRef<HTMLDivElement>(null);
20
+
21
+ return (
22
+ <AccordionPrimitive.Item
23
+ ref={itemRef}
24
+ data-slot="accordion-item"
25
+ className={cn("cursor-pointer border rounded-lg p-5", className)}
26
+ onClick={(e) => {
27
+ // Evita abrir/fechar quando o clique já é no Trigger
28
+ if ((e.target as HTMLElement).closest("[data-slot='accordion-trigger']")) return;
29
+
30
+ // Procura o trigger interno e clica nele
31
+ const trigger = itemRef.current?.querySelector("[data-slot='accordion-trigger']") as HTMLElement | null;
32
+ trigger?.click();
33
+ }}
34
+ {...props}
35
+ >
36
+ {children}
37
+ </AccordionPrimitive.Item>
38
+ );
39
+ }
40
+
41
+ function AccordionTrigger({
42
+ className,
43
+ children,
44
+ ...props
45
+ }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
46
+ return (
47
+ <AccordionPrimitive.Header className="flex">
48
+ <AccordionPrimitive.Trigger
49
+ data-slot="accordion-trigger"
50
+ className={cn(
51
+ "cursor-pointer focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
52
+ className
53
+ )}
54
+ {...props}
55
+ >
56
+ {children}
57
+ <ChevronDownIcon className="size-5! text-gray-950 pointer-events-none shrink-0 translate-y-0.5 transition-transform duration-200" />
58
+ </AccordionPrimitive.Trigger>
59
+ </AccordionPrimitive.Header>
60
+ )
61
+ }
62
+
63
+ function AccordionContent({
64
+ className,
65
+ children,
66
+ ...props
67
+ }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
68
+ return (
69
+ <AccordionPrimitive.Content
70
+ data-slot="accordion-content"
71
+ className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
72
+ {...props}
73
+ >
74
+ <div className={cn("pt-3 paragraph-small-regular text-gray-500", className)}>{children}</div>
75
+ </AccordionPrimitive.Content>
76
+ )
77
+ }
78
+
79
+ export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
@@ -0,0 +1,45 @@
1
+ import * as React from "react"
2
+ import { Slot } from "@radix-ui/react-slot"
3
+ import { cva, type VariantProps } from "class-variance-authority"
4
+ import { cn } from "../../../infra/utils/clsx"
5
+
6
+ const badgeVariants = cva(
7
+ "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
13
+ secondary:
14
+ "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
15
+ destructive:
16
+ "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
17
+ outline:
18
+ "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: "default",
23
+ },
24
+ }
25
+ )
26
+
27
+ function Badge({
28
+ className,
29
+ variant,
30
+ asChild = false,
31
+ ...props
32
+ }: React.ComponentProps<"span"> &
33
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
34
+ const Comp = asChild ? Slot : "span"
35
+
36
+ return (
37
+ <Comp
38
+ data-slot="badge"
39
+ className={cn(badgeVariants({ variant }), className)}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ export { Badge, badgeVariants }
@@ -0,0 +1,91 @@
1
+ import * as React from "react";
2
+ import { cn } from "../../../infra/utils/clsx";
3
+
4
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
5
+ return (
6
+ <div
7
+ data-slot="card"
8
+ className={cn(
9
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
10
+ className,
11
+ )}
12
+ {...props}
13
+ />
14
+ );
15
+ }
16
+
17
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
18
+ return (
19
+ <div
20
+ data-slot="card-header"
21
+ className={cn(
22
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
23
+ className,
24
+ )}
25
+ {...props}
26
+ />
27
+ );
28
+ }
29
+
30
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
31
+ return (
32
+ <div
33
+ data-slot="card-title"
34
+ className={cn("leading-none font-semibold", className)}
35
+ {...props}
36
+ />
37
+ );
38
+ }
39
+
40
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
41
+ return (
42
+ <div
43
+ data-slot="card-description"
44
+ className={cn("text-muted-foreground text-sm", className)}
45
+ {...props}
46
+ />
47
+ );
48
+ }
49
+
50
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
51
+ return (
52
+ <div
53
+ data-slot="card-action"
54
+ className={cn(
55
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
56
+ className,
57
+ )}
58
+ {...props}
59
+ />
60
+ );
61
+ }
62
+
63
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
64
+ return (
65
+ <div
66
+ data-slot="card-content"
67
+ className={cn("px-6", className)}
68
+ {...props}
69
+ />
70
+ );
71
+ }
72
+
73
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="card-footer"
77
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+
83
+ export {
84
+ Card,
85
+ CardHeader,
86
+ CardFooter,
87
+ CardTitle,
88
+ CardAction,
89
+ CardDescription,
90
+ CardContent,
91
+ };
@@ -0,0 +1,124 @@
1
+ import * as React from "react"
2
+ import {
3
+ ChevronLeftIcon,
4
+ ChevronRightIcon,
5
+ MoreHorizontalIcon,
6
+ } from "lucide-react"
7
+ import { cn } from "../../../infra/utils/clsx"
8
+ import { Button, buttonVariants } from "../buttons/Button"
9
+
10
+ function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
11
+ return (
12
+ <nav
13
+ role="navigation"
14
+ aria-label="pagination"
15
+ data-slot="pagination"
16
+ className={cn("mx-auto flex w-full justify-center", className)}
17
+ {...props}
18
+ />
19
+ )
20
+ }
21
+
22
+ function PaginationContent({
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<"ul">) {
26
+ return (
27
+ <ul
28
+ data-slot="pagination-content"
29
+ className={cn("flex flex-row items-center gap-1.5", className)}
30
+ {...props}
31
+ />
32
+ )
33
+ }
34
+
35
+ function PaginationItem({ ...props }: React.ComponentProps<"li">) {
36
+ return <li data-slot="pagination-item" {...props} />
37
+ }
38
+
39
+ type PaginationLinkProps = {
40
+ isActive?: boolean
41
+ } & Pick<React.ComponentProps<typeof Button>, "size"> &
42
+ React.ComponentProps<"a">
43
+
44
+ function PaginationLink({
45
+ className,
46
+ isActive,
47
+ size = "icon-sm",
48
+ ...props
49
+ }: PaginationLinkProps) {
50
+ return (
51
+ <a
52
+ aria-current={isActive ? "page" : undefined}
53
+ data-slot="pagination-link"
54
+ data-active={isActive}
55
+ className={cn(
56
+ buttonVariants({
57
+ variant: isActive ? "secondary" : "ghost",
58
+ size,
59
+ }),
60
+ className
61
+ )}
62
+ {...props}
63
+ />
64
+ )
65
+ }
66
+
67
+ function PaginationPrevious({
68
+ className,
69
+ ...props
70
+ }: React.ComponentProps<typeof PaginationLink>) {
71
+ return (
72
+ <PaginationLink
73
+ aria-label="Go to previous page"
74
+ size="default"
75
+ className={cn("gap-1 size-8 sm:pl-2.5", className)}
76
+ {...props}
77
+ >
78
+ <ChevronLeftIcon />
79
+ </PaginationLink>
80
+ )
81
+ }
82
+
83
+ function PaginationNext({
84
+ className,
85
+ ...props
86
+ }: React.ComponentProps<typeof PaginationLink>) {
87
+ return (
88
+ <PaginationLink
89
+ aria-label="Go to next page"
90
+ size="default"
91
+ className={cn("gap-1 size-8 sm:pr-2.5", className)}
92
+ {...props}
93
+ >
94
+ <ChevronRightIcon />
95
+ </PaginationLink>
96
+ )
97
+ }
98
+
99
+ function PaginationEllipsis({
100
+ className,
101
+ ...props
102
+ }: React.ComponentProps<"span">) {
103
+ return (
104
+ <span
105
+ aria-hidden
106
+ data-slot="pagination-ellipsis"
107
+ className={cn("flex size-9 items-center justify-center", className)}
108
+ {...props}
109
+ >
110
+ <MoreHorizontalIcon className="size-4 mt-1.5" />
111
+ <span className="sr-only">More pages</span>
112
+ </span>
113
+ )
114
+ }
115
+
116
+ export {
117
+ Pagination,
118
+ PaginationContent,
119
+ PaginationLink,
120
+ PaginationItem,
121
+ PaginationPrevious,
122
+ PaginationNext,
123
+ PaginationEllipsis,
124
+ }
@@ -0,0 +1,57 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
5
+ import { cn } from "../../../infra/utils/clsx"
6
+
7
+ function ScrollArea({
8
+ className,
9
+ children,
10
+ ...props
11
+ }: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
12
+ return (
13
+ <ScrollAreaPrimitive.Root
14
+ data-slot="scroll-area"
15
+ className={cn("relative", className)}
16
+ {...props}
17
+ >
18
+ <ScrollAreaPrimitive.Viewport
19
+ data-slot="scroll-area-viewport"
20
+ className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
21
+ >
22
+ {children}
23
+ </ScrollAreaPrimitive.Viewport>
24
+ <ScrollBar />
25
+ <ScrollAreaPrimitive.Corner />
26
+ </ScrollAreaPrimitive.Root>
27
+ )
28
+ }
29
+
30
+ function ScrollBar({
31
+ className,
32
+ orientation = "vertical",
33
+ ...props
34
+ }: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
35
+ return (
36
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
37
+ data-slot="scroll-area-scrollbar"
38
+ orientation={orientation}
39
+ className={cn(
40
+ "flex touch-none p-px transition-colors select-none",
41
+ orientation === "vertical" &&
42
+ "h-full w-2.5 border-l border-l-transparent",
43
+ orientation === "horizontal" &&
44
+ "h-2.5 flex-col border-t border-t-transparent",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ <ScrollAreaPrimitive.ScrollAreaThumb
50
+ data-slot="scroll-area-thumb"
51
+ className="bg-border relative flex-1 rounded-full"
52
+ />
53
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
54
+ )
55
+ }
56
+
57
+ export { ScrollArea, ScrollBar }
@@ -0,0 +1,27 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as SeparatorPrimitive from "@radix-ui/react-separator"
5
+ import { cn } from "../../../infra/utils/clsx"
6
+
7
+ function Separator({
8
+ className,
9
+ orientation = "horizontal",
10
+ decorative = true,
11
+ ...props
12
+ }: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
13
+ return (
14
+ <SeparatorPrimitive.Root
15
+ data-slot="separator"
16
+ decorative={decorative}
17
+ orientation={orientation}
18
+ className={cn(
19
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ )
25
+ }
26
+
27
+ export { Separator }