Refactor environment variable declarations, enhance image handling in item forms, and update asset references in SvelteKit project for improved functionality and performance.
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m53s

This commit is contained in:
eewing
2026-02-17 15:13:03 -06:00
parent 9022114c8d
commit 7ac169c1e4
238 changed files with 35126 additions and 1344 deletions
+1
View File
@@ -12,6 +12,7 @@ export interface StackqItem {
Has_Parent: boolean;
Parent: string; // relation id
Stock: boolean;
Image?: string; // file filename
created: string;
updated: string;
expand?: {
+12 -4
View File
@@ -45,11 +45,13 @@ export const actions: Actions = {
const Has_Parent = parseBool(form.get("Has_Parent"));
const Parent = (form.get("Parent") as string)?.trim() ?? "";
const Stock = parseBool(form.get("Stock"));
const imageFileCreate = form.get("Image") as File | null;
const hasImage = imageFileCreate && imageFileCreate.size > 0;
if (!Item) return fail(400, { error: "Item name is required", form: "create" });
try {
await locals.pb.collection(COLLECTION).create({
const body: Record<string, unknown> = {
Item,
SKU,
Description,
@@ -61,7 +63,9 @@ export const actions: Actions = {
Has_Parent: !!Has_Parent,
Parent: Parent || null,
Stock: !!Stock,
});
};
if (hasImage) body.Image = imageFileCreate;
await locals.pb.collection(COLLECTION).create(body);
} catch (e: unknown) {
const message = e && typeof e === "object" && "message" in e ? String((e as { message: string }).message) : "Create failed";
return fail(500, { error: message, form: "create" });
@@ -85,11 +89,13 @@ export const actions: Actions = {
const Has_Parent = parseBool(form.get("Has_Parent"));
const Parent = (form.get("Parent") as string)?.trim() ?? "";
const Stock = parseBool(form.get("Stock"));
const Image = form.get("Image") as File | null;
const imageFile = Image && Image.size > 0 ? Image : undefined;
if (!Item) return fail(400, { error: "Item name is required", form: "update" });
try {
await locals.pb.collection(COLLECTION).update(id, {
const body: Record<string, unknown> = {
Item,
SKU,
Description,
@@ -101,7 +107,9 @@ export const actions: Actions = {
Has_Parent: !!Has_Parent,
Parent: Parent || null,
Stock: !!Stock,
});
};
if (imageFile) body.Image = imageFile;
await locals.pb.collection(COLLECTION).update(id, body);
} catch (e: unknown) {
const message = e && typeof e === "object" && "message" in e ? String((e as { message: string }).message) : "Update failed";
return fail(500, { error: message, form: "update" });
+20 -1
View File
@@ -25,6 +25,12 @@
}
const items = $derived(data?.items ?? []);
const PB_BASE = "https://pocketbase.ccllc.pro";
const COLLECTION = "Stackq_Items";
function imageUrl(item: StackqItem): string | null {
if (!item.Image) return null;
return `${PB_BASE}/api/files/${COLLECTION}/${item.id}/${item.Image}`;
}
</script>
<svelte:head>
@@ -50,6 +56,7 @@
<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head>Image</Table.Head>
<Table.Head>Item</Table.Head>
<Table.Head>SKU</Table.Head>
<Table.Head class="max-w-[200px]">Description</Table.Head>
@@ -68,13 +75,25 @@
<Table.Body>
{#if items.length === 0}
<Table.Row>
<Table.Cell colspan="13" class="h-24 text-center text-muted-foreground">
<Table.Cell colspan="14" class="h-24 text-center text-muted-foreground">
No items.
</Table.Cell>
</Table.Row>
{:else}
{#each items as item (item.id)}
<Table.Row>
<Table.Cell class="w-16">
{#if imageUrl(item)}
<img
src={imageUrl(item)!}
alt=""
class="size-14 rounded border object-cover"
loading="lazy"
/>
{:else}
<span class="text-muted-foreground text-xs"></span>
{/if}
</Table.Cell>
<Table.Cell class="font-medium">{item.Item ?? "—"}</Table.Cell>
<Table.Cell class="font-mono text-xs">{item.SKU ?? "—"}</Table.Cell>
<Table.Cell class="max-w-[200px] truncate" title={item.Description ?? ""}>
+22
View File
@@ -4,9 +4,15 @@
import { Label } from "$lib/components/ui/label";
import { enhance } from "$app/forms";
import { Camera, X } from "@lucide/svelte";
import { pb } from "$lib/pocketbase";
import { UOM_OPTIONS, CATAGORY_OPTIONS, SUB_CATAGORY_OPTIONS } from "$lib/constants/items";
import type { StackqItem } from "$lib/types/items";
const COLLECTION = "Stackq_Items";
function itemImageUrl(recordId: string, filename: string): string {
return `${pb.baseUrl}/api/files/${COLLECTION}/${recordId}/${filename}`;
}
let {
item = null,
itemsForParent = [],
@@ -141,6 +147,7 @@
<form
method="POST"
action={action}
enctype="multipart/form-data"
use:enhance={() => async ({ update, result }) => {
await update();
if (result.type === "success" && result.data?.success) {
@@ -201,6 +208,21 @@
<Input id="Description" name="Description" value={defaultDesc} />
</div>
<div class="space-y-2">
<Label for="Image">Image</Label>
{#if isEdit && item?.Image}
<div class="flex flex-wrap items-center gap-3">
<img
src={itemImageUrl(item!.id, item!.Image)}
alt=""
class="size-20 rounded border object-cover"
/>
<span class="text-muted-foreground text-sm">Replace:</span>
</div>
{/if}
<Input id="Image" name="Image" type="file" accept="image/*" />
</div>
<div class="grid grid-cols-2 gap-4">
<div class="space-y-2">
<Label for="UOM">UOM</Label>
+28 -1
View File
@@ -26,6 +26,13 @@
const items = $derived(data?.items ?? []);
const itemsForParent = $derived(data?.itemsForParent ?? []);
const PB_BASE = "https://pocketbase.ccllc.pro";
const COLLECTION = "Stackq_Items";
function imageUrl(item: StackqItem): string | null {
if (!item.Image) return null;
return `${PB_BASE}/api/files/${COLLECTION}/${item.id}/${item.Image}`;
}
function asList(val: string | string[] | undefined): string[] {
if (val == null) return [];
return Array.isArray(val) ? val : [val];
@@ -92,6 +99,7 @@
<Table.Root>
<Table.Header>
<Table.Row>
<Table.Head>Image</Table.Head>
<Table.Head>Item</Table.Head>
<Table.Head>SKU</Table.Head>
<Table.Head class="max-w-[200px]">Description</Table.Head>
@@ -111,13 +119,32 @@
<Table.Body>
{#if items.length === 0}
<Table.Row>
<Table.Cell colspan="14" class="h-24 text-center text-muted-foreground">
<Table.Cell colspan="15" class="h-24 text-center text-muted-foreground">
No items. Create one or check PocketBase collection name and auth.
</Table.Cell>
</Table.Row>
{:else}
{#each items as item (item.id)}
<Table.Row>
<Table.Cell class="w-16">
{#if imageUrl(item)}
<a
href={imageUrl(item)!}
target="_blank"
rel="noopener noreferrer"
class="block overflow-hidden rounded border"
>
<img
src={imageUrl(item)!}
alt=""
class="size-14 object-cover"
loading="lazy"
/>
</a>
{:else}
<span class="text-muted-foreground text-xs"></span>
{/if}
</Table.Cell>
<Table.Cell class="font-medium">{item.Item ?? "—"}</Table.Cell>
<Table.Cell class="font-mono text-xs">{item.SKU ?? "—"}</Table.Cell>
<Table.Cell class="max-w-[200px] truncate" title={item.Description ?? ""}>