import { Router, Response } from 'express'; import db from '../database'; import { AuthRequest } from '../middleware/auth'; const router = Router(); // List appointments router.get('/', (req: AuthRequest, res: Response) => { try { const { status, date, ownerId } = req.query; let query = ` SELECT a.*, o.first_name as owner_first_name, o.last_name as owner_last_name, o.phone as owner_phone, v.year, v.make, v.model FROM appointments a LEFT JOIN owners o ON a.owner_id = o.id LEFT JOIN vehicles v ON a.vehicle_id = v.id `; const conditions: string[] = []; const params: any[] = []; if (status) { conditions.push('a.status = ?'); params.push(status); } if (date) { conditions.push('a.requested_date = ?'); params.push(date); } if (ownerId) { conditions.push('a.owner_id = ?'); params.push(Number(ownerId)); } if (conditions.length > 0) query += ' WHERE ' + conditions.join(' AND '); query += ' ORDER BY a.requested_date ASC, a.requested_time ASC'; const appointments = db.prepare(query).all(...params); res.json(appointments); } catch (error: any) { res.status(500).json({ error: error.message }); } }); // Get appointment router.get('/:id', (req: AuthRequest, res: Response) => { try { const appointment = db.prepare(` SELECT a.*, o.first_name as owner_first_name, o.last_name as owner_last_name, o.phone as owner_phone, o.email as owner_email, v.year, v.make, v.model FROM appointments a LEFT JOIN owners o ON a.owner_id = o.id LEFT JOIN vehicles v ON a.vehicle_id = v.id WHERE a.id = ? `).get(req.params.id); if (!appointment) return res.status(404).json({ error: 'Appointment not found' }); res.json(appointment); } catch (error: any) { res.status(500).json({ error: error.message }); } }); // Create appointment router.post('/', (req: AuthRequest, res: Response) => { try { const { ownerId, shopId, vehicleId, serviceDescription, requestedDate, requestedTime, durationMinutes, notes } = req.body; if (!requestedDate) return res.status(400).json({ error: 'Requested date required' }); const result = db.prepare(` INSERT INTO appointments (owner_id, shop_id, vehicle_id, service_description, requested_date, requested_time, duration_minutes, notes) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `).run(ownerId || null, shopId || null, vehicleId || null, serviceDescription || null, requestedDate, requestedTime || null, durationMinutes || 60, notes || null); const appointment = db.prepare('SELECT * FROM appointments WHERE id = ?').get(result.lastInsertRowid); res.status(201).json(appointment); } catch (error: any) { res.status(500).json({ error: error.message }); } }); // Update appointment router.put('/:id', (req: AuthRequest, res: Response) => { try { const appt = db.prepare('SELECT * FROM appointments WHERE id = ?').get(req.params.id) as any; if (!appt) return res.status(404).json({ error: 'Appointment not found' }); const { ownerId, vehicleId, serviceDescription, requestedDate, requestedTime, durationMinutes, status, notes } = req.body; db.prepare(` UPDATE appointments SET owner_id = ?, vehicle_id = ?, service_description = ?, requested_date = ?, requested_time = ?, duration_minutes = ?, status = ?, notes = ?, updated_at = datetime('now') WHERE id = ? `).run( ownerId !== undefined ? (ownerId || null) : appt.owner_id, vehicleId !== undefined ? (vehicleId || null) : appt.vehicle_id, serviceDescription ?? appt.service_description, requestedDate ?? appt.requested_date, requestedTime ?? appt.requested_time, durationMinutes ?? appt.duration_minutes, status ?? appt.status, notes ?? appt.notes, appt.id, ); const updated = db.prepare('SELECT * FROM appointments WHERE id = ?').get(appt.id); res.json(updated); } catch (error: any) { res.status(500).json({ error: error.message }); } }); // Delete appointment router.delete('/:id', (req: AuthRequest, res: Response) => { try { db.prepare('DELETE FROM appointments WHERE id = ?').run(req.params.id); res.json({ success: true }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); // --- Deferred Services --- router.get('/deferred', (req: AuthRequest, res: Response) => { try { const { status, vehicleId } = req.query; let query = ` SELECT d.*, o.first_name as owner_first_name, o.last_name as owner_last_name, v.year, v.make, v.model, j.job_number FROM deferred_services d LEFT JOIN owners o ON d.owner_id = o.id LEFT JOIN vehicles v ON d.vehicle_id = v.id LEFT JOIN jobs j ON d.job_id = j.id `; const conditions: string[] = []; const params: any[] = []; if (status) { conditions.push('d.status = ?'); params.push(status); } if (vehicleId) { conditions.push('d.vehicle_id = ?'); params.push(Number(vehicleId)); } if (conditions.length > 0) query += ' WHERE ' + conditions.join(' AND '); query += ' ORDER BY d.follow_up_date ASC'; const deferred = db.prepare(query).all(...params); res.json(deferred); } catch (error: any) { res.status(500).json({ error: error.message }); } }); router.post('/deferred', (req: AuthRequest, res: Response) => { try { const { jobId, vehicleId, ownerId, description, reason, followUpDate } = req.body; if (!description) return res.status(400).json({ error: 'Description required' }); const result = db.prepare(` INSERT INTO deferred_services (job_id, vehicle_id, owner_id, description, reason, follow_up_date) VALUES (?, ?, ?, ?, ?, ?) `).run(jobId || null, vehicleId || null, ownerId || null, description, reason || null, followUpDate || null); const deferred = db.prepare('SELECT * FROM deferred_services WHERE id = ?').get(result.lastInsertRowid); res.status(201).json(deferred); } catch (error: any) { res.status(500).json({ error: error.message }); } }); router.put('/deferred/:id', (req: AuthRequest, res: Response) => { try { const existing = db.prepare('SELECT * FROM deferred_services WHERE id = ?').get(req.params.id) as any; if (!existing) return res.status(404).json({ error: 'Deferred service not found' }); const { status, followUpDate } = req.body; db.prepare('UPDATE deferred_services SET status = ?, follow_up_date = ? WHERE id = ?') .run(status ?? existing.status, followUpDate ?? existing.follow_up_date, existing.id); const updated = db.prepare('SELECT * FROM deferred_services WHERE id = ?').get(existing.id); res.json(updated); } catch (error: any) { res.status(500).json({ error: error.message }); } }); router.delete('/deferred/:id', (req: AuthRequest, res: Response) => { try { db.prepare('DELETE FROM deferred_services WHERE id = ?').run(req.params.id); res.json({ success: true }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); export default router;