252 lines
6.4 KiB
JavaScript
252 lines
6.4 KiB
JavaScript
const express = require("express");
|
|
const router = express.Router();
|
|
const { query } = require("../db");
|
|
const { v4: uuidv4 } = require("uuid");
|
|
|
|
// GET all profiles
|
|
router.get("/", async (req, res) => {
|
|
try {
|
|
const result = await query("SELECT * FROM profiles ORDER BY name ASC");
|
|
res.json({ success: true, profiles: result.rows });
|
|
} catch (err) {
|
|
console.error("Error fetching profiles:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to fetch profiles" });
|
|
}
|
|
});
|
|
|
|
// GET single profile by ID
|
|
router.get("/:id", async (req, res) => {
|
|
try {
|
|
const result = await query("SELECT * FROM profiles WHERE id = $1", [
|
|
req.params.id,
|
|
]);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res
|
|
.status(404)
|
|
.json({ success: false, message: "Profile not found" });
|
|
}
|
|
|
|
// Also get profile's songs with their preferred keys
|
|
const songsResult = await query(
|
|
`
|
|
SELECT s.*, psk.song_key as preferred_key
|
|
FROM songs s
|
|
INNER JOIN profile_songs ps ON s.id = ps.song_id
|
|
LEFT JOIN profile_song_keys psk ON ps.profile_id = psk.profile_id AND ps.song_id = psk.song_id
|
|
WHERE ps.profile_id = $1
|
|
ORDER BY s.title ASC
|
|
`,
|
|
[req.params.id],
|
|
);
|
|
|
|
res.json({
|
|
success: true,
|
|
profile: result.rows[0],
|
|
songs: songsResult.rows,
|
|
});
|
|
} catch (err) {
|
|
console.error("Error fetching profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to fetch profile" });
|
|
}
|
|
});
|
|
|
|
// POST create new profile
|
|
router.post("/", async (req, res) => {
|
|
try {
|
|
const {
|
|
first_name,
|
|
last_name,
|
|
name,
|
|
email,
|
|
contact_number,
|
|
notes,
|
|
default_key,
|
|
} = req.body;
|
|
|
|
const profileName = name || `${first_name || ""} ${last_name || ""}`.trim();
|
|
if (!profileName) {
|
|
return res
|
|
.status(400)
|
|
.json({ success: false, message: "Name is required" });
|
|
}
|
|
|
|
const id = uuidv4();
|
|
|
|
const result = await query(
|
|
`INSERT INTO profiles (id, first_name, last_name, name, email, contact_number, notes, default_key)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
RETURNING *`,
|
|
[
|
|
id,
|
|
first_name || "",
|
|
last_name || "",
|
|
profileName,
|
|
email || "",
|
|
contact_number || "",
|
|
notes || "",
|
|
default_key || "C",
|
|
],
|
|
);
|
|
|
|
res.status(201).json({ success: true, profile: result.rows[0] });
|
|
} catch (err) {
|
|
console.error("Error creating profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to create profile" });
|
|
}
|
|
});
|
|
|
|
// PUT update profile
|
|
router.put("/:id", async (req, res) => {
|
|
try {
|
|
const {
|
|
first_name,
|
|
last_name,
|
|
name,
|
|
email,
|
|
contact_number,
|
|
notes,
|
|
default_key,
|
|
} = req.body;
|
|
|
|
const result = await query(
|
|
`UPDATE profiles
|
|
SET first_name = COALESCE($1, first_name),
|
|
last_name = COALESCE($2, last_name),
|
|
name = COALESCE($3, name),
|
|
email = COALESCE($4, email),
|
|
contact_number = COALESCE($5, contact_number),
|
|
notes = COALESCE($6, notes),
|
|
default_key = COALESCE($7, default_key)
|
|
WHERE id = $8
|
|
RETURNING *`,
|
|
[
|
|
first_name,
|
|
last_name,
|
|
name,
|
|
email,
|
|
contact_number,
|
|
notes,
|
|
default_key,
|
|
req.params.id,
|
|
],
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res
|
|
.status(404)
|
|
.json({ success: false, message: "Profile not found" });
|
|
}
|
|
|
|
res.json({ success: true, profile: result.rows[0] });
|
|
} catch (err) {
|
|
console.error("Error updating profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to update profile" });
|
|
}
|
|
});
|
|
|
|
// DELETE profile
|
|
router.delete("/:id", async (req, res) => {
|
|
try {
|
|
const result = await query(
|
|
"DELETE FROM profiles WHERE id = $1 RETURNING id",
|
|
[req.params.id],
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res
|
|
.status(404)
|
|
.json({ success: false, message: "Profile not found" });
|
|
}
|
|
|
|
res.json({ success: true, message: "Profile deleted" });
|
|
} catch (err) {
|
|
console.error("Error deleting profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to delete profile" });
|
|
}
|
|
});
|
|
|
|
// POST add song to profile
|
|
router.post("/:id/songs/:songId", async (req, res) => {
|
|
try {
|
|
const { id, songId } = req.params;
|
|
const { song_key } = req.body;
|
|
|
|
const psId = uuidv4();
|
|
|
|
// Add song to profile
|
|
await query(
|
|
`INSERT INTO profile_songs (id, profile_id, song_id)
|
|
VALUES ($1, $2, $3)
|
|
ON CONFLICT (profile_id, song_id) DO NOTHING`,
|
|
[psId, id, songId],
|
|
);
|
|
|
|
// If key provided, set it
|
|
if (song_key) {
|
|
const pskId = uuidv4();
|
|
await query(
|
|
`INSERT INTO profile_song_keys (id, profile_id, song_id, song_key)
|
|
VALUES ($1, $2, $3, $4)
|
|
ON CONFLICT (profile_id, song_id) DO UPDATE SET song_key = $4`,
|
|
[pskId, id, songId, song_key],
|
|
);
|
|
}
|
|
|
|
res.json({ success: true, message: "Song added to profile" });
|
|
} catch (err) {
|
|
console.error("Error adding song to profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to add song to profile" });
|
|
}
|
|
});
|
|
|
|
// DELETE remove song from profile
|
|
router.delete("/:id/songs/:songId", async (req, res) => {
|
|
try {
|
|
const { id, songId } = req.params;
|
|
|
|
await query(
|
|
"DELETE FROM profile_songs WHERE profile_id = $1 AND song_id = $2",
|
|
[id, songId],
|
|
);
|
|
await query(
|
|
"DELETE FROM profile_song_keys WHERE profile_id = $1 AND song_id = $2",
|
|
[id, songId],
|
|
);
|
|
|
|
res.json({ success: true, message: "Song removed from profile" });
|
|
} catch (err) {
|
|
console.error("Error removing song from profile:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to remove song from profile" });
|
|
}
|
|
});
|
|
|
|
// GET profile count
|
|
router.get("/stats/count", async (req, res) => {
|
|
try {
|
|
const result = await query("SELECT COUNT(*) as count FROM profiles");
|
|
res.json({ success: true, count: parseInt(result.rows[0].count) });
|
|
} catch (err) {
|
|
console.error("Error counting profiles:", err);
|
|
res
|
|
.status(500)
|
|
.json({ success: false, message: "Failed to count profiles" });
|
|
}
|
|
});
|
|
|
|
module.exports = router;
|