diff --git a/backend/src/app.ts b/backend/src/app.ts index c638703..bf9d6c5 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -15,12 +15,13 @@ app.get('/', (req, res) => { }) app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => { + const monthId = req.body.monthId let startSeconds = 0 let endSeconds = Number.MAX_SAFE_INTEGER - if (req.body.monthId != -1) { - const month = req.body.monthId % 12 - const year = Math.floor(req.body.monthId / 12) + 2023 + if (monthId != -1) { + const month = monthId % 12 + const year = Math.floor(monthId / 12) + 2023 const startDate = new Date(year, month, 1) const endDate = new Date(year, month + 1, -1) @@ -35,6 +36,8 @@ app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => { 'SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as Complete, ' + 'SUM(CASE WHEN status = "Postponed" THEN 1 ELSE 0 END) as Postponed, ' + 'SUM(CASE WHEN status = "Pending" THEN 1 ELSE 0 END) as Pending, ' + + 'SUM(payoutEB) as TotalEB, ' + + 'SUM(payoutIP) as TotalIP, ' + 'SUM(payoutEB) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageEB, ' + 'SUM(payoutIP) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageIP ' + 'FROM Games WHERE postdate BETWEEN :startSeconds AND :endSeconds', @@ -46,7 +49,90 @@ app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => { } } ) - res.json(serverGameStats[0]) + res.send(serverGameStats[0]) +}) + +app.post('/api/serverstats/rolestats', jsonParser, async (req, res) => { + const monthId = req.body.monthId + + let startSeconds = 0 + let endSeconds = Number.MAX_SAFE_INTEGER + + if (monthId != -1) { + const month = monthId % 12 + const year = Math.floor(monthId / 12) + 2023 + + const startDate = new Date(year, month, 1) + const endDate = new Date(year, month + 1, -1) + + startSeconds = startDate.getTime() / 1000 + endSeconds = endDate.getTime() / 1000 + } + + const games = await Game.findAll({ + include: [ + { model: Character, as: 'characterPickedForGame' }, + { model: Character, as: 'characterAppliedForGame' } + ], + where: { postdate: { [Op.between]: [startSeconds, endSeconds] } } + }) + + // count active roles + let activeCharacters = new Map() + let pickedCharacterCount = new Map() + let appedCharacterCount = new Map() + + games.forEach((game, gameNum) => { + const picks = game.dataValues.characterPickedForGame + const appls = game.dataValues.characterAppliedForGame + + picks.forEach((character, characterNum) => { + const role = character.dataValues.role + // Count role application + pickedCharacterCount.set( + role, (pickedCharacterCount.get(role) || 0) + 1 + ) + }) + + appls.forEach((character, characterNum) => { + const role = character.dataValues.role + const charId = character.dataValues.id + // Add apllied characters to active list + if (!activeCharacters.has(role)) { + activeCharacters.set(role, new Set()) + } + activeCharacters.get(role).add(charId) + // Count role application + appedCharacterCount.set( + role, (appedCharacterCount.get(role) || 0) + 1 + ) + }) + }) + + const roleNames = [ + 'Fixer', + 'Tech', + 'Medtech', + 'Media', + 'Netrunner', + 'Solo', + 'Nomad', + 'Exec', + 'Lawman', + 'Rocker' + ] + + const result = {} + + roleNames.forEach((roleName) => { + result[roleName] = { + apps: appedCharacterCount.get(roleName) || 0, + picks: pickedCharacterCount.get(roleName) || 0, + active: activeCharacters.has(roleName) ?activeCharacters.get(roleName).size : 0 + } + }) + + res.send(result) }) app.get('/api/character/:characterId', async (req, res) => { @@ -72,7 +158,7 @@ app.post('/api/character', jsonParser, async (req, res) => { ) res.setHeader('Content-Type', 'application/json') - res.json({ characterData, pageCount }) + res.send({ characterData, pageCount }) }) app.get('/api/game/:gameId', async (req, res) => { diff --git a/frontend/src/vues/CharacterList.vue b/frontend/src/vues/CharacterList.vue index 1a332ae..22dd629 100644 --- a/frontend/src/vues/CharacterList.vue +++ b/frontend/src/vues/CharacterList.vue @@ -85,7 +85,7 @@ watch(route, (newValue, oldValue) => { }) let debounce = null -watch(filtervalue, (oldFilter, newFilter) => { +watch(filtervalue, (newFilter, oldFilter) => { debounce = clearTimeout(debounce) debounce = setTimeout(() => { loadData() diff --git a/frontend/src/vues/ServerStats.vue b/frontend/src/vues/ServerStats.vue index ae33a74..2c4fc95 100644 --- a/frontend/src/vues/ServerStats.vue +++ b/frontend/src/vues/ServerStats.vue @@ -2,36 +2,46 @@