From 96e35dc21d9fcf17b40e3c1afab4e52f6baafacc Mon Sep 17 00:00:00 2001 From: Gabriel Santana de Menezes Date: Sat, 9 May 2026 21:03:43 -0400 Subject: [PATCH] feat: restructure navbar and fix dead-end navigation across pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restructure the AppShell navbar for better UX grouping: rename "Organizações" to "Equipe", consolidate Org Dashboard and admin items inside the Equipe dropdown, add a persistent "+ Nova Tarefa" CTA button, and replace the isolated logout button with an avatar dropdown showing user name and email. Add "Buscar Organização" to the Equipe dropdown for all roles. Mobile nav simplified to Dashboard · Tarefas · + · Equipe. Per-page fixes: remove non-functional chevron and dead links from ProjectsPage; replace the PDF export button in DashboardPage with a working "Copiar Relatório" clipboard button; remove dead info links from OrganizationsPage; remove the broken support link from LoginPage; add Lista/Quadro view toggle to TaskListPage header. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/components/AppShell.tsx | 281 +++++++++++++++-------- frontend/src/pages/DashboardPage.tsx | 35 ++- frontend/src/pages/LoginPage.tsx | 5 +- frontend/src/pages/OrganizationsPage.tsx | 19 +- frontend/src/pages/ProjectsPage.tsx | 16 +- frontend/src/pages/TaskListPage.tsx | 32 ++- 6 files changed, 244 insertions(+), 144 deletions(-) diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx index d80da52..1c42ebe 100644 --- a/frontend/src/components/AppShell.tsx +++ b/frontend/src/components/AppShell.tsx @@ -2,17 +2,20 @@ import React, { useState } from "react"; import { Layout, ListTodo, - PlusCircle, + Plus, Columns, LogOut, Settings, Building2, Clock, ChevronDown, - Shield, FolderKanban, BarChart3, PieChart, + Search, + User, + Users, + PlusCircle, } from "lucide-react"; import { NavLink, Outlet, Navigate, Link } from "react-router-dom"; import { useAuth } from "../contexts/AuthContext"; @@ -43,7 +46,11 @@ export function AppShell() { const [showOrgModal, setShowOrgModal] = useState(false); const [showOrgSwitcher, setShowOrgSwitcher] = useState(false); const [showTasksDropdown, setShowTasksDropdown] = useState(false); - const [showOrgDropdown, setShowOrgDropdown] = useState(false); + const [showTeamDropdown, setShowTeamDropdown] = useState(false); + const [showAvatarDropdown, setShowAvatarDropdown] = useState(false); + + const isAdmin = + activeOrg?.roles.includes("OWNER") || activeOrg?.roles.includes("ADMIN"); React.useEffect(() => { if (isAuthenticated && user && user.organizations.length === 0) { @@ -181,10 +188,11 @@ export function AppShell() { )} + {/* Desktop Navigation */} -
+ {/* Right Actions */} +
+ + + Nova Tarefa + +
-
+ + {/* Avatar Dropdown */} +
+ + {showAvatarDropdown && ( + <> +
setShowAvatarDropdown(false)} + /> + +
+

+ {user?.name} +

+

+ {user?.email} +

+
+ +
+ + )}
@@ -383,7 +447,7 @@ export function AppShell() { } > - Dash + Dashboard {/* Mobile Tarefas Group */} @@ -437,59 +501,88 @@ export function AppShell() { )}
- {(activeOrg?.roles.includes("OWNER") || - activeOrg?.roles.includes("ADMIN")) && ( - - - Projetos - - )} - {(activeOrg?.roles.includes("OWNER") || - activeOrg?.roles.includes("ADMIN")) && ( - - cn(navLinkClassName({ isActive }), "flex-col gap-0.5 py-1") - } - > - - Org - - )} + {/* Mobile + New Task */} + + + Nova + - {/* Mobile Organizações Group */} + {/* Mobile Equipe Group */}
- {showOrgDropdown && ( + {showTeamDropdown && ( <>
setShowOrgDropdown(false)} + onClick={() => setShowTeamDropdown(false)} /> + {isAdmin && ( + <> + setShowTeamDropdown(false)} + className={dropdownItemClassName} + > + + Projetos + + setShowTeamDropdown(false)} + className={(props) => + cn(dropdownItemClassName(props), "mt-1") + } + > + + Dashboard da Org + + setShowTeamDropdown(false)} + className={(props) => + cn(dropdownItemClassName(props), "mt-1") + } + > + + Gestão + +
+ + )} setShowOrgDropdown(false)} + onClick={() => setShowTeamDropdown(false)} className={dropdownItemClassName} > @@ -497,7 +590,7 @@ export function AppShell() { setShowOrgDropdown(false)} + onClick={() => setShowTeamDropdown(false)} className={(props) => cn(dropdownItemClassName(props), "mt-1") } @@ -505,20 +598,16 @@ export function AppShell() { Pedidos - {activeOrg?.roles.some( - (role) => role === "OWNER" || role === "ADMIN", - ) && ( - setShowOrgDropdown(false)} - className={(props) => - cn(dropdownItemClassName(props), "mt-1") - } - > - - Gestão - - )} + setShowTeamDropdown(false)} + className={(props) => + cn(dropdownItemClassName(props), "mt-1") + } + > + + Buscar Org + )} diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index 349ea66..3b10989 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -10,7 +10,8 @@ import { Layout, FileText, Filter, - Download, + Copy, + Check, AlertCircle, Loader2, History, @@ -30,6 +31,7 @@ export const DashboardPage: React.FC = () => { const [startDate, setStartDate] = useState(startOfMonth(new Date())); const [endDate, setEndDate] = useState(endOfMonth(new Date())); const [error, setError] = useState(null); + const [copied, setCopied] = useState(false); const fetchDashboardData = async () => { setIsLoading(true); @@ -57,6 +59,24 @@ export const DashboardPage: React.FC = () => { return `${h}h ${m}m`; }; + const handleCopyReport = () => { + if (!data) return; + const header = "Tarefa\tProjeto\tConcluída em\tStatus"; + const rows = data.finishedTasksInPeriod.map((task) => + [ + task.title, + task.project?.name ?? "-", + task.finishedAt + ? format(new Date(task.finishedAt), "dd/MM/yyyy HH:mm") + : "-", + "Finalizado", + ].join("\t"), + ); + navigator.clipboard.writeText([header, ...rows].join("\n")); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + return (
{/* Header & Filters */} @@ -199,10 +219,6 @@ export const DashboardPage: React.FC = () => { ) : "0h 0m"}
-
{ Relatório de Entregas
-
diff --git a/frontend/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx index 446728d..e8921b0 100644 --- a/frontend/src/pages/LoginPage.tsx +++ b/frontend/src/pages/LoginPage.tsx @@ -106,13 +106,10 @@ export const LoginPage: React.FC = () => { -
+

Não tem uma conta? Criar conta

-

- Precisa de ajuda? Falar com suporte -

diff --git a/frontend/src/pages/OrganizationsPage.tsx b/frontend/src/pages/OrganizationsPage.tsx index 50ba29c..ada6e28 100644 --- a/frontend/src/pages/OrganizationsPage.tsx +++ b/frontend/src/pages/OrganizationsPage.tsx @@ -1,13 +1,12 @@ import { useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { - Building2, - Plus, - Search, - Users, - Settings, + Building2, + Plus, + Search, + Users, + Settings, ArrowRight, - ExternalLink, ShieldCheck, UserPlus, X, @@ -238,10 +237,6 @@ export function OrganizationsPage() {

Organizações são espaços isolados para seus projetos e tarefas. Você pode alternar facilmente entre elas e gerenciar diferentes equipes.

- - Entender hierarquia - -
@@ -252,10 +247,6 @@ export function OrganizationsPage() {

Crie uma organização em segundos e comece a convidar seus membros. O BeeTask facilita a colaboração desde o primeiro dia.

- - Dicas de onboarding - -
diff --git a/frontend/src/pages/ProjectsPage.tsx b/frontend/src/pages/ProjectsPage.tsx index 209c7d2..323d9f2 100644 --- a/frontend/src/pages/ProjectsPage.tsx +++ b/frontend/src/pages/ProjectsPage.tsx @@ -4,15 +4,12 @@ import { FolderKanban, Plus, Search, - Building2, ArrowRight, Loader2, X, Target, Rocket, ShieldCheck, - ExternalLink, - ChevronRight } from "lucide-react"; import { useAuth } from "../contexts/AuthContext"; import { projectService, type Project } from "../services/projectService"; @@ -146,7 +143,7 @@ export const ProjectsPage: React.FC = () => { -
+
{[1, 2, 3].map(i => (
@@ -154,9 +151,6 @@ export const ProjectsPage: React.FC = () => {
))}
-
@@ -233,10 +227,6 @@ export const ProjectsPage: React.FC = () => {

Cada projeto pode ser encarado como um objetivo específico. Use-os para separar demandas de diferentes clientes ou departamentos da sua organização.

- - Melhores práticas de organização - -
@@ -247,10 +237,6 @@ export const ProjectsPage: React.FC = () => {

Projetos herdam as permissões da organização. Apenas membros autorizados podem visualizar e interagir com as tarefas de cada projeto.

- - Ver detalhes de visibilidade - -
diff --git a/frontend/src/pages/TaskListPage.tsx b/frontend/src/pages/TaskListPage.tsx index b396e42..dabffa3 100644 --- a/frontend/src/pages/TaskListPage.tsx +++ b/frontend/src/pages/TaskListPage.tsx @@ -4,7 +4,9 @@ import { Calendar, CheckCircle2, Clock, + Columns, Filter, + List, Plus, RefreshCw, Search, @@ -107,13 +109,29 @@ export function TaskListPage() { Visualize e organize suas atividades em tempo real.

- - - Criar Tarefa - +
+ {/* View toggle */} +
+ + + Lista + + + + Quadro + +
+ + + Criar Tarefa + +