import axios from 'axios'; import { MeasurementCategory } from "@/components/Measurements/models/Category"; import { MeasurementEntry } from "@/components/Measurements/models/Entry"; import { ApiMeasurementCategoryType } from '@/types'; import { API_MAX_PAGE_SIZE } from "@/core/lib/consts"; import { fetchPaginated } from '@/core/lib/requests'; import { makeHeader, makeUrl } from "@/core/lib/url"; export const API_MEASUREMENTS_CATEGORY_PATH = 'measurement-category'; export const API_MEASUREMENTS_ENTRY_PATH = 'measurement'; export type MeasurementQueryOptions = { filtersetQueryCategories?: object, filtersetQueryEntries?: object, } export const getMeasurementCategories = async (options?: MeasurementQueryOptions): Promise => { const { filtersetQueryCategories = {}, filtersetQueryEntries = {} } = options || {}; const categories: MeasurementCategory[] = []; const categoryUrl = makeUrl(API_MEASUREMENTS_CATEGORY_PATH, { query: { limit: API_MAX_PAGE_SIZE, ...filtersetQueryCategories } }); for await (const page of fetchPaginated(categoryUrl, makeHeader())) { for (const catData of page) { categories.push(MeasurementCategory.fromJson(catData)); } } // Load entries for each category const entryResponses = categories.map(async (category) => { const out: MeasurementEntry[] = []; const url = makeUrl(API_MEASUREMENTS_ENTRY_PATH, { query: { category: category.id, limit: API_MAX_PAGE_SIZE, ...filtersetQueryEntries, } }); // Collect all pages of entries for await (const page of fetchPaginated(url, makeHeader())) { for (const entries of page) { out.push(MeasurementEntry.fromJson(entries)); } } return out; }); const settingsResponses = await Promise.all(entryResponses); // Save entries to each category let categoryId: string; settingsResponses.forEach((entries) => { if (entries.length > 0) { categoryId = entries[0].category; categories.findLast(c => c.id === categoryId)!.entries = entries; } }); return categories; }; export const getMeasurementCategory = async (id: string): Promise => { const { data: receivedCategories } = await axios.get( makeUrl(API_MEASUREMENTS_CATEGORY_PATH, { id: id }), { headers: makeHeader() }, ); const category = MeasurementCategory.fromJson(receivedCategories); const measurements: MeasurementEntry[] = []; const url = makeUrl(API_MEASUREMENTS_ENTRY_PATH, { query: { category: category.id } }); // Collect all pages of entries for await (const page of fetchPaginated(url, makeHeader())) { for (const entries of page) { measurements.push(MeasurementEntry.fromJson(entries)); } } category.entries = measurements; return category; }; export interface AddMeasurementCategoryParams { name: string; unit: string; } export const addMeasurementCategory = async (data: AddMeasurementCategoryParams): Promise => { const response = await axios.post( makeUrl(API_MEASUREMENTS_CATEGORY_PATH,), { name: data.name, unit: data.unit }, { headers: makeHeader() } ); return MeasurementCategory.fromJson(response.data); }; export interface editMeasurementCategoryParams { id: string, name: string; unit: string; } export const editMeasurementCategory = async (data: editMeasurementCategoryParams): Promise => { const response = await axios.patch( makeUrl(API_MEASUREMENTS_CATEGORY_PATH, { id: data.id }), { name: data.name, unit: data.unit }, { headers: makeHeader() } ); return MeasurementCategory.fromJson(response.data); }; export const deleteMeasurementCategory = async (id: string): Promise => { await axios.delete(makeUrl(API_MEASUREMENTS_CATEGORY_PATH, { id: id }), { headers: makeHeader() }); }; export const deleteMeasurementEntry = async (id: string): Promise => { await axios.delete(makeUrl(API_MEASUREMENTS_ENTRY_PATH, { id: id }), { headers: makeHeader() }); }; export interface editMeasurementParams { id: string, categoryId?: string, date: Date; value: number; notes: string; } export const editMeasurementEntry = async (data: editMeasurementParams): Promise => { const response = await axios.patch( makeUrl(API_MEASUREMENTS_ENTRY_PATH, { id: data.id }), { // the server field is a datetime, send the full timestamp date: data.date.toISOString(), value: data.value, notes: data.notes }, { headers: makeHeader() } ); return MeasurementEntry.fromJson(response.data); }; export interface AddMeasurementParams { categoryId: string; date: Date; value: number; notes: string; } export const addMeasurementEntry = async (data: AddMeasurementParams): Promise => { const response = await axios.post( makeUrl(API_MEASUREMENTS_ENTRY_PATH), { category: data.categoryId, // the server field is a datetime, send the full timestamp date: data.date.toISOString(), value: data.value, notes: data.notes }, { headers: makeHeader() } ); return MeasurementEntry.fromJson(response.data); };