diff --git a/src/components/utils/AuthProvider.js b/src/components/utils/AuthProvider.js index 2cc2662..28d8f38 100644 --- a/src/components/utils/AuthProvider.js +++ b/src/components/utils/AuthProvider.js @@ -1,49 +1,90 @@ -import React, { createContext, useContext, useState } from 'react'; +import React, { createContext, useContext, useState, useEffect } from 'react'; // 1. Criação do Contexto -const AuthContext = createContext(); +const AuthContext = createContext(null); -// Função que será usada para envolver a aplicação +// Hook customizado para facilitar o uso nos componentes +export function useAuth() { + const context = useContext(AuthContext); + if (!context) { + // Isso é crucial para evitar o erro "useAuth() is undefined" + throw new Error('useAuth must be used within an AuthProvider'); + } + return context; +} + +// O Provedor Principal export function AuthProvider({ children }) { - // 2. Estado para armazenar o token e o tipo de token const [accessToken, setAccessToken] = useState(null); const [tokenType, setTokenType] = useState(null); + const [refreshToken, setRefreshToken] = useState(null); - // Função para salvar o token recebido após o login/refresh + // 🔑 Carrega o token do localStorage na inicialização + useEffect(() => { + // Essa lógica garante que o token permanece após o refresh da página + const storedToken = localStorage.getItem('access_token'); + const storedTokenType = localStorage.getItem('token_type'); + const storedRefreshToken = localStorage.getItem('refresh_token'); + + if (storedToken && storedTokenType) { + setAccessToken(storedToken); + setTokenType(storedTokenType); + // O refreshToken é essencial para a renovação futura + setRefreshToken(storedRefreshToken); + } + }, []); + + // --- FUNÇÕES DE MUDANÇA (SET/CLEAR) --- + + /** + * Função para salvar os tokens após um login ou renovação (refresh). + * @param {Object} tokenResponse O objeto completo retornado pelo Supabase Auth. + */ const setAuthTokens = (tokenResponse) => { - // Certifique-se de que a resposta contém os tokens if (tokenResponse && tokenResponse.access_token && tokenResponse.token_type) { + // 1. Atualiza o estado do React setAccessToken(tokenResponse.access_token); setTokenType(tokenResponse.token_type); - - // OPCIONAL: Salvar no localStorage para persistência entre recargas de página + setRefreshToken(tokenResponse.refresh_token); + + // 2. Persiste no localStorage (para não perder ao recarregar a página) localStorage.setItem('access_token', tokenResponse.access_token); localStorage.setItem('token_type', tokenResponse.token_type); + localStorage.setItem('refresh_token', tokenResponse.refresh_token); } }; - // Função para remover o token no logout + /** + * Função para remover todos os tokens (Logout). + */ const clearAuthTokens = () => { setAccessToken(null); setTokenType(null); + setRefreshToken(null); + // Remove do localStorage localStorage.removeItem('access_token'); localStorage.removeItem('token_type'); + localStorage.removeItem('refresh_token'); }; - // 3. O valor que será fornecido a todos os componentes + // --- FUNÇÕES DE USO (GET) --- + + /** + * Retorna a string completa para o cabeçalho Authorization (ex: "Bearer "). + */ + const getAuthorizationHeader = () => + accessToken && tokenType ? `${tokenType} ${accessToken}` : ''; + + // --- VALOR DO CONTEXTO --- + const contextValue = { - // O valor do token para usar em requisições accessToken, tokenType, - // A função para salvar o token após o login/refresh - setAuthTokens, - // A função de logout - clearAuthTokens, - // Um helper para saber se está logado + refreshToken, isAuthenticated: !!accessToken, - // Helper para montar o cabeçalho 'Authorization' - getAuthorizationHeader: () => - accessToken && tokenType ? `${tokenType} ${accessToken}` : '' + setAuthTokens, // Usado para CRIAR/MUDAR (Login/Refresh) + clearAuthTokens, // Usado para MUDAR (Logout) + getAuthorizationHeader, // Usado para PEGAR (Endpoints) }; return ( @@ -51,9 +92,4 @@ export function AuthProvider({ children }) { {children} ); -} - -// 4. Hook customizado para facilitar o uso nos componentes -export function useAuth() { - return useContext(AuthContext); } \ No newline at end of file diff --git a/src/components/utils/Functions-Endpoints/Patient.js b/src/components/utils/Functions-Endpoints/Patient.js new file mode 100644 index 0000000..dc94350 --- /dev/null +++ b/src/components/utils/Functions-Endpoints/Patient.js @@ -0,0 +1,25 @@ +import API_KEY from "../apiKeys"; + + + +const GetByID = async (ID,authHeader) => { + + console.log(authHeader, 'mostrando autorização dentro da função') + + var myHeaders = new Headers(); + myHeaders.append('apikey', API_KEY) + myHeaders.append('Authorization', authHeader) + + var requestOptions = { + method: 'GET', + redirect: 'follow', + headers:myHeaders +}; + + +const result = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?id=eq.${ID}`, requestOptions) +const DictPaciente = await result.json() +return DictPaciente +} + +export {GetByID} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 3eb62a0..4bfc68d 100644 --- a/src/index.js +++ b/src/index.js @@ -3,11 +3,14 @@ import ReactDOM from 'react-dom/client'; import './assets/scss/bootstrap.scss'; import './assets/scss/app.scss'; import App from './App'; +import { AuthProvider } from "./components/utils/AuthProvider"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + + + , ); diff --git a/src/pages/Details.jsx b/src/pages/Details.jsx index 8ac7ea2..38ef1db 100644 --- a/src/pages/Details.jsx +++ b/src/pages/Details.jsx @@ -1,10 +1,16 @@ import React, { useEffect, useState } from "react"; import avatarPlaceholder from '../assets/images/avatar_placeholder.png'; import { useParams } from "react-router-dom"; +import API_KEY from "../components/utils/apiKeys"; +import {GetByID} from "../components/utils/Functions-Endpoints/Patient" + +import { useAuth } from "../components/utils/AuthProvider"; + + const Details = () => { const parametros = useParams(); - + const {getAuthorizationHeader, isAuthenticated} = useAuth(); const [paciente, setPaciente] = useState({}); const [anexos, setAnexos] = useState([]); const [selectedFile, setSelectedFile] = useState(null); @@ -15,17 +21,20 @@ const Details = () => { useEffect(() => { if (!patientID) return; console.log(patientID, 'teu id') - fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}`) - .then(res => res.json()) + const authHeader = getAuthorizationHeader() - .then(result => {console.log(result.data)}) - .catch(err => console.error("Erro ao buscar paciente:", err)); + GetByID(patientID, authHeader) + .then((data) => { + console.log(data, "paciente vindo da API"); + setPaciente(data[0]); // supabase retorna array + }) + .catch((err) => console.error("Erro ao buscar paciente:", err)); - fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`) + /*fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientID}/anexos`) .then(res => res.json()) .then(data => setAnexos(data.data || [])) .catch(err => console.error("Erro ao buscar anexos:", err)); - +*/ }, [patientID]); const handleUpload = async () => { @@ -101,7 +110,7 @@ const Details = () => {
-

