85 lines
2.7 KiB
JavaScript
85 lines
2.7 KiB
JavaScript
import express from 'express'
|
|
import cors from 'cors'
|
|
import dotenv from 'dotenv'
|
|
import { pool } from './db.js'
|
|
|
|
dotenv.config()
|
|
|
|
const app = express()
|
|
app.use(cors())
|
|
app.use(express.json())
|
|
|
|
// Simple health
|
|
app.get('/api/health', (req, res) => res.json({ ok: true }))
|
|
|
|
// List available cargobikes
|
|
app.get('/api/bikes', async (req, res) => {
|
|
// fixed bike types
|
|
const bikes = [1000, 2000, 3000, 4000, 5000]
|
|
res.json({ bikes })
|
|
})
|
|
|
|
// Create a booking
|
|
app.post('/api/bookings', async (req, res) => {
|
|
try {
|
|
const { bike_type, start_date, end_date, start_time, end_time, name, email } = req.body
|
|
if (!bike_type || !start_date || !end_date || !name || !email) {
|
|
return res.status(400).json({ error: 'Missing fields' })
|
|
}
|
|
|
|
const text = `INSERT INTO bookings(bike_type, start_date, start_time, end_date, end_time, name, email) VALUES($1, $2, $3, $4, $5, $6, $7) RETURNING *`
|
|
const values = [bike_type, start_date, start_time || null, end_date, end_time || null, name, email]
|
|
const result = await pool.query(text, values)
|
|
res.status(201).json({ booking: result.rows[0] })
|
|
} catch (err) {
|
|
console.error(err)
|
|
res.status(500).json({ error: 'Server error' })
|
|
}
|
|
})
|
|
|
|
// List bookings (simple)
|
|
app.get('/api/bookings', async (req, res) => {
|
|
try {
|
|
const result = await pool.query('SELECT * FROM bookings ORDER BY created_at DESC LIMIT 100')
|
|
res.json({ bookings: result.rows })
|
|
} catch (err) {
|
|
console.error(err)
|
|
res.status(500).json({ error: 'Server error' })
|
|
}
|
|
})
|
|
|
|
// --- ensure DB tables exist (auto-migration for dev) ---
|
|
async function ensureTables() {
|
|
const createSql = `
|
|
CREATE TABLE IF NOT EXISTS bookings (
|
|
id SERIAL PRIMARY KEY,
|
|
bike_type INTEGER NOT NULL,
|
|
start_date DATE NOT NULL,
|
|
start_time TIME,
|
|
end_date DATE NOT NULL,
|
|
end_time TIME,
|
|
name TEXT NOT NULL,
|
|
email TEXT NOT NULL,
|
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
|
|
);
|
|
`
|
|
|
|
try {
|
|
await pool.query(createSql)
|
|
// Ensure new columns exist if the table was created earlier without time columns
|
|
await pool.query(`ALTER TABLE bookings ADD COLUMN IF NOT EXISTS start_time TIME;`)
|
|
await pool.query(`ALTER TABLE bookings ADD COLUMN IF NOT EXISTS end_time TIME;`)
|
|
console.log('Database: bookings table is present (created if it did not exist)')
|
|
} catch (err) {
|
|
// If DATABASE_URL is not configured or DB not reachable, warn but still allow server to start for frontend dev
|
|
console.warn('Warning: could not ensure bookings table (DB may be unavailable).', err.message)
|
|
}
|
|
}
|
|
|
|
const port = process.env.PORT || 3000
|
|
|
|
// Run migrations (if possible) then start server
|
|
;(async () => {
|
|
await ensureTables()
|
|
app.listen(port, () => console.log(`Backend listening on port ${port}`))
|
|
})()
|