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 + +