From 2a284f9e6e80615c4501c40a013f9fd7d37e9e26 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Thu, 14 May 2026 04:54:22 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20add=20Configura=C3=A7=C3=B5es=20pag?= =?UTF-8?q?e=20with=20profile/integration=20cards?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move user profile card and Google connect button from sidebar footer to a dedicated Configurações view. Sidebar footer now shows a compact user button that navigates to settings. All roles have access. Co-Authored-By: Claude Sonnet 4.6 --- frontend/App.tsx | 15 ++-- frontend/components/Sidebar.tsx | 72 +++++---------- frontend/views/ConfiguracoesView.tsx | 129 +++++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 57 deletions(-) create mode 100644 frontend/views/ConfiguracoesView.tsx diff --git a/frontend/App.tsx b/frontend/App.tsx index 5b15e03..cb58f00 100644 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -23,6 +23,7 @@ import { DentistRegisterView } from './views/DentistRegisterView.tsx'; import { DentistasView, EspecialidadesView, PlanosView, SyncView, ProcedimentosView } from './views/AdminViews.tsx'; import { NotificationsView } from './views/NotificationsView.tsx'; import { ReportsView } from './views/ReportsView.tsx'; +import { ConfiguracoesView } from './views/ConfiguracoesView.tsx'; export type ViewKey = | 'landing' @@ -45,7 +46,8 @@ export type ViewKey = | 'clinicas' | 'sync' | 'relatorios' - | 'cadastro-dentista'; + | 'cadastro-dentista' + | 'configuracoes'; // ------- URL <-> VIEW mapping ------- const ROUTE_MAP: Record = { @@ -71,6 +73,7 @@ const ROUTE_MAP: Record = { '/notificacoes': 'notificacoes', '/relatorios': 'relatorios', '/cadastro-dentista': 'cadastro-dentista', + '/configuracoes': 'configuracoes', }; const VIEW_TO_ROUTE: Record = { @@ -94,7 +97,8 @@ const VIEW_TO_ROUTE: Record = { notificacoes: '/notificacoes', relatorios: '/relatorios', sync: '/admin/sync', - 'cadastro-dentista': '/cadastro-dentista' + 'cadastro-dentista': '/cadastro-dentista', + configuracoes: '/configuracoes', }; /** Resolve current URL to a ViewKey */ @@ -121,9 +125,9 @@ const App: React.FC = () => { if (role === 'admin' || role === 'donoclinica') return true; const permissions: Record = { - paciente: ['tratamentos', 'notificacoes'], - dentista: ['dashboard', 'pacientes', 'agenda', 'ortodontia', 'tratamentos', 'notificacoes', 'clinicas'], - funcionario: ['dashboard', 'leads', 'pacientes', 'agenda', 'financeiro', 'tratamentos', 'lancar-gto', 'relatorios', 'notificacoes', 'clinicas'], + paciente: ['tratamentos', 'notificacoes', 'configuracoes'], + dentista: ['dashboard', 'pacientes', 'agenda', 'ortodontia', 'tratamentos', 'notificacoes', 'clinicas', 'configuracoes'], + funcionario: ['dashboard', 'leads', 'pacientes', 'agenda', 'financeiro', 'tratamentos', 'lancar-gto', 'relatorios', 'notificacoes', 'clinicas', 'configuracoes'], }; return permissions[role]?.includes(view) || false; @@ -225,6 +229,7 @@ const App: React.FC = () => { case 'notificacoes': return ; case 'relatorios': return ; case 'cadastro-dentista': return ; + case 'configuracoes': return ; case 'login': default: return { diff --git a/frontend/components/Sidebar.tsx b/frontend/components/Sidebar.tsx index a4a2487..3f5a43f 100644 --- a/frontend/components/Sidebar.tsx +++ b/frontend/components/Sidebar.tsx @@ -1,11 +1,9 @@ import React from 'react'; import { Users, Calendar as CalendarIcon, LayoutDashboard, Stethoscope, - DollarSign, RefreshCw, Database, Activity, BookOpen, Award, Megaphone, LogOut, ClipboardList, Bell, Building2, User, BarChart3 + DollarSign, RefreshCw, Database, Activity, BookOpen, Award, Megaphone, LogOut, ClipboardList, Bell, Building2, User, BarChart3, Settings } from 'lucide-react'; import { HybridBackend } from '../services/backend.ts'; -import { GoogleConnectButton } from './GoogleConnectButton.tsx'; -import { useState, useEffect } from 'react'; interface SidebarProps { activeTab: string; @@ -13,27 +11,12 @@ interface SidebarProps { } export const Sidebar: React.FC = ({ activeTab, setActiveTab }) => { - const [connectedAccounts, setConnectedAccounts] = useState([]); const currentRole = HybridBackend.getCurrentRole(); const userName = HybridBackend.getCurrentUserName(); const userEmail = HybridBackend.getCurrentUser(); const activeWorkspace = HybridBackend.getActiveWorkspace(); const clinColor = activeWorkspace?.cor || '#2563eb'; - const fetchGoogleStatus = async () => { - try { - const response = await fetch('/api/auth/google/status'); - const data = await response.json(); - setConnectedAccounts(data); - } catch (error) { - console.error("Erro ao buscar status do Google:", error); - } - }; - - useEffect(() => { - fetchGoogleStatus(); - }, []); - const menuItems = [ { id: 'dashboard', label: 'VISÃO GERAL', icon: LayoutDashboard }, { id: 'clinicas', label: 'MINHAS CLÍNICAS', icon: Building2 }, @@ -51,11 +34,12 @@ export const Sidebar: React.FC = ({ activeTab, setActiveTab }) => { id: 'planos', label: 'PLANOS / CONVÊNIOS', icon: BookOpen }, { id: 'notificacoes', label: 'NOTIFICAÇÕES', icon: Bell }, { id: 'sync', label: 'SINCRONIZAÇÃO', icon: RefreshCw }, + { id: 'configuracoes', label: 'CONFIGURAÇÕES', icon: Settings }, ].filter(item => { if (['admin', 'donoclinica'].includes(currentRole)) return true; - if (currentRole === 'paciente') return ['tratamentos', 'notificacoes'].includes(item.id); - if (currentRole === 'dentista') return ['dashboard', 'pacientes', 'tratamentos', 'agenda', 'ortodontia', 'notificacoes', 'clinicas'].includes(item.id); - if (currentRole === 'funcionario') return ['dashboard', 'leads', 'pacientes', 'tratamentos', 'lancar-gto', 'agenda', 'financeiro', 'relatorios', 'notificacoes', 'clinicas'].includes(item.id); + if (currentRole === 'paciente') return ['tratamentos', 'notificacoes', 'configuracoes'].includes(item.id); + if (currentRole === 'dentista') return ['dashboard', 'pacientes', 'tratamentos', 'agenda', 'ortodontia', 'notificacoes', 'clinicas', 'configuracoes'].includes(item.id); + if (currentRole === 'funcionario') return ['dashboard', 'leads', 'pacientes', 'tratamentos', 'lancar-gto', 'agenda', 'financeiro', 'relatorios', 'notificacoes', 'clinicas', 'configuracoes'].includes(item.id); return false; }); @@ -105,39 +89,23 @@ export const Sidebar: React.FC = ({ activeTab, setActiveTab }) => })} -
- {/* User Profile Section */} -
-
-
- -
-
-

{userName}

-

{userEmail}

-
+
+ +
+
+
+ ); +};