fix(frontend): Resolve login redirection and inject JWT token on requests

This commit is contained in:
VPS 4 Builder
2026-05-13 10:04:49 +02:00
parent e260eed28b
commit 526495db96
2 changed files with 73 additions and 88 deletions
+2 -1
View File
@@ -170,7 +170,8 @@ const App: React.FC = () => {
// Keep URL in sync when view changes programmatically via sidebar // Keep URL in sync when view changes programmatically via sidebar
const handleNavigate = (view: ViewKey) => { const handleNavigate = (view: ViewKey) => {
if (isViewAllowed(view, currentRole)) { const freshRole = HybridBackend.getCurrentRole();
if (isViewAllowed(view, freshRole)) {
setCurrentView(view); setCurrentView(view);
navigate(view); navigate(view);
setSidebarOpen(false); // Close sidebar on mobile after navigation setSidebarOpen(false); // Close sidebar on mobile after navigation
+71 -87
View File
@@ -22,12 +22,13 @@ const enforceUppercase = <T extends object>(data: T): T => {
const API_URL = import.meta.env.VITE_API_URL || '/api'; const API_URL = import.meta.env.VITE_API_URL || '/api';
// Returns headers always including the JWT token stored after login // Returns headers always including the JWT token stored after login
const getAuthHeaders = (): HeadersInit => { const apiFetch = async (url: string, options: RequestInit = {}) => {
const token = localStorage.getItem('SCOREODONTO_AUTH_TOKEN'); const token = localStorage.getItem('SCOREODONTO_AUTH_TOKEN');
return { const headers = {
'Content-Type': 'application/json', ...options.headers,
...(token ? { 'Authorization': `Bearer ${token}` } : {}) ...(token ? { 'Authorization': `Bearer ${token}` } : {})
}; };
return fetch(url, { ...options, headers });
}; };
export const HybridBackend = { export const HybridBackend = {
@@ -45,7 +46,7 @@ export const HybridBackend = {
const cleanPass = pass.trim(); const cleanPass = pass.trim();
try { try {
const res = await fetch(`${API_URL}/login`, { const res = await apiFetch(`${API_URL}/login`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: cleanEmail, password: cleanPass }) body: JSON.stringify({ email: cleanEmail, password: cleanPass })
@@ -144,7 +145,7 @@ export const HybridBackend = {
}, },
getDashboardStats: async () => { getDashboardStats: async () => {
const res = await fetch(`${API_URL}/dashboard/stats`); const res = await apiFetch(`${API_URL}/dashboard/stats`);
return await res.json(); return await res.json();
}, },
@@ -206,7 +207,7 @@ export const HybridBackend = {
}, },
getPacientes: async (termo: string = ''): Promise<Paciente[]> => { getPacientes: async (termo: string = ''): Promise<Paciente[]> => {
const res = await fetch(`${API_URL}/pacientes`); const res = await apiFetch(`${API_URL}/pacientes`);
const data = await res.json(); const data = await res.json();
if (!termo) return data; if (!termo) return data;
const t = termo.toUpperCase(); const t = termo.toUpperCase();
@@ -223,7 +224,7 @@ export const HybridBackend = {
savePaciente: async (paciente: Partial<Paciente>) => { savePaciente: async (paciente: Partial<Paciente>) => {
const data = enforceUppercase(paciente); const data = enforceUppercase(paciente);
const body = { ...data, id: Math.random().toString() }; const body = { ...data, id: Math.random().toString() };
const res = await fetch(`${API_URL}/pacientes`, { const res = await apiFetch(`${API_URL}/pacientes`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -233,7 +234,7 @@ export const HybridBackend = {
updatePaciente: async (paciente: Paciente) => { updatePaciente: async (paciente: Paciente) => {
const data = enforceUppercase(paciente); const data = enforceUppercase(paciente);
const res = await fetch(`${API_URL}/pacientes/${paciente.id}`, { const res = await apiFetch(`${API_URL}/pacientes/${paciente.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -243,18 +244,18 @@ export const HybridBackend = {
getDentistas: async (clinicaId?: string): Promise<Dentista[]> => { getDentistas: async (clinicaId?: string): Promise<Dentista[]> => {
const url = clinicaId ? `${API_URL}/dentistas?clinicaId=${clinicaId}` : `${API_URL}/dentistas`; const url = clinicaId ? `${API_URL}/dentistas?clinicaId=${clinicaId}` : `${API_URL}/dentistas`;
const res = await fetch(url); const res = await apiFetch(url);
return await res.json(); return await res.json();
}, },
getPlanos: async (): Promise<Plano[]> => { getPlanos: async (): Promise<Plano[]> => {
const res = await fetch(`${API_URL}/planos`); const res = await apiFetch(`${API_URL}/planos`);
return await res.json(); return await res.json();
}, },
updateDentista: async (dentista: Dentista) => { updateDentista: async (dentista: Dentista) => {
const data = enforceUppercase(dentista); const data = enforceUppercase(dentista);
const res = await fetch(`${API_URL}/dentistas/${dentista.id}`, { const res = await apiFetch(`${API_URL}/dentistas/${dentista.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -266,7 +267,7 @@ export const HybridBackend = {
const activeW = HybridBackend.getActiveWorkspace(); const activeW = HybridBackend.getActiveWorkspace();
const data = enforceUppercase(dentista); const data = enforceUppercase(dentista);
const body = { ...data, id: Math.random().toString(), clinica_id: activeW?.id }; const body = { ...data, id: Math.random().toString(), clinica_id: activeW?.id };
const res = await fetch(`${API_URL}/dentistas`, { const res = await apiFetch(`${API_URL}/dentistas`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -275,7 +276,7 @@ export const HybridBackend = {
}, },
reorderDentistas: async (orders: { id: string; ordem: number }[]) => { reorderDentistas: async (orders: { id: string; ordem: number }[]) => {
const res = await fetch(`${API_URL}/dentistas/reorder`, { const res = await apiFetch(`${API_URL}/dentistas/reorder`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orders }) body: JSON.stringify({ orders })
@@ -284,16 +285,16 @@ export const HybridBackend = {
}, },
deleteDentista: async (id: string) => { deleteDentista: async (id: string) => {
await fetch(`${API_URL}/dentistas/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/dentistas/${id}`, { method: 'DELETE' });
}, },
getHorariosByDentista: async (dentistaId: string, clinicaId: string): Promise<DentistaHorario[]> => { getHorariosByDentista: async (dentistaId: string, clinicaId: string): Promise<DentistaHorario[]> => {
const res = await fetch(`${API_URL}/dentistas/${dentistaId}/horarios?clinicaId=${clinicaId}`); const res = await apiFetch(`${API_URL}/dentistas/${dentistaId}/horarios?clinicaId=${clinicaId}`);
return await res.json(); return await res.json();
}, },
saveHorario: async (horario: Partial<DentistaHorario>) => { saveHorario: async (horario: Partial<DentistaHorario>) => {
const res = await fetch(`${API_URL}/dentistas/horarios`, { const res = await apiFetch(`${API_URL}/dentistas/horarios`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(horario) body: JSON.stringify(horario)
@@ -302,17 +303,17 @@ export const HybridBackend = {
}, },
deleteHorario: async (id: string) => { deleteHorario: async (id: string) => {
await fetch(`${API_URL}/dentistas/horarios/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/dentistas/horarios/${id}`, { method: 'DELETE' });
}, },
getProductivityReport: async (clinicaId: string, start?: string, end?: string) => { getProductivityReport: async (clinicaId: string, start?: string, end?: string) => {
const res = await fetch(`${API_URL}/reports/productivity?clinicaId=${clinicaId}&start=${start || ''}&end=${end || ''}`); const res = await apiFetch(`${API_URL}/reports/productivity?clinicaId=${clinicaId}&start=${start || ''}&end=${end || ''}`);
return await res.json(); return await res.json();
}, },
updateEspecialidade: async (esp: Especialidade) => { updateEspecialidade: async (esp: Especialidade) => {
const data = enforceUppercase(esp); const data = enforceUppercase(esp);
const res = await fetch(`${API_URL}/especialidades/${esp.id}`, { const res = await apiFetch(`${API_URL}/especialidades/${esp.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -323,7 +324,7 @@ export const HybridBackend = {
saveEspecialidade: async (esp: Partial<Especialidade>) => { saveEspecialidade: async (esp: Partial<Especialidade>) => {
const data = enforceUppercase(esp); const data = enforceUppercase(esp);
const body = { ...data, id: Math.random().toString() }; const body = { ...data, id: Math.random().toString() };
const res = await fetch(`${API_URL}/especialidades`, { const res = await apiFetch(`${API_URL}/especialidades`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -332,7 +333,7 @@ export const HybridBackend = {
}, },
reorderEspecialidades: async (orders: { id: string; ordem: number }[]) => { reorderEspecialidades: async (orders: { id: string; ordem: number }[]) => {
const res = await fetch(`${API_URL}/especialidades/reorder`, { const res = await apiFetch(`${API_URL}/especialidades/reorder`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orders }) body: JSON.stringify({ orders })
@@ -341,12 +342,12 @@ export const HybridBackend = {
}, },
deleteEspecialidade: async (id: string) => { deleteEspecialidade: async (id: string) => {
await fetch(`${API_URL}/especialidades/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/especialidades/${id}`, { method: 'DELETE' });
}, },
updateProcedimento: async (proc: Procedimento) => { updateProcedimento: async (proc: Procedimento) => {
const data = enforceUppercase(proc); const data = enforceUppercase(proc);
const res = await fetch(`${API_URL}/procedimentos/${proc.id}`, { const res = await apiFetch(`${API_URL}/procedimentos/${proc.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -357,7 +358,7 @@ export const HybridBackend = {
saveProcedimento: async (proc: Partial<Procedimento>) => { saveProcedimento: async (proc: Partial<Procedimento>) => {
const data = enforceUppercase(proc); const data = enforceUppercase(proc);
const body = { ...data, id: Math.random().toString() }; const body = { ...data, id: Math.random().toString() };
const res = await fetch(`${API_URL}/procedimentos`, { const res = await apiFetch(`${API_URL}/procedimentos`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -366,7 +367,7 @@ export const HybridBackend = {
}, },
reorderProcedimentos: async (orders: { id: string; ordem: number }[]) => { reorderProcedimentos: async (orders: { id: string; ordem: number }[]) => {
const res = await fetch(`${API_URL}/procedimentos/reorder`, { const res = await apiFetch(`${API_URL}/procedimentos/reorder`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ orders }) body: JSON.stringify({ orders })
@@ -375,12 +376,12 @@ export const HybridBackend = {
}, },
deleteProcedimento: async (id: string) => { deleteProcedimento: async (id: string) => {
await fetch(`${API_URL}/procedimentos/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/procedimentos/${id}`, { method: 'DELETE' });
}, },
updatePlano: async (plano: Plano) => { updatePlano: async (plano: Plano) => {
const data = enforceUppercase(plano); const data = enforceUppercase(plano);
const res = await fetch(`${API_URL}/planos/${plano.id}`, { const res = await apiFetch(`${API_URL}/planos/${plano.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -391,7 +392,7 @@ export const HybridBackend = {
savePlano: async (plano: Partial<Plano>) => { savePlano: async (plano: Partial<Plano>) => {
const data = enforceUppercase(plano); const data = enforceUppercase(plano);
const body = { ...data, id: Math.random().toString() }; const body = { ...data, id: Math.random().toString() };
const res = await fetch(`${API_URL}/planos`, { const res = await apiFetch(`${API_URL}/planos`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -400,57 +401,55 @@ export const HybridBackend = {
}, },
deletePlano: async (id: string) => { deletePlano: async (id: string) => {
await fetch(`${API_URL}/planos/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/planos/${id}`, { method: 'DELETE' });
}, },
getEspecialidades: async (): Promise<Especialidade[]> => { getEspecialidades: async (): Promise<Especialidade[]> => {
const res = await fetch(`${API_URL}/especialidades`); const res = await apiFetch(`${API_URL}/especialidades`);
return await res.json(); return await res.json();
}, },
getProcedimentos: async (): Promise<Procedimento[]> => { getProcedimentos: async (): Promise<Procedimento[]> => {
const res = await fetch(`${API_URL}/procedimentos`); const res = await apiFetch(`${API_URL}/procedimentos`);
return await res.json(); return await res.json();
}, },
getFinanceiro: async (): Promise<FinanceiroItem[]> => { getFinanceiro: async (): Promise<FinanceiroItem[]> => {
const res = await fetch(`${API_URL}/financeiro`); const res = await apiFetch(`${API_URL}/financeiro`);
return await res.json(); return await res.json();
}, },
saveFinanceiro: async (item: Partial<FinanceiroItem>) => { saveFinanceiro: async (item: Partial<FinanceiroItem>) => {
const data = enforceUppercase(item); const data = enforceUppercase(item);
const res = await fetch(`${API_URL}/financeiro`, { const res = await apiFetch(`${API_URL}/financeiro`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data), body: JSON.stringify(data)});
});
return await res.json(); return await res.json();
}, },
updateFinanceiro: async (item: FinanceiroItem) => { updateFinanceiro: async (item: FinanceiroItem) => {
const data = enforceUppercase(item); const data = enforceUppercase(item);
const res = await fetch(`${API_URL}/financeiro/${item.id}`, { const res = await apiFetch(`${API_URL}/financeiro/${item.id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data), body: JSON.stringify(data)});
});
return await res.json(); return await res.json();
}, },
deleteFinanceiro: async (id: string) => { deleteFinanceiro: async (id: string) => {
await fetch(`${API_URL}/financeiro/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/financeiro/${id}`, { method: 'DELETE' });
}, },
getAgendamentos: async (): Promise<Agendamento[]> => { getAgendamentos: async (): Promise<Agendamento[]> => {
const res = await fetch(`${API_URL}/agendamentos`, { headers: getAuthHeaders() }); const res = await apiFetch(`${API_URL}/agendamentos`, { });
return await res.json(); return await res.json();
}, },
salvarAgendamento: async (ag: Partial<Agendamento>) => { salvarAgendamento: async (ag: Partial<Agendamento>) => {
const res = await fetch(`${API_URL}/agendamentos`, { const res = await apiFetch(`${API_URL}/agendamentos`, {
method: 'POST', method: 'POST',
headers: getAuthHeaders(), ,
body: JSON.stringify(ag) body: JSON.stringify(ag)
}); });
if (!res.ok) { if (!res.ok) {
@@ -461,9 +460,9 @@ export const HybridBackend = {
}, },
atualizarAgendamento: async (id: string, data: Partial<Agendamento>) => { atualizarAgendamento: async (id: string, data: Partial<Agendamento>) => {
const res = await fetch(`${API_URL}/agendamentos/${id}`, { const res = await apiFetch(`${API_URL}/agendamentos/${id}`, {
method: 'PUT', method: 'PUT',
headers: getAuthHeaders(), ,
body: JSON.stringify(data) body: JSON.stringify(data)
}); });
if (!res.ok) { if (!res.ok) {
@@ -474,7 +473,7 @@ export const HybridBackend = {
}, },
excluirAgendamento: async (id: string) => { excluirAgendamento: async (id: string) => {
await fetch(`${API_URL}/agendamentos/${id}`, { method: 'DELETE', headers: getAuthHeaders() }); await apiFetch(`${API_URL}/agendamentos/${id}`, { method: 'DELETE'});
}, },
getOrtoTreatments: async (): Promise<TratamentoOrto[]> => { getOrtoTreatments: async (): Promise<TratamentoOrto[]> => {
@@ -492,15 +491,13 @@ export const HybridBackend = {
medicacao: 'NENHUMA', medicacao: 'NENHUMA',
alergias: 'NENHUMA', alergias: 'NENHUMA',
respiracaoBucal: false, respiracaoBucal: false,
habitos: 'BRUXISMO LEVE NOTURNO', habitos: 'BRUXISMO LEVE NOTURNO'},
},
diagnostico: { diagnostico: {
classeAngle: 'II', classeAngle: 'II',
perfil: 'Convexo', perfil: 'Convexo',
apinhamento: 'Moderado', apinhamento: 'Moderado',
mordida: 'Profunda', mordida: 'Profunda',
linhaMedia: '1MM PARA ESQUERDA', linhaMedia: '1MM PARA ESQUERDA'},
},
dataInicio: '2024-08-10', dataInicio: '2024-08-10',
tipoAparelho: 'AUTOLIGADO METÁLICO', tipoAparelho: 'AUTOLIGADO METÁLICO',
extracoes: 'NÃO', extracoes: 'NÃO',
@@ -528,8 +525,7 @@ export const HybridBackend = {
proximoRetorno: '2024-09-10', proximoRetorno: '2024-09-10',
fio: '0.12', fio: '0.12',
higiene: 8, higiene: 8,
cooperacao: 'Boa', cooperacao: 'Boa'},
},
{ {
id: 'ev2', id: 'ev2',
data: '2024-09-10', data: '2024-09-10',
@@ -538,8 +534,7 @@ export const HybridBackend = {
proximoRetorno: '2024-10-10', proximoRetorno: '2024-10-10',
fio: '0.14', fio: '0.14',
higiene: 7, higiene: 7,
cooperacao: 'Boa', cooperacao: 'Boa'},
},
{ {
id: 'ev3', id: 'ev3',
data: '2024-10-10', data: '2024-10-10',
@@ -549,8 +544,7 @@ export const HybridBackend = {
fio: '0.16', fio: '0.16',
elastico: 'CLASSE II', elastico: 'CLASSE II',
higiene: 6, higiene: 6,
cooperacao: 'Média', cooperacao: 'Média'},
},
{ {
id: 'ev4', id: 'ev4',
data: '2025-11-10', data: '2025-11-10',
@@ -562,8 +556,7 @@ export const HybridBackend = {
procedimentos: ['Profilaxia'], procedimentos: ['Profilaxia'],
higiene: 5, higiene: 5,
cooperacao: 'Média', cooperacao: 'Média',
observacoes: 'HIGIENE ABAIXO DO IDEAL. ORIENTAÇÕES REFORÇADAS.', observacoes: 'HIGIENE ABAIXO DO IDEAL. ORIENTAÇÕES REFORÇADAS.'},
},
{ {
id: 'ev5', id: 'ev5',
data: '2026-01-14', data: '2026-01-14',
@@ -573,8 +566,7 @@ export const HybridBackend = {
fio: '0.16', fio: '0.16',
elastico: 'CLASSE II', elastico: 'CLASSE II',
higiene: 6, higiene: 6,
cooperacao: 'Média', cooperacao: 'Média'},
},
], ],
flags: [ flags: [
{ tipo: 'warning', mensagem: 'HIGIENE ABAIXO DO IDEAL' }, { tipo: 'warning', mensagem: 'HIGIENE ABAIXO DO IDEAL' },
@@ -583,8 +575,7 @@ export const HybridBackend = {
fotos: [ fotos: [
{ url: '', tipo: 'inicio', data: '2024-08-10' }, { url: '', tipo: 'inicio', data: '2024-08-10' },
{ url: '', tipo: 'atual', data: '2026-01-14' }, { url: '', tipo: 'atual', data: '2026-01-14' },
], ]},
},
{ {
id: 't2', id: 't2',
pacienteId: '2', pacienteId: '2',
@@ -601,15 +592,13 @@ export const HybridBackend = {
periodonto: 'RECESSÃO GENGIVAL LEVE EM 31-41', periodonto: 'RECESSÃO GENGIVAL LEVE EM 31-41',
implantes: 'NENHUM', implantes: 'NENHUM',
recessoes: '31 E 41 - CLASSE I MILLER', recessoes: '31 E 41 - CLASSE I MILLER',
mobilidade: 'NENHUMA', mobilidade: 'NENHUMA'},
},
diagnostico: { diagnostico: {
classeAngle: 'III', classeAngle: 'III',
perfil: 'Côncavo', perfil: 'Côncavo',
apinhamento: 'Severo', apinhamento: 'Severo',
mordida: 'Cruzada', mordida: 'Cruzada',
linhaMedia: '3MM PARA DIREITA', linhaMedia: '3MM PARA DIREITA'},
},
dataInicio: '2024-03-05', dataInicio: '2024-03-05',
tipoAparelho: 'AUTOLIGADO CERÂMICO', tipoAparelho: 'AUTOLIGADO CERÂMICO',
extracoes: '1º PRÉ-MOLARES SUPERIORES (14 E 24)', extracoes: '1º PRÉ-MOLARES SUPERIORES (14 E 24)',
@@ -637,8 +626,7 @@ export const HybridBackend = {
proximoRetorno: '2024-04-05', proximoRetorno: '2024-04-05',
fio: '0.14', fio: '0.14',
higiene: 9, higiene: 9,
cooperacao: 'Boa', cooperacao: 'Boa'},
},
{ {
id: 'ev7', id: 'ev7',
data: '2025-06-05', data: '2025-06-05',
@@ -648,8 +636,7 @@ export const HybridBackend = {
fio: '0.19x0.25', fio: '0.19x0.25',
procedimentos: ['IPR'], procedimentos: ['IPR'],
higiene: 8, higiene: 8,
cooperacao: 'Boa', cooperacao: 'Boa'},
},
{ {
id: 'ev8', id: 'ev8',
data: '2026-02-05', data: '2026-02-05',
@@ -659,8 +646,7 @@ export const HybridBackend = {
fio: '0.19x0.25', fio: '0.19x0.25',
elastico: 'CLASSE III', elastico: 'CLASSE III',
higiene: 9, higiene: 9,
cooperacao: 'Boa', cooperacao: 'Boa'},
},
], ],
flags: [ flags: [
{ tipo: 'danger', mensagem: 'COMPLEXIDADE ALTA - APINHAMENTO SEVERO' }, { tipo: 'danger', mensagem: 'COMPLEXIDADE ALTA - APINHAMENTO SEVERO' },
@@ -669,8 +655,7 @@ export const HybridBackend = {
fotos: [ fotos: [
{ url: '', tipo: 'inicio', data: '2024-03-05' }, { url: '', tipo: 'inicio', data: '2024-03-05' },
{ url: '', tipo: 'atual', data: '2026-02-05' }, { url: '', tipo: 'atual', data: '2026-02-05' },
], ]},
},
]; ];
}, },
@@ -686,8 +671,7 @@ export const HybridBackend = {
procedimentos: evolucao.procedimentos, procedimentos: evolucao.procedimentos,
higiene: evolucao.higiene, higiene: evolucao.higiene,
cooperacao: evolucao.cooperacao, cooperacao: evolucao.cooperacao,
observacoes: evolucao.observacoes, observacoes: evolucao.observacoes};
};
console.log(`[Mock] Evolução salva no tratamento ${tratamentoId}:`, newEv); console.log(`[Mock] Evolução salva no tratamento ${tratamentoId}:`, newEv);
return newEv; return newEv;
}, },
@@ -703,7 +687,7 @@ export const HybridBackend = {
salvarAgendamento: async (agendamento: Partial<Agendamento>) => { salvarAgendamento: async (agendamento: Partial<Agendamento>) => {
const data = enforceUppercase(agendamento); const data = enforceUppercase(agendamento);
const body = { id: Math.random().toString(), ...data }; const body = { id: Math.random().toString(), ...data };
const res = await fetch(`${API_URL}/agendamentos`, { const res = await apiFetch(`${API_URL}/agendamentos`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body) body: JSON.stringify(body)
@@ -713,7 +697,7 @@ export const HybridBackend = {
atualizarAgendamento: async (id: string, agendamento: Partial<Agendamento>) => { atualizarAgendamento: async (id: string, agendamento: Partial<Agendamento>) => {
const data = enforceUppercase(agendamento); const data = enforceUppercase(agendamento);
const res = await fetch(`${API_URL}/agendamentos/${id}`, { const res = await apiFetch(`${API_URL}/agendamentos/${id}`, {
method: 'PUT', method: 'PUT',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data) body: JSON.stringify(data)
@@ -722,7 +706,7 @@ export const HybridBackend = {
}, },
excluirAgendamento: async (id: string) => { excluirAgendamento: async (id: string) => {
await fetch(`${API_URL}/agendamentos/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/agendamentos/${id}`, { method: 'DELETE' });
}, },
// --- LEAD & NOTIFICATION METHODS --- // --- LEAD & NOTIFICATION METHODS ---
@@ -738,7 +722,7 @@ export const HybridBackend = {
dataCadastro: new Date().toISOString(), dataCadastro: new Date().toISOString(),
status: 'Novo' status: 'Novo'
}; };
await fetch(`${API_URL}/leads`, { await apiFetch(`${API_URL}/leads`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newLead) body: JSON.stringify(newLead)
@@ -747,13 +731,13 @@ export const HybridBackend = {
}, },
getLeads: async (): Promise<Lead[]> => { getLeads: async (): Promise<Lead[]> => {
const res = await fetch(`${API_URL}/leads`); const res = await apiFetch(`${API_URL}/leads`);
return await res.json(); return await res.json();
}, },
getNotifications: async (): Promise<Notificacao[]> => { getNotifications: async (): Promise<Notificacao[]> => {
try { try {
const res = await fetch(`${API_URL}/notificacoes`); const res = await apiFetch(`${API_URL}/notificacoes`);
return await res.json(); return await res.json();
} catch { } catch {
return []; return [];
@@ -762,7 +746,7 @@ export const HybridBackend = {
markNotificationRead: async (id: string) => { markNotificationRead: async (id: string) => {
try { try {
await fetch(`${API_URL}/notificacoes/${id}/read`, { method: 'PUT' }); await apiFetch(`${API_URL}/notificacoes/${id}/read`, { method: 'PUT' });
} catch (err) { } catch (err) {
console.error("Erro ao marcar como lida:", err); console.error("Erro ao marcar como lida:", err);
} }
@@ -770,7 +754,7 @@ export const HybridBackend = {
markAllNotificationsRead: async () => { markAllNotificationsRead: async () => {
try { try {
await fetch(`${API_URL}/notificacoes/read-all`, { method: 'POST' }); await apiFetch(`${API_URL}/notificacoes/read-all`, { method: 'POST' });
} catch (err) { } catch (err) {
console.error("Erro ao marcar todas como lidas:", err); console.error("Erro ao marcar todas como lidas:", err);
} }
@@ -778,19 +762,19 @@ export const HybridBackend = {
deleteNotification: async (id: string) => { deleteNotification: async (id: string) => {
try { try {
await fetch(`${API_URL}/notificacoes/${id}`, { method: 'DELETE' }); await apiFetch(`${API_URL}/notificacoes/${id}`, { method: 'DELETE' });
} catch (err) { } catch (err) {
console.error("Erro ao excluir notificação:", err); console.error("Erro ao excluir notificação:", err);
} }
}, },
getSettings: async (): Promise<Settings> => { getSettings: async (): Promise<Settings> => {
const res = await fetch(`${API_URL}/settings`); const res = await apiFetch(`${API_URL}/settings`);
return await res.json(); return await res.json();
}, },
saveSettings: async (settings: Settings) => { saveSettings: async (settings: Settings) => {
const res = await fetch(`${API_URL}/settings`, { const res = await apiFetch(`${API_URL}/settings`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(settings) body: JSON.stringify(settings)
@@ -800,7 +784,7 @@ export const HybridBackend = {
getGoogleEvents: async (): Promise<any[]> => { getGoogleEvents: async (): Promise<any[]> => {
try { try {
const res = await fetch(`${API_URL}/google/events`); const res = await apiFetch(`${API_URL}/google/events`);
return await res.json(); return await res.json();
} catch { } catch {
return []; return [];