mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 20:08:14 +00:00
321a6298a4
- Pharmacy: the sidebar entry now expands into Pharmacy + a new Inventory page (searchable medication stock with derived in-stock/low/out availability, backed by /api/inventory). Fix the dispensing-queue "Expiring" badge so it only flags courses ending within the next 7 days, not ones already elapsed. - Lab "Add analysis result": the patient picker no longer lists patients until you type and supports arrow-key + Enter selection; the test field offers a catalog of common analyses with an Advanced option (custom analysis + ref range); submitted results now show immediately in a Recent results feed. - Analysis: add a Live panel (real-time line chart) and replace the flat trend sparklines with bklit-ui area + bar charts (installed from the @bklit shadcn registry; chart CSS variables wired into the theme for light and dark). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import { apiFetch } from "@/lib/api-client";
|
|
|
|
// A pharmacy stock item. Mirrors the backend `src/types/inventory.ts`. Scoped to
|
|
// the active clinic. `expiresAt` is an ISO YYYY-MM-DD date (or null).
|
|
export type InventoryItem = {
|
|
id: string;
|
|
name: string;
|
|
form: string;
|
|
strength: string;
|
|
unit: string;
|
|
stockQuantity: number;
|
|
reorderThreshold: number;
|
|
location: string;
|
|
expiresAt: string | null;
|
|
notes: string | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
};
|
|
|
|
// The fields the inventory dialog collects.
|
|
export type InventoryInput = {
|
|
name: string;
|
|
form?: string;
|
|
strength?: string;
|
|
unit?: string;
|
|
stockQuantity?: number;
|
|
reorderThreshold?: number;
|
|
location?: string;
|
|
expiresAt?: string | null;
|
|
notes?: string | null;
|
|
};
|
|
|
|
export type Availability = "in-stock" | "low" | "out";
|
|
|
|
// Derived stock status: out at zero, low at/under the reorder threshold,
|
|
// otherwise in stock. Computed on the client (not persisted).
|
|
export function availabilityOf(item: InventoryItem): Availability {
|
|
if (item.stockQuantity <= 0) return "out";
|
|
if (item.stockQuantity <= item.reorderThreshold) return "low";
|
|
return "in-stock";
|
|
}
|
|
|
|
export function listInventory(): Promise<InventoryItem[]> {
|
|
return apiFetch<InventoryItem[]>("/api/inventory");
|
|
}
|
|
|
|
export function createInventory(input: InventoryInput): Promise<InventoryItem> {
|
|
return apiFetch<InventoryItem>("/api/inventory", {
|
|
method: "POST",
|
|
body: JSON.stringify(input),
|
|
});
|
|
}
|
|
|
|
export function updateInventory(
|
|
id: string,
|
|
input: InventoryInput,
|
|
): Promise<InventoryItem> {
|
|
return apiFetch<InventoryItem>(`/api/inventory/${id}`, {
|
|
method: "PUT",
|
|
body: JSON.stringify(input),
|
|
});
|
|
}
|
|
|
|
export function deleteInventory(id: string): Promise<void> {
|
|
return apiFetch<void>(`/api/inventory/${id}`, { method: "DELETE" });
|
|
}
|