xertica-ui 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 (141) hide show
  1. package/App.tsx +182 -0
  2. package/README.md +330 -0
  3. package/assets/xertica-logo.svg +38 -0
  4. package/assets/xertica-x-logo.svg +21 -0
  5. package/bin/cli.ts +193 -0
  6. package/components/AssistenteXertica.tsx +2003 -0
  7. package/components/AudioPlayer.tsx +203 -0
  8. package/components/CodeBlock.tsx +242 -0
  9. package/components/DocumentEditor.tsx +504 -0
  10. package/components/ForgotPasswordPage.tsx +170 -0
  11. package/components/FormattedDocument.tsx +87 -0
  12. package/components/HomeContent.tsx +123 -0
  13. package/components/HomePage.tsx +70 -0
  14. package/components/LanguageSelector.tsx +54 -0
  15. package/components/LoginPage.tsx +199 -0
  16. package/components/MarkdownMessage.tsx +62 -0
  17. package/components/ModernChatInput.tsx +502 -0
  18. package/components/PodcastPlayer.tsx +409 -0
  19. package/components/ResetPasswordPage.tsx +234 -0
  20. package/components/Sidebar.tsx +489 -0
  21. package/components/TemplateContent.tsx +629 -0
  22. package/components/TemplatePage.tsx +70 -0
  23. package/components/ThemeToggle.tsx +65 -0
  24. package/components/VerifyEmailPage.tsx +187 -0
  25. package/components/XerticaLogo.tsx +69 -0
  26. package/components/XerticaOrbe.tsx +1339 -0
  27. package/components/XerticaXLogo.tsx +53 -0
  28. package/components/examples/DrawingMapExample.tsx +530 -0
  29. package/components/examples/FilterableMapExample.tsx +380 -0
  30. package/components/examples/LocationPickerExample.tsx +330 -0
  31. package/components/examples/MapExamples.tsx +280 -0
  32. package/components/examples/MapShowcase.tsx +446 -0
  33. package/components/examples/RouteMapExamples.tsx +329 -0
  34. package/components/examples/SimpleFilterableMap.tsx +192 -0
  35. package/components/examples/index.ts +52 -0
  36. package/components/figma/ImageWithFallback.tsx +27 -0
  37. package/components/index.ts +44 -0
  38. package/components/media/AudioPlayer.tsx +278 -0
  39. package/components/media/FloatingMediaWrapper.tsx +166 -0
  40. package/components/media/VideoPlayer.tsx +285 -0
  41. package/components/ui/accordion.tsx +66 -0
  42. package/components/ui/alert-dialog.tsx +159 -0
  43. package/components/ui/alert.tsx +91 -0
  44. package/components/ui/aspect-ratio.tsx +11 -0
  45. package/components/ui/avatar.tsx +65 -0
  46. package/components/ui/badge.tsx +55 -0
  47. package/components/ui/breadcrumb.tsx +109 -0
  48. package/components/ui/button.tsx +78 -0
  49. package/components/ui/calendar.tsx +235 -0
  50. package/components/ui/card.tsx +92 -0
  51. package/components/ui/carousel.tsx +241 -0
  52. package/components/ui/chart.tsx +353 -0
  53. package/components/ui/checkbox.tsx +32 -0
  54. package/components/ui/collapsible.tsx +33 -0
  55. package/components/ui/command.tsx +177 -0
  56. package/components/ui/context-menu.tsx +252 -0
  57. package/components/ui/dialog.tsx +138 -0
  58. package/components/ui/drawer.tsx +134 -0
  59. package/components/ui/dropdown-menu.tsx +257 -0
  60. package/components/ui/empty.tsx +90 -0
  61. package/components/ui/file-upload.tsx +152 -0
  62. package/components/ui/form.tsx +195 -0
  63. package/components/ui/google-maps-loader.tsx +379 -0
  64. package/components/ui/hover-card.tsx +44 -0
  65. package/components/ui/index.ts +242 -0
  66. package/components/ui/input-otp.tsx +77 -0
  67. package/components/ui/input.tsx +38 -0
  68. package/components/ui/label.tsx +24 -0
  69. package/components/ui/map-config.ts +12 -0
  70. package/components/ui/map-layers.tsx +129 -0
  71. package/components/ui/map.exports.ts +31 -0
  72. package/components/ui/map.tsx +412 -0
  73. package/components/ui/menubar.tsx +276 -0
  74. package/components/ui/navigation-menu.tsx +162 -0
  75. package/components/ui/notification-badge.tsx +61 -0
  76. package/components/ui/page-header.tsx +229 -0
  77. package/components/ui/pagination.tsx +127 -0
  78. package/components/ui/popover.tsx +48 -0
  79. package/components/ui/progress.tsx +31 -0
  80. package/components/ui/radio-group.tsx +56 -0
  81. package/components/ui/rating.tsx +102 -0
  82. package/components/ui/resizable.tsx +405 -0
  83. package/components/ui/route-map.tsx +246 -0
  84. package/components/ui/scroll-area.tsx +58 -0
  85. package/components/ui/search.tsx +70 -0
  86. package/components/ui/select.tsx +176 -0
  87. package/components/ui/separator.tsx +28 -0
  88. package/components/ui/sheet.tsx +138 -0
  89. package/components/ui/sidebar.tsx +726 -0
  90. package/components/ui/simple-map.tsx +92 -0
  91. package/components/ui/skeleton.tsx +13 -0
  92. package/components/ui/slider.tsx +58 -0
  93. package/components/ui/sonner.tsx +77 -0
  94. package/components/ui/stats-card.tsx +84 -0
  95. package/components/ui/stepper.tsx +126 -0
  96. package/components/ui/switch.tsx +34 -0
  97. package/components/ui/table.tsx +116 -0
  98. package/components/ui/tabs.tsx +66 -0
  99. package/components/ui/textarea.tsx +26 -0
  100. package/components/ui/timeline.tsx +140 -0
  101. package/components/ui/toggle-group.tsx +71 -0
  102. package/components/ui/toggle.tsx +46 -0
  103. package/components/ui/tooltip.tsx +61 -0
  104. package/components/ui/tree-view.tsx +123 -0
  105. package/components/ui/use-mobile.ts +24 -0
  106. package/components/ui/utils.ts +6 -0
  107. package/components/ui/xertica-assistant.tsx +1420 -0
  108. package/contexts/ApiKeyContext.tsx +123 -0
  109. package/contexts/AssistenteContext.tsx +118 -0
  110. package/contexts/BrandColorsContext.tsx +551 -0
  111. package/contexts/LanguageContext.tsx +36 -0
  112. package/contexts/ThemeContext.tsx +85 -0
  113. package/dist/cli.js +20922 -0
  114. package/eslint.config.js +41 -0
  115. package/guidelines/Guidelines.md +61 -0
  116. package/hooks/useTheme.ts +4 -0
  117. package/imports/Podcast.tsx +389 -0
  118. package/imports/XerticaAi.tsx +46 -0
  119. package/imports/XerticaX.tsx +20 -0
  120. package/imports/svg-aueiaqngck.ts +11 -0
  121. package/imports/svg-v9krss1ozd.ts +16 -0
  122. package/imports/svg-vhrdofe3qe.ts +5 -0
  123. package/index.css +4448 -0
  124. package/index.html +14 -0
  125. package/main.tsx +10 -0
  126. package/package.json +119 -0
  127. package/postcss.config.js +6 -0
  128. package/routes.tsx +33 -0
  129. package/styles/globals.css +15 -0
  130. package/styles/xertica/app-overrides/chat.css +61 -0
  131. package/styles/xertica/app-overrides/scrollbar.css +33 -0
  132. package/styles/xertica/base.css +70 -0
  133. package/styles/xertica/integrations/google-maps.css +76 -0
  134. package/styles/xertica/integrations/sonner.css +73 -0
  135. package/styles/xertica/theme-map.css +88 -0
  136. package/styles/xertica/tokens.css +190 -0
  137. package/tsconfig.json +31 -0
  138. package/tsconfig.node.json +10 -0
  139. package/utils/gemini.ts +140 -0
  140. package/vite-env.d.ts +12 -0
  141. package/vite.config.ts +36 -0
@@ -0,0 +1,489 @@
1
+ import React, { useState, useRef, useEffect } from "react";
2
+ import {
3
+ Menu,
4
+ ArrowLeft,
5
+ LogOut,
6
+ Settings,
7
+ MoreHorizontal,
8
+ ChevronRight,
9
+ } from "lucide-react";
10
+ import { routes } from "../routes";
11
+ import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar";
12
+ import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
13
+ import { Tooltip, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
14
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
15
+ import { cn } from "./ui/utils";
16
+ import { XerticaLogo } from "./XerticaLogo";
17
+ import { XerticaXLogo } from "./XerticaXLogo";
18
+
19
+ // TooltipContent customizado para a Sidebar com seta branca
20
+ function SidebarTooltipContent({
21
+ className,
22
+ sideOffset = 0,
23
+ children,
24
+ ...props
25
+ }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
26
+ return (
27
+ <TooltipPrimitive.Content
28
+ data-slot="tooltip-content"
29
+ sideOffset={sideOffset}
30
+ className={cn(
31
+ "bg-popover text-popover-foreground shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
32
+ className,
33
+ )}
34
+ {...props}
35
+ >
36
+ {children}
37
+ <TooltipPrimitive.Arrow
38
+ className="fill-popover z-50 drop-shadow-sm"
39
+ width={8}
40
+ height={4}
41
+ />
42
+ </TooltipPrimitive.Content>
43
+ );
44
+ }
45
+
46
+ interface SubMenuItem {
47
+ id: string;
48
+ label: string;
49
+ path: string;
50
+ }
51
+
52
+ interface NavigationItem {
53
+ path: string;
54
+ label: string;
55
+ icon: any;
56
+ active: boolean;
57
+ subItems?: SubMenuItem[];
58
+ }
59
+
60
+ interface SidebarProps {
61
+ expanded: boolean;
62
+ onToggle: () => void;
63
+ user: { email: string } | null;
64
+ onLogout: () => void;
65
+ location: { pathname: string };
66
+ navigate: (path: string) => void;
67
+ }
68
+
69
+ export function Sidebar({
70
+ expanded,
71
+ onToggle,
72
+ user,
73
+ onLogout,
74
+ location,
75
+ navigate,
76
+ }: SidebarProps) {
77
+ const navRef = useRef<HTMLDivElement>(null);
78
+ const [hasOverflow, setHasOverflow] = useState(false);
79
+ const [visibleItems, setVisibleItems] = useState<NavigationItem[]>([]);
80
+ const [overflowItems, setOverflowItems] = useState<NavigationItem[]>([]);
81
+ const [openSubmenu, setOpenSubmenu] = useState<string | null>(null);
82
+
83
+ // Tradução direta para português
84
+ const labelTranslations: Record<string, string> = {
85
+ home: "Início",
86
+ dashboard: "Dashboard",
87
+ components: "Componentes",
88
+ };
89
+
90
+ // Exemplo de subitens - você pode passar isso como prop também
91
+ const subItemsExample: Record<string, SubMenuItem[]> = {
92
+ "/components": [
93
+ { id: "buttons", label: "Botões", path: "/components/buttons" },
94
+ { id: "forms", label: "Formulários", path: "/components/forms" },
95
+ { id: "tables", label: "Tabelas", path: "/components/tables" },
96
+ ],
97
+ };
98
+
99
+ const navigationItems: NavigationItem[] = routes.map((route) => ({
100
+ ...route,
101
+ label:
102
+ labelTranslations[route.label.toLowerCase()] ||
103
+ route.label,
104
+ active: location.pathname === route.path || location.pathname.startsWith(route.path + "/"),
105
+ subItems: subItemsExample[route.path],
106
+ }));
107
+
108
+ const isSettingsActive = location.pathname === "/settings";
109
+
110
+ // Detectar overflow vertical
111
+ useEffect(() => {
112
+ const checkOverflow = () => {
113
+ if (!navRef.current) return;
114
+
115
+ const navHeight = navRef.current.clientHeight;
116
+ const itemHeight = 44; // h-10 + gap
117
+ const maxVisibleItems = Math.floor(navHeight / itemHeight);
118
+
119
+ if (navigationItems.length > maxVisibleItems) {
120
+ setHasOverflow(true);
121
+ setVisibleItems(navigationItems.slice(0, maxVisibleItems - 1));
122
+ setOverflowItems(navigationItems.slice(maxVisibleItems - 1));
123
+ } else {
124
+ setHasOverflow(false);
125
+ setVisibleItems(navigationItems);
126
+ setOverflowItems([]);
127
+ }
128
+ };
129
+
130
+ checkOverflow();
131
+ window.addEventListener("resize", checkOverflow);
132
+ return () => window.removeEventListener("resize", checkOverflow);
133
+ }, [navigationItems.length]);
134
+
135
+ const handleNavigate = (path: string) => {
136
+ navigate(path);
137
+ setOpenSubmenu(null);
138
+ // Fecha o menu no mobile após navegar
139
+ if (window.innerWidth < 768) {
140
+ onToggle();
141
+ }
142
+ };
143
+
144
+ const renderMenuItem = (item: NavigationItem, showEllipsis: boolean = false) => {
145
+ const Icon = item.icon;
146
+ const hasSubItems = item.subItems && item.subItems.length > 0;
147
+
148
+ const buttonContent = (
149
+ <button
150
+ onClick={hasSubItems ? undefined : () => handleNavigate(item.path)}
151
+ className={
152
+ expanded
153
+ ? item.active
154
+ ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
155
+ : "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
156
+ : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 " +
157
+ (item.active
158
+ ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
159
+ : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground")
160
+ }
161
+ >
162
+ <Icon className="w-5 h-5 flex-shrink-0" />
163
+ {expanded && (
164
+ <>
165
+ <span className="truncate text-sidebar-foreground flex-1 text-left">
166
+ {item.label}
167
+ </span>
168
+ {hasSubItems && (
169
+ <MoreHorizontal className="w-4 h-4 flex-shrink-0 text-sidebar-foreground/60" />
170
+ )}
171
+ </>
172
+ )}
173
+ </button>
174
+ );
175
+
176
+ if (hasSubItems || showEllipsis) {
177
+ return (
178
+ <Popover
179
+ key={item.path}
180
+ open={openSubmenu === item.path}
181
+ onOpenChange={(open) => setOpenSubmenu(open ? item.path : null)}
182
+ >
183
+ <PopoverTrigger asChild>
184
+ {!expanded ? (
185
+ <Tooltip>
186
+ <TooltipTrigger asChild>
187
+ {buttonContent}
188
+ </TooltipTrigger>
189
+ <SidebarTooltipContent side="right" sideOffset={0}>
190
+ <p>{item.label}</p>
191
+ </SidebarTooltipContent>
192
+ </Tooltip>
193
+ ) : (
194
+ buttonContent
195
+ )}
196
+ </PopoverTrigger>
197
+ <PopoverContent
198
+ side="right"
199
+ align="start"
200
+ className="w-56 p-2 bg-popover border border-border rounded-[var(--radius-card)] shadow-lg"
201
+ sideOffset={8}
202
+ >
203
+ <div className="space-y-1">
204
+ {/* Item principal clicável */}
205
+ {!showEllipsis && (
206
+ <button
207
+ onClick={() => handleNavigate(item.path)}
208
+ className="w-full h-9 flex items-center gap-2 px-3 rounded-[var(--radius-button)] transition-all duration-200 text-popover-foreground/80 hover:bg-accent hover:text-accent-foreground text-left"
209
+ >
210
+ <span className="truncate">{item.label}</span>
211
+ </button>
212
+ )}
213
+
214
+ {/* Subitens */}
215
+ {hasSubItems && item.subItems && (
216
+ <>
217
+ {!showEllipsis && (
218
+ <div className="h-px bg-border my-1" />
219
+ )}
220
+ {item.subItems.map((subItem) => (
221
+ <button
222
+ key={subItem.id}
223
+ onClick={() => handleNavigate(subItem.path)}
224
+ className="w-full h-9 flex items-center gap-2 px-3 pl-5 rounded-[var(--radius-button)] transition-all duration-200 text-popover-foreground/70 hover:bg-accent hover:text-accent-foreground text-left"
225
+ >
226
+ <ChevronRight className="w-3 h-3 flex-shrink-0" />
227
+ <span className="truncate text-sm">{subItem.label}</span>
228
+ </button>
229
+ ))}
230
+ </>
231
+ )}
232
+ </div>
233
+ </PopoverContent>
234
+ </Popover>
235
+ );
236
+ }
237
+
238
+ // Item normal sem subitens
239
+ const simpleButton = (
240
+ <button
241
+ key={item.path}
242
+ onClick={() => handleNavigate(item.path)}
243
+ className={
244
+ expanded
245
+ ? item.active
246
+ ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
247
+ : "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
248
+ : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 " +
249
+ (item.active
250
+ ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
251
+ : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground")
252
+ }
253
+ >
254
+ <Icon className="w-5 h-5 flex-shrink-0" />
255
+ {expanded && (
256
+ <span className="truncate text-sidebar-foreground">
257
+ {item.label}
258
+ </span>
259
+ )}
260
+ </button>
261
+ );
262
+
263
+ // Adiciona tooltip quando colapsado
264
+ if (!expanded) {
265
+ return (
266
+ <Tooltip key={item.path}>
267
+ <TooltipTrigger asChild>
268
+ {simpleButton}
269
+ </TooltipTrigger>
270
+ <SidebarTooltipContent side="right" sideOffset={0}>
271
+ <p>{item.label}</p>
272
+ </SidebarTooltipContent>
273
+ </Tooltip>
274
+ );
275
+ }
276
+
277
+ return simpleButton;
278
+ };
279
+
280
+ return (
281
+ <TooltipProvider delayDuration={300}>
282
+ {/* Sidebar */}
283
+ <div
284
+ className={`bg-sidebar text-sidebar-foreground transition-all duration-300 ease-in-out flex flex-col z-50 ${
285
+ expanded
286
+ ? "fixed inset-0 md:fixed md:inset-y-0 md:left-0 md:w-64"
287
+ : "fixed inset-y-0 left-0 w-20 -translate-x-full md:translate-x-0"
288
+ }`}
289
+ >
290
+ {/* Botão Toggle Menu */}
291
+ <div className="p-[14px] pt-[13px] pr-[14px] pb-[12px] pl-[14px]">
292
+ <button
293
+ onClick={onToggle}
294
+ className="w-full h-10 flex items-center gap-3 px-3 justify-center rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
295
+ >
296
+ {expanded ? (
297
+ <ArrowLeft className="w-5 h-5" />
298
+ ) : (
299
+ <Menu className="w-5 h-5" />
300
+ )}
301
+ </button>
302
+ </div>
303
+
304
+ {/* Logo */}
305
+ <div className="px-4 py-4">
306
+ <div
307
+ className={`flex items-center h-10 ${expanded ? "justify-center" : "justify-center"}`}
308
+ >
309
+ <div className="flex items-center justify-center flex-shrink-0">
310
+ {expanded ? (
311
+ <XerticaLogo
312
+ className="h-5 w-auto"
313
+ variant="white"
314
+ />
315
+ ) : (
316
+ <XerticaXLogo
317
+ className="h-5 w-auto"
318
+ variant="white"
319
+ />
320
+ )}
321
+ </div>
322
+ </div>
323
+ </div>
324
+
325
+ {/* Navegação */}
326
+ <nav className="flex-1 px-4 py-4 overflow-hidden" ref={navRef}>
327
+ <div className="space-y-1">
328
+ {/* Itens visíveis */}
329
+ {(hasOverflow ? visibleItems : navigationItems).map((item) =>
330
+ renderMenuItem(item)
331
+ )}
332
+
333
+ {/* Botão de overflow (ellipsis) */}
334
+ {hasOverflow && (
335
+ <Popover>
336
+ <PopoverTrigger asChild>
337
+ <button
338
+ className={
339
+ expanded
340
+ ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
341
+ : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
342
+ }
343
+ >
344
+ <MoreHorizontal className="w-5 h-5 flex-shrink-0" />
345
+ {expanded && (
346
+ <span className="truncate text-sidebar-foreground">
347
+ Mais opções
348
+ </span>
349
+ )}
350
+ </button>
351
+ </PopoverTrigger>
352
+ <PopoverContent
353
+ side="right"
354
+ align="start"
355
+ className="w-56 p-2 bg-popover border border-border rounded-[var(--radius-card)] shadow-lg"
356
+ sideOffset={8}
357
+ >
358
+ <div className="space-y-1">
359
+ {overflowItems.map((item) => {
360
+ const Icon = item.icon;
361
+ return (
362
+ <button
363
+ key={item.path}
364
+ onClick={() => handleNavigate(item.path)}
365
+ className="w-full h-9 flex items-center gap-2 px-3 rounded-[var(--radius-button)] transition-all duration-200 text-popover-foreground/80 hover:bg-accent hover:text-accent-foreground text-left"
366
+ >
367
+ <Icon className="w-4 h-4 flex-shrink-0" />
368
+ <span className="truncate">{item.label}</span>
369
+ </button>
370
+ );
371
+ })}
372
+ </div>
373
+ </PopoverContent>
374
+ </Popover>
375
+ )}
376
+ </div>
377
+ </nav>
378
+
379
+ {/* Footer da sidebar - Usuário */}
380
+ <div className="p-4 space-y-2">
381
+ {/* Avatar do usuário */}
382
+ {!expanded ? (
383
+ <Tooltip>
384
+ <TooltipTrigger asChild>
385
+ <button
386
+ className="w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
387
+ >
388
+ <Avatar className="w-7 h-7 flex-shrink-0">
389
+ <AvatarFallback className="bg-sidebar-foreground/15 text-sidebar-foreground text-xs">
390
+ A
391
+ </AvatarFallback>
392
+ </Avatar>
393
+ </button>
394
+ </TooltipTrigger>
395
+ <SidebarTooltipContent side="right" sideOffset={0}>
396
+ <p>Ariel</p>
397
+ </SidebarTooltipContent>
398
+ </Tooltip>
399
+ ) : (
400
+ <button
401
+ className="w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
402
+ >
403
+ <Avatar className="w-7 h-7 flex-shrink-0">
404
+ <AvatarFallback className="bg-sidebar-foreground/15 text-sidebar-foreground text-xs">
405
+ A
406
+ </AvatarFallback>
407
+ </Avatar>
408
+ <span className="text-sidebar-foreground truncate">
409
+ Ariel
410
+ </span>
411
+ </button>
412
+ )}
413
+
414
+ {/* Botão Configurações */}
415
+ {!expanded ? (
416
+ <Tooltip>
417
+ <TooltipTrigger asChild>
418
+ <button
419
+ onClick={() => {
420
+ navigate("/settings");
421
+ if (window.innerWidth < 768) {
422
+ onToggle();
423
+ }
424
+ }}
425
+ className={"w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 " +
426
+ (isSettingsActive
427
+ ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
428
+ : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground")
429
+ }
430
+ >
431
+ <Settings className="w-5 h-5 flex-shrink-0" />
432
+ </button>
433
+ </TooltipTrigger>
434
+ <SidebarTooltipContent side="right" sideOffset={0}>
435
+ <p>Configurações</p>
436
+ </SidebarTooltipContent>
437
+ </Tooltip>
438
+ ) : (
439
+ <button
440
+ onClick={() => {
441
+ navigate("/settings");
442
+ if (window.innerWidth < 768) {
443
+ onToggle();
444
+ }
445
+ }}
446
+ className={
447
+ isSettingsActive
448
+ ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm"
449
+ : "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
450
+ }
451
+ >
452
+ <Settings className="w-5 h-5 flex-shrink-0" />
453
+ <span className="truncate text-sidebar-foreground">
454
+ Configurações
455
+ </span>
456
+ </button>
457
+ )}
458
+
459
+ {/* Botão Sair */}
460
+ {!expanded ? (
461
+ <Tooltip>
462
+ <TooltipTrigger asChild>
463
+ <button
464
+ onClick={onLogout}
465
+ className="w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
466
+ >
467
+ <LogOut className="w-5 h-5 flex-shrink-0" />
468
+ </button>
469
+ </TooltipTrigger>
470
+ <SidebarTooltipContent side="right" sideOffset={0}>
471
+ <p>Sair</p>
472
+ </SidebarTooltipContent>
473
+ </Tooltip>
474
+ ) : (
475
+ <button
476
+ onClick={onLogout}
477
+ className="w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
478
+ >
479
+ <LogOut className="w-5 h-5 flex-shrink-0" />
480
+ <span className="truncate text-sidebar-foreground">
481
+ Sair
482
+ </span>
483
+ </button>
484
+ )}
485
+ </div>
486
+ </div>
487
+ </TooltipProvider>
488
+ );
489
+ }