From 7570b57d3374b86f201eaff1770ee745bb952229 Mon Sep 17 00:00:00 2001 From: vidane Date: Sat, 2 May 2026 18:03:39 -0400 Subject: [PATCH] Add src/app/api/projects/route.ts --- src/app/api/projects/route.ts | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/app/api/projects/route.ts diff --git a/src/app/api/projects/route.ts b/src/app/api/projects/route.ts new file mode 100644 index 0000000..0e1d2bd --- /dev/null +++ b/src/app/api/projects/route.ts @@ -0,0 +1,60 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { getDb } from '@/server/db'; +import { projects } from '@/server/db/schema'; +import { asc } from 'drizzle-orm'; + +export async function GET() { + const db = getDb(); + + try { + const result = await db + .select() + .from(projects) + .orderBy(asc(projects.sortOrder)); + + return NextResponse.json(result); + } catch (error) { + console.error('Error fetching projects:', error); + return NextResponse.json({ error: 'Failed to fetch projects' }, { status: 500 }); + } +} + +export async function POST(request: NextRequest) { + const db = getDb(); + let body; + + try { + body = await request.json(); + } catch { + return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 }); + } + + const { name, description = '', color = '#3b82f6' } = body; + + if (!name?.trim()) { + return NextResponse.json({ error: 'Name is required' }, { status: 400 }); + } + + try { + // Get max sort order + const maxSort = await db + .select({ max: projects.sortOrder }) + .from(projects) + .limit(1); + + const [newProject] = await db + .insert(projects) + .values({ + name: name.trim(), + description: description?.trim() || '', + color, + sortOrder: (maxSort[0]?.max ?? -1) + 1, + }) + .returning(); + + return NextResponse.json(newProject, { status: 201 }); + } catch (error) { + console.error('Error creating project:', error); + return NextResponse.json({ error: 'Failed to create project' }, { status: 500 }); + } +}