mirror of
https://github.com/andwati/cymelle.git
synced 2026-11-09 18:25:13 +00:00
completed frontend v1
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import type {ApiErrorResponse} from "#/types/api";
|
||||
|
||||
const API_BASE_URL =
|
||||
import.meta.env.VITE_API_BASE_URL ?? "http://localhost:8080/api";
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number;
|
||||
code: string;
|
||||
details: unknown;
|
||||
|
||||
constructor(status: number, error: ApiErrorResponse) {
|
||||
super(error.message || "Request failed");
|
||||
this.name = "ApiError";
|
||||
this.status = status;
|
||||
this.code = error.error;
|
||||
this.details = error.details;
|
||||
}
|
||||
}
|
||||
|
||||
type RequestOptions = {
|
||||
method?: "GET" | "POST" | "DELETE" | "PUT" | "PATCH";
|
||||
body?: unknown;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
|
||||
export async function apiRequest<T>(
|
||||
path: string,
|
||||
options: RequestOptions = {},
|
||||
): Promise<T> {
|
||||
const response = await fetch(`${API_BASE_URL}${path}`, {
|
||||
method: options.method ?? "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: options.body ? JSON.stringify(options.body) : undefined,
|
||||
signal: options.signal,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let errorBody: ApiErrorResponse;
|
||||
|
||||
try {
|
||||
errorBody = await response.json();
|
||||
} catch {
|
||||
errorBody = {
|
||||
error: "REQUEST_FAILED",
|
||||
message: `Request failed with status ${response.status}`,
|
||||
details: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
path,
|
||||
};
|
||||
}
|
||||
|
||||
throw new ApiError(response.status, errorBody);
|
||||
}
|
||||
|
||||
if (response.status === 204) {
|
||||
return undefined as T;
|
||||
}
|
||||
|
||||
return response.json() as Promise<T>;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import {apiRequest} from "#/api/client";
|
||||
import type {FareCalculationResponse} from "#/types/fare";
|
||||
|
||||
export function calculateFare(
|
||||
distanceKm: number,
|
||||
surgeMultiplier?: number,
|
||||
signal?: AbortSignal,
|
||||
) {
|
||||
const params = new URLSearchParams();
|
||||
params.set("distanceKm", String(distanceKm));
|
||||
|
||||
if (surgeMultiplier !== undefined) {
|
||||
params.set("surgeMultiplier", String(surgeMultiplier));
|
||||
}
|
||||
|
||||
return apiRequest<FareCalculationResponse>(
|
||||
`/fare/calculate?${params.toString()}`,
|
||||
{signal},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import {apiRequest} from "#/api/client";
|
||||
import type {InventoryResponse, LowStockInventoryResponse,} from "#/types/inventory";
|
||||
|
||||
export function getInventory(signal?: AbortSignal) {
|
||||
return apiRequest<InventoryResponse>("/inventory", {signal});
|
||||
}
|
||||
|
||||
export function getLowStockInventory(
|
||||
threshold?: number,
|
||||
signal?: AbortSignal,
|
||||
) {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (threshold !== undefined) {
|
||||
params.set("threshold", String(threshold));
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
|
||||
return apiRequest<LowStockInventoryResponse>(
|
||||
`/inventory/low-stock${query ? `?${query}` : ""}`,
|
||||
{signal},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import {apiRequest} from "#/api/client";
|
||||
import type {PageResponse} from "#/types/api";
|
||||
import type {CancelOrderResponse, Order, OrderFilters, OrderSummary,} from "#/types/order";
|
||||
|
||||
export function getOrders(
|
||||
filters: OrderFilters,
|
||||
page = 0,
|
||||
size = 20,
|
||||
signal?: AbortSignal,
|
||||
) {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
if (filters.status) {
|
||||
params.set("status", filters.status);
|
||||
}
|
||||
|
||||
if (filters.from) {
|
||||
params.set("from", filters.from);
|
||||
}
|
||||
|
||||
if (filters.to) {
|
||||
params.set("to", filters.to);
|
||||
}
|
||||
|
||||
params.set("page", String(page));
|
||||
params.set("size", String(size));
|
||||
|
||||
return apiRequest<PageResponse<OrderSummary>>(`/orders?${params.toString()}`, {
|
||||
signal,
|
||||
});
|
||||
}
|
||||
|
||||
export function getOrder(id: string, signal?: AbortSignal) {
|
||||
return apiRequest<Order>(`/orders/${id}`, {signal});
|
||||
}
|
||||
|
||||
export function cancelOrder(id: string) {
|
||||
return apiRequest<CancelOrderResponse>(`/orders/${id}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user