242 lines
5.1 KiB
JavaScript
242 lines
5.1 KiB
JavaScript
import express from "express";
|
|
import { v4 as uuidv4 } from "uuid";
|
|
import { validate, listValidation } from "../middleware/validate.js";
|
|
|
|
const router = express.Router();
|
|
|
|
// In-memory store (replace with database in production)
|
|
const lists = new Map([
|
|
[
|
|
"1",
|
|
{
|
|
id: "1",
|
|
name: "Sunday Morning",
|
|
date: "2026-01-26",
|
|
songs: ["1", "2"],
|
|
createdBy: "system",
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
],
|
|
[
|
|
"2",
|
|
{
|
|
id: "2",
|
|
name: "Wednesday Night",
|
|
date: "2026-01-22",
|
|
songs: ["2"],
|
|
createdBy: "system",
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
],
|
|
]);
|
|
|
|
// Get all lists
|
|
router.get("/", (req, res) => {
|
|
const { search, upcoming } = req.query;
|
|
|
|
let result = Array.from(lists.values());
|
|
|
|
// Search filter
|
|
if (search) {
|
|
const searchLower = search.toLowerCase();
|
|
result = result.filter((list) =>
|
|
list.name.toLowerCase().includes(searchLower),
|
|
);
|
|
}
|
|
|
|
// Upcoming filter
|
|
if (upcoming === "true") {
|
|
const today = new Date().toISOString().split("T")[0];
|
|
result = result.filter((list) => list.date >= today);
|
|
}
|
|
|
|
// Sort by date (newest first)
|
|
result.sort((a, b) => new Date(b.date) - new Date(a.date));
|
|
|
|
res.json({
|
|
lists: result,
|
|
total: result.length,
|
|
});
|
|
});
|
|
|
|
// Get single list with populated songs
|
|
router.get("/:id", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
res.json({ list });
|
|
});
|
|
|
|
// Create list
|
|
router.post("/", validate(listValidation), (req, res) => {
|
|
const { name, date, songs: songIds } = req.body;
|
|
|
|
const list = {
|
|
id: uuidv4(),
|
|
name,
|
|
date: date || new Date().toISOString().split("T")[0],
|
|
songs: songIds || [],
|
|
createdBy: req.user.id,
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
lists.set(list.id, list);
|
|
|
|
res.status(201).json({
|
|
message: "List created successfully",
|
|
list,
|
|
});
|
|
});
|
|
|
|
// Update list
|
|
router.put("/:id", validate(listValidation), (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
const { name, date, songs: songIds } = req.body;
|
|
|
|
const updatedList = {
|
|
...list,
|
|
name: name || list.name,
|
|
date: date || list.date,
|
|
songs: songIds !== undefined ? songIds : list.songs,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
lists.set(list.id, updatedList);
|
|
|
|
res.json({
|
|
message: "List updated successfully",
|
|
list: updatedList,
|
|
});
|
|
});
|
|
|
|
// Delete list
|
|
router.delete("/:id", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
lists.delete(req.params.id);
|
|
|
|
res.json({ message: "List deleted successfully" });
|
|
});
|
|
|
|
// Add song to list
|
|
router.post("/:id/songs", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
const { songId, position } = req.body;
|
|
|
|
if (!songId) {
|
|
return res.status(400).json({ error: "Song ID required" });
|
|
}
|
|
|
|
const songs = [...list.songs];
|
|
|
|
if (position !== undefined && position >= 0 && position <= songs.length) {
|
|
songs.splice(position, 0, songId);
|
|
} else {
|
|
songs.push(songId);
|
|
}
|
|
|
|
list.songs = songs;
|
|
list.updatedAt = new Date().toISOString();
|
|
lists.set(list.id, list);
|
|
|
|
res.json({
|
|
message: "Song added to list",
|
|
list,
|
|
});
|
|
});
|
|
|
|
// Remove song from list
|
|
router.delete("/:id/songs/:songId", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
const songIndex = list.songs.indexOf(req.params.songId);
|
|
if (songIndex === -1) {
|
|
return res.status(404).json({ error: "Song not in list" });
|
|
}
|
|
|
|
list.songs.splice(songIndex, 1);
|
|
list.updatedAt = new Date().toISOString();
|
|
lists.set(list.id, list);
|
|
|
|
res.json({
|
|
message: "Song removed from list",
|
|
list,
|
|
});
|
|
});
|
|
|
|
// Reorder songs in list
|
|
router.put("/:id/reorder", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
const { songs: newOrder } = req.body;
|
|
|
|
if (!Array.isArray(newOrder)) {
|
|
return res.status(400).json({ error: "Songs array required" });
|
|
}
|
|
|
|
list.songs = newOrder;
|
|
list.updatedAt = new Date().toISOString();
|
|
lists.set(list.id, list);
|
|
|
|
res.json({
|
|
message: "List reordered successfully",
|
|
list,
|
|
});
|
|
});
|
|
|
|
// Duplicate list
|
|
router.post("/:id/duplicate", (req, res) => {
|
|
const list = lists.get(req.params.id);
|
|
|
|
if (!list) {
|
|
return res.status(404).json({ error: "List not found" });
|
|
}
|
|
|
|
const duplicateList = {
|
|
...list,
|
|
id: uuidv4(),
|
|
name: `${list.name} (Copy)`,
|
|
songs: [...list.songs],
|
|
createdBy: req.user.id,
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
lists.set(duplicateList.id, duplicateList);
|
|
|
|
res.status(201).json({
|
|
message: "List duplicated successfully",
|
|
list: duplicateList,
|
|
});
|
|
});
|
|
|
|
export default router;
|