modified: src/components/AppShell.jsx modified: src/config/api.js modified: src/config/permissions.js modified: src/data/mockData.js modified: src/hooks/useAgenda.js modified: src/hooks/useAuth.js modified: src/mappers/appointmentMapper.js modified: src/pages/AgendaPage.jsx modified: src/pages/AuthPages.jsx modified: src/pages/HomePage.jsx modified: src/pages/MedicalRecordsPage.jsx modified: src/pages/MessagesPage.jsx modified: src/pages/NotFoundPage.jsx modified: src/pages/PatientsPage.jsx modified: src/pages/ReportsPage.jsx modified: src/pages/TeamPage.jsx modified: src/pages/UsersPage.jsx modified: src/pages/VisitsPage.jsx modified: src/repositories/authRepository.js new file: src/repositories/availabilityRepository.js modified: src/repositories/communicationRepository.js modified: src/repositories/patientRepository.js modified: src/repositories/professionalRepository.js modified: src/repositories/profileRepository.js modified: src/repositories/reportRepository.js modified: src/repositories/repositoryUtils.js modified: src/repositories/settingsRepository.js modified: src/repositories/userRepository.js modified: src/repositories/visitRepository.js
187 lines
5.3 KiB
JavaScript
187 lines
5.3 KiB
JavaScript
import { apiConfig, getAuthenticatedHeaders } from '../config/api.js'
|
|
import { getResponseError, normalizeCollection, normalizeItem } from './repositoryUtils.js'
|
|
|
|
const availabilityBaseUrl = `${apiConfig.restUrl}/doctor_availability`
|
|
const exceptionsBaseUrl = `${apiConfig.restUrl}/doctor_exceptions`
|
|
|
|
export const availabilityRepository = {
|
|
async getAll(filters = {}) {
|
|
const query = buildRestQuery(filters)
|
|
const response = await fetch(`${availabilityBaseUrl}?${query.toString()}`, {
|
|
headers: getAuthenticatedHeaders(),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao listar disponibilidades.'))
|
|
}
|
|
|
|
return normalizeCollection(await response.json(), []).map(mapAvailability)
|
|
},
|
|
|
|
async create(data) {
|
|
const response = await fetch(availabilityBaseUrl, {
|
|
method: 'POST',
|
|
headers: getAuthenticatedHeaders({ Prefer: 'return=representation' }),
|
|
body: JSON.stringify(toAvailabilityPayload(data)),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao criar disponibilidade.'))
|
|
}
|
|
|
|
return mapAvailability(normalizeItem(await response.json()))
|
|
},
|
|
|
|
async update(id, data) {
|
|
const response = await fetch(`${availabilityBaseUrl}?id=eq.${encodeURIComponent(id)}`, {
|
|
method: 'PATCH',
|
|
headers: getAuthenticatedHeaders({ Prefer: 'return=representation' }),
|
|
body: JSON.stringify(toAvailabilityPayload(data)),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao atualizar disponibilidade.'))
|
|
}
|
|
|
|
return mapAvailability(normalizeItem(await response.json()))
|
|
},
|
|
|
|
async remove(id) {
|
|
const response = await fetch(`${availabilityBaseUrl}?id=eq.${encodeURIComponent(id)}`, {
|
|
method: 'DELETE',
|
|
headers: getAuthenticatedHeaders(),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao deletar disponibilidade.'))
|
|
}
|
|
|
|
return true
|
|
},
|
|
|
|
async getExceptions(filters = {}) {
|
|
const query = buildRestQuery(filters)
|
|
const response = await fetch(`${exceptionsBaseUrl}?${query.toString()}`, {
|
|
headers: getAuthenticatedHeaders(),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao listar excecoes de agenda.'))
|
|
}
|
|
|
|
return normalizeCollection(await response.json(), []).map(mapException)
|
|
},
|
|
|
|
async createException(data) {
|
|
const response = await fetch(exceptionsBaseUrl, {
|
|
method: 'POST',
|
|
headers: getAuthenticatedHeaders({ Prefer: 'return=representation' }),
|
|
body: JSON.stringify(toExceptionPayload(data)),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao criar excecao de agenda.'))
|
|
}
|
|
|
|
return mapException(normalizeItem(await response.json()))
|
|
},
|
|
|
|
async getAvailableSlots({ date, doctorId }) {
|
|
const response = await fetch(`${apiConfig.functionsUrl.replace(/\/+$/, '')}/get-available-slots`, {
|
|
method: 'POST',
|
|
headers: getAuthenticatedHeaders(),
|
|
body: JSON.stringify({
|
|
doctor_id: doctorId,
|
|
date,
|
|
}),
|
|
})
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await getResponseError(response, 'Falha ao calcular slots disponíveis.'))
|
|
}
|
|
|
|
const data = await response.json()
|
|
return normalizeCollection(data, ['slots']).map(mapSlot)
|
|
},
|
|
}
|
|
|
|
function buildRestQuery(filters) {
|
|
const query = new URLSearchParams()
|
|
query.set('select', '*')
|
|
|
|
if (filters.doctorId) query.set('doctor_id', `eq.${filters.doctorId}`)
|
|
if (filters.weekday !== undefined) query.set('weekday', `eq.${filters.weekday}`)
|
|
if (filters.active !== undefined) query.set('active', `eq.${filters.active}`)
|
|
if (filters.appointmentType) query.set('appointment_type', `eq.${filters.appointmentType}`)
|
|
if (filters.date) query.set('date', `eq.${filters.date}`)
|
|
if (filters.kind) query.set('kind', `eq.${filters.kind}`)
|
|
if (filters.order) query.set('order', filters.order)
|
|
|
|
return query
|
|
}
|
|
|
|
function toAvailabilityPayload(data) {
|
|
return cleanPayload({
|
|
doctor_id: data.doctorId,
|
|
weekday: data.weekday,
|
|
start_time: data.startTime,
|
|
end_time: data.endTime,
|
|
slot_minutes: data.slotMinutes,
|
|
appointment_type: data.appointmentType,
|
|
active: data.active,
|
|
})
|
|
}
|
|
|
|
function toExceptionPayload(data) {
|
|
return cleanPayload({
|
|
doctor_id: data.doctorId,
|
|
date: data.date,
|
|
kind: data.kind,
|
|
start_time: data.startTime,
|
|
end_time: data.endTime,
|
|
reason: data.reason,
|
|
created_by: data.createdBy,
|
|
})
|
|
}
|
|
|
|
function mapAvailability(item) {
|
|
return {
|
|
id: item.id,
|
|
doctorId: item.doctor_id,
|
|
weekday: item.weekday,
|
|
startTime: item.start_time,
|
|
endTime: item.end_time,
|
|
slotMinutes: item.slot_minutes,
|
|
appointmentType: item.appointment_type,
|
|
active: item.active,
|
|
createdAt: item.created_at,
|
|
updatedAt: item.updated_at,
|
|
}
|
|
}
|
|
|
|
function mapException(item) {
|
|
return {
|
|
id: item.id,
|
|
doctorId: item.doctor_id,
|
|
date: item.date,
|
|
kind: item.kind,
|
|
startTime: item.start_time,
|
|
endTime: item.end_time,
|
|
reason: item.reason,
|
|
createdBy: item.created_by,
|
|
}
|
|
}
|
|
|
|
function mapSlot(slot) {
|
|
return {
|
|
time: slot.time,
|
|
available: Boolean(slot.available),
|
|
}
|
|
}
|
|
|
|
function cleanPayload(payload) {
|
|
return Object.fromEntries(
|
|
Object.entries(payload).filter(([, value]) => value !== undefined),
|
|
)
|
|
}
|