File size: 1,959 Bytes
f75bff1 8ecab61 f75bff1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | const API_BASE = '/api'
class ApiError extends Error {
constructor(message, status, data) {
super(message)
this.status = status
this.data = data
}
}
async function request(endpoint, options = {}) {
const url = `${API_BASE}${endpoint}`
const config = {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
}
try {
const response = await fetch(url, config)
const data = await response.json()
if (!response.ok) {
// Parse Django REST Framework field-specific validation errors
let message = 'Request failed'
if (typeof data === 'object' && data !== null) {
const errors = []
for (const [field, value] of Object.entries(data)) {
if (Array.isArray(value)) {
errors.push(...value)
} else if (typeof value === 'string') {
errors.push(value)
}
}
if (errors.length > 0) {
message = errors.join('. ')
} else if (data.message) {
message = data.message
}
}
throw new ApiError(message, response.status, data)
}
return data
} catch (error) {
if (error instanceof ApiError) {
throw error
}
throw new ApiError('Network error', 0, { originalError: error })
}
}
export const api = {
// Profiles
getProfiles: () => request('/profiles/'),
getProfile: (id) => request(`/profiles/${id}/`),
// Simulation
runSimulation: (config, numTeams = 10, startDate) => request('/profiles/simulate/', {
method: 'POST',
body: JSON.stringify({ config, num_teams: numTeams, start_date: startDate })
}),
// Analytics
getProfileDays: (id, day) => request(`/profiles/${id}/days/${day}/`),
getProfileOverview: (id, day) => request(`/profiles/${id}/overview/${day}/`),
getOverviewByDay: (day) => request(`/profiles/overview/${day}/`),
getOverviewTotal: () => request('/profiles/overview/')
}
|