Seed shelf UI: source links, lots, and what's left (#51) (#68)
Build image / build-and-push (push) Successful in 11s

Co-authored-by: Steve Dudenhoeffer <[email protected]>
This commit was merged in pull request #68.
This commit is contained in:
2026-07-21 06:03:12 +00:00
committed by steve
parent 7f8b5254d0
commit 5d9b10d7c7
15 changed files with 1067 additions and 11 deletions
+15
View File
@@ -7,8 +7,11 @@ import { CategoryChips } from '@/components/plants/CategoryChips'
import { PlantCard } from '@/components/plants/PlantCard'
import { PlantFormModal } from '@/components/plants/PlantFormModal'
import { DeletePlantModal } from '@/components/plants/DeletePlantModal'
import { SeedLotModal } from '@/components/plants/SeedLotModal'
import { DeleteSeedLotModal } from '@/components/plants/DeleteSeedLotModal'
import { PlantPicker } from '@/editor/PlantPicker'
import { filterPlants, usePlants, type CategoryFilter, type Plant } from '@/lib/plants'
import { lotsByPlant, useSeedLots, type SeedLot } from '@/lib/seedLots'
import type { UnitPref } from '@/lib/units'
import { usePageTitle } from '@/lib/usePageTitle'
@@ -19,6 +22,9 @@ type Dialog =
| { kind: 'duplicate'; plant: Plant }
| { kind: 'delete'; plant: Plant }
| { kind: 'picker' }
| { kind: 'addLot'; plant: Plant }
| { kind: 'editLot'; plant: Plant; lot: SeedLot }
| { kind: 'deleteLot'; lot: SeedLot }
| null
// There's no per-user unit preference server-side (only per-garden), so the
@@ -35,6 +41,8 @@ function loadUnit(): UnitPref {
export function PlantsPage() {
usePageTitle('Plants')
const plants = usePlants()
const seedLots = useSeedLots()
const lots = useMemo(() => lotsByPlant(seedLots.data), [seedLots.data])
const [unit, setUnit] = useState<UnitPref>(() => loadUnit())
const [query, setQuery] = useState('')
const [category, setCategory] = useState<CategoryFilter>('all')
@@ -108,9 +116,13 @@ export function PlantsPage() {
key={p.id}
plant={p}
unit={unit}
lots={lots.get(p.id) ?? []}
onEdit={() => setDialog({ kind: 'edit', plant: p })}
onDelete={() => setDialog({ kind: 'delete', plant: p })}
onDuplicate={() => setDialog({ kind: 'duplicate', plant: p })}
onAddLot={() => setDialog({ kind: 'addLot', plant: p })}
onEditLot={(lot) => setDialog({ kind: 'editLot', plant: p, lot })}
onDeleteLot={(lot) => setDialog({ kind: 'deleteLot', lot })}
/>
))}
</div>
@@ -121,6 +133,9 @@ export function PlantsPage() {
{dialog?.kind === 'edit' && <PlantFormModal plant={dialog.plant} unit={unit} onClose={close} />}
{dialog?.kind === 'duplicate' && <PlantFormModal template={dialog.plant} unit={unit} onClose={close} />}
{dialog?.kind === 'delete' && <DeletePlantModal plant={dialog.plant} onClose={close} />}
{dialog?.kind === 'addLot' && <SeedLotModal plant={dialog.plant} onClose={close} />}
{dialog?.kind === 'editLot' && <SeedLotModal plant={dialog.plant} lot={dialog.lot} onClose={close} />}
{dialog?.kind === 'deleteLot' && <DeleteSeedLotModal lot={dialog.lot} onClose={close} />}
{dialog?.kind === 'picker' && (
<PlantPicker
unit={unit}