diff --git a/src/app/api/inventory/[id]/route.ts b/src/app/api/inventory/[id]/route.ts index b2ed152..9b58e2e 100644 --- a/src/app/api/inventory/[id]/route.ts +++ b/src/app/api/inventory/[id]/route.ts @@ -34,7 +34,7 @@ export async function PUT( ) { try { const { id } = await params; - const { name, quantity, value, location } = await request.json(); + const { name, quantity, value, location, status } = await request.json(); if (!name || quantity === undefined || value === undefined) { return NextResponse.json( @@ -58,6 +58,7 @@ export async function PUT( quantity, value, location || '', + status || 'active', id ); @@ -81,13 +82,17 @@ export async function PUT( if (currentItem.location !== (location || '')) { auditQueries.create.run(id, 'UPDATE', 'location', currentItem.location || '', location || ''); } + if (currentItem.status !== (status || 'active')) { + auditQueries.create.run(id, 'UPDATE', 'status', currentItem.status || 'active', status || 'active'); + } return NextResponse.json({ id: id, name, quantity, value, - location: location || '' + location: location || '', + status: status || 'active' }); } catch (error) { console.error('Error updating inventory item:', error); diff --git a/src/app/api/inventory/route.ts b/src/app/api/inventory/route.ts index fa36d6b..564eca3 100644 --- a/src/app/api/inventory/route.ts +++ b/src/app/api/inventory/route.ts @@ -2,9 +2,18 @@ import { NextRequest, NextResponse } from 'next/server'; import { inventoryQueries, auditQueries } from '@/lib/database'; // GET /api/inventory - Get all inventory items -export async function GET() { +export async function GET(request: NextRequest) { try { - const items = inventoryQueries.getAll.all(); + const { searchParams } = new URL(request.url); + const status = searchParams.get('status'); + + let items; + if (status) { + items = inventoryQueries.getByStatus.all(status); + } else { + items = inventoryQueries.getActive.all(); // Default to active items only + } + return NextResponse.json(items); } catch (error) { console.error('Error fetching inventory:', error); @@ -18,7 +27,7 @@ export async function GET() { // POST /api/inventory - Create new inventory item export async function POST(request: NextRequest) { try { - const { name, quantity, value, location } = await request.json(); + const { name, quantity, value, location, status } = await request.json(); if (!name || quantity === undefined || value === undefined) { return NextResponse.json( @@ -27,7 +36,7 @@ export async function POST(request: NextRequest) { ); } - const result = inventoryQueries.create.run(name, quantity, value, location || ''); + const result = inventoryQueries.create.run(name, quantity, value, location || '', status || 'active'); const itemId = result.lastInsertRowid; // Log the creation @@ -39,7 +48,8 @@ export async function POST(request: NextRequest) { name, quantity, value, - location: location || '' + location: location || '', + status: status || 'active' }, { status: 201 } ); diff --git a/src/app/api/users/route.ts b/src/app/api/users/route.ts new file mode 100644 index 0000000..70bc98c --- /dev/null +++ b/src/app/api/users/route.ts @@ -0,0 +1,48 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { userQueries } from '@/lib/database'; + +export async function GET() { + try { + const users = userQueries.getAll.all(); + return NextResponse.json(users); + } catch (error) { + console.error('Error fetching users:', error); + return NextResponse.json( + { error: 'Failed to fetch users' }, + { status: 500 } + ); + } +} + +export async function POST(request: NextRequest) { + try { + const { name, email } = await request.json(); + + if (!name || !email) { + return NextResponse.json( + { error: 'Name and email are required' }, + { status: 400 } + ); + } + + // Check if user already exists + const existingUser = userQueries.getByEmail.get(email); + if (existingUser) { + return NextResponse.json( + { error: 'User with this email already exists' }, + { status: 409 } + ); + } + + const result = userQueries.create.run(name, email); + const newUser = userQueries.getById.get(result.lastInsertRowid); + + return NextResponse.json(newUser, { status: 201 }); + } catch (error) { + console.error('Error creating user:', error); + return NextResponse.json( + { error: 'Failed to create user' }, + { status: 500 } + ); + } +} diff --git a/src/app/globals.css b/src/app/globals.css index dc98be7..efa8047 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -3,6 +3,56 @@ @custom-variant dark (&:is(.dark *)); +/* Mobile-friendly touch targets and scrolling */ +html { + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + overscroll-behavior-y: none; +} + +/* Better touch targets */ +.touch-manipulation { + touch-action: manipulation; + -webkit-tap-highlight-color: transparent; +} + +/* Smooth scrolling for mobile */ +* { + -webkit-overflow-scrolling: touch; +} + +/* Prevent zoom on inputs on iOS */ +input[type="text"], +input[type="number"], +input[type="email"], +input[type="password"], +select, +textarea { + font-size: 16px; +} + +@media (max-width: 640px) { + /* Larger touch targets on mobile */ + button, + input[type="button"], + input[type="submit"], + input[type="checkbox"], + select { + min-height: 44px; + } + + /* Better spacing for mobile */ + .container { + padding-left: 1rem; + padding-right: 1rem; + } +} + @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); diff --git a/src/app/inventory/[id]/page.tsx b/src/app/inventory/[id]/page.tsx index f158435..5227711 100644 --- a/src/app/inventory/[id]/page.tsx +++ b/src/app/inventory/[id]/page.tsx @@ -9,6 +9,7 @@ interface InventoryItem { quantity: number; value: number; location: string; + status: string; created_at: string; updated_at: string; } @@ -34,7 +35,8 @@ export default function ItemPage({ params }: { params: Promise<{ id: string }> } name: '', quantity: 0, value: 0, - location: '' + location: '', + status: 'active' }); // Initialize item ID from params @@ -59,7 +61,8 @@ export default function ItemPage({ params }: { params: Promise<{ id: string }> } name: data.name, quantity: data.quantity, value: data.value, - location: data.location + location: data.location, + status: data.status || 'active' }); } else { console.error('Item not found'); @@ -129,7 +132,8 @@ export default function ItemPage({ params }: { params: Promise<{ id: string }> } name: item.name, quantity: item.quantity, value: item.value, - location: item.location + location: item.location, + status: item.status || 'active' }); } setIsEditing(false); @@ -183,33 +187,33 @@ export default function ItemPage({ params }: { params: Promise<{ id: string }> } } return ( -
{item.quantity}
+{item.quantity}
+${item.value.toFixed(2)}
+${item.value.toFixed(2)}
+ +{item.location || 'Not specified'}
++ {item.status === 'checked-out' ? 'Checked Out' : + item.status === 'used-up' ? 'Used Up' : + item.status === 'active' ? 'Active' : + item.status} +
+${(item.quantity * item.value).toFixed(2)}
+{item.location || 'Not specified'}
+ + {/* Desktop Layout */} +{item.quantity}
+${item.value.toFixed(2)}
+${(item.quantity * item.value).toFixed(2)}
+{item.location || 'Not specified'}
++ {item.status === 'checked-out' ? 'Checked Out' : + item.status === 'used-up' ? 'Used Up' : + item.status === 'active' ? 'Active' : + item.status} +
+${(item.quantity * item.value).toFixed(2)}
+No changes recorded for this item.
+No changes recorded for this item.
) : ( -