import { Button } from '@/components/ui/Button' import { cn } from '@/lib/cn' import { SourceLink } from './SourceLink' import { formatCost, formatQuantity, formatUnitCost, lotState, type LotState, type SeedLot, } from '@/lib/seedLots' const STATE_LABEL: Record = { over: 'over-planted', empty: 'empty', low: 'low', ok: 'in stock', unknown: 'no count', } // Encoded in colour AND words, because this is the thing you skim down a list of // twenty packets deciding what to order — a bare number doesn't survive that. const STATE_CLASS: Record = { // "over" is a discrepancy to look at rather than a shortage to act on, so it // reads as a distinct warning rather than sharing "low"'s styling. over: 'bg-orange-500/25 text-orange-900 dark:text-orange-200', empty: 'bg-red-500/15 text-red-800 dark:text-red-300', low: 'bg-amber-500/20 text-amber-800 dark:text-amber-300', ok: 'bg-accent/20 text-accent-strong', unknown: 'bg-border/60 text-muted', } export function LotStateChip({ state, className }: { state: LotState; className?: string }) { return ( {STATE_LABEL[state]} ) } /** A proportional bar for how much of a lot is left, so the state reads before * any of the text does. Omitted when there's no quantity to be a fraction of. */ function RemainingBar({ lot }: { lot: SeedLot }) { if (lot.quantity <= 0) return null const pct = Math.max(0, Math.min(100, (lot.remaining / lot.quantity) * 100)) const state = lotState(lot) return (
) } /** * A plant's purchases: what came from where, and what's left of each. * * Two lots of the same variety are two separate rows with independent counts, * which is the whole reason inventory lives on the purchase rather than on the * plant (#50). */ export function SeedLotList({ lots, canEdit, onAdd, onEdit, onDelete, }: { lots: SeedLot[] canEdit: boolean onAdd: () => void onEdit: (lot: SeedLot) => void onDelete: (lot: SeedLot) => void }) { return (
{lots.length === 0 && (

No seed recorded. Add a lot to track what you bought and how much is left.

)} {lots.map((lot) => ( onEdit(lot)} onDelete={() => onDelete(lot)} /> ))} {canEdit && ( )}
) } function LotRow({ lot, canEdit, onEdit, onDelete, }: { lot: SeedLot canEdit: boolean onEdit: () => void onDelete: () => void }) { const cost = formatCost(lot.costCents) const unitCost = formatUnitCost(lot) return (

{formatQuantity(lot.remaining)} / {formatQuantity(lot.quantity)} {lot.unit}

{lot.vendor && {lot.vendor}} {lot.packedForYear != null && packed for {lot.packedForYear}} {lot.purchasedAt && bought {lot.purchasedAt}} {lot.germinationPct != null && {lot.germinationPct}% germ.} {cost && {unitCost ? `${cost} (${unitCost})` : cost}}

{canEdit && (
)}
{lot.notes &&

{lot.notes}

}
) }