From a8a2d5c09a05096374e49c84203033301d02798a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Gustavo?=
<166467972+JoaoGustavo-dev@users.noreply.github.com>
Date: Sun, 21 Sep 2025 16:58:18 -0300
Subject: [PATCH] add login screen in doctors page
---
susconecta/app/layout.tsx | 7 +-
susconecta/app/login/page.tsx | 124 +++++++++++++++++++++++
susconecta/app/profissional/page.tsx | 47 ++++++---
susconecta/components/ProtectedRoute.tsx | 40 ++++++++
susconecta/hooks/useAuth.tsx | 90 ++++++++++++++++
5 files changed, 292 insertions(+), 16 deletions(-)
create mode 100644 susconecta/app/login/page.tsx
create mode 100644 susconecta/components/ProtectedRoute.tsx
create mode 100644 susconecta/hooks/useAuth.tsx
diff --git a/susconecta/app/layout.tsx b/susconecta/app/layout.tsx
index f127de6..52ed9d1 100644
--- a/susconecta/app/layout.tsx
+++ b/susconecta/app/layout.tsx
@@ -1,5 +1,6 @@
import type React from "react"
import type { Metadata } from "next"
+import { AuthProvider } from "@/hooks/useAuth"
import "./globals.css"
export const metadata: Metadata = {
@@ -17,7 +18,11 @@ export default function RootLayout({
}) {
return (
-
{children}
+
+
+ {children}
+
+
)
}
diff --git a/susconecta/app/login/page.tsx b/susconecta/app/login/page.tsx
new file mode 100644
index 0000000..e563c6d
--- /dev/null
+++ b/susconecta/app/login/page.tsx
@@ -0,0 +1,124 @@
+'use client'
+import { useState } from 'react'
+import { useRouter } from 'next/navigation'
+import Link from 'next/link'
+import { useAuth } from '@/hooks/useAuth'
+import { Button } from '@/components/ui/button'
+import { Input } from '@/components/ui/input'
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
+import { Alert, AlertDescription } from '@/components/ui/alert'
+
+export default function LoginPage() {
+ const [credentials, setCredentials] = useState({ email: '', password: '' })
+ const [error, setError] = useState('')
+ const [loading, setLoading] = useState(false)
+ const router = useRouter()
+ const { login } = useAuth()
+
+ const handleLogin = async (e: React.FormEvent) => {
+ e.preventDefault()
+ setLoading(true)
+ setError('')
+
+ // Simular delay de autenticação
+ await new Promise(resolve => setTimeout(resolve, 1000))
+
+ // Tentar fazer login usando o contexto
+ const success = login(credentials.email, credentials.password)
+
+ if (success) {
+ // Aguardar um pouco para garantir que o estado foi atualizado
+ setTimeout(() => {
+ // Tentar router.push primeiro
+ router.push('/profissional')
+
+ // Fallback: usar window.location se router.push não funcionar
+ setTimeout(() => {
+ if (window.location.pathname === '/login') {
+ window.location.href = '/profissional'
+ }
+ }, 100)
+ }, 100)
+ } else {
+ setError('Email ou senha incorretos')
+ }
+
+ setLoading(false)
+ }
+
+ return (
+
+
+
+
+ Login Profissional de Saúde
+
+
+ Entre com suas credenciais para acessar o sistema
+
+
+
+
+
+ Acesso ao Sistema
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/susconecta/app/profissional/page.tsx b/susconecta/app/profissional/page.tsx
index d69ffda..76f070c 100644
--- a/susconecta/app/profissional/page.tsx
+++ b/susconecta/app/profissional/page.tsx
@@ -2,6 +2,8 @@
import React, { useState } from "react";
import Link from "next/link";
+import ProtectedRoute from "@/components/ProtectedRoute";
+import { useAuth } from "@/hooks/useAuth";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
@@ -65,6 +67,7 @@ const colorsByType = {
};
const ProfissionalPage = () => {
+ const { logout, userEmail } = useAuth();
const [activeSection, setActiveSection] = useState('calendario');
const [pacienteSelecionado, setPacienteSelecionado] = useState(null);
const [events, setEvents] = useState([
@@ -615,20 +618,33 @@ const ProfissionalPage = () => {
};
return (
-
-
-
-
-
-
-
-
-
-
Conta do profissional
-
{medico.nome}
-
{medico.identificacao}
-
-
+
+
+
+
+
+
+
+
+
+
+
+
Conta do profissional
+
{medico.nome}
+
{medico.identificacao}
+ {userEmail && (
+
Logado como: {userEmail}
+ )}
+
+
+
+
{}
@@ -851,7 +867,8 @@ const ProfissionalPage = () => {
)}
-
+
+
);
};
diff --git a/susconecta/components/ProtectedRoute.tsx b/susconecta/components/ProtectedRoute.tsx
new file mode 100644
index 0000000..ae0d93a
--- /dev/null
+++ b/susconecta/components/ProtectedRoute.tsx
@@ -0,0 +1,40 @@
+'use client'
+import { useEffect } from 'react'
+import { useRouter } from 'next/navigation'
+import { useAuth } from '@/hooks/useAuth'
+
+interface ProtectedRouteProps {
+ children: React.ReactNode
+}
+
+export default function ProtectedRoute({ children }: ProtectedRouteProps) {
+ const { isAuthenticated, checkAuth } = useAuth()
+ const router = useRouter()
+
+ useEffect(() => {
+ // Verificar autenticação sempre que o componente montar
+ checkAuth()
+ }, [checkAuth])
+
+ useEffect(() => {
+ if (!isAuthenticated) {
+ console.log('Usuário não autenticado, redirecionando para login...')
+ router.push('/login')
+ } else {
+ console.log('Usuário autenticado!')
+ }
+ }, [isAuthenticated, router])
+
+ if (!isAuthenticated) {
+ return (
+
+
+
+
Redirecionando para login...
+
+
+ )
+ }
+
+ return <>{children}>
+}
\ No newline at end of file
diff --git a/susconecta/hooks/useAuth.tsx b/susconecta/hooks/useAuth.tsx
new file mode 100644
index 0000000..c000fc8
--- /dev/null
+++ b/susconecta/hooks/useAuth.tsx
@@ -0,0 +1,90 @@
+'use client'
+import { createContext, useContext, useEffect, useState, ReactNode } from 'react'
+import { useRouter } from 'next/navigation'
+
+interface AuthContextType {
+ isAuthenticated: boolean
+ userEmail: string | null
+ login: (email: string, password: string) => boolean
+ logout: () => void
+ checkAuth: () => void
+}
+
+const AuthContext = createContext(undefined)
+
+export function AuthProvider({ children }: { children: ReactNode }) {
+ const [isAuthenticated, setIsAuthenticated] = useState(false)
+ const [userEmail, setUserEmail] = useState(null)
+ const [isLoading, setIsLoading] = useState(true)
+ const router = useRouter()
+
+ const checkAuth = () => {
+ if (typeof window !== 'undefined') {
+ const auth = localStorage.getItem('isAuthenticated')
+ const email = localStorage.getItem('userEmail')
+
+ if (auth === 'true' && email) {
+ setIsAuthenticated(true)
+ setUserEmail(email)
+ } else {
+ setIsAuthenticated(false)
+ setUserEmail(null)
+ }
+ }
+ setIsLoading(false)
+ }
+
+ useEffect(() => {
+ checkAuth()
+ }, [])
+
+ const login = (email: string, password: string): boolean => {
+ if (email === 'teste@gmail.com' && password === '123456') {
+ localStorage.setItem('isAuthenticated', 'true')
+ localStorage.setItem('userEmail', email)
+ setIsAuthenticated(true)
+ setUserEmail(email)
+ return true
+ }
+ return false
+ }
+
+ const logout = () => {
+ localStorage.removeItem('isAuthenticated')
+ localStorage.removeItem('userEmail')
+ setIsAuthenticated(false)
+ setUserEmail(null)
+ router.push('/login')
+ }
+
+ if (isLoading) {
+ return (
+
+ )
+ }
+
+ return (
+
+ {children}
+
+ )
+}
+
+export const useAuth = () => {
+ const context = useContext(AuthContext)
+ if (context === undefined) {
+ throw new Error('useAuth deve ser usado dentro de AuthProvider')
+ }
+ return context
+}
\ No newline at end of file
--
2.47.2