fix: status de consultas
This commit is contained in:
parent
2ad8e8ae27
commit
29be7aec71
@ -63,7 +63,7 @@ const ConsultaModal: React.FC<ConsultaModalProps> = ({
|
|||||||
const [tipo, setTipo] = useState("");
|
const [tipo, setTipo] = useState("");
|
||||||
const [motivo, setMotivo] = useState("");
|
const [motivo, setMotivo] = useState("");
|
||||||
const [observacoes, setObservacoes] = useState("");
|
const [observacoes, setObservacoes] = useState("");
|
||||||
const [status, setStatus] = useState<string>("agendada");
|
const [status, setStatus] = useState<string>("requested");
|
||||||
|
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@ -118,7 +118,7 @@ const ConsultaModal: React.FC<ConsultaModalProps> = ({
|
|||||||
setTipo("");
|
setTipo("");
|
||||||
setMotivo("");
|
setMotivo("");
|
||||||
setObservacoes("");
|
setObservacoes("");
|
||||||
setStatus("agendada");
|
setStatus("requested");
|
||||||
}
|
}
|
||||||
setError(null);
|
setError(null);
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
@ -166,13 +166,23 @@ const ConsultaModal: React.FC<ConsultaModalProps> = ({
|
|||||||
|
|
||||||
if (editing) {
|
if (editing) {
|
||||||
// Atualizar consulta existente
|
// Atualizar consulta existente
|
||||||
|
// Validar se o status é válido
|
||||||
|
const validStatuses: AppointmentStatus[] = [
|
||||||
|
'requested', 'confirmed', 'checked_in', 'in_progress', 'completed', 'cancelled', 'no_show'
|
||||||
|
];
|
||||||
|
const finalStatus = validStatuses.includes(status as AppointmentStatus)
|
||||||
|
? (status as AppointmentStatus)
|
||||||
|
: 'confirmed';
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
scheduled_at: iso,
|
scheduled_at: iso,
|
||||||
chief_complaint: motivo || undefined,
|
chief_complaint: motivo || undefined,
|
||||||
notes: observacoes || undefined,
|
notes: observacoes || undefined,
|
||||||
status: status as AppointmentStatus,
|
status: finalStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
console.log('[ConsultaModal] Enviando atualização:', payload);
|
||||||
|
|
||||||
const updated = await appointmentService.update(editing.id, payload);
|
const updated = await appointmentService.update(editing.id, payload);
|
||||||
|
|
||||||
// Converter para formato esperado
|
// Converter para formato esperado
|
||||||
@ -342,11 +352,13 @@ const ConsultaModal: React.FC<ConsultaModalProps> = ({
|
|||||||
value={status}
|
value={status}
|
||||||
onChange={(e) => setStatus(e.target.value)}
|
onChange={(e) => setStatus(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="agendada">Agendada</option>
|
<option value="requested">Solicitada</option>
|
||||||
<option value="confirmada">Confirmada</option>
|
<option value="confirmed">Confirmada</option>
|
||||||
<option value="cancelada">Cancelada</option>
|
<option value="checked_in">Check-in Realizado</option>
|
||||||
<option value="realizada">Realizada</option>
|
<option value="in_progress">Em Andamento</option>
|
||||||
<option value="faltou">Faltou</option>
|
<option value="completed">Concluída</option>
|
||||||
|
<option value="cancelled">Cancelada</option>
|
||||||
|
<option value="no_show">Faltou</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ const PainelMedico: React.FC = () => {
|
|||||||
const [filtroData, setFiltroData] = useState("hoje");
|
const [filtroData, setFiltroData] = useState("hoje");
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
const [editing, setEditing] = useState<ConsultaUI | null>(null);
|
const [editing, setEditing] = useState<any>(null);
|
||||||
const [relatorioModalOpen, setRelatorioModalOpen] = useState(false);
|
const [relatorioModalOpen, setRelatorioModalOpen] = useState(false);
|
||||||
const [loadingRelatorio, setLoadingRelatorio] = useState(false);
|
const [loadingRelatorio, setLoadingRelatorio] = useState(false);
|
||||||
const [laudos, setLaudos] = useState<Report[]>([]);
|
const [laudos, setLaudos] = useState<Report[]>([]);
|
||||||
@ -291,27 +291,63 @@ const PainelMedico: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleEditConsulta = (consulta: ConsultaUI) => {
|
const handleEditConsulta = (consulta: ConsultaUI) => {
|
||||||
setEditing(consulta);
|
// Converter ConsultaUI para Appointment compatível com o modal
|
||||||
|
const appointmentData: any = {
|
||||||
|
id: consulta.id,
|
||||||
|
patient_id: consulta.pacienteId,
|
||||||
|
doctor_id: consulta.medicoId,
|
||||||
|
scheduled_at: consulta.dataHora,
|
||||||
|
status: consulta.status,
|
||||||
|
appointment_type: consulta.tipo,
|
||||||
|
notes: consulta.observacoes,
|
||||||
|
pacienteId: consulta.pacienteId,
|
||||||
|
medicoId: consulta.medicoId,
|
||||||
|
dataHora: consulta.dataHora,
|
||||||
|
};
|
||||||
|
setEditing(appointmentData);
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteConsulta = async (id: string) => {
|
const handleDeleteConsulta = async (id: string) => {
|
||||||
if (!window.confirm("Deseja realmente excluir esta consulta?")) return;
|
if (!window.confirm("Deseja realmente excluir esta consulta?")) return;
|
||||||
try {
|
try {
|
||||||
const raw = localStorage.getItem("consultas_local");
|
await appointmentService.delete(id);
|
||||||
if (raw) {
|
|
||||||
const lista: ServiceConsulta[] = JSON.parse(raw);
|
|
||||||
const nova = lista.filter((c) => c.id !== id);
|
|
||||||
localStorage.setItem("consultas_local", JSON.stringify(nova));
|
|
||||||
toast.success("Consulta excluída");
|
toast.success("Consulta excluída");
|
||||||
fetchConsultas();
|
fetchConsultas();
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Erro ao excluir consulta:", error);
|
console.error("Erro ao excluir consulta:", error);
|
||||||
toast.error("Erro ao excluir consulta");
|
toast.error("Erro ao excluir consulta");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleUpdateStatus = async (id: string, newStatus: string) => {
|
||||||
|
try {
|
||||||
|
console.log(`[PainelMedico] Atualizando status da consulta ${id} para ${newStatus}`);
|
||||||
|
|
||||||
|
// Mapear status em português para inglês
|
||||||
|
const statusMap: Record<string, string> = {
|
||||||
|
'agendada': 'requested',
|
||||||
|
'confirmada': 'confirmed',
|
||||||
|
'em_andamento': 'in_progress',
|
||||||
|
'concluida': 'completed',
|
||||||
|
'cancelada': 'cancelled',
|
||||||
|
'falta': 'no_show',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mappedStatus = statusMap[newStatus.toLowerCase()] || newStatus;
|
||||||
|
|
||||||
|
await appointmentService.update(id, {
|
||||||
|
status: mappedStatus as any
|
||||||
|
});
|
||||||
|
|
||||||
|
toast.success("Status atualizado com sucesso!");
|
||||||
|
fetchConsultas();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Erro ao atualizar status:", error);
|
||||||
|
toast.error("Erro ao atualizar status da consulta");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSaveConsulta = () => {
|
const handleSaveConsulta = () => {
|
||||||
setModalOpen(false);
|
setModalOpen(false);
|
||||||
setEditing(null);
|
setEditing(null);
|
||||||
|
|||||||
@ -38,8 +38,15 @@ class ApiClient {
|
|||||||
|
|
||||||
if (token && config.headers) {
|
if (token && config.headers) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
|
|
||||||
|
// Adicionar Prefer header para operações de escrita retornarem dados
|
||||||
|
const method = config.method?.toUpperCase();
|
||||||
|
if (method === 'POST' || method === 'PATCH' || method === 'PUT') {
|
||||||
|
config.headers['Prefer'] = 'return=representation';
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`[ApiClient] Request: ${config.method?.toUpperCase()} ${
|
`[ApiClient] Request: ${method} ${
|
||||||
config.url
|
config.url
|
||||||
} - Token presente: ${token.substring(0, 20)}...`
|
} - Token presente: ${token.substring(0, 20)}...`
|
||||||
);
|
);
|
||||||
|
|||||||
@ -94,14 +94,32 @@ class AppointmentService {
|
|||||||
* Atualiza agendamento existente
|
* Atualiza agendamento existente
|
||||||
*/
|
*/
|
||||||
async update(id: string, data: UpdateAppointmentInput): Promise<Appointment> {
|
async update(id: string, data: UpdateAppointmentInput): Promise<Appointment> {
|
||||||
|
console.log('[appointmentService] Atualizando consulta:', id, data);
|
||||||
|
|
||||||
|
try {
|
||||||
const response = await apiClient.patch<Appointment[]>(
|
const response = await apiClient.patch<Appointment[]>(
|
||||||
`${this.basePath}?id=eq.${id}`,
|
`${this.basePath}?id=eq.${id}`,
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (response.data && response.data.length > 0) {
|
|
||||||
return response.data[0];
|
console.log('[appointmentService] Resposta da atualização:', response.status, response.data);
|
||||||
|
|
||||||
|
// Se retornou 204 (No Content), buscar o registro atualizado
|
||||||
|
if (response.status === 204 || !response.data || response.data.length === 0) {
|
||||||
|
console.log('[appointmentService] Buscando registro atualizado...');
|
||||||
|
const getResponse = await apiClient.get<Appointment[]>(`${this.basePath}?id=eq.${id}`);
|
||||||
|
if (getResponse.data && getResponse.data.length > 0) {
|
||||||
|
return getResponse.data[0];
|
||||||
|
}
|
||||||
|
throw new Error("Agendamento não encontrado após atualização");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.data[0];
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('[appointmentService] Erro ao atualizar:', error);
|
||||||
|
console.error('[appointmentService] Error response:', error?.response?.data);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
throw new Error("Agendamento não encontrado");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user