we're about to port the chrome-extension. everything else mostly works
This commit is contained in:
@@ -73,6 +73,91 @@ router.get('/', (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Get all packs with their favor bias (MUST be before /:id)
|
||||
router.get('/packs', (req, res) => {
|
||||
try {
|
||||
const packs = db.prepare('SELECT * FROM packs ORDER BY name').all();
|
||||
res.json(packs);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Get pack metadata (MUST be before /:id)
|
||||
router.get('/meta/packs', (req, res) => {
|
||||
try {
|
||||
const packs = db.prepare(`
|
||||
SELECT
|
||||
pack_name as name,
|
||||
COUNT(*) as total_count,
|
||||
SUM(CASE WHEN enabled = 1 THEN 1 ELSE 0 END) as enabled_count,
|
||||
SUM(play_count) as total_plays
|
||||
FROM games
|
||||
GROUP BY pack_name
|
||||
ORDER BY pack_name
|
||||
`).all();
|
||||
res.json(packs);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Export games as CSV (MUST be before /:id)
|
||||
router.get('/export/csv', authenticateToken, (req, res) => {
|
||||
try {
|
||||
const games = db.prepare('SELECT * FROM games ORDER BY pack_name, title').all();
|
||||
|
||||
const records = games.map(game => ({
|
||||
'Pack Name': game.pack_name,
|
||||
'Title': game.title,
|
||||
'Min Players': game.min_players,
|
||||
'Max Players': game.max_players,
|
||||
'Length (minutes)': game.length_minutes || '',
|
||||
'Audience': game.has_audience ? 'Yes' : 'No',
|
||||
'Family Friendly': game.family_friendly ? 'Yes' : 'No',
|
||||
'Game Type': game.game_type || '',
|
||||
'Secondary Type': game.secondary_type || ''
|
||||
}));
|
||||
|
||||
const csv = stringify(records, { header: true });
|
||||
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename="jackbox-games.csv"');
|
||||
res.send(csv);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Set favor bias for a pack (MUST be before /:id)
|
||||
router.patch('/packs/:name/favor', authenticateToken, (req, res) => {
|
||||
try {
|
||||
const { favor_bias } = req.body;
|
||||
|
||||
// Validate favor_bias value
|
||||
if (![1, -1, 0].includes(favor_bias)) {
|
||||
return res.status(400).json({ error: 'favor_bias must be 1 (favor), -1 (disfavor), or 0 (neutral)' });
|
||||
}
|
||||
|
||||
// Update pack favor bias
|
||||
const packStmt = db.prepare('UPDATE packs SET favor_bias = ? WHERE name = ?');
|
||||
const packResult = packStmt.run(favor_bias, req.params.name);
|
||||
|
||||
if (packResult.changes === 0) {
|
||||
// Pack doesn't exist, create it
|
||||
const insertStmt = db.prepare('INSERT INTO packs (name, favor_bias) VALUES (?, ?)');
|
||||
insertStmt.run(req.params.name, favor_bias);
|
||||
}
|
||||
|
||||
res.json({
|
||||
message: 'Pack favor bias updated successfully',
|
||||
favor_bias
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Get single game by ID
|
||||
router.get('/:id', (req, res) => {
|
||||
try {
|
||||
@@ -224,25 +309,6 @@ router.patch('/:id/toggle', authenticateToken, (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Get list of unique pack names
|
||||
router.get('/meta/packs', (req, res) => {
|
||||
try {
|
||||
const packs = db.prepare(`
|
||||
SELECT
|
||||
pack_name,
|
||||
COUNT(*) as game_count,
|
||||
SUM(enabled) as enabled_count
|
||||
FROM games
|
||||
GROUP BY pack_name
|
||||
ORDER BY pack_name
|
||||
`).all();
|
||||
|
||||
res.json(packs);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle entire pack (admin only)
|
||||
router.patch('/packs/:name/toggle', authenticateToken, (req, res) => {
|
||||
try {
|
||||
@@ -264,33 +330,6 @@ router.patch('/packs/:name/toggle', authenticateToken, (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
// Export games to CSV (admin only)
|
||||
router.get('/export/csv', authenticateToken, (req, res) => {
|
||||
try {
|
||||
const games = db.prepare('SELECT * FROM games ORDER BY pack_name, title').all();
|
||||
|
||||
const csvData = games.map(game => ({
|
||||
'Game Pack': game.pack_name,
|
||||
'Game Title': game.title,
|
||||
'Min. Players': game.min_players,
|
||||
'Max. Players': game.max_players,
|
||||
'Length': game.length_minutes ? `${game.length_minutes} minutes` : '????',
|
||||
'Audience': game.has_audience ? 'Yes' : 'No',
|
||||
'Family Friendly?': game.family_friendly ? 'Yes' : 'No',
|
||||
'Game Type': game.game_type || '',
|
||||
'Secondary Type': game.secondary_type || ''
|
||||
}));
|
||||
|
||||
const csv = stringify(csvData, { header: true });
|
||||
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=games-export.csv');
|
||||
res.send(csv);
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Import games from CSV (admin only)
|
||||
router.post('/import/csv', authenticateToken, (req, res) => {
|
||||
try {
|
||||
@@ -360,5 +399,31 @@ function parseBoolean(value) {
|
||||
return value.toLowerCase() === 'yes' ? 1 : 0;
|
||||
}
|
||||
|
||||
// Set favor bias for a game (1 = favor, -1 = disfavor, 0 = neutral)
|
||||
router.patch('/:id/favor', authenticateToken, (req, res) => {
|
||||
try {
|
||||
const { favor_bias } = req.body;
|
||||
|
||||
// Validate favor_bias value
|
||||
if (![1, -1, 0].includes(favor_bias)) {
|
||||
return res.status(400).json({ error: 'favor_bias must be 1 (favor), -1 (disfavor), or 0 (neutral)' });
|
||||
}
|
||||
|
||||
const stmt = db.prepare('UPDATE games SET favor_bias = ? WHERE id = ?');
|
||||
const result = stmt.run(favor_bias, req.params.id);
|
||||
|
||||
if (result.changes === 0) {
|
||||
return res.status(404).json({ error: 'Game not found' });
|
||||
}
|
||||
|
||||
res.json({
|
||||
message: 'Favor bias updated successfully',
|
||||
favor_bias
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user