todo-list/server.js
2026-06-11 18:49:05 +00:00

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}`));
});