fix(frontend): Resolve login redirection and inject JWT token on requests
This commit is contained in:
+2
-1
@@ -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
|
||||||
|
|||||||
@@ -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 [];
|
||||||
|
|||||||
Reference in New Issue
Block a user