From 4919b1d4e411c59655519335e7f7a68c9c61cf3c Mon Sep 17 00:00:00 2001 From: Hardik Date: Fri, 15 May 2026 00:54:54 +0530 Subject: [PATCH] feat(inventory): inline site selector above items table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Items page now fetches all active sites and passes them alongside preferredSiteId to ItemsTable. A "Working Site" row appears at the top of the table — selecting a site calls setPreferredSite, revalidates the page, and shows distances in the vendor sub-rows. A status hint ("Distances shown from selected site") appears when a site is active; "No site selected — distances hidden" is the empty-state label. Co-Authored-By: Claude Sonnet 4.6 --- .../(portal)/inventory/items/items-table.tsx | 43 ++++++++++++++++++- .../app/(portal)/inventory/items/page.tsx | 23 +++++----- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/App/pelagia-portal/app/(portal)/inventory/items/items-table.tsx b/App/pelagia-portal/app/(portal)/inventory/items/items-table.tsx index cdf05d9..f78164f 100644 --- a/App/pelagia-portal/app/(portal)/inventory/items/items-table.tsx +++ b/App/pelagia-portal/app/(portal)/inventory/items/items-table.tsx @@ -1,9 +1,10 @@ "use client"; -import { useState, useMemo } from "react"; +import { useState, useMemo, useTransition } from "react"; import { Search, X, ChevronDown, ChevronRight, MapPin, Tag } from "lucide-react"; import { formatCurrency } from "@/lib/utils"; import { addToCart } from "@/lib/cart"; +import { setPreferredSite } from "@/app/actions/site-preference"; type VendorOption = { vendorId: string; @@ -25,11 +26,24 @@ function formatDist(km: number) { return km < 1 ? `${Math.round(km * 1000)} m` : `${km.toFixed(0)} km`; } -export function ItemsTable({ items, hasSite }: { items: CatalogItem[]; hasSite: boolean }) { +type SiteOption = { id: string; name: string; code: string }; + +export function ItemsTable({ + items, + hasSite, + sites = [], + preferredSiteId = null, +}: { + items: CatalogItem[]; + hasSite: boolean; + sites?: SiteOption[]; + preferredSiteId?: string | null; +}) { const [query, setQuery] = useState(""); const [expandedId, setExpandedId] = useState(null); const [sortBy, setSortBy] = useState<"distance" | "price">(hasSite ? "distance" : "price"); const [added, setAdded] = useState>({}); + const [sitePending, startSiteTransition] = useTransition(); const filtered = useMemo(() => { const q = query.toLowerCase().trim(); @@ -79,6 +93,31 @@ export function ItemsTable({ items, hasSite }: { items: CatalogItem[]; hasSite: return (
+ {/* Site selector */} + {sites.length > 0 && ( +
+ + + + {sitePending && Updating…} + {!sitePending && preferredSiteId && ( + Distances shown from selected site + )} +
+ )} + {/* Toolbar */}
diff --git a/App/pelagia-portal/app/(portal)/inventory/items/page.tsx b/App/pelagia-portal/app/(portal)/inventory/items/page.tsx index 775a04a..de81fd7 100644 --- a/App/pelagia-portal/app/(portal)/inventory/items/page.tsx +++ b/App/pelagia-portal/app/(portal)/inventory/items/page.tsx @@ -11,7 +11,7 @@ export default async function InventoryItemsPage() { const session = await auth(); if (!session?.user) redirect("/login"); - const [user, products] = await Promise.all([ + const [user, products, sites] = await Promise.all([ db.user.findUnique({ where: { id: session.user.id }, include: { @@ -33,6 +33,11 @@ export default async function InventoryItemsPage() { }, orderBy: { name: "asc" }, }), + db.site.findMany({ + where: { isActive: true }, + orderBy: { name: "asc" }, + select: { id: true, name: true, code: true }, + }), ]); const site = user?.preferredSite ?? null; @@ -61,16 +66,14 @@ export default async function InventoryItemsPage() {

Browse Items

-

- Search the catalogue and add items to your cart. - {site ? ( - Distances shown from {site.name}. - ) : ( - Select a site in the header to enable distance sorting. - )} -

+

Search the catalogue and add items to your cart.

- +
); }