From 26a10ac4f7d79fbf534f6b35d5d67483eb9e3353 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Wed, 13 May 2026 22:56:30 +0200 Subject: [PATCH] =?UTF-8?q?fix(nav):=20corrige=20sistema=20de=20navega?= =?UTF-8?q?=C3=A7=C3=A3o=20p=C3=B3s-login=20e=20sincroniza=C3=A7=C3=A3o=20?= =?UTF-8?q?de=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causa raiz do login não navegar: getCurrentRole() retornava null quando vinculos.role era NULL no banco, fazendo isViewAllowed() retornar false e handleNavigate() falhar silenciosamente sem nenhum feedback. Fixes: - backend.ts: getCurrentRole usa workspace?.role || 'paciente' para garantir que nunca retorne null/undefined - App.tsx: onLoginSuccess usa setCurrentView+navigate diretamente, sem passar pela guarda de permissão (desnecessária pós-autenticação) - App.tsx: mount effect sempre chama navigate(currentView) para sincronizar a URL com a view real — antes só executava com hash vazio, deixando /#/login na URL ao recarregar com usuário autenticado - LoginView.tsx: remove spinner isInitializing de 3s que bloqueava o formulário em toda montagem do componente Co-Authored-By: Claude Sonnet 4.6 --- frontend/App.tsx | 12 +++++++----- frontend/services/backend.ts | 2 +- frontend/views/LoginView.tsx | 20 ++------------------ 3 files changed, 10 insertions(+), 24 deletions(-) diff --git a/frontend/App.tsx b/frontend/App.tsx index 633227b..de345d1 100644 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -210,11 +210,11 @@ const App: React.FC = () => { document.documentElement.style.setProperty('--brand-color-soft', `${clinColor}11`); }, [clinColor]); - // On mount: if there's no hash yet, write the current view into the URL + // On mount: always sync URL to match the actual current view. + // This handles auth redirects (e.g. reload at /#/login while authenticated shows dashboard + // but URL would stay /#/login without this call). useEffect(() => { - if (!window.location.hash || window.location.hash === '#update_db') { - navigate(currentView); - } + navigate(currentView); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -244,7 +244,9 @@ const App: React.FC = () => { default: return { const role = HybridBackend.getCurrentRole(); - handleNavigate(getDefaultViewForRole(role)); + const view = getDefaultViewForRole(role); + setCurrentView(view); + navigate(view); }} />; } }; diff --git a/frontend/services/backend.ts b/frontend/services/backend.ts index f060e7a..5f77fb3 100644 --- a/frontend/services/backend.ts +++ b/frontend/services/backend.ts @@ -141,7 +141,7 @@ export const HybridBackend = { getCurrentRole: (): string => { const workspace = HybridBackend.getActiveWorkspace(); - return workspace ? workspace.role : 'paciente'; + return workspace?.role || 'paciente'; }, getDashboardStats: async () => { diff --git a/frontend/views/LoginView.tsx b/frontend/views/LoginView.tsx index ddc9820..203accb 100644 --- a/frontend/views/LoginView.tsx +++ b/frontend/views/LoginView.tsx @@ -1,5 +1,5 @@ -import React, { useState, useEffect } from 'react'; -import { Database, Lock, User, ArrowRight, ShieldCheck, Loader2 } from 'lucide-react'; +import React, { useState } from 'react'; +import { Database, Lock, User, ArrowRight, ShieldCheck } from 'lucide-react'; import { HybridBackend } from '../services/backend.ts'; interface LoginViewProps { @@ -11,12 +11,6 @@ export const LoginView: React.FC = ({ onLoginSuccess }) => { const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); - const [isInitializing, setIsInitializing] = useState(true); - - useEffect(() => { - const timer = setTimeout(() => setIsInitializing(false), 3000); - return () => clearTimeout(timer); - }, []); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -37,16 +31,6 @@ export const LoginView: React.FC = ({ onLoginSuccess }) => { } }; - if (isInitializing) { - return ( -
- -

Inicializando Sistema...

- V1.0.2 -
- ); - } - return (