@greatapps/common 1.1.128 → 1.1.130

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 (152) hide show
  1. package/dist/components/account/ConfirmDeleteAccountModal.mjs.map +1 -1
  2. package/dist/components/account/DeleteAccountModal.mjs.map +1 -1
  3. package/dist/components/account/IsntPossibleDeleteAccountModal.mjs.map +1 -1
  4. package/dist/components/account/hooks/useTwoFactorAuthForm.mjs.map +1 -1
  5. package/dist/components/layouts/AppMobileNavBar.mjs.map +1 -1
  6. package/dist/components/layouts/AppNavBar.mjs.map +1 -1
  7. package/dist/components/layouts/NavBar.mjs.map +1 -1
  8. package/dist/components/navigation/NavItemsContext.mjs.map +1 -1
  9. package/dist/components/navigation/ProjectSelectorPopover.mjs +2 -10
  10. package/dist/components/navigation/ProjectSelectorPopover.mjs.map +1 -1
  11. package/dist/components/navigation/shells/TabsMobileShell.mjs.map +1 -1
  12. package/dist/components/navigation/subcomponents/ProjectSelector.mjs +2 -2
  13. package/dist/components/navigation/subcomponents/ProjectSelector.mjs.map +1 -1
  14. package/dist/components/pages/notifications/Notifications.mjs.map +1 -1
  15. package/dist/components/ui/buttons/Button.mjs.map +1 -1
  16. package/dist/components/ui/buttons/CancelButton.mjs.map +1 -1
  17. package/dist/components/ui/buttons/CopyButton.mjs.map +1 -1
  18. package/dist/components/ui/data-display/Accordion.mjs.map +1 -1
  19. package/dist/components/ui/data-display/Badge.mjs.map +1 -1
  20. package/dist/components/ui/data-display/Card.mjs.map +1 -1
  21. package/dist/components/ui/data-display/Pagination.mjs.map +1 -1
  22. package/dist/components/ui/data-display/ScrollArea.mjs.map +1 -1
  23. package/dist/components/ui/data-display/Separator.mjs.map +1 -1
  24. package/dist/components/ui/data-display/Table.mjs.map +1 -1
  25. package/dist/components/ui/data-display/Tabs.mjs.map +1 -1
  26. package/dist/components/ui/feedback/CircularProgress.mjs.map +1 -1
  27. package/dist/components/ui/feedback/DefaultCircularProgress.mjs.map +1 -1
  28. package/dist/components/ui/feedback/LoadingOverlay.mjs.map +1 -1
  29. package/dist/components/ui/feedback/Progress.mjs.map +1 -1
  30. package/dist/components/ui/feedback/Toast.mjs.map +1 -1
  31. package/dist/components/ui/form/Calendar.mjs.map +1 -1
  32. package/dist/components/ui/form/Checkbox.mjs.map +1 -1
  33. package/dist/components/ui/form/DatePicker.mjs.map +1 -1
  34. package/dist/components/ui/form/DateRangePicker.mjs.map +1 -1
  35. package/dist/components/ui/form/Input.mjs.map +1 -1
  36. package/dist/components/ui/form/InputOtp.mjs.map +1 -1
  37. package/dist/components/ui/form/RadioGroup.mjs.map +1 -1
  38. package/dist/components/ui/form/Select.mjs +1 -1
  39. package/dist/components/ui/form/Select.mjs.map +1 -1
  40. package/dist/components/ui/form/Switch.mjs.map +1 -1
  41. package/dist/components/ui/form/Textarea.mjs.map +1 -1
  42. package/dist/components/ui/overlay/Command.mjs.map +1 -1
  43. package/dist/components/ui/overlay/Dialog.mjs.map +1 -1
  44. package/dist/components/ui/overlay/Popover.mjs.map +1 -1
  45. package/dist/components/ui/overlay/Sheet.mjs.map +1 -1
  46. package/dist/components/ui/overlay/Tooltip.mjs.map +1 -1
  47. package/dist/hooks/copy-to-clipboard.hook.mjs.map +1 -1
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/modules/accounts/actions/account-management.action.mjs.map +1 -1
  50. package/dist/modules/accounts/actions/find-current-account.action.mjs.map +1 -1
  51. package/dist/modules/accounts/actions/list-currencies.action.mjs.map +1 -1
  52. package/dist/modules/accounts/actions/list-timezones.action.mjs.map +1 -1
  53. package/dist/modules/accounts/hooks/current-account.hook.mjs.map +1 -1
  54. package/dist/modules/accounts/hooks/useAccountManagement.mjs.map +1 -1
  55. package/dist/modules/accounts/hooks/useCurrencies.mjs.map +1 -1
  56. package/dist/modules/accounts/hooks/useTimezones.mjs.map +1 -1
  57. package/dist/modules/auth/hooks/login.hook.mjs.map +1 -1
  58. package/dist/modules/auth/hooks/logout.hook.mjs.map +1 -1
  59. package/dist/modules/auth/hooks/register.hook.mjs.map +1 -1
  60. package/dist/modules/ia-credits/actions/list-ia-credits.action.mjs.map +1 -1
  61. package/dist/modules/projects/actions/add-project-user.action.mjs.map +1 -1
  62. package/dist/modules/projects/actions/list-available-users.action.mjs.map +1 -1
  63. package/dist/modules/projects/actions/list-project-users.action.mjs.map +1 -1
  64. package/dist/modules/projects/actions/remove-project-user.action.mjs.map +1 -1
  65. package/dist/modules/projects/hooks/list-available-users.hook.mjs.map +1 -1
  66. package/dist/modules/projects/hooks/list-project-users.hook.mjs.map +1 -1
  67. package/dist/modules/subscriptions/actions/list-subscriptions.action.mjs.map +1 -1
  68. package/dist/modules/subscriptions/hooks/find-active-subscription.hook.mjs.map +1 -1
  69. package/dist/modules/subscriptions/hooks/list-subscriptions.hook.mjs.map +1 -1
  70. package/dist/modules/users/action/find-user-by-id.action.mjs.map +1 -1
  71. package/dist/modules/users/action/list-messages.action.mjs.map +1 -1
  72. package/dist/modules/users/action/mark-all-messages-as-read.action.mjs.map +1 -1
  73. package/dist/modules/users/action/mark-message-as-read.action.mjs.map +1 -1
  74. package/dist/modules/users/hooks/messages.hook.mjs.map +1 -1
  75. package/dist/modules/whitelabel/actions/find-whitelabel.action.mjs.map +1 -1
  76. package/dist/utils/safeServerAction.mjs.map +1 -1
  77. package/dist/utils/withAction.mjs.map +1 -1
  78. package/package.json +84 -84
  79. package/src/components/account/ConfirmDeleteAccountModal.tsx +55 -55
  80. package/src/components/account/DeleteAccountModal.tsx +130 -130
  81. package/src/components/account/IsntPossibleDeleteAccountModal.tsx +49 -49
  82. package/src/components/account/hooks/useTwoFactorAuthForm.tsx +101 -101
  83. package/src/components/layouts/AppMobileNavBar.tsx +125 -125
  84. package/src/components/layouts/AppNavBar.tsx +57 -57
  85. package/src/components/layouts/NavBar.tsx +139 -139
  86. package/src/components/navigation/NavItemsContext.ts +20 -20
  87. package/src/components/navigation/ProjectSelectorPopover.tsx +4 -7
  88. package/src/components/navigation/shells/TabsMobileShell.tsx +72 -72
  89. package/src/components/navigation/subcomponents/ProjectSelector.tsx +2 -4
  90. package/src/components/pages/notifications/Notifications.tsx +160 -160
  91. package/src/components/ui/buttons/Button.tsx +57 -57
  92. package/src/components/ui/buttons/CancelButton.tsx +14 -14
  93. package/src/components/ui/buttons/CopyButton.tsx +54 -54
  94. package/src/components/ui/data-display/Accordion.tsx +81 -81
  95. package/src/components/ui/data-display/Badge.tsx +47 -47
  96. package/src/components/ui/data-display/Card.tsx +93 -93
  97. package/src/components/ui/data-display/Pagination.tsx +126 -126
  98. package/src/components/ui/data-display/ScrollArea.tsx +59 -59
  99. package/src/components/ui/data-display/Separator.tsx +29 -29
  100. package/src/components/ui/data-display/Table.tsx +117 -117
  101. package/src/components/ui/data-display/Tabs.tsx +67 -67
  102. package/src/components/ui/feedback/CircularProgress.tsx +75 -75
  103. package/src/components/ui/feedback/DefaultCircularProgress.tsx +53 -53
  104. package/src/components/ui/feedback/LoadingOverlay.tsx +31 -31
  105. package/src/components/ui/feedback/Progress.tsx +40 -40
  106. package/src/components/ui/feedback/Toast.tsx +101 -101
  107. package/src/components/ui/form/Calendar.tsx +228 -228
  108. package/src/components/ui/form/Checkbox.tsx +31 -31
  109. package/src/components/ui/form/DatePicker.tsx +97 -97
  110. package/src/components/ui/form/DateRangePicker.tsx +108 -108
  111. package/src/components/ui/form/Input.tsx +20 -20
  112. package/src/components/ui/form/InputOtp.tsx +80 -80
  113. package/src/components/ui/form/RadioGroup.tsx +45 -45
  114. package/src/components/ui/form/Select.tsx +200 -200
  115. package/src/components/ui/form/Switch.tsx +32 -32
  116. package/src/components/ui/form/Textarea.tsx +19 -19
  117. package/src/components/ui/overlay/Command.tsx +185 -185
  118. package/src/components/ui/overlay/Dialog.tsx +151 -151
  119. package/src/components/ui/overlay/Popover.tsx +49 -49
  120. package/src/components/ui/overlay/Sheet.tsx +159 -159
  121. package/src/components/ui/overlay/Tooltip.tsx +62 -62
  122. package/src/hooks/copy-to-clipboard.hook.tsx +67 -67
  123. package/src/index.ts +346 -346
  124. package/src/modules/accounts/actions/account-management.action.ts +90 -90
  125. package/src/modules/accounts/actions/find-current-account.action.ts +9 -9
  126. package/src/modules/accounts/actions/list-currencies.action.ts +8 -8
  127. package/src/modules/accounts/actions/list-timezones.action.ts +8 -8
  128. package/src/modules/accounts/hooks/current-account.hook.tsx +22 -22
  129. package/src/modules/accounts/hooks/useAccountManagement.ts +85 -85
  130. package/src/modules/accounts/hooks/useCurrencies.ts +15 -15
  131. package/src/modules/accounts/hooks/useTimezones.ts +15 -15
  132. package/src/modules/auth/hooks/login.hook.tsx +17 -17
  133. package/src/modules/auth/hooks/logout.hook.tsx +11 -11
  134. package/src/modules/auth/hooks/register.hook.tsx +11 -11
  135. package/src/modules/ia-credits/actions/list-ia-credits.action.ts +8 -8
  136. package/src/modules/projects/actions/add-project-user.action.ts +9 -9
  137. package/src/modules/projects/actions/list-available-users.action.ts +9 -9
  138. package/src/modules/projects/actions/list-project-users.action.ts +9 -9
  139. package/src/modules/projects/actions/remove-project-user.action.ts +9 -9
  140. package/src/modules/projects/hooks/list-available-users.hook.ts +33 -33
  141. package/src/modules/projects/hooks/list-project-users.hook.ts +33 -33
  142. package/src/modules/subscriptions/actions/list-subscriptions.action.ts +9 -9
  143. package/src/modules/subscriptions/hooks/find-active-subscription.hook.ts +19 -19
  144. package/src/modules/subscriptions/hooks/list-subscriptions.hook.ts +17 -17
  145. package/src/modules/users/action/find-user-by-id.action.ts +8 -8
  146. package/src/modules/users/action/list-messages.action.ts +12 -12
  147. package/src/modules/users/action/mark-all-messages-as-read.action.ts +8 -8
  148. package/src/modules/users/action/mark-message-as-read.action.ts +8 -8
  149. package/src/modules/users/hooks/messages.hook.ts +60 -60
  150. package/src/modules/whitelabel/actions/find-whitelabel.action.ts +23 -23
  151. package/src/utils/safeServerAction.ts +21 -21
  152. package/src/utils/withAction.ts +13 -13
