89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
const express = require('express');
|
|
const { Pool } = require('pg');
|
|
const path = require('path');
|
|
|
|
const app = express();
|
|
app.use(express.json());
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
const pool = new Pool({
|
|
connectionString: process.env.DATABASE_URL,
|
|
});
|
|
|
|
async function initDB() {
|
|
const client = await pool.connect();
|
|
try {
|
|
await client.query(`
|
|
CREATE TABLE IF NOT EXISTS todos (
|
|
id SERIAL PRIMARY KEY,
|
|
text TEXT NOT NULL,
|
|
done BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
)
|
|
`);
|
|
console.log('Database table ready');
|
|
} finally {
|
|
client.release();
|
|
}
|
|
}
|
|
|
|
// GET /api/todos
|
|
app.get('/api/todos', async (req, res) => {
|
|
try {
|
|
const { rows } = await pool.query('SELECT * FROM todos ORDER BY created_at DESC');
|
|
res.json(rows);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Failed to fetch todos' });
|
|
}
|
|
});
|
|
|
|
// POST /api/todos
|
|
app.post('/api/todos', async (req, res) => {
|
|
const { text } = req.body;
|
|
if (!text || typeof text !== 'string' || !text.trim()) {
|
|
return res.status(400).json({ error: '"text" is required' });
|
|
}
|
|
try {
|
|
const { rows } = await pool.query(
|
|
'INSERT INTO todos (text) VALUES ($1) RETURNING *',
|
|
[text.trim()]
|
|
);
|
|
res.status(201).json(rows[0]);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Failed to create todo' });
|
|
}
|
|
});
|
|
|
|
// PUT /api/todos/:id/toggle
|
|
app.put('/api/todos/:id/toggle', async (req, res) => {
|
|
try {
|
|
const { rows } = await pool.query(
|
|
'UPDATE todos SET done = NOT done WHERE id = $1 RETURNING *',
|
|
[req.params.id]
|
|
);
|
|
if (rows.length === 0) return res.status(404).json({ error: 'Todo not found' });
|
|
res.json(rows[0]);
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Failed to toggle todo' });
|
|
}
|
|
});
|
|
|
|
// DELETE /api/todos/:id
|
|
app.delete('/api/todos/:id', async (req, res) => {
|
|
try {
|
|
const { rowCount } = await pool.query('DELETE FROM todos WHERE id = $1', [req.params.id]);
|
|
if (rowCount === 0) return res.status(404).json({ error: 'Todo not found' });
|
|
res.json({ message: 'Todo deleted' });
|
|
} catch (err) {
|
|
console.error(err);
|
|
res.status(500).json({ error: 'Failed to delete todo' });
|
|
}
|
|
});
|
|
|
|
initDB().then(() => {
|
|
const PORT = process.env.PORT || 3000;
|
|
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|
|
});
|