forked from RiseUP/riseup-squad23
273 lines
10 KiB
JavaScript
273 lines
10 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { FaCalendarAlt, FaCalendarCheck, FaFileAlt, FaUserMd, FaClock } from 'react-icons/fa';
|
|
import { useAuth } from '../components/utils/AuthProvider';
|
|
import API_KEY from '../components/utils/apiKeys';
|
|
import './style/inicioPaciente.css';
|
|
|
|
function InicioPaciente() {
|
|
const navigate = useNavigate();
|
|
const { getAuthorizationHeader, isAuthenticated } = useAuth();
|
|
const [agendamentos, setAgendamentos] = useState([]);
|
|
const [medicos, setMedicos] = useState([]);
|
|
const [agendamentosComMedicos, setAgendamentosComMedicos] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [pacienteId, setPacienteId] = useState(null);
|
|
|
|
useEffect(() => {
|
|
const userId = localStorage.getItem('user_id') || localStorage.getItem('patient_id');
|
|
setPacienteId(userId);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const fetchMedicos = async () => {
|
|
try {
|
|
const authHeader = getAuthorizationHeader();
|
|
|
|
const myHeaders = new Headers();
|
|
myHeaders.append("apikey", API_KEY);
|
|
myHeaders.append("Authorization", authHeader);
|
|
|
|
const requestOptions = {
|
|
method: 'GET',
|
|
headers: myHeaders,
|
|
redirect: 'follow'
|
|
};
|
|
|
|
const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/doctors", requestOptions);
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setMedicos(data);
|
|
console.log(' Médicos carregados:', data.length);
|
|
} else {
|
|
console.error(' Erro ao buscar médicos:', response.status);
|
|
}
|
|
} catch (error) {
|
|
console.error(' Erro ao buscar médicos:', error);
|
|
}
|
|
};
|
|
|
|
const fetchAgendamentos = async () => {
|
|
try {
|
|
const authHeader = getAuthorizationHeader();
|
|
|
|
const myHeaders = new Headers();
|
|
myHeaders.append("apikey", API_KEY);
|
|
myHeaders.append("Authorization", authHeader);
|
|
|
|
const requestOptions = {
|
|
method: 'GET',
|
|
headers: myHeaders,
|
|
redirect: 'follow'
|
|
};
|
|
|
|
// Buscar todos os agendamentos (depois filtraremos pelo paciente)
|
|
const response = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments", requestOptions);
|
|
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setAgendamentos(data);
|
|
console.log(' Agendamentos carregados:', data.length);
|
|
} else {
|
|
console.error(' Erro ao buscar agendamentos:', response.status);
|
|
}
|
|
} catch (error) {
|
|
console.error(' Erro ao buscar agendamentos:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
if (isAuthenticated) {
|
|
fetchMedicos();
|
|
fetchAgendamentos();
|
|
}
|
|
}, [isAuthenticated, getAuthorizationHeader]);
|
|
|
|
useEffect(() => {
|
|
if (agendamentos.length > 0 && medicos.length > 0) {
|
|
const agendamentosComNomes = agendamentos.map(agendamento => {
|
|
const medico = medicos.find(m => m.id === agendamento.doctor_id);
|
|
return {
|
|
...agendamento,
|
|
nomeMedico: medico?.full_name || 'Médico não encontrado',
|
|
especialidadeMedico: medico?.specialty || ''
|
|
};
|
|
});
|
|
setAgendamentosComMedicos(agendamentosComNomes);
|
|
}
|
|
}, [agendamentos, medicos]);
|
|
|
|
const meusAgendamentos = agendamentosComMedicos.filter(a =>
|
|
pacienteId ? a.patient_id === pacienteId : true
|
|
);
|
|
|
|
const hoje = new Date();
|
|
hoje.setHours(0, 0, 0, 0);
|
|
|
|
const agendamentosFuturos = meusAgendamentos.filter(a => {
|
|
if (!a.scheduled_at) return false;
|
|
const dataAgendamento = new Date(a.scheduled_at);
|
|
return dataAgendamento >= hoje && a.status !== 'cancelled' && a.status !== 'completed';
|
|
}).sort((a, b) => new Date(a.scheduled_at) - new Date(b.scheduled_at));
|
|
|
|
const proximasConsultas = agendamentosFuturos.length;
|
|
const consultasHoje = agendamentosFuturos.filter(a => {
|
|
const dataAgendamento = new Date(a.scheduled_at);
|
|
dataAgendamento.setHours(0, 0, 0, 0);
|
|
return dataAgendamento.getTime() === hoje.getTime();
|
|
}).length;
|
|
|
|
const consultasPendentes = meusAgendamentos.filter(a =>
|
|
a.status === 'pending' || a.status === 'requested'
|
|
).length;
|
|
|
|
const historicoConsultas = meusAgendamentos.filter(a =>
|
|
a.status === 'completed'
|
|
).length;
|
|
|
|
return (
|
|
<div className="dashboard-paciente-container">
|
|
<div className="dashboard-paciente-header">
|
|
<h1>Bem-vindo ao MediConnect</h1>
|
|
<p>Gerencie suas consultas e acompanhe seu histórico médico</p>
|
|
</div>
|
|
|
|
<div className="stats-paciente-grid">
|
|
<div className="stat-paciente-card">
|
|
<div className="stat-paciente-info">
|
|
<span className="stat-paciente-label">Próximas Consultas</span>
|
|
<span className="stat-paciente-value">{proximasConsultas}</span>
|
|
</div>
|
|
<div className="stat-paciente-icon-wrapper blue">
|
|
<FaCalendarAlt className="stat-paciente-icon" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="stat-paciente-card">
|
|
<div className="stat-paciente-info">
|
|
<span className="stat-paciente-label">Consultas Hoje</span>
|
|
<span className="stat-paciente-value">{consultasHoje}</span>
|
|
</div>
|
|
<div className="stat-paciente-icon-wrapper green">
|
|
<FaCalendarCheck className="stat-paciente-icon" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="stat-paciente-card">
|
|
<div className="stat-paciente-info">
|
|
<span className="stat-paciente-label">Aguardando</span>
|
|
<span className="stat-paciente-value">{loading ? '...' : consultasPendentes}</span>
|
|
</div>
|
|
<div className="stat-paciente-icon-wrapper purple">
|
|
<FaClock className="stat-paciente-icon" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="stat-paciente-card">
|
|
<div className="stat-paciente-info">
|
|
<span className="stat-paciente-label">Realizadas</span>
|
|
<span className="stat-paciente-value">{historicoConsultas}</span>
|
|
</div>
|
|
<div className="stat-paciente-icon-wrapper orange">
|
|
<FaFileAlt className="stat-paciente-icon" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="quick-actions-paciente">
|
|
<h2>Acesso Rápido</h2>
|
|
<div className="actions-paciente-grid">
|
|
<div className="action-paciente-button" onClick={() => navigate('/paciente/agendamento')}>
|
|
<FaCalendarCheck className="action-paciente-icon" />
|
|
<div className="action-paciente-info">
|
|
<span className="action-paciente-title">Minhas Consultas</span>
|
|
<span className="action-paciente-desc">Ver todos os agendamentos</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="action-paciente-button" onClick={() => navigate('/paciente/laudo')}>
|
|
<FaFileAlt className="action-paciente-icon" />
|
|
<div className="action-paciente-info">
|
|
<span className="action-paciente-title">Meus Laudos</span>
|
|
<span className="action-paciente-desc">Acessar documentos médicos</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="action-paciente-button" onClick={() => navigate('/paciente/agendamento')}>
|
|
<FaUserMd className="action-paciente-icon" />
|
|
<div className="action-paciente-info">
|
|
<span className="action-paciente-title">Meus Médicos</span>
|
|
<span className="action-paciente-desc">Ver histórico de atendimentos</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="proximas-consultas-section">
|
|
<h2>Próximas Consultas</h2>
|
|
{loading ? (
|
|
<div className="no-consultas-content">
|
|
<p>Carregando suas consultas...</p>
|
|
</div>
|
|
) : agendamentosFuturos.length > 0 ? (
|
|
<div className="consultas-paciente-list">
|
|
{agendamentosFuturos.slice(0, 3).map(agendamento => (
|
|
<div key={agendamento.id} className="consulta-paciente-item">
|
|
<div className="consulta-paciente-info">
|
|
<div className="consulta-paciente-time-date">
|
|
<p className="consulta-paciente-hora">
|
|
{new Date(agendamento.scheduled_at).toLocaleTimeString('pt-BR', {
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
})}
|
|
</p>
|
|
<p className="consulta-paciente-data">
|
|
{new Date(agendamento.scheduled_at).toLocaleDateString('pt-BR', {
|
|
day: '2-digit',
|
|
month: 'short',
|
|
year: 'numeric'
|
|
})}
|
|
</p>
|
|
</div>
|
|
<div className="consulta-paciente-detalhes">
|
|
<p className="consulta-paciente-medico">
|
|
<FaUserMd className="consulta-icon" />
|
|
<strong>Dr(a):</strong> {agendamento.nomeMedico}
|
|
</p>
|
|
{agendamento.especialidadeMedico && (
|
|
<p className="consulta-paciente-especialidade">
|
|
{agendamento.especialidadeMedico}
|
|
</p>
|
|
)}
|
|
</div>
|
|
<span className={`consulta-paciente-status status-${agendamento.status}`}>
|
|
{agendamento.status === 'scheduled' ? 'Confirmado' :
|
|
agendamento.status === 'pending' ? 'Aguardando' :
|
|
agendamento.status === 'requested' ? 'Solicitado' : agendamento.status}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
))}
|
|
{agendamentosFuturos.length > 3 && (
|
|
<button className="view-all-paciente-button" onClick={() => navigate('/paciente/agendamento')}>
|
|
Ver todas as consultas
|
|
</button>
|
|
)}
|
|
</div>
|
|
) : (
|
|
<div className="no-consultas-content">
|
|
<FaCalendarCheck className="no-consultas-icon" />
|
|
<p>Você não tem consultas agendadas</p>
|
|
<button className="agendar-paciente-button" onClick={() => navigate('/paciente/agendamento/criar')}>
|
|
Agendar Consulta
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default InicioPaciente; |