151 lines
4.0 KiB
JavaScript
151 lines
4.0 KiB
JavaScript
import express from "express";
|
|
import { join, dirname } from "path";
|
|
import { fileURLToPath } from "url";
|
|
import db from "./db.js";
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
app.use(express.json());
|
|
|
|
// Serve Vue build in production
|
|
const distPath = join(__dirname, "../dist");
|
|
app.use(express.static(distPath));
|
|
|
|
// ── Students ──────────────────────────────────────────────────────────────
|
|
|
|
app.get("/api/students", (_req, res) => {
|
|
res.json(
|
|
db.prepare("SELECT * FROM students ORDER BY lastName, firstName").all(),
|
|
);
|
|
});
|
|
|
|
app.post("/api/students", (req, res) => {
|
|
const { id, firstName, lastName, age, sex, weight, height, imc } = req.body;
|
|
db.prepare(
|
|
`
|
|
INSERT INTO students (id, firstName, lastName, age, sex, weight, height, imc)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
`,
|
|
).run(id, firstName, lastName, age, sex, weight, height, imc);
|
|
res.status(201).json({ id });
|
|
});
|
|
|
|
app.put("/api/students/:id", (req, res) => {
|
|
const { firstName, lastName, age, sex, weight, height, imc } = req.body;
|
|
const info = db
|
|
.prepare(
|
|
`
|
|
UPDATE students SET firstName=?, lastName=?, age=?, sex=?, weight=?, height=?, imc=?
|
|
WHERE id=?
|
|
`,
|
|
)
|
|
.run(firstName, lastName, age, sex, weight, height, imc, req.params.id);
|
|
if (info.changes === 0) return res.status(404).json({ error: "Not found" });
|
|
res.json({ ok: true });
|
|
});
|
|
|
|
app.delete("/api/students/:id", (req, res) => {
|
|
// CASCADE deletes linked activities automatically (FK ON DELETE CASCADE)
|
|
db.prepare("DELETE FROM students WHERE id=?").run(req.params.id);
|
|
res.json({ ok: true });
|
|
});
|
|
|
|
// ── Activities ────────────────────────────────────────────────────────────
|
|
|
|
app.get("/api/activities", (_req, res) => {
|
|
res.json(
|
|
db.prepare("SELECT * FROM activities ORDER BY createdAt DESC").all(),
|
|
);
|
|
});
|
|
|
|
app.post("/api/activities", (req, res) => {
|
|
const {
|
|
id,
|
|
studentId,
|
|
type,
|
|
durationInput,
|
|
durationUnit,
|
|
duration,
|
|
displayDuration,
|
|
intensity,
|
|
lifestyle,
|
|
anxiety,
|
|
grade,
|
|
date,
|
|
} = req.body;
|
|
db.prepare(
|
|
`
|
|
INSERT INTO activities
|
|
(id, studentId, type, durationInput, durationUnit, duration, displayDuration, intensity, lifestyle, anxiety, grade, date)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
`,
|
|
).run(
|
|
id,
|
|
studentId,
|
|
type,
|
|
durationInput,
|
|
durationUnit,
|
|
duration,
|
|
displayDuration,
|
|
intensity,
|
|
lifestyle,
|
|
anxiety ?? 0,
|
|
grade,
|
|
date,
|
|
);
|
|
res.status(201).json({ id });
|
|
});
|
|
|
|
app.put("/api/activities/:id", (req, res) => {
|
|
const {
|
|
type,
|
|
durationInput,
|
|
durationUnit,
|
|
duration,
|
|
displayDuration,
|
|
intensity,
|
|
lifestyle,
|
|
anxiety,
|
|
grade,
|
|
date,
|
|
} = req.body;
|
|
const info = db
|
|
.prepare(
|
|
`
|
|
UPDATE activities
|
|
SET type=?, durationInput=?, durationUnit=?, duration=?, displayDuration=?,
|
|
intensity=?, lifestyle=?, anxiety=?, grade=?, date=?
|
|
WHERE id=?
|
|
`,
|
|
)
|
|
.run(
|
|
type,
|
|
durationInput,
|
|
durationUnit,
|
|
duration,
|
|
displayDuration,
|
|
intensity,
|
|
lifestyle,
|
|
anxiety ?? 0,
|
|
grade,
|
|
date,
|
|
req.params.id,
|
|
);
|
|
if (info.changes === 0) return res.status(404).json({ error: "Not found" });
|
|
res.json({ ok: true });
|
|
});
|
|
|
|
app.delete("/api/activities/:id", (req, res) => {
|
|
db.prepare("DELETE FROM activities WHERE id=?").run(req.params.id);
|
|
res.json({ ok: true });
|
|
});
|
|
|
|
// ── SPA fallback ──────────────────────────────────────────────────────────
|
|
app.get("*", (_req, res) => {
|
|
res.sendFile(join(distPath, "index.html"));
|
|
});
|
|
|
|
app.listen(PORT, () => console.log(`SB Sports API running on :${PORT}`));
|