Files
FamilyHUB/frontend/src/api/transactions.ts
T

108 lines
3.0 KiB
TypeScript

export interface Transaction {
id: number
family_id: number
description: string | null
type: string
datetime: string
category: string
amount: number
created_at: string
created_by: number
receipt_id: number | null
}
interface TransactionsResponse {
items: Transaction[]
}
interface GetTransactionsOptions {
familyId?: number
limit?: number
offset?: number
}
export async function getTransactions(options: GetTransactionsOptions = {}): Promise<Transaction[]> {
const params = new URLSearchParams()
if (typeof options.familyId === 'number' && Number.isFinite(options.familyId) && options.familyId > 0) {
params.set('family_id', String(options.familyId))
}
params.set('limit', String(options.limit ?? 100))
params.set('offset', String(options.offset ?? 0))
const query = params.toString()
const response = await fetch(`/api/v1/transactions${query ? `?${query}` : ''}`)
if (!response.ok) {
throw new Error(`Failed to fetch transactions: ${response.status}`)
}
const payload = await response.json() as TransactionsResponse
return Array.isArray(payload.items) ? payload.items : []
}
export interface CreateTransactionData {
family_id: number
type?: string
category?: string
amount?: number
datetime?: string
description?: string
receipt_number?: string
receipt_date?: string
}
// TODO: Replace with the authenticated user id when frontend auth is implemented.
const TRANSACTION_CREATOR_ID = 1
export async function createTransaction(data: CreateTransactionData): Promise<Transaction> {
const response = await fetch('/api/v1/transactions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
...data,
created_by: TRANSACTION_CREATOR_ID,
}),
})
if (!response.ok) {
const error = await response.json().catch(() => ({ message: response.statusText }))
throw new Error(error.message || `Failed to create transaction: ${response.status}`)
}
return response.json() as Promise<Transaction>
}
export interface CreateTransactionPhotoData {
photo: File
family_id: number
type?: string
category?: string
description?: string
}
export async function createTransactionFromPhoto(data: CreateTransactionPhotoData): Promise<Transaction> {
const formData = new FormData()
formData.append('photo', data.photo)
formData.append('family_id', String(data.family_id))
formData.append('created_by', String(TRANSACTION_CREATOR_ID))
if (data.type) formData.append('type', data.type)
if (data.category) formData.append('category', data.category)
if (data.description) formData.append('description', data.description)
const response = await fetch('/api/v1/transactions', {
method: 'POST',
body: formData,
})
if (!response.ok) {
const error = await response.json().catch(() => ({ message: response.statusText }))
throw new Error(error.message || `Failed to create transaction from photo: ${response.status}`)
}
return response.json() as Promise<Transaction>
}