From 612a70ee902b589c8dc98f8567be2c00eb4bfca6 Mon Sep 17 00:00:00 2001 From: Lucas Rodrigues Date: Fri, 10 Oct 2025 20:04:17 -0300 Subject: [PATCH] criando users --- components/doctor-layout.tsx | 231 ++++++++++++++++++---------------- components/manager-layout.tsx | 66 ++++++---- 2 files changed, 170 insertions(+), 127 deletions(-) diff --git a/components/doctor-layout.tsx b/components/doctor-layout.tsx index 34ab89e..27d5cdc 100644 --- a/components/doctor-layout.tsx +++ b/components/doctor-layout.tsx @@ -1,10 +1,11 @@ "use client"; 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"; // <-- 1. IMPORTAÇÃO ADICIONADA + import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; @@ -24,43 +25,63 @@ interface DoctorData { permissions: object; } -interface DoctorLayoutProps { +interface PatientLayoutProps { children: React.ReactNode; } -export default function DoctorLayout({ children }: DoctorLayoutProps) { +export default function DoctorLayout({ children }: PatientLayoutProps) { const [doctorData, setDoctorData] = useState(null); const [sidebarCollapsed, setSidebarCollapsed] = useState(false); const [showLogoutDialog, setShowLogoutDialog] = useState(false); - const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); // Novo estado para menu mobile + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const [windowWidth, setWindowWidth] = useState(0); - const isMobile = windowWidth < 1024; // breakpoint lg + const isMobile = windowWidth < 1024; const router = useRouter(); const pathname = usePathname(); + // ================================================================== + // 2. BLOCO DE SEGURANÇA CORRIGIDO + // ================================================================== useEffect(() => { - const data = localStorage.getItem("doctorData"); - if (data) { - setDoctorData(JSON.parse(data)); + const userInfoString = localStorage.getItem("user_info"); + const token = Cookies.get("access_token"); + + if (userInfoString && token) { + const userInfo = JSON.parse(userInfoString); + + // 3. "TRADUZIMOS" os dados da API para o formato que o layout espera + setDoctorData({ + id: userInfo.id || "", + name: userInfo.user_metadata?.full_name || "Doutor(a)", + email: userInfo.email || "", + specialty: userInfo.user_metadata?.specialty || "Especialidade", + // Campos que não vêm do login, definidos como vazios para não quebrar + phone: userInfo.phone || "", + cpf: "", + crm: "", + department: "", + permissions: {}, + }); } else { + // Se faltar o token ou os dados, volta para o login router.push("/doctor/login"); } }, [router]); useEffect(() => { - const handleResize = () => setWindowWidth(window.innerWidth); - handleResize(); // inicializa com a largura atual - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); + const handleResize = () => setWindowWidth(window.innerWidth); + handleResize(); // inicializa com a largura atual + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); +}, []); - useEffect(() => { - if (isMobile) { - setSidebarCollapsed(true); - } else { - setSidebarCollapsed(false); - } - }, [isMobile]); +useEffect(() => { + if (isMobile) { + setSidebarCollapsed(true); + } else { + setSidebarCollapsed(false); + } +}, [isMobile]); const handleLogout = () => { setShowLogoutDialog(true); @@ -82,7 +103,7 @@ export default function DoctorLayout({ children }: DoctorLayoutProps) { const menuItems = [ { - href: "/doctor/dashboard", + href: "#", icon: Home, label: "Dashboard", // Botão para o dashboard do médico @@ -112,17 +133,17 @@ export default function DoctorLayout({ children }: DoctorLayoutProps) { } return ( -
+
{/* Sidebar para desktop */} -
-
+
+
{!sidebarCollapsed && (
-
-
+
+
- MidConnecta + MidConnecta
)} -
+ MedConnect +
+ )} +
+
- -
-
- {/* Se a sidebar estiver recolhida, o avatar e o texto do usuário também devem ser condensados ou ocultados */} - {!sidebarCollapsed && ( - <> - - - - {doctorData.name - .split(" ") - .map((n) => n[0]) - .join("")} - - -
-

{doctorData.name}

-

{doctorData.specialty}

-
- - )} - {sidebarCollapsed && ( - {/* Centraliza o avatar quando recolhido */} +
+
+ {/* Se a sidebar estiver recolhida, o avatar e o texto do usuário também devem ser condensados ou ocultados */} + {!sidebarCollapsed && ( + <> + {doctorData.name @@ -213,33 +218,49 @@ export default function DoctorLayout({ children }: DoctorLayoutProps) { .join("")} - )} -
+
+

{doctorData.name}

+

{doctorData.specialty}

+
+ + )} + {sidebarCollapsed && ( + {/* Centraliza o avatar quando recolhido */} + + + {doctorData.name + .split(" ") + .map((n) => n[0]) + .join("")} + + + )} +
- {/* Novo botão de sair, usando a mesma estrutura dos itens de menu */} -
- - {!sidebarCollapsed && Sair} -
+ {/* Novo botão de sair, usando a mesma estrutura dos itens de menu */} +
+ + {!sidebarCollapsed && Sair}
- +
+
{/* Sidebar para mobile (apresentado como um menu overlay) */} {isMobileMenuOpen && ( -
+
)} -
-
+
+
-
-
+
+
- Hospital System + Hospital System
@@ -331,4 +352,4 @@ export default function DoctorLayout({ children }: DoctorLayoutProps) {
); -} +} \ No newline at end of file diff --git a/components/manager-layout.tsx b/components/manager-layout.tsx index 9f94be4..47ff1d2 100644 --- a/components/manager-layout.tsx +++ b/components/manager-layout.tsx @@ -4,6 +4,8 @@ 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"; // <-- 1. IMPORTAÇÃO ADICIONADA + import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; @@ -37,7 +39,7 @@ interface ManagerData { permissions: object; } -interface ManagerLayoutProps { +interface ManagerLayoutProps { // Corrigi o nome da prop aqui children: React.ReactNode; } @@ -48,15 +50,34 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { const router = useRouter(); const pathname = usePathname(); + // ================================================================== + // 2. BLOCO DE SEGURANÇA CORRIGIDO + // ================================================================== useEffect(() => { - const data = localStorage.getItem("managerData"); - if (data) { - setManagerData(JSON.parse(data)); + const userInfoString = localStorage.getItem("user_info"); + const token = Cookies.get("access_token"); + + if (userInfoString && token) { + const userInfo = JSON.parse(userInfoString); + + // 3. "TRADUZIMOS" os dados da API para o formato que o layout espera + setManagerData({ + id: userInfo.id || "", + name: userInfo.user_metadata?.full_name || "Gestor(a)", + email: userInfo.email || "", + department: userInfo.user_metadata?.role || "Gestão", + // Campos que não vêm do login, definidos como vazios para não quebrar + phone: userInfo.phone || "", + cpf: "", + permissions: {}, + }); } else { + // Se faltar o token ou os dados, volta para o login router.push("/manager/login"); } }, [router]); + // 🔥 Responsividade automática da sidebar useEffect(() => { const handleResize = () => { @@ -84,9 +105,9 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { const cancelLogout = () => setShowLogoutDialog(false); const menuItems = [ - { href: "/manager/dashboard", icon: Home, label: "Dashboard" }, + { href: "/manager/dashboard/", icon: Home, label: "Dashboard" }, { href: "#", icon: Calendar, label: "Relatórios gerenciais" }, - { href: "/manager/usuario", icon: User, label: "Gestão de Usuários" }, + { href: "/manager/usuario/", icon: User, label: "Gestão de Usuários" }, { href: "/manager/home", icon: User, label: "Gestão de Médicos" }, { href: "#", icon: Calendar, label: "Configurações" }, ]; @@ -96,20 +117,20 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { } return ( -
+
{/* Sidebar */}
{/* Logo + collapse button */} -
+
{!sidebarCollapsed && (
-
-
+
+
- + MidConnecta
@@ -139,10 +160,11 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { return (
{!sidebarCollapsed && ( @@ -168,10 +190,10 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { {!sidebarCollapsed && (
-

+

{managerData.name}

-

+

{managerData.department}

@@ -204,14 +226,14 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) { ${sidebarCollapsed ? "ml-16" : "ml-64"}`} > {/* Header */} -
+
{/* Search */}
- +
@@ -220,7 +242,7 @@ export default function ManagerLayout({ children }: ManagerLayoutProps) {