{paciente.nome || "-"}

+

{paciente.full_name || "-"}

@@ -109,11 +118,11 @@ const Details = () => {
-

{paciente.data_nascimento || "-"}

+

{paciente.birth_date || "-"}

-

{paciente.sexo || "-"}

+

{paciente.sex || "-"}

diff --git a/src/pages/DoctorCadastroManager.jsx b/src/pages/DoctorCadastroManager.jsx index 5c9d802..ac36ee2 100644 --- a/src/pages/DoctorCadastroManager.jsx +++ b/src/pages/DoctorCadastroManager.jsx @@ -1,13 +1,15 @@ import React, { useState } from 'react'; // Importamos os dois novos componentes que criamos - +import { useAuth } from '../components/utils/AuthProvider'; import DoctorForm from '../components/doctors/DoctorForm'; +import API_KEY from '../components/utils/apiKeys'; + function DoctorCadastroManager( ) { // Este estado vai controlar qual "tela" mostrar: 'list' (lista) ou 'form' (formulário) - + const { getAuthorizationHeader, isAuthenticated } = useAuth(); var myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); @@ -16,28 +18,40 @@ function DoctorCadastroManager( ) { const [showModal, setShowModal] = useState(false); const [modalMsg, setModalMsg] = useState(''); - // Função que será chamada para "salvar" o paciente - const handleSavePatient = (patientData) => { - console.log('Salvando médico:', patientData); + // Função que será chamada para salvar o médico no banco de dados + const handleSaveDoctor = async (doctorData) => { + const authHeader = getAuthorizationHeader(); - var raw = JSON.stringify(patientData) + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append("apikey", API_KEY) + myHeaders.append("Authorization", authHeader) + + + console.log('Salvando paciente:', doctorData); + + var raw = JSON.stringify(doctorData); + console.log(doctorData, 'aqui') var requestOptions = { - method:'POST', - header: myHeaders, - body:raw, - redirect:'follow' + method: 'POST', + headers: myHeaders, + body: raw, + redirect: 'follow' + }; + + try { + const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1//doctors", requestOptions); + const result = await response.json(); + console.log("Médico salvo no backend:", result); + + return result; + } catch (error) { + console.error("Erro ao salvar Médico:", error); + throw error; } - - fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes", requestOptions) - .then(response => response.text()) - .then(result => console.log(result)) - .catch(error => console.log('error', error)); - - setModalMsg(`Médico "${patientData.nome}" salvo com sucesso!`); - setShowModal(true); - - }; +}; return ( <> @@ -68,7 +82,7 @@ function DoctorCadastroManager( ) {
diff --git a/src/pages/DoctorTable.jsx b/src/pages/DoctorTable.jsx index 1dc6467..5ccd992 100644 --- a/src/pages/DoctorTable.jsx +++ b/src/pages/DoctorTable.jsx @@ -1,6 +1,11 @@ import React, { useState, useEffect } from "react"; import API_KEY from "../components/utils/apiKeys"; +import { useAuth } from "../components/utils/AuthProvider"; + + function TableDoctor({ setCurrentPage, setPatientID }) { + const {getAuthorizationHeader, isAuthenticated} = useAuth(); + const [medicos, setMedicos] = useState([]); const [search, setSearch] = useState(""); const [filtroAniversariante, setFiltroAniversariante] = useState(false); @@ -40,10 +45,14 @@ function TableDoctor({ setCurrentPage, setPatientID }) { // Buscar médicos da API useEffect(() => { - var myHeaders = new Headers(); - myHeaders.append("apikey", API_KEY); - + const authHeader = getAuthorizationHeader() + + console.log(authHeader, 'aqui autorização') + + var myHeaders = new Headers(); + myHeaders.append("apikey", API_KEY); + myHeaders.append("Authorization", `${authHeader}`); var requestOptions = { method: 'GET', headers: myHeaders, diff --git a/src/pages/EditPage.jsx b/src/pages/EditPage.jsx index 1b94620..5b1ccda 100644 --- a/src/pages/EditPage.jsx +++ b/src/pages/EditPage.jsx @@ -3,32 +3,39 @@ import React from 'react' import PatientForm from '../components/patients/PatientForm' import {useEffect, useState} from 'react' - +import { GetByID } from '../components/utils/Functions-Endpoints/Patient' +import API_KEY from '../components/utils/apiKeys' +import { useParams } from 'react-router-dom' +import { useAuth } from '../components/utils/AuthProvider' const EditPage = ( {id, setCurrentPage}) => { - + const Parametros = useParams() const [PatientToPUT, setPatientPUT] = useState({}) - var requestOptions = { - method: 'GET', - redirect: 'follow' -}; + const { getAuthorizationHeader, isAuthenticated } = useAuth(); + +const PatientID = Parametros.id useEffect(() => { + const authHeader = getAuthorizationHeader() + + GetByID(PatientID, authHeader) + .then((data) => { + console.log(data[0], "paciente vindo da API"); + setPatientPUT(data[0]); // supabase retorna array + }) + .catch((err) => console.error("Erro ao buscar paciente:", err)); -fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${id}`, requestOptions) - .then(response => response.json()) - .then(result => result.data) - .then(data => setPatientPUT(data)) - .catch(error => console.log('error', error)); -}, [id,requestOptions]) +}, [PatientID]) const HandlePutPatient = async () => { + const authHeader = getAuthorizationHeader() var myHeaders = new Headers(); - myHeaders.append("Authorization", "Bearer "); + myHeaders.append('apikey', API_KEY) + myHeaders.append("Authorization", authHeader); myHeaders.append("Content-Type", "application/json"); var raw = JSON.stringify(PatientToPUT); @@ -43,10 +50,7 @@ const HandlePutPatient = async () => { }; try { - const response = await fetch( - "https://mock.apidog.com/m1/1053378-0-default/pacientes/" + PatientToPUT.id, - requestOptions - ); + const response = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?id=eq.${PatientID}`,requestOptions); // se o backend retorna JSON const result = await response.json(); diff --git a/src/pages/Inicio.jsx b/src/pages/Inicio.jsx index 5a1456f..f383422 100644 --- a/src/pages/Inicio.jsx +++ b/src/pages/Inicio.jsx @@ -33,7 +33,7 @@ function Inicio({ setCurrentPage }) { fetch("https://yuanqfswhberkoevtmfr.supabase.co/auth/v1/token?grant_type=password", requestOptions) .then(response => response.json()) - .then(result => console.log(result.access_token)) + .then(result => {setAuthTokens(result); console.log(result)}) .catch(error => console.log('error', error)); diff --git a/src/pages/PatientCadastroManager.jsx b/src/pages/PatientCadastroManager.jsx index aa521e6..08d2fc2 100644 --- a/src/pages/PatientCadastroManager.jsx +++ b/src/pages/PatientCadastroManager.jsx @@ -1,17 +1,23 @@ import {useState} from 'react'; import PatientForm from '../components/patients/PatientForm'; import API_KEY from '../components/utils/apiKeys'; +import { useAuth } from '../components/utils/AuthProvider'; function PatientCadastroManager( {setCurrentPage} ) { - + const { getAuthorizationHeader, isAuthenticated } = useAuth(); const [formData, setFormData] = useState({}) - var myHeaders = new Headers(); - myHeaders.append("Content-Type", "application/json"); - myHeaders.append("apikey", API_KEY) - myHeaders.append("Authorization", `Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6ImJGVUlxQzNzazNjUms5RlMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3l1YW5xZnN3aGJlcmtvZXZ0bWZyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiJjN2ZjZDcwMi05YTZlLTRiN2MtYWJkMy05NTZiMjVhZjQwN2QiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzU4OTczMTkxLCJpYXQiOjE3NTg5Njk1OTEsImVtYWlsIjoicmlzZXVwQHBvcGNvZGUuY29tLmJyIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6eyJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZnVsbF9uYW1lIjoiUmlzZVVwIFBvcGNvZGUifSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc1ODk2OTU5MX1dLCJzZXNzaW9uX2lkIjoiNzc1ZTA4NGYtM2RhNi00NjE5LWE5MmUtMDUwY2ZmMWU4NTg4IiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.80loeCsbb7zsS5FYYh-KwhYi3frbBeZogXHF0rHZfLE`) - + // Função que será chamada para "salvar" o paciente const handleSavePatient = async (patientData) => { + const authHeader = getAuthorizationHeader(); + + + var myHeaders = new Headers(); + myHeaders.append("Content-Type", "application/json"); + myHeaders.append("apikey", API_KEY) + myHeaders.append("Authorization", authHeader) + + console.log('Salvando paciente:', patientData); var raw = JSON.stringify(patientData); diff --git a/src/pages/TablePaciente.jsx b/src/pages/TablePaciente.jsx index b0f5565..666fe6c 100644 --- a/src/pages/TablePaciente.jsx +++ b/src/pages/TablePaciente.jsx @@ -6,7 +6,7 @@ import { useAuth } from "../components/utils/AuthProvider"; function TablePaciente({ setCurrentPage, setPatientID }) { - + const {getAuthorizationHeader, isAuthenticated} = useAuth(); const [pacientes, setPacientes] = useState([]); @@ -19,7 +19,7 @@ function TablePaciente({ setCurrentPage, setPatientID }) { const [showDeleteModal, setShowDeleteModal] = useState(false); const [selectedPatientId, setSelectedPatientId] = useState(null); - console.log(getAuthorizationHeader(), 'aqui' ) + const GetAnexos = async (id) => { var myHeaders = new Headers(); @@ -73,20 +73,22 @@ function TablePaciente({ setCurrentPage, setPatientID }) { // função de exclusão atualizada const deletePatient = async (id) => { + + const authHeader = getAuthorizationHeader() console.log(id) var myHeaders = new Headers(); myHeaders.append('apikey', API_KEY); - myHeaders.append("Authorization", `Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6ImJGVUlxQzNzazNjUms5RlMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3l1YW5xZnN3aGJlcmtvZXZ0bWZyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiJjN2ZjZDcwMi05YTZlLTRiN2MtYWJkMy05NTZiMjVhZjQwN2QiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzU4OTc3NTg5LCJpYXQiOjE3NTg5NzM5ODksImVtYWlsIjoicmlzZXVwQHBvcGNvZGUuY29tLmJyIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6eyJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZnVsbF9uYW1lIjoiUmlzZVVwIFBvcGNvZGUifSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc1ODk3Mzk4OX1dLCJzZXNzaW9uX2lkIjoiNGI2NzY4YTEtMmE5Yi00NjhkLWJlYjItZjhhMDQ0NjU5MGFjIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.9lV7msK_taipCOrSxeRud2a8aEo8N6wR9Wc5xFjci2A`) - myHeaders.append("Prefer", "return=minimal") + myHeaders.append("Authorization", authHeader) + var requestOptions = { method: "DELETE", redirect: "follow", headers:myHeaders }; try { const result = await fetch( - `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients/?id=eq.${id}`, + `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?id=eq.${id}`, requestOptions ); - //setPacientes((prev) => prev.filter((p) => p.id !== id)); + setPacientes((prev) => prev.filter((p) => p.id !== id)); console.log(result) } catch (error) { console.log("Deu problema", error); @@ -97,9 +99,14 @@ function TablePaciente({ setCurrentPage, setPatientID }) { // Requisição inicial para buscar pacientes useEffect(() => { + + const authHeader = getAuthorizationHeader() + + console.log(authHeader, 'aqui autorização') + var myHeaders = new Headers(); myHeaders.append("apikey", API_KEY); - myHeaders.append("Authorization", `Bearer eyJhbGciOiJIUzI1NiIsImtpZCI6ImJGVUlxQzNzazNjUms5RlMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3l1YW5xZnN3aGJlcmtvZXZ0bWZyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiJjN2ZjZDcwMi05YTZlLTRiN2MtYWJkMy05NTZiMjVhZjQwN2QiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzU4OTc3NTg5LCJpYXQiOjE3NTg5NzM5ODksImVtYWlsIjoicmlzZXVwQHBvcGNvZGUuY29tLmJyIiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCIsInByb3ZpZGVycyI6WyJlbWFpbCJdfSwidXNlcl9tZXRhZGF0YSI6eyJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZnVsbF9uYW1lIjoiUmlzZVVwIFBvcGNvZGUifSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc1ODk3Mzk4OX1dLCJzZXNzaW9uX2lkIjoiNGI2NzY4YTEtMmE5Yi00NjhkLWJlYjItZjhhMDQ0NjU5MGFjIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.9lV7msK_taipCOrSxeRud2a8aEo8N6wR9Wc5xFjci2A`); + myHeaders.append("Authorization", `${authHeader}`); var requestOptions = { method: 'GET', headers: myHeaders, @@ -275,19 +282,21 @@ function TablePaciente({ setCurrentPage, setPatientID }) { - + + + {/* Botão que abre o modal */}