@@ -1,139 +1,139 @@
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
- onAppIconClick?: () => void;
13
- activeApp?: "gapps" | "gpages";
14
- showExpandButton?: boolean;
15
- onExpandClick?: () => void;
16
- children?: React.ReactNode;
17
- className?: string;
18
- };
19
-
20
- function NavBar({
21
- onLogoClick,
22
- onAppIconClick,
23
- activeApp,
24
- showExpandButton = false,
25
- onExpandClick,
26
- children,
27
- className,
28
- }: NavBarProps) {
29
- return (
30
- <div
31
- className={cn(
32
- "hidden md:flex flex-col justify-between h-screen p-4 border-r border-gray-200 overflow-visible z-40 bg-white",
33
- className,
34
- )}
35
- >
36
- <div className="flex flex-col gap-4 items-center mt-[6.5px]">
37
- {/* GreatApps logo */}
38
- <div className="relative">
39
- <Tooltip>
40
- <TooltipTrigger
41
- className="cursor-pointer"
42
- asChild
43
- onClick={onLogoClick}
44
- >
45
- <Image
46
- src="/icons/great-icon.svg"
47
- alt="Great Icon"
48
- width={28}
49
- height={28}
50
- />
51
- </TooltipTrigger>
52
- <TooltipContent side="right">GreatApps</TooltipContent>
53
- </Tooltip>
54
- <div
55
- className={cn(
56
- "absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 bg-gray-950 rounded-r-xl transition-opacity duration-300",
57
- activeApp === "gapps" ? "opacity-100" : "opacity-0",
58
- )}
59
- />
60
- </div>
61
-
62
- <div className="relative w-full mt-[7.5px]">
63
- <Separator />
64
- {showExpandButton && (
65
- <Tooltip>
66
- <TooltipTrigger asChild>
67
- <button
68
- onClick={onExpandClick}
69
- 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"
70
- >
71
- <ChevronRight size={16} className="text-gray-500" />
72
- </button>
73
- </TooltipTrigger>
74
- <TooltipContent side="right">Expandir menu</TooltipContent>
75
- </Tooltip>
76
- )}
77
- </div>
78
-
79
- {/* GreatPages icon */}
80
- <div className="flex flex-col gap-2">
81
- <div className="relative">
82
- <Tooltip>
83
- <TooltipTrigger asChild onClick={onAppIconClick}>
84
- {activeApp === "gpages" ? (
85
- <div
86
- className="size-10 rounded-xl cursor-pointer p-[2px]"
87
- style={{
88
- border: "1.5px solid rgba(153,234,255,0.75)",
89
- background: "white",
90
- boxShadow:
91
- "0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)",
92
- }}
93
- >
94
- <div
95
- className="w-full h-full rounded-lg flex items-center justify-center"
96
- style={{
97
- background:
98
- "radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)",
99
- }}
100
- >
101
- <Image
102
- src="/icons/icon-navbar.svg"
103
- alt="GreatPages"
104
- width={24}
105
- height={24}
106
- />
107
- </div>
108
- </div>
109
- ) : (
110
- <div className="size-10 flex items-center justify-center rounded-lg cursor-pointer hover:bg-gray-100 transition-colors duration-300">
111
- <Image
112
- src="/icons/icon-navbar.svg"
113
- alt="GreatPages"
114
- width={28}
115
- height={28}
116
- />
117
- </div>
118
- )}
119
- </TooltipTrigger>
120
- <TooltipContent side="right">GreatPages</TooltipContent>
121
- </Tooltip>
122
- <div
123
- className={cn(
124
- "absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 rounded-r-xl transition-opacity duration-300",
125
- activeApp === "gpages" ? "opacity-100" : "opacity-0",
126
- )}
127
- style={{ backgroundColor: "#6ADCFF" }}
128
- />
129
- </div>
130
- </div>
131
- </div>
132
-
133
- <div className="flex flex-col items-center gap-2">{children}</div>
134
- </div>
135
- );
136
- }
137
-
138
- export { NavBar };
139
- export type { NavBarProps };
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
+ onAppIconClick?: () => void;
13
+ activeApp?: "gapps" | "gpages";
14
+ showExpandButton?: boolean;
15
+ onExpandClick?: () => void;
16
+ children?: React.ReactNode;
17
+ className?: string;
18
+ };
19
+
20
+ function NavBar({
21
+ onLogoClick,
22
+ onAppIconClick,
23
+ activeApp,
24
+ showExpandButton = false,
25
+ onExpandClick,
26
+ children,
27
+ className,
28
+ }: NavBarProps) {
29
+ return (
30
+ <div
31
+ className={cn(
32
+ "hidden md:flex flex-col justify-between h-screen p-4 border-r border-gray-200 overflow-visible z-40 bg-white",
33
+ className,
34
+ )}
35
+ >
36
+ <div className="flex flex-col gap-4 items-center mt-[6.5px]">
37
+ {/* GreatApps logo */}
38
+ <div className="relative">
39
+ <Tooltip>
40
+ <TooltipTrigger
41
+ className="cursor-pointer"
42
+ asChild
43
+ onClick={onLogoClick}
44
+ >
45
+ <Image
46
+ src="/icons/great-icon.svg"
47
+ alt="Great Icon"
48
+ width={28}
49
+ height={28}
50
+ />
51
+ </TooltipTrigger>
52
+ <TooltipContent side="right">GreatApps</TooltipContent>
53
+ </Tooltip>
54
+ <div
55
+ className={cn(
56
+ "absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 bg-gray-950 rounded-r-xl transition-opacity duration-300",
57
+ activeApp === "gapps" ? "opacity-100" : "opacity-0",
58
+ )}
59
+ />
60
+ </div>
61
+
62
+ <div className="relative w-full mt-[7.5px]">
63
+ <Separator />
64
+ {showExpandButton && (
65
+ <Tooltip>
66
+ <TooltipTrigger asChild>
67
+ <button
68
+ onClick={onExpandClick}
69
+ 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"
70
+ >
71
+ <ChevronRight size={16} className="text-gray-500" />
72
+ </button>
73
+ </TooltipTrigger>
74
+ <TooltipContent side="right">Expandir menu</TooltipContent>
75
+ </Tooltip>
76
+ )}
77
+ </div>
78
+
79
+ {/* GreatPages icon */}
80
+ <div className="flex flex-col gap-2">
81
+ <div className="relative">
82
+ <Tooltip>
83
+ <TooltipTrigger asChild onClick={onAppIconClick}>
84
+ {activeApp === "gpages" ? (
85
+ <div
86
+ className="size-10 rounded-xl cursor-pointer p-[2px]"
87
+ style={{
88
+ border: "1.5px solid rgba(153,234,255,0.75)",
89
+ background: "white",
90
+ boxShadow:
91
+ "0 0 8px rgba(153,234,255,0.5), 0 0 18px rgba(153,234,255,0.2)",
92
+ }}
93
+ >
94
+ <div
95
+ className="w-full h-full rounded-lg flex items-center justify-center"
96
+ style={{
97
+ background:
98
+ "radial-gradient(circle at center, rgba(255,255,255,0.95) 0%, rgba(153,234,255,0.45) 100%)",
99
+ }}
100
+ >
101
+ <Image
102
+ src="/icons/icon-navbar.svg"
103
+ alt="GreatPages"
104
+ width={24}
105
+ height={24}
106
+ />
107
+ </div>
108
+ </div>
109
+ ) : (
110
+ <div className="size-10 flex items-center justify-center rounded-lg cursor-pointer hover:bg-gray-100 transition-colors duration-300">
111
+ <Image
112
+ src="/icons/icon-navbar.svg"
113
+ alt="GreatPages"
114
+ width={28}
115
+ height={28}
116
+ />
117
+ </div>
118
+ )}
119
+ </TooltipTrigger>
120
+ <TooltipContent side="right">GreatPages</TooltipContent>
121
+ </Tooltip>
122
+ <div
123
+ className={cn(
124
+ "absolute -left-[22px] top-1/2 -translate-y-1/2 w-[3px] h-5 rounded-r-xl transition-opacity duration-300",
125
+ activeApp === "gpages" ? "opacity-100" : "opacity-0",
126
+ )}
127
+ style={{ backgroundColor: "#6ADCFF" }}
128
+ />
129
+ </div>
130
+ </div>
131
+ </div>
132
+
133
+ <div className="flex flex-col items-center gap-2">{children}</div>
134
+ </div>
135
+ );
136
+ }
137
+
138
+ export { NavBar };
139
+ export type { NavBarProps };
@@ -1,20 +1,20 @@
1
- 'use client';
2
-
3
- import { createContext, useContext } from 'react';
4
- import type { NavItemConfig } from './subcomponents/NavItems';
5
-
6
- interface NavItemsContextValue {
7
- navItems: NavItemConfig[];
8
- setNavItems: (items: NavItemConfig[]) => void;
9
- mobileVariant: 'sheet' | 'tabs';
10
- }
11
-
12
- export const NavItemsContext = createContext<NavItemsContextValue>({
13
- navItems: [],
14
- setNavItems: () => {},
15
- mobileVariant: 'sheet',
16
- });
17
-
18
- export function useNavItemsContext(): NavItemsContextValue {
19
- return useContext(NavItemsContext);
20
- }
1
+ 'use client';
2
+
3
+ import { createContext, useContext } from 'react';
4
+ import type { NavItemConfig } from './subcomponents/NavItems';
5
+
6
+ interface NavItemsContextValue {
7
+ navItems: NavItemConfig[];
8
+ setNavItems: (items: NavItemConfig[]) => void;
9
+ mobileVariant: 'sheet' | 'tabs';
10
+ }
11
+
12
+ export const NavItemsContext = createContext<NavItemsContextValue>({
13
+ navItems: [],
14
+ setNavItems: () => {},
15
+ mobileVariant: 'sheet',
16
+ });
17
+
18
+ export function useNavItemsContext(): NavItemsContextValue {
19
+ return useContext(NavItemsContext);
20
+ }
@@ -4,7 +4,6 @@ import { Dispatch, RefObject, SetStateAction } from 'react';
4
4
  import Image from 'next/image';
5
5
  import {
6
6
  Button,
7
- Checkbox,
8
7
  Command,
9
8
  CommandEmpty,
10
9
  CommandInput,
@@ -17,7 +16,7 @@ import {
17
16
  TooltipContent,
18
17
  TooltipTrigger,
19
18
  } from '../../index';
20
- import { ChevronDown, FolderOpen, Plus, Settings } from 'lucide-react';
19
+ import { CheckIcon, ChevronDown, FolderOpen, Plus, Settings } from 'lucide-react';
21
20
  import type { NavigationProject } from './types';
22
21
 
23
22
  interface ProjectSelectorPopoverProps {
@@ -132,11 +131,9 @@ export function ProjectSelectorPopover({
132
131
  />
133
132
  {project.title}
134
133
  </div>
135
- <Checkbox
136
- checked={isSelected}
137
- onCheckedChange={() => onSelectProject(project)}
138
- className="rounded-full border-0 data-[state=checked]:bg-white data-[state=checked]:border! data-[state=checked]:border-gray-200! text-gray-950!"
139
- />
134
+ {isSelected && (
135
+ <CheckIcon className="size-4 text-gray-950" />
136
+ )}
140
137
  </div>
141
138
  </CommandItem>
142
139
  );
@@ -1,72 +1,72 @@
1
- 'use client';
2
-
3
- import { ReactNode, useRef, useEffect } from 'react';
4
- import { AppNavigationContext } from '../AppNavigationContext';
5
- import { useNavItemsContext } from '../NavItemsContext';
6
-
7
- function InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {
8
- const { navItems } = useNavItemsContext();
9
- const tabsListRef = useRef<HTMLDivElement>(null);
10
- const activeTabRef = useRef<HTMLButtonElement>(null);
11
-
12
- const activeLabel = navItems.find((i) => i.isActive)?.label;
13
-
14
- // Scroll active tab into center when active item changes
15
- useEffect(() => {
16
- if (activeTabRef.current && tabsListRef.current) {
17
- const tabsList = tabsListRef.current;
18
- const activeTabElement = activeTabRef.current;
19
- const tabsListRect = tabsList.getBoundingClientRect();
20
- const activeTabRect = activeTabElement.getBoundingClientRect();
21
- const scrollLeft =
22
- activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;
23
- tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });
24
- }
25
- }, [activeLabel]);
26
-
27
- if (!navItems.length) return null;
28
-
29
- return (
30
- <div
31
- ref={tabsListRef}
32
- className="md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide"
33
- style={{ top: topOffset }}
34
- >
35
- {navItems.map((item) => (
36
- <button
37
- key={item.label}
38
- ref={item.isActive ? activeTabRef : undefined}
39
- onClick={item.onClick}
40
- className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${
41
- item.isActive
42
- ? 'border-gray-950 text-gray-950'
43
- : 'border-transparent text-gray-500 hover:text-gray-900'
44
- }`}
45
- >
46
- {item.icon && <item.icon size={16} className="shrink-0" />}
47
- <span
48
- className={
49
- item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'
50
- }
51
- >
52
- {item.label}
53
- </span>
54
- </button>
55
- ))}
56
- </div>
57
- );
58
- }
59
-
60
- export function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {
61
- return (
62
- <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>
63
- {/*
64
- Children are hidden visually, but NavItems' useEffect still fires inside
65
- display:none — React effects are tied to commit phase, not layout visibility.
66
- This registers navItems in NavItemsContext so InternalTabsBar can read them.
67
- */}
68
- <div className="hidden">{children}</div>
69
- <InternalTabsBar topOffset={topOffset} />
70
- </AppNavigationContext.Provider>
71
- );
72
- }
1
+ 'use client';
2
+
3
+ import { ReactNode, useRef, useEffect } from 'react';
4
+ import { AppNavigationContext } from '../AppNavigationContext';
5
+ import { useNavItemsContext } from '../NavItemsContext';
6
+
7
+ function InternalTabsBar({ topOffset = '72px' }: { topOffset?: string }) {
8
+ const { navItems } = useNavItemsContext();
9
+ const tabsListRef = useRef<HTMLDivElement>(null);
10
+ const activeTabRef = useRef<HTMLButtonElement>(null);
11
+
12
+ const activeLabel = navItems.find((i) => i.isActive)?.label;
13
+
14
+ // Scroll active tab into center when active item changes
15
+ useEffect(() => {
16
+ if (activeTabRef.current && tabsListRef.current) {
17
+ const tabsList = tabsListRef.current;
18
+ const activeTabElement = activeTabRef.current;
19
+ const tabsListRect = tabsList.getBoundingClientRect();
20
+ const activeTabRect = activeTabElement.getBoundingClientRect();
21
+ const scrollLeft =
22
+ activeTabElement.offsetLeft - tabsListRect.width / 2 + activeTabRect.width / 2;
23
+ tabsList.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });
24
+ }
25
+ }, [activeLabel]);
26
+
27
+ if (!navItems.length) return null;
28
+
29
+ return (
30
+ <div
31
+ ref={tabsListRef}
32
+ className="md:hidden fixed left-0 right-0 z-40 bg-white border-b border-gray-200 flex overflow-x-auto scrollbar-hide"
33
+ style={{ top: topOffset }}
34
+ >
35
+ {navItems.map((item) => (
36
+ <button
37
+ key={item.label}
38
+ ref={item.isActive ? activeTabRef : undefined}
39
+ onClick={item.onClick}
40
+ className={`flex items-center gap-2 px-4 py-3 shrink-0 border-b-2 transition-colors ${
41
+ item.isActive
42
+ ? 'border-gray-950 text-gray-950'
43
+ : 'border-transparent text-gray-500 hover:text-gray-900'
44
+ }`}
45
+ >
46
+ {item.icon && <item.icon size={16} className="shrink-0" />}
47
+ <span
48
+ className={
49
+ item.isActive ? 'paragraph-small-semibold' : 'paragraph-small-medium'
50
+ }
51
+ >
52
+ {item.label}
53
+ </span>
54
+ </button>
55
+ ))}
56
+ </div>
57
+ );
58
+ }
59
+
60
+ export function TabsMobileShell({ children, topOffset }: { children: ReactNode; topOffset?: string }) {
61
+ return (
62
+ <AppNavigationContext.Provider value={{ breakpoint: 'mobile' }}>
63
+ {/*
64
+ Children are hidden visually, but NavItems' useEffect still fires inside
65
+ display:none — React effects are tied to commit phase, not layout visibility.
66
+ This registers navItems in NavItemsContext so InternalTabsBar can read them.
67
+ */}
68
+ <div className="hidden">{children}</div>
69
+ <InternalTabsBar topOffset={topOffset} />
70
+ </AppNavigationContext.Provider>
71
+ );
72
+ }
@@ -58,12 +58,10 @@ export function ProjectSelector({
58
58
  <div className="skeleton h-4 w-32 rounded" />
59
59
  ) : (
60
60
  <span
61
- className="cursor-pointer paragraph-medium-semibold text-gray-600 truncate"
61
+ className="cursor-pointer paragraph-medium-semibold text-gray-600 truncate max-w-[140px] inline-block"
62
62
  onClick={() => setIsPopoverOpen((v) => !v)}
63
63
  >
64
- {selectedProject?.title && selectedProject.title.length > 15
65
- ? `${selectedProject.title.slice(0, 15)}…`
66
- : selectedProject?.title}
64
+ {selectedProject?.title}
67
65
  </span>
68
66
  )}
69
67
  <ProjectSelectorPopover