import type { Reagent, ReagentColumn } from '../types' export const REAGENT_COLUMN_LABELS: Record = { name: 'Name', catalog: 'Catalog #', lot: 'Lot #', expiry: 'Expiry', storage: 'Storage', location: 'Location', stock: 'Stock', supplier: 'Supplier', } export interface ReagentRowClassOptions { lowStockThreshold: number draggedId?: string | null dragOverId?: string | null now?: Date } export function getReagentColumnValue(reagent: Reagent, column: ReagentColumn): unknown { switch (column) { case 'name': return reagent.name case 'catalog': return reagent.catalogNumber case 'lot': return reagent.lotNumber case 'expiry': return reagent.expiryDate ? new Date(reagent.expiryDate).getTime() : null case 'storage': return reagent.storageCondition case 'location': return reagent.location case 'stock': return reagent.stockLevel case 'supplier': return reagent.supplier default: return null } } export function isReagentExpired(reagent: Reagent, now = new Date()): boolean { if (!reagent.expiryDate) return false const expiry = new Date(reagent.expiryDate) return expiry < now } export function isReagentExpiringSoon( reagent: Reagent, daysThreshold = 30, now = new Date() ): boolean { if (!reagent.expiryDate) return false const expiry = new Date(reagent.expiryDate) const daysUntilExpiry = (expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24) return daysUntilExpiry > 0 && daysUntilExpiry <= daysThreshold } /** Relative expiry for an expiring-soon reagent, e.g. `3 days left` (3d). */ export function formatReagentExpiresIn(reagent: Reagent, now = new Date()): string { if (!reagent.expiryDate) return '' const days = Math.ceil((new Date(reagent.expiryDate).getTime() - now.getTime()) / (1000 * 60 * 60 * 24)) return `${days} ${days === 1 ? 'day' : 'days'} left` } export function isReagentLowStock(reagent: Reagent, lowStockThreshold: number): boolean { if (reagent.stockLevel === undefined) return false return reagent.stockLevel <= lowStockThreshold } export function formatReagentExpiryDate(date: Date | string | undefined): string { if (!date) return '-' const parsed = new Date(date) return parsed.toLocaleDateString('en-US', { year: 'numeric', month: 'short' }) } export function getReagentStockLevel(reagent: Reagent): number { return reagent.stockLevel ?? 0 } export function getReagentRowClasses( reagent: Reagent, options: ReagentRowClassOptions ): string[] { const classes: string[] = ['mint-reagent-list__row'] if (isReagentExpired(reagent, options.now)) { classes.push('mint-reagent-list__row--expired') } else if (isReagentExpiringSoon(reagent, 30, options.now)) { classes.push('mint-reagent-list__row--expiring-soon') } if (isReagentLowStock(reagent, options.lowStockThreshold)) { classes.push('mint-reagent-list__row--low-stock') } if (options.draggedId === reagent.id) { classes.push('mint-reagent-list__row--dragging') } if (options.dragOverId === reagent.id) { classes.push('mint-reagent-list__row--drag-over') } return classes }