Create a frontend wireframe. (#7)
Sets up API methods and types. Sets up a colorscheme. Sets up a homepage. Removes tailwind in favor of mui for now. Reviewed-on: #7 Co-authored-by: Drew Galbraith <drew@tiramisu.one> Co-committed-by: Drew Galbraith <drew@tiramisu.one>
This commit is contained in:
parent
7d2b7fc90c
commit
d60d834f38
27 changed files with 3114 additions and 977 deletions
113
frontend/app/services/api.ts
Normal file
113
frontend/app/services/api.ts
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
import type {
|
||||
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()
|
||||
Loading…
Add table
Add a link
Reference in a new issue