436 lines
13 KiB
JavaScript

import InputMask from "react-input-mask";
import "./style/formagendamentos.css";
import { useState, useEffect, useCallback } from "react";
import { GetPatientByCPF, GetAllPatients } from "../utils/Functions-Endpoints/Patient";
import { GetAllDoctors } from "../utils/Functions-Endpoints/Doctor";
import { useAuth } from "../utils/AuthProvider";
import API_KEY from "../utils/apiKeys";
const FormNovaConsulta = ({ onCancel, onSave, setAgendamento, agendamento }) => {
const { getAuthorizationHeader } = useAuth();
const [sessoes, setSessoes] = useState(1);
const [tempoBaseConsulta] = useState(30);
const [showSuccessModal, setShowSuccessModal] = useState(false);
const [todosProfissionais, setTodosProfissionais] = useState([]);
const [profissionaisFiltrados, setProfissionaisFiltrados] = useState([]);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [horarioInicio, setHorarioInicio] = useState('');
const [horarioTermino, setHorarioTermino] = useState('');
const [horariosDisponiveis, sethorariosDisponiveis] = useState([]);
const [todosPacientes, setTodosPacientes] = useState([])
const [pacientesFiltrados, setPacientesFiltrados] = useState([])
const [isDropdownPacienteOpen, setIsDropdownPacienteOpen] = useState(false)
const [status, setStatus] = useState("confirmed")
let authHeader = getAuthorizationHeader()
const FormatCPF = (valor) => {
const digits = String(valor).replace(/\D/g, '').slice(0, 11);
return digits
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d)/, '$1.$2')
.replace(/(\d{3})(\d{1,2})$/, '$1-$2');
};
const handleChange = (e) => {
const { value, name } = e.target;
if (name === 'email') {
setAgendamento(prev => ({
...prev,
contato: { ...prev.contato, email: value }
}));
} else if (name === 'status') {
setAgendamento(prev => ({
...prev,
status: prev.status === 'requested' ? 'confirmed' : 'requested'
}));
} else if (name === 'paciente_cpf') {
const cpfFormatted = FormatCPF(value);
const fetchPatient = async () => {
const patientData = await GetPatientByCPF(cpfFormatted, authHeader);
if (patientData) {
setAgendamento(prev => ({
...prev,
paciente_nome: patientData.full_name,
patient_id: patientData.id
}));
}
};
setAgendamento(prev => ({ ...prev, paciente_cpf: cpfFormatted }));
fetchPatient();
} else if (name === 'convenio') {
setAgendamento(prev => ({ ...prev, insurance_provider: value }));
} else {
setAgendamento(prev => ({ ...prev, [name]: value }));
}
};
const ChamarMedicos = useCallback(async () => {
const Medicos = await GetAllDoctors(authHeader);
setTodosProfissionais(Medicos);
}, [authHeader]);
const ChamarPacientes = useCallback (async () => {
const Pacientes = await GetAllPatients(authHeader);
setTodosPacientes(Pacientes)
console.log("pacientes")
console.log(Pacientes)
}, [authHeader])
useEffect(() => {
console.log("Horario","tessssste" )
if (agendamento?.scheduled_at) {
setHorarioInicio(formatarHora(agendamento.scheduled_at));
}
}, [])
useEffect(() => {
ChamarMedicos();
}, [ChamarMedicos]);
useEffect(() => {
ChamarPacientes()
}, [ChamarPacientes])
useEffect(() => {
if (!agendamento.dataAtendimento || !agendamento.doctor_id) return;
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("apikey", API_KEY);
myHeaders.append("Authorization", `Bearer ${authHeader.split(' ')[1]}`);
const raw = JSON.stringify({
doctor_id: agendamento.doctor_id,
start_date: agendamento.dataAtendimento,
end_date: `${agendamento.dataAtendimento}T23:59:59.999Z`,
});
const requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
};
fetch("https://yuanqfswhberkoevtmfr.supabase.co/functions/v1/get-available-slots", requestOptions)
.then(response => response.json())
.then(result => sethorariosDisponiveis(result))
.catch(error => console.log('error', error));
}, [agendamento.dataAtendimento, agendamento.doctor_id, authHeader]);
const handleSearchProfissional = (e) => {
const term = e.target.value;
handleChange(e);
if (term.trim() === '') {
setProfissionaisFiltrados([]);
setIsDropdownOpen(false);
return;
}
const filtered = todosProfissionais.filter(p =>
p.full_name.toLowerCase().includes(term.toLowerCase())
);
setProfissionaisFiltrados(filtered);
setIsDropdownOpen(filtered.length > 0);
};
const handleSearchPaciente = (e) => {
const term = e.target.value;
handleChange(e);
if (term.trim() === '') {
setPacientesFiltrados([]);
setIsDropdownPacienteOpen(false);
return;
}
const filtered = todosPacientes.filter(p =>
p.full_name.toLowerCase().includes(term.toLowerCase())
);
console.log(filtered.length > 0, "filtrados")
setPacientesFiltrados(filtered);
setIsDropdownPacienteOpen(filtered.length > 0);
}
const handleSelectProfissional = (profissional) => {
setAgendamento(prev => ({
...prev,
doctor_id: profissional.id,
nome_medico: profissional.full_name
}));
setProfissionaisFiltrados([]);
setIsDropdownOpen(false);
};
const handleSelectPaciente = (paciente) => {
setAgendamento(prev => ({
...prev,
patient_id:paciente.id,
paciente_nome: paciente.full_name,
paciente_cpf: paciente.cpf
}))
setProfissionaisFiltrados([])
setIsDropdownPacienteOpen(false)
}
const formatarHora = (datetimeString) => {
return datetimeString?.substring(11, 16) || '';
};
const opcoesDeHorario = horariosDisponiveis?.slots?.map(item => ({
value: formatarHora(item.datetime),
label: formatarHora(item.datetime),
disabled: !item.available
})) || [];
const calcularHorarioTermino = useCallback((inicio, sessoes, tempoBase) => {
if (!inicio || inicio.length !== 5 || !inicio.includes(':')) return '';
const [horas, minutos] = inicio.split(':').map(Number);
const minutosInicio = (horas * 60) + minutos;
const duracaoTotalMinutos = sessoes * tempoBase;
const minutosTermino = minutosInicio + duracaoTotalMinutos;
const horaTermino = Math.floor(minutosTermino / 60) % 24;
const minutoTermino = minutosTermino % 60;
const formatar = (num) => String(num).padStart(2, '0');
return `${formatar(horaTermino)}:${formatar(minutoTermino)}`;
}, []);
useEffect(() => {
const novoTermino = calcularHorarioTermino(horarioInicio, sessoes, tempoBaseConsulta);
setHorarioTermino(novoTermino);
setAgendamento(prev => ({
...prev,
horarioTermino: novoTermino
}));
}, [horarioInicio, sessoes, tempoBaseConsulta, setAgendamento, calcularHorarioTermino]);
const handleSubmit = (e) => {
e.preventDefault();
setShowSuccessModal(true);
};
const handleCloseModal = () => {
setShowSuccessModal(false);
onSave({ ...agendamento, horarioInicio: horarioInicio, status:status });
};
const handleCheckbox = () => {
if(status === "confirmed"){
setStatus("requested")
}else{
setStatus("confirmed")
}
}
return (<div className="form-container">
{showSuccessModal && (
<div className="modal-overlay">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">Sucesso</h5>
</div>
<div className="modal-body">
<p className="modal-message">Agendamento salvo com sucesso!</p>
</div>
<div className="modal-footer">
<button onClick={handleCloseModal} className="modal-confirm-btn">Fechar</button>
</div>
</div>
</div>
)}
<form className="form-agendamento" onSubmit={handleSubmit}>
<h2 className="section-title">Informações do paciente</h2>
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-um">
<div className="campo-de-input-container">
<div className="campo-de-input">
<label>Nome *</label>
<input
type="text"
name="paciente_nome"
placeholder="Insira o nome do paciente"
required
onChange={(e) => handleSearchPaciente(e)}
value={agendamento?.paciente_nome || ""}
autoComplete="off"
/>
</div>
{isDropdownPacienteOpen && pacientesFiltrados.length > 0 && (
<div className="dropdown-pacientes">
{pacientesFiltrados.map((paciente) => (
<div
key={paciente.id}
className="dropdown-item"
onClick={() => handleSelectPaciente(paciente)}
>
{`${paciente.full_name.split(" ")[0]} ${paciente.full_name.split(" ")[1]} - ${paciente.cpf}`}
</div>
))}
</div>
)}
</div>
<div className="campo-de-input campo-cpf">
<label>CPF do paciente</label>
<input
type="text"
name="paciente_cpf"
placeholder="000.000.000-00"
onChange={handleChange}
value={agendamento.paciente_cpf}
/>
</div>
</div>
<div className="campos-informacoes-paciente" id="informacoes-paciente-linha-tres">
<div>
<label>Convênio</label>
<select name="convenio" onChange={handleChange} value={agendamento.insurance_provider}>
<option value="publico">Público</option>
<option value="unimed">Unimed</option>
<option value="bradesco_saude">Bradesco Saúde</option>
<option value="hapvida">Hapvida</option>
</select>
</div>
</div>
<h2 className="section-title">Informações do atendimento</h2>
<div className="campo-informacoes-atendimento">
<div className="campo-de-input-container">
<div className="campo-de-input">
<label>Nome do profissional *</label>
<input
type="text"
name="nome_medico"
onChange={handleSearchProfissional}
value={agendamento?.nome_medico || ''}
autoComplete="off"
required
/>
</div>
{isDropdownOpen && profissionaisFiltrados.length > 0 && (
<div className="dropdown-profissionais">
{profissionaisFiltrados.map((profissional) => (
<div
key={profissional.id}
className="dropdown-item"
onClick={() => handleSelectProfissional(profissional)}
>
{profissional.full_name}
</div>
))}
</div>
)}
</div>
<div className="tipo_atendimento">
<label>Tipo de atendimento *</label>
<select name="tipo_atendimento" onChange={handleChange} value={agendamento.tipo_atendimento}>
<option value="presencial">Presencial</option>
<option value="teleconsulta">Teleconsulta</option>
</select>
</div>
</div>
<section id="informacoes-atendimento-segunda-linha">
<div className="campo-informacoes-atendimento">
<div className="campo-de-input">
<label>Data *</label>
<input
type="date"
name="dataAtendimento"
onChange={handleChange}
value={agendamento.dataAtendimento}
required
/>
</div>
<div className="linha">
<div className="campo-de-input">
<label htmlFor="inicio">Início *</label>
<select
id="inicio"
name="inicio"
required
value={horarioInicio}
onChange={(e) => setHorarioInicio(e.target.value)}
>
<option value="" disabled>Selecione a hora de início</option>
{opcoesDeHorario.map((opcao, index) => (
<option key={index} value={opcao.value} disabled={opcao.disabled}>
{opcao.label}
{opcao.disabled && " (Indisponível)"}
</option>
))}
</select>
</div>
<div className="campo-de-input">
<label htmlFor="termino">Término *</label>
<input
type="text"
id="termino"
name="termino"
value={horarioTermino || '— —'}
readOnly
className="horario-termino-readonly"
/>
</div>
</div>
</div>
<div className="campo-de-input observacoes">
<label>Observações</label>
<textarea
name="observacoes"
rows="4"
cols="1"
onChange={handleChange}
value={agendamento.observacoes || ''}
/>
</div>
</section>
<div className="campo-de-input-check">
<input
className="form-check-input form-custom-check"
type="checkbox"
name="status"
onChange={handleCheckbox}
checked={status === "requested"}
/>
<label className="form-check-label checkbox-label" htmlFor="status">
Adicionar à fila de espera
</label>
</div>
<div className="form-actions">
<button type="submit" className="btn-primary">Salvar agendamento</button>
<button type="button" className="btn-cancel" onClick={onCancel}>Cancelar</button>
</div>
</form>
</div>
);
};
export default FormNovaConsulta;