83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { auth } from "@/auth";
|
|
import { db } from "@/lib/db";
|
|
import { redirect } from "next/navigation";
|
|
import { distanceKm } from "@/lib/geo";
|
|
import { ItemsTable } from "./items-table";
|
|
import type { Metadata } from "next";
|
|
|
|
export const metadata: Metadata = { title: "Browse Items" };
|
|
|
|
interface Props {
|
|
searchParams: Promise<{ siteId?: string }>;
|
|
}
|
|
|
|
export default async function InventoryItemsPage({ searchParams }: Props) {
|
|
const session = await auth();
|
|
if (!session?.user) redirect("/login");
|
|
|
|
const { siteId } = await searchParams;
|
|
|
|
const [site, products, sites] = await Promise.all([
|
|
siteId
|
|
? db.site.findUnique({
|
|
where: { id: siteId, isActive: true },
|
|
select: { id: true, name: true, latitude: true, longitude: true },
|
|
})
|
|
: Promise.resolve(null),
|
|
db.product.findMany({
|
|
where: { isActive: true },
|
|
include: {
|
|
vendorPrices: {
|
|
where: { vendor: { isActive: true } },
|
|
include: {
|
|
vendor: {
|
|
select: { id: true, name: true, isVerified: true, latitude: true, longitude: true },
|
|
},
|
|
},
|
|
orderBy: { price: "asc" },
|
|
},
|
|
},
|
|
orderBy: { name: "asc" },
|
|
}),
|
|
db.site.findMany({
|
|
where: { isActive: true },
|
|
orderBy: { name: "asc" },
|
|
select: { id: true, name: true, code: true },
|
|
}),
|
|
]);
|
|
|
|
const items = products.map((p) => ({
|
|
id: p.id,
|
|
code: p.code,
|
|
name: p.name,
|
|
description: p.description ?? "",
|
|
vendors: p.vendorPrices.map((vp) => {
|
|
let dist: number | null = null;
|
|
if (site?.latitude && site.longitude && vp.vendor.latitude && vp.vendor.longitude) {
|
|
dist = distanceKm(site.latitude, site.longitude, vp.vendor.latitude, vp.vendor.longitude);
|
|
}
|
|
return {
|
|
vendorId: vp.vendor.id,
|
|
vendorName: vp.vendor.name,
|
|
isVerified: vp.vendor.isVerified,
|
|
price: Number(vp.price),
|
|
distanceKm: dist,
|
|
};
|
|
}),
|
|
}));
|
|
|
|
return (
|
|
<div className="max-w-6xl">
|
|
<div className="mb-6">
|
|
<h1 className="text-2xl font-semibold text-neutral-900">Browse Items</h1>
|
|
<p className="mt-1 text-sm text-neutral-500">Search the catalogue and add items to your cart.</p>
|
|
</div>
|
|
<ItemsTable
|
|
items={items}
|
|
hasSite={!!site}
|
|
sites={sites}
|
|
currentSiteId={siteId ?? null}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|