From cfc6a105b5b157d051af0b78abc946843a09341f Mon Sep 17 00:00:00 2001 From: m1guelmcf Date: Tue, 18 Nov 2025 21:21:59 -0300 Subject: [PATCH] nova sidebar --- components/Sidebar.tsx | 548 +++++++++++++++++++--------------- components/ui/userToolTip.tsx | 134 +++++---- 2 files changed, 380 insertions(+), 302 deletions(-) diff --git a/components/Sidebar.tsx b/components/Sidebar.tsx index 577d49c..f1ba0b8 100644 --- a/components/Sidebar.tsx +++ b/components/Sidebar.tsx @@ -5,271 +5,331 @@ import type React from "react"; import { useState, useEffect } from "react"; import { useRouter, usePathname } from "next/navigation"; import Link from "next/link"; -import Cookies from "js-cookie"; // Mantido apenas para a limpeza de segurança no logout +import Cookies from "js-cookie"; import { api } from "@/services/api.mjs"; import { Button } from "@/components/ui/button"; -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; -import { LogOut, ChevronLeft, ChevronRight, Home, CalendarCheck2, ClipboardPlus, CalendarClock, Users, SquareUser, ClipboardList, Stethoscope, ClipboardMinus } from "lucide-react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; + +import { + LogOut, + ChevronLeft, + ChevronRight, + Home, + CalendarCheck2, + ClipboardPlus, + CalendarClock, + Users, + SquareUser, + ClipboardList, + Stethoscope, + ClipboardMinus, +} from "lucide-react"; + import SidebarUserSection from "@/components/ui/userToolTip"; interface UserData { + id: string; + email: string; + app_metadata: { + user_role: string; + }; + user_metadata: { + cpf: string; + email_verified: boolean; + full_name: string; + phone_mobile: string; + role: string; + }; + identities: { + identity_id: string; id: string; - email: string; - app_metadata: { - user_role: string; - }; - user_metadata: { - cpf: string; - email_verified: boolean; - full_name: string; - phone_mobile: string; - role: string; - }; - identities: { - identity_id: string; - id: string; - user_id: string; - provider: string; - }[]; - is_anonymous: boolean; + user_id: string; + provider: string; + }[]; + is_anonymous: boolean; } interface MenuItem { - href: string; - icon: React.ElementType; - label: string; + href: string; + icon: React.ElementType; + label: string; } interface SidebarProps { - children: React.ReactNode; + children: React.ReactNode; } export default function Sidebar({ children }: SidebarProps) { - const [userData, setUserData] = useState(); - const [role, setRole] = useState(); - const [sidebarCollapsed, setSidebarCollapsed] = useState(false); - const [showLogoutDialog, setShowLogoutDialog] = useState(false); - const router = useRouter(); - const pathname = usePathname(); + const [userData, setUserData] = useState(); + const [role, setRole] = useState(); + const [sidebarCollapsed, setSidebarCollapsed] = useState(false); + const [showLogoutDialog, setShowLogoutDialog] = useState(false); + const router = useRouter(); + const pathname = usePathname(); - useEffect(() => { - const userInfoString = localStorage.getItem("user_info"); - // --- ALTERAÇÃO 1: Buscando o token no localStorage --- - const token = localStorage.getItem("token"); + useEffect(() => { + const userInfoString = localStorage.getItem("user_info"); + const token = localStorage.getItem("token"); - if (userInfoString && token) { - const userInfo = JSON.parse(userInfoString); + if (userInfoString && token) { + const userInfo = JSON.parse(userInfoString); - setUserData({ - id: userInfo.id ?? "", - email: userInfo.email ?? "", - app_metadata: { - user_role: userInfo.app_metadata?.user_role ?? "patient", - }, - user_metadata: { - cpf: userInfo.user_metadata?.cpf ?? "", - email_verified: userInfo.user_metadata?.email_verified ?? false, - full_name: userInfo.user_metadata?.full_name ?? "", - phone_mobile: userInfo.user_metadata?.phone_mobile ?? "", - role: userInfo.user_metadata?.role ?? "", - }, - identities: - userInfo.identities?.map((identity: any) => ({ - identity_id: identity.identity_id ?? "", - id: identity.id ?? "", - user_id: identity.user_id ?? "", - provider: identity.provider ?? "", - })) ?? [], - is_anonymous: userInfo.is_anonymous ?? false, - }); - setRole(userInfo.user_metadata?.role); - } else { - // O redirecionamento para /login já estava correto. Ótimo! - router.push("/login"); - } - }, [router]); - - useEffect(() => { - const handleResize = () => { - if (window.innerWidth < 1024) { - setSidebarCollapsed(true); - } else { - setSidebarCollapsed(false); - } - }; - handleResize(); - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); - - const handleLogout = () => setShowLogoutDialog(true); - - // --- ALTERAÇÃO 2: A função de logout agora é MUITO mais simples --- - const confirmLogout = async () => { - try { - // Chama a função centralizada para fazer o logout no servidor - await api.logout(); - } catch (error) { - // O erro já é logado dentro da função api.logout, não precisamos fazer nada aqui - } finally { - // A responsabilidade do componente é apenas limpar o estado local e redirecionar - localStorage.removeItem("user_info"); - localStorage.removeItem("token"); - Cookies.remove("access_token"); // Limpeza de segurança - - setShowLogoutDialog(false); - router.push("/"); // Redireciona para a home - } - }; - - const cancelLogout = () => setShowLogoutDialog(false); - - const SetMenuItems = (role: any) => { - const patientItems: MenuItem[] = [ - { href: "/patient/dashboard", icon: Home, label: "Dashboard" }, - { - href: "/patient/schedule", - icon: CalendarClock, - label: "Agendar Consulta", - }, - { - href: "/patient/appointments", - icon: CalendarCheck2, - label: "Minhas Consultas", - }, - { href: "/patient/reports", icon: ClipboardPlus, label: "Meus Laudos" }, - { href: "/patient/profile", icon: SquareUser, label: "Meus Dados" }, - ]; - - const doctorItems: MenuItem[] = [ - { href: "/doctor/dashboard", icon: Home, label: "Dashboard" }, - { href: "/doctor/medicos", icon: Users, label: "Gestão de Pacientes" }, - { href: "/doctor/consultas", icon: CalendarCheck2, label: "Consultas" }, - { - href: "/doctor/disponibilidade", - icon: ClipboardList, - label: "Disponibilidade", - }, - ]; - - const secretaryItems: MenuItem[] = [ - { href: "/secretary/dashboard", icon: Home, label: "Dashboard" }, - { - href: "/secretary/appointments", - icon: CalendarCheck2, - label: "Consultas", - }, - { - href: "/secretary/schedule", - icon: CalendarClock, - label: "Agendar Consulta", - }, - { - href: "/secretary/pacientes", - icon: Users, - label: "Gestão de Pacientes", - }, - ]; - - const managerItems: MenuItem[] = [ - { href: "/manager/dashboard", icon: Home, label: "Dashboard" }, - { href: "#", icon: ClipboardMinus, label: "Relatórios gerenciais" }, - { href: "/manager/usuario", icon: Users, label: "Gestão de Usuários" }, - { href: "/manager/home", icon: Stethoscope, label: "Gestão de Médicos" }, - { href: "/manager/pacientes", icon: Users, label: "Gestão de Pacientes" }, - { href: "/secretary/appointments", icon: CalendarCheck2, label: "Consultas" }, //adicionar botão de voltar pra pagina anterior - ]; - - let menuItems: MenuItem[]; - switch (role) { - case "gestor": - menuItems = managerItems; - break; - case "admin": - menuItems = managerItems; - break; - case "medico": - menuItems = doctorItems; - break; - case "secretaria": - menuItems = secretaryItems; - break; - case "paciente": - menuItems = patientItems; - break; - default: - menuItems = patientItems; - break; - } - return menuItems; - }; - - const menuItems = SetMenuItems(role); - - if (!userData) { - return
Carregando...
; + setUserData({ + id: userInfo.id ?? "", + email: userInfo.email ?? "", + app_metadata: { + user_role: userInfo.app_metadata?.user_role ?? "patient", + }, + user_metadata: { + cpf: userInfo.user_metadata?.cpf ?? "", + email_verified: userInfo.user_metadata?.email_verified ?? false, + full_name: userInfo.user_metadata?.full_name ?? "", + phone_mobile: userInfo.user_metadata?.phone_mobile ?? "", + role: userInfo.user_metadata?.role ?? "", + }, + identities: + userInfo.identities?.map((identity: any) => ({ + identity_id: identity.identity_id ?? "", + id: identity.id ?? "", + user_id: identity.user_id ?? "", + provider: identity.provider ?? "", + })) ?? [], + is_anonymous: userInfo.is_anonymous ?? false, + }); + setRole(userInfo.user_metadata?.role); + } else { + router.push("/login"); } + }, [router]); + useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 1024) { + setSidebarCollapsed(true); + } else { + setSidebarCollapsed(false); + } + }; + handleResize(); + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, []); + + const handleLogout = () => setShowLogoutDialog(true); + + const confirmLogout = async () => { + try { + await api.logout(); + } catch (error) { + } finally { + localStorage.removeItem("user_info"); + localStorage.removeItem("token"); + Cookies.remove("access_token"); + + setShowLogoutDialog(false); + router.push("/"); + } + }; + + const cancelLogout = () => setShowLogoutDialog(false); + + const SetMenuItems = (role: any) => { + const patientItems: MenuItem[] = [ + { href: "/patient/dashboard", icon: Home, label: "Dashboard" }, + { + href: "/patient/schedule", + icon: CalendarClock, + label: "Agendar Consulta", + }, + { + href: "/patient/appointments", + icon: CalendarCheck2, + label: "Minhas Consultas", + }, + { href: "/patient/reports", icon: ClipboardPlus, label: "Meus Laudos" }, + { href: "/patient/profile", icon: SquareUser, label: "Meus Dados" }, + ]; + + const doctorItems: MenuItem[] = [ + { href: "/doctor/dashboard", icon: Home, label: "Dashboard" }, + { href: "/doctor/medicos", icon: Users, label: "Gestão de Pacientes" }, + { href: "/doctor/consultas", icon: CalendarCheck2, label: "Consultas" }, + { + href: "/doctor/disponibilidade", + icon: ClipboardList, + label: "Disponibilidade", + }, + ]; + + const secretaryItems: MenuItem[] = [ + { href: "/secretary/dashboard", icon: Home, label: "Dashboard" }, + { + href: "/secretary/appointments", + icon: CalendarCheck2, + label: "Consultas", + }, + { + href: "/secretary/schedule", + icon: CalendarClock, + label: "Agendar Consulta", + }, + { + href: "/secretary/pacientes", + icon: Users, + label: "Gestão de Pacientes", + }, + ]; + + const managerItems: MenuItem[] = [ + { href: "/manager/dashboard", icon: Home, label: "Dashboard" }, + { href: "#", icon: ClipboardMinus, label: "Relatórios gerenciais" }, + { href: "/manager/usuario", icon: Users, label: "Gestão de Usuários" }, + { href: "/manager/home", icon: Stethoscope, label: "Gestão de Médicos" }, + { href: "/manager/pacientes", icon: Users, label: "Gestão de Pacientes" }, + { + href: "/secretary/appointments", + icon: CalendarCheck2, + label: "Consultas", + }, + ]; + + switch (role) { + case "gestor": + case "admin": + return managerItems; + case "medico": + return doctorItems; + case "secretaria": + return secretaryItems; + case "paciente": + default: + return patientItems; + } + }; + + const menuItems = SetMenuItems(role); + + if (!userData) { return ( -
-
-
- {!sidebarCollapsed && ( -
- {/* 🛑 SUBSTITUIÇÃO: Usando a tag com o caminho da logo */} - Logo MediConnect - MedConnect -
- )} - -
- - - -
- -
-
-
{children}
-
- - - - - Confirmar Saída - Deseja realmente sair do sistema? Você precisará fazer login novamente para acessar sua conta. - - - - - - - -
+
+ Carregando... +
); + } + + return ( +
+
+ {/* TOPO */} +
+ {!sidebarCollapsed && ( +
+
+ Logo MedConnect +
+ + + MedConnect + +
+ )} + + +
+ + {/* MENU */} + + + {/* PERFIL ORIGINAL + NOME BRANCO */} +
+ +
+
+
+
{children}
+
+ + + + Confirmar Saída + + Deseja realmente sair do sistema? Você precisará fazer login + novamente. + + + + + + + + +   +
+ ); } diff --git a/components/ui/userToolTip.tsx b/components/ui/userToolTip.tsx index 3c8de8d..d86cda1 100644 --- a/components/ui/userToolTip.tsx +++ b/components/ui/userToolTip.tsx @@ -2,7 +2,14 @@ import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; -import { CalendarCheck2, CalendarClock, ClipboardPlus, Home, LogOut, SquareUser } from "lucide-react"; +import { + CalendarCheck2, + CalendarClock, + ClipboardPlus, + Home, + LogOut, + SquareUser, +} from "lucide-react"; import { Popover, PopoverTrigger, @@ -34,45 +41,52 @@ export default function SidebarUserSection({ handleLogout, isActive, }: Props) { - const pathname = usePathname(); - const menuItems: any[] = [ - { href: "/patient/schedule", icon: CalendarClock, label: "Agendar Consulta" }, - { href: "/patient/appointments", icon: CalendarCheck2, label: "Minhas Consultas" }, - { href: "/patient/reports", icon: ClipboardPlus, label: "Meus Laudos" }, - { href: "/patient/profile", icon: SquareUser, label: "Meus Dados" }, - ] + const pathname = usePathname(); + const menuItems: any[] = [ + { + href: "/patient/schedule", + icon: CalendarClock, + label: "Agendar Consulta", + }, + { + href: "/patient/appointments", + icon: CalendarCheck2, + label: "Minhas Consultas", + }, + { href: "/patient/reports", icon: ClipboardPlus, label: "Meus Laudos" }, + { href: "/patient/profile", icon: SquareUser, label: "Meus Dados" }, + ]; return (
{/* POPUP DE INFORMAÇÕES DO USUÁRIO */} -
- - - - {userData.user_metadata.full_name - .split(" ") - .map((n) => n[0]) - .join("")} - - +
+ + + + {userData.user_metadata.full_name + .split(" ") + .map((n) => n[0]) + .join("")} + + - {!sidebarCollapsed && ( -
-

- {userData.user_metadata.full_name} -

-

- {userData.app_metadata.user_role} -

-
- )} -
+ {!sidebarCollapsed && ( +
+

+ {userData.user_metadata.full_name} +

+

+ {userData.app_metadata.user_role} +

+
+ )} +
{/* Card flutuante */} @@ -83,43 +97,47 @@ export default function SidebarUserSection({ >
- {/* Botão de sair */} +    
); }