From 0c57897e467cb1187d9866303b6f9d4a503e9126 Mon Sep 17 00:00:00 2001 From: Gabriel Menezes Date: Sun, 11 Oct 2026 17:15:51 -0400 Subject: [PATCH] refactor: remove top header, migrate user profile, timer status, and workspace switcher to sidebar with single-word nav items --- .../src/components/layout/AppShell.tsx | 22 +- .../src/components/layout/Sidebar.tsx | 348 +++++++++++++++--- 2 files changed, 326 insertions(+), 44 deletions(-) diff --git a/new-frontend/src/components/layout/AppShell.tsx b/new-frontend/src/components/layout/AppShell.tsx index 435db8f..f6648ab 100644 --- a/new-frontend/src/components/layout/AppShell.tsx +++ b/new-frontend/src/components/layout/AppShell.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { Outlet } from 'react-router-dom' import { Sidebar } from './Sidebar' -import { Header } from './Header' +import { Menu as MenuIcon } from 'lucide-react' export const AppShell = () => { const [isMobileOpen, setIsMobileOpen] = useState(false) @@ -20,7 +20,25 @@ export const AppShell = () => { {/* Main Content Area */}
-
setIsMobileOpen(true)} /> + {/* Mobile-only compact top bar to open drawer on smartphones */} +
+ +
+ 🐝 + + BeeTask + +
+
+
+
diff --git a/new-frontend/src/components/layout/Sidebar.tsx b/new-frontend/src/components/layout/Sidebar.tsx index a8aec72..6346709 100644 --- a/new-frontend/src/components/layout/Sidebar.tsx +++ b/new-frontend/src/components/layout/Sidebar.tsx @@ -1,4 +1,5 @@ -import { NavLink } from 'react-router-dom' +import { useState, useRef, useEffect } from 'react' +import { NavLink, Link, useNavigate } from 'react-router-dom' import { LayoutDashboard, ListTodo, @@ -11,10 +12,19 @@ import { Building2, Sun, Moon, + Clock, + Square, + ChevronDown, + Check, + PlusCircle, + User, + LogOut, } from 'lucide-react' import { Chip, ChipLabel } from '@heroui/react' import { useAuth } from '../../contexts/AuthContext' import { useTheme } from '../../contexts/ThemeContext' +import { useTimer } from '../../contexts/TimerContext' +import { formatSecondsToTimer } from '../../lib/timeUtils' interface SidebarProps { isMobileOpen: boolean @@ -22,15 +32,52 @@ interface SidebarProps { } export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => { - const { activeOrg } = useAuth() + const { user, activeOrg, setActiveOrg, logout } = useAuth() const { theme, toggleTheme } = useTheme() + const { activeTask, activeSeconds, stopTimer } = useTimer() + const navigate = useNavigate() + const [showOrgDropdown, setShowOrgDropdown] = useState(false) + const [showUserMenu, setShowUserMenu] = useState(false) + + const orgRef = useRef(null) + const userRef = useRef(null) + + // Close dropdowns on outside click + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (orgRef.current && !orgRef.current.contains(e.target as Node)) { + setShowOrgDropdown(false) + } + if (userRef.current && !userRef.current.contains(e.target as Node)) { + setShowUserMenu(false) + } + } + document.addEventListener('mousedown', handleClickOutside) + return () => document.removeEventListener('mousedown', handleClickOutside) + }, []) + + const userInitials = user?.name + ? user.name + .split(' ') + .slice(0, 2) + .map((n) => n[0]) + .join('') + .toUpperCase() + : 'U' + + const handleLogout = () => { + logout() + navigate('/login') + } + + // All navigation items strictly formatted with a SINGLE WORD const navItems = [ { - group: 'Principal', + group: 'Geral', links: [ - { to: '/dashboard', label: 'Meu Dashboard', icon: }, - { to: '/tasks', label: 'Tarefas & Board', icon: }, + { to: '/dashboard', label: 'Dashboard', icon: }, + { to: '/tasks', label: 'Tarefas', icon: }, ], }, { @@ -41,10 +88,10 @@ export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => { ], }, { - group: 'Gestão & Equipe', + group: 'Gestão', links: [ - { to: '/analytics', label: 'Analytics da Org', icon: }, - { to: '/members', label: 'Membros & Squads', icon: }, + { to: '/analytics', label: 'Analytics', icon: }, + { to: '/members', label: 'Membros', icon: }, { to: '/organization/settings', label: 'Configurações', icon: }, ], }, @@ -52,22 +99,22 @@ export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => { const navContent = (
- {/* Brand & Logo */} -
- -
+ {/* Brand & Logo + Mobile Close */} +
+ +
🐝
- + BeeTask - - v3.0 + + v3
-

+

Workspace Ágil

@@ -77,30 +124,168 @@ export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => {
- {/* Nav List */} -
+ {/* Workspace Switcher in Sidebar */} +
+ + + {/* Workspace Dropdown Popover */} + {showOrgDropdown && ( +
+
+ + Seus Workspaces + + + {user?.organizations?.length || 0} + +
+ +
+ {user?.organizations?.map((org) => { + const isActive = org.id === activeOrg?.id + return ( + + ) + })} +
+ +
+ { + setShowOrgDropdown(false) + onCloseMobile() + }} + className="flex items-center gap-2 p-2 rounded-xl text-xs font-semibold text-brand hover:bg-brand/10 transition-colors" + > + + Gerenciar Workspaces + +
+
+ )} +
+ + {/* Active Running Task Activity Status Banner */} + {activeTask && ( +
+
+
+
+ + + + + + Atividade Ativa + +
+ + {/* Pause/Stop Timer Button */} + +
+ +

+ {activeTask.title} +

+ +
+ + {formatSecondsToTimer(activeSeconds)} +
+
+
+ )} + + {/* Navigation List - Single-Word Items */} +
{navItems.map((group, idx) => ( -
-

+

+

{group.group}

-
+
{group.links.map((link) => ( - `flex items-center gap-3 px-3 py-2.5 rounded-xl text-xs font-semibold transition-all ${ + `flex items-center gap-3 px-3 py-2 rounded-xl text-xs font-semibold transition-all ${ isActive ? 'bg-brand text-white shadow-md shadow-brand/20 font-bold' - : 'text-text-muted hover:text-text-main hover:bg-surface-muted' + : 'text-muted hover:text-foreground hover:bg-surface-raised' }` } > @@ -113,29 +298,51 @@ export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => { ))}
- {/* Bottom Workspace Card Info */} -
-
-
-
- + {/* Bottom User Profile, Theme & Logout Card */} +
+
+ {/* User Photo & Info */} +
+
+

+ {user?.name || 'Usuário'} +

+

+ {user?.email} +

+
+ + + {/* Theme Toggle Button */}
+ + {/* User Popover Menu */} + {showUserMenu && ( +
+
+

{user?.name || 'Usuário'}

+

{user?.email}

+
+ + { + setShowUserMenu(false) + onCloseMobile() + }} + className="flex items-center gap-2.5 px-3 py-2 rounded-xl text-xs font-medium text-foreground hover:bg-surface-raised hover:text-brand transition-colors" + > + + Meu Perfil + + + { + setShowUserMenu(false) + onCloseMobile() + }} + className="flex items-center gap-2.5 px-3 py-2 rounded-xl text-xs font-medium text-foreground hover:bg-surface-raised hover:text-brand transition-colors" + > + + Configurações + + + { + setShowUserMenu(false) + onCloseMobile() + }} + className="flex items-center gap-2.5 px-3 py-2 rounded-xl text-xs font-medium text-foreground hover:bg-surface-raised hover:text-brand transition-colors" + > + + Workspaces + + +
+ +
+
+ )}
) @@ -159,7 +423,7 @@ export const Sidebar = ({ isMobileOpen, onCloseMobile }: SidebarProps) => { {isMobileOpen && (