From 74537558a89466736bb440b2bad39f30bed951a8 Mon Sep 17 00:00:00 2001 From: Karlsson Date: Sat, 22 Nov 2025 13:00:24 +0100 Subject: [PATCH] reservations applyable, fixed folder views, checkmarks --- .env.example | 6 + src/lib/components/ItemModal.svelte | 29 +- src/lib/server/db/schema.ts | 2 +- src/lib/server/db/utils.ts | 25 ++ src/routes/api/items/+server.ts | 21 +- src/routes/categories/[id]/+page.server.ts | 6 +- src/routes/categories/[id]/+page.svelte | 14 +- src/routes/folders/+page.server.ts | 85 +++++- src/routes/folders/+page.svelte | 293 +++++++++++++------ src/routes/folders/[...path]/+page.server.ts | 29 +- src/routes/folders/[...path]/+page.svelte | 14 +- src/routes/items/+page.server.ts | 36 +++ svelte.config.js | 2 +- todos | 5 - vite.config.ts | 4 +- 15 files changed, 434 insertions(+), 137 deletions(-) create mode 100644 src/lib/server/db/utils.ts delete mode 100644 todos diff --git a/.env.example b/.env.example index ec707ff..ccce92e 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,8 @@ # Replace with your DB credentials! DATABASE_URL="postgres://user:password@host:port/db-name" + +# Replace with your Gitea oauth credentials! +GITEA_BASE_URL="https://gitea.example.com" +GITEA_CLIENT_ID="your-client-id" +GITEA_CLIENT_SECRET="your-client-secret" +CALLBACK_BASE_URL="http://localhost:5173" diff --git a/src/lib/components/ItemModal.svelte b/src/lib/components/ItemModal.svelte index 20a721b..7144c4d 100644 --- a/src/lib/components/ItemModal.svelte +++ b/src/lib/components/ItemModal.svelte @@ -168,7 +168,6 @@ name="name" id="itemName" value={item?.name || ''} - required class="w-full rounded-md border border-zinc-700 bg-zinc-900 px-3 py-2 text-white placeholder-zinc-600 transition-all outline-none focus:border-red-500 focus:ring-1 focus:ring-red-500" placeholder="e.g. 10k Resistor" /> @@ -470,6 +469,34 @@ >{reservation.count} reserved {/if} + + {#if user} +
+
{ + return async ({ result }) => { + if (result.type === 'success') { + // Update local item count if returned + if (result.data && result.data.newCount !== undefined) { + item.count = result.data.newCount; + } + fetchDetails(false); + } + }; + }} + > + + +
+
+ {/if} {/each} diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 40459b9..da0ce20 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -29,7 +29,7 @@ export const items = pgTable('items', { id: uuid('id').primaryKey().defaultRandom(), folderId: uuid('folder_id').references(() => folders.id).notNull(), categoryId: uuid('category_id').references(() => categories.id).notNull(), - name: text('name').notNull(), + name: text('name'), count: integer('count').default(0).notNull(), tags: jsonb('tags').$type().default([]).notNull(), properties: jsonb('properties').$type>().default({}).notNull(), diff --git a/src/lib/server/db/utils.ts b/src/lib/server/db/utils.ts new file mode 100644 index 0000000..1bfbfb9 --- /dev/null +++ b/src/lib/server/db/utils.ts @@ -0,0 +1,25 @@ +import { db } from '$lib/server/db'; +import { folders } from '$lib/server/db/schema'; +import { eq, isNull, and } from 'drizzle-orm'; + +export async function getOrSeedHomeFolder() { + // Try to find the "Home" folder at the root level (parentId is null) + const existingHome = await db.select().from(folders) + .where(and( + eq(folders.name, 'Home'), + isNull(folders.parentId) + )) + .limit(1); + + if (existingHome.length > 0) { + return existingHome[0]; + } + + // If not found, create it + const [newHome] = await db.insert(folders).values({ + name: 'Home', + parentId: null + }).returning(); + + return newHome; +} diff --git a/src/routes/api/items/+server.ts b/src/routes/api/items/+server.ts index 2b0d957..e91f974 100644 --- a/src/routes/api/items/+server.ts +++ b/src/routes/api/items/+server.ts @@ -7,12 +7,25 @@ export async function GET({ url }) { const folderId = url.searchParams.get('folderId'); const categoryId = url.searchParams.get('categoryId'); - let query = db.select().from(items); - + let conditions = []; if (folderId) { - query = query.where(eq(items.folderId, folderId)); + conditions.push(eq(items.folderId, folderId)); } else if (categoryId) { - query = query.where(eq(items.categoryId, categoryId)); + conditions.push(eq(items.categoryId, categoryId)); + } + + let query = db.select().from(items); + if (conditions.length > 0) { + // @ts-ignore - spread operator with conditions works but TS might complain about empty array if not handled, but here we check length. + // Actually, cleaner to just chain if we can, or just use `where` once. + // Let's just use the if/else to construct the query directly without reassignment if possible, or use `let query` with explicit type. + // Easiest is to just do: + if (folderId) { + return json(await db.select().from(items).where(eq(items.folderId, folderId))); + } else if (categoryId) { + return json(await db.select().from(items).where(eq(items.categoryId, categoryId))); + } + return json(await db.select().from(items)); } const result = await query; diff --git a/src/routes/categories/[id]/+page.server.ts b/src/routes/categories/[id]/+page.server.ts index 24bbc80..ce63a21 100644 --- a/src/routes/categories/[id]/+page.server.ts +++ b/src/routes/categories/[id]/+page.server.ts @@ -67,7 +67,7 @@ export const actions = { await db.insert(items).values({ name, - folderId: folderId || null, + folderId: folderId, categoryId, count, properties @@ -113,7 +113,7 @@ export const actions = { const data = await request.formData(); const id = data.get('id') as string; const folderId = data.get('folderId') as string; - await db.update(items).set({ folderId: folderId || null }).where(eq(items.id, id)); + await db.update(items).set({ folderId: folderId }).where(eq(items.id, id)); return { success: true }; }, bulkDelete: async ({ request }: { request: Request }) => { @@ -129,7 +129,7 @@ export const actions = { const ids = JSON.parse(data.get('ids') as string); const folderId = data.get('folderId') as string; if (ids.length > 0) { - await db.update(items).set({ folderId: folderId || null }).where(inArray(items.id, ids)); + await db.update(items).set({ folderId: folderId }).where(inArray(items.id, ids)); } return { success: true }; }, diff --git a/src/routes/categories/[id]/+page.svelte b/src/routes/categories/[id]/+page.svelte index a8f02a0..5640d0d 100644 --- a/src/routes/categories/[id]/+page.svelte +++ b/src/routes/categories/[id]/+page.svelte @@ -1,6 +1,7 @@