Initial commit: buildfor_life_repair inventory system
SvelteKit + PostgreSQL app for tracking vintage computers, audio equipment, components, and installation history. Features device/component CRUD, operation logs, QR code labels, global search, image uploads, and dark mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { devices, deviceImages, locations } from '$lib/server/db/schema.js';
|
||||
import { eq, ilike, or, count, desc, and, sql } from 'drizzle-orm';
|
||||
|
||||
export const load: PageServerLoad = async ({ url }) => {
|
||||
const category = url.searchParams.get('category');
|
||||
const condition = url.searchParams.get('condition');
|
||||
const search = url.searchParams.get('q');
|
||||
const page = Math.max(1, Number(url.searchParams.get('page') ?? 1));
|
||||
const pageSize = 24;
|
||||
|
||||
const conditions = [eq(devices.disabled, false)];
|
||||
|
||||
if (category) {
|
||||
conditions.push(eq(devices.category, category));
|
||||
}
|
||||
if (condition === 'needs-repair') {
|
||||
conditions.push(
|
||||
or(eq(devices.condition, 'In Repair'), eq(devices.condition, 'Waiting for Repair'))!
|
||||
);
|
||||
} else if (condition) {
|
||||
conditions.push(eq(devices.condition, condition));
|
||||
}
|
||||
if (search) {
|
||||
conditions.push(
|
||||
or(
|
||||
ilike(devices.title, `%${search}%`),
|
||||
ilike(devices.brand, `%${search}%`),
|
||||
ilike(devices.model, `%${search}%`),
|
||||
ilike(devices.serialNumber, `%${search}%`)
|
||||
)!
|
||||
);
|
||||
}
|
||||
|
||||
const where = conditions.length > 0 ? and(...conditions) : undefined;
|
||||
|
||||
const [totalResult] = await db.select({ value: count() }).from(devices).where(where);
|
||||
const total = totalResult?.value ?? 0;
|
||||
|
||||
const deviceList = await db
|
||||
.select({
|
||||
id: devices.id,
|
||||
title: devices.title,
|
||||
category: devices.category,
|
||||
brand: devices.brand,
|
||||
model: devices.model,
|
||||
condition: devices.condition,
|
||||
year: devices.year,
|
||||
locationName: locations.name
|
||||
})
|
||||
.from(devices)
|
||||
.leftJoin(locations, eq(devices.locationId, locations.id))
|
||||
.where(where)
|
||||
.orderBy(desc(devices.updatedAt))
|
||||
.limit(pageSize)
|
||||
.offset((page - 1) * pageSize);
|
||||
|
||||
// Fetch first image for each device
|
||||
const deviceIds = deviceList.map((d) => d.id);
|
||||
let imageMap: Record<string, string> = {};
|
||||
if (deviceIds.length > 0) {
|
||||
const images = await db
|
||||
.select({
|
||||
deviceId: deviceImages.deviceId,
|
||||
thumbnailPath: deviceImages.thumbnailPath,
|
||||
filePath: deviceImages.filePath
|
||||
})
|
||||
.from(deviceImages)
|
||||
.where(sql`${deviceImages.deviceId} IN ${deviceIds}`)
|
||||
.orderBy(deviceImages.sortOrder);
|
||||
|
||||
for (const img of images) {
|
||||
if (!imageMap[img.deviceId]) {
|
||||
imageMap[img.deviceId] = img.thumbnailPath ?? img.filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
devices: deviceList.map((d) => ({
|
||||
...d,
|
||||
thumbnail: imageMap[d.id] ?? null
|
||||
})),
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
filters: { category, condition, search }
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user