v0.15.0 — Inventory depth (HomeBox parity) + Locations page

Rounds out Inventory toward HomeBox, and gives Locations a real home.

Inventory:
- Attach manuals, receipts, and warranty docs (any file), not just photos —
  attachment uploader now has a kind picker; WARRANTY kind added
- Richer purchase/warranty: purchasedFrom, warrantyDetails, lifetimeWarranty,
  insured (item dialog + detail facts + header badge)
- Schedule recurring maintenance from an item (creates a Task linked via
  itemId); item detail shows its maintenance with overdue flagged. Task create
  now accepts itemId/animalId

Locations:
- New Locations page + nav: browse/add/rename/move/delete the whole place tree
  (LocationManager over the existing /api/locations routes); shows plant/item
  counts per place. The spot to merge near-dupes before dropping legacy zone

Verified end-to-end against a running server (new fields round-trip, maintenance
task links to item, MANUAL attachment stored). tsc + 33 tests + build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-16 00:34:07 -05:00
parent cffa739056
commit 63569aabd3
15 changed files with 481 additions and 21 deletions

View File

@@ -0,0 +1,35 @@
import { db } from "@/lib/db";
import { LocationManager } from "@/components/locations/location-manager";
export const metadata = { title: "Locations" };
export default async function LocationsPage() {
const locations = await db.location.findMany({
where: { active: true },
orderBy: { name: "asc" },
select: {
id: true,
name: true,
kind: true,
parentId: true,
_count: {
select: {
plants: { where: { active: true } },
items: { where: { active: true } },
},
},
},
});
return (
<div className="space-y-6 max-w-2xl">
<div>
<h1 className="font-display text-2xl font-semibold">Locations</h1>
<p className="text-sm text-muted-foreground mt-0.5">
Manage the places on your property nest them as deep as you like.
</p>
</div>
<LocationManager locations={locations} />
</div>
);
}