Frontend API structure.

This commit is contained in:
Drew 2025-09-22 02:00:26 -07:00
parent 7d2b7fc90c
commit c443a13a14
10 changed files with 1810 additions and 4 deletions

View file

@ -0,0 +1,113 @@
import {
Task,
CreateTaskRequest,
UpdateTaskRequest,
ApiError,
} from '~/types/task'
const API_BASE_URL = '/api'
class ApiClient {
private async fetchWrapper<T>(
endpoint: string,
options: RequestInit = {}
): Promise<T> {
const url = `${API_BASE_URL}${endpoint}`
const config: RequestInit = {
headers: {
'Content-Type': 'application/json',
...options.headers,
},
...options,
}
if (process.env.NODE_ENV === 'development') {
console.log(`API Request: ${config.method || 'GET'} ${url}`, {
body: config.body,
headers: config.headers,
})
}
try {
const response = await fetch(url, config)
if (process.env.NODE_ENV === 'development') {
console.log(`API Response: ${response.status} ${response.statusText}`, {
url,
status: response.status,
})
}
if (!response.ok) {
let errorMessage = `HTTP ${response.status}: ${response.statusText}`
try {
const errorData = await response.json()
errorMessage = errorData.message || errorMessage
} catch {
// If JSON parsing fails, use the default error message
}
throw new Error(errorMessage)
}
if (response.status === 204) {
return null as T
}
const data = await response.json()
if (process.env.NODE_ENV === 'development') {
console.log('API Response Data:', data)
}
return data
} catch (error) {
const apiError: ApiError = {
message:
error instanceof Error ? error.message : 'Unknown error occurred',
status:
error instanceof Error && 'status' in error
? (error as { status?: number }).status
: undefined,
}
if (process.env.NODE_ENV === 'development') {
console.error('API Error:', apiError)
}
throw apiError
}
}
async listTasks(): Promise<Task[]> {
return this.fetchWrapper<Task[]>('/tasks')
}
async getTask(id: string): Promise<Task> {
return this.fetchWrapper<Task>(`/tasks/${id}`)
}
async createTask(data: CreateTaskRequest): Promise<Task> {
return this.fetchWrapper<Task>('/tasks', {
method: 'POST',
body: JSON.stringify(data),
})
}
async updateTask(id: string, data: UpdateTaskRequest): Promise<Task> {
return this.fetchWrapper<Task>(`/tasks/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
})
}
async deleteTask(id: string): Promise<void> {
return this.fetchWrapper<void>(`/tasks/${id}`, {
method: 'DELETE',
})
}
}
export const apiClient = new ApiClient()