mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 03:20:12 +08:00
feat: add sessions page
This commit is contained in:
1 parent
50e53b5667
commit
fe1f595f0f
8 files changed
+107
-25
No files matched your search
@@ -1,3 +1,7 @@
|
|||||||
|
body {
|
||||||
|
font-family: 'sans';
|
||||||
|
}
|
||||||
|
|
||||||
table,
|
table,
|
||||||
tr,
|
tr,
|
||||||
td,
|
td,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { userCount } from '../models/users.js'
|
import { userCount } from '../models/users.js'
|
||||||
import { sessionCount, sessionCompleted } from '../models/quests.js'
|
import { sessionCount, sessionCompleted } from '../models/sessions.js'
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export async function homeController(req, res) {
|
export async function homeController(req, res) {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { sessionList } from '../models/sessions.js'
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export async function sessionListController(req, res) {
|
||||||
|
const sessions = await sessionList()
|
||||||
|
res.render('sessions', { sessions })
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import { Session } from '@linux-odyssey/models'
|
|
||||||
|
|
||||||
export function sessionCount() {
|
|
||||||
return Session.find().count()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function sessionCompleted() {
|
|
||||||
return Session.find({ status: 'finished' }).count()
|
|
||||||
}
|
|
||||||
|
|
||||||
export function averageTimeUsage() {
|
|
||||||
return Session.aggregate([
|
|
||||||
{
|
|
||||||
$group: {
|
|
||||||
_id: '$quest',
|
|
||||||
average: {
|
|
||||||
$avg: {
|
|
||||||
$subtract: ['$finishedAt', '$createdAt'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import { Session } from '@linux-odyssey/models'
|
||||||
|
|
||||||
|
export function sessionCount() {
|
||||||
|
return Session.find().count()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sessionCompleted() {
|
||||||
|
return Session.find({ status: 'finished' }).count()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function averageTimeUsage() {
|
||||||
|
return Session.aggregate([
|
||||||
|
{
|
||||||
|
$group: {
|
||||||
|
_id: '$quest',
|
||||||
|
average: {
|
||||||
|
$avg: {
|
||||||
|
$subtract: ['$finishedAt', '$createdAt'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTime(time) {
|
||||||
|
const seconds = Math.floor(time / 1000)
|
||||||
|
const minutes = Math.floor(seconds / 60)
|
||||||
|
const hours = Math.floor(minutes / 60)
|
||||||
|
return `${hours}h ${minutes % 60}m ${seconds % 60}s`
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sessionList() {
|
||||||
|
const sessions = await Session.aggregate([
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: 'users',
|
||||||
|
localField: 'user',
|
||||||
|
foreignField: '_id',
|
||||||
|
as: 'user',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ $unwind: '$user' },
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: 'commands',
|
||||||
|
localField: '_id',
|
||||||
|
foreignField: 'session',
|
||||||
|
as: 'commands',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
console.log(sessions)
|
||||||
|
return sessions.map(
|
||||||
|
({ user, quest, status, createdAt, finishedAt, commands }) => {
|
||||||
|
return {
|
||||||
|
user: user.username,
|
||||||
|
quest,
|
||||||
|
status,
|
||||||
|
createdAt: createdAt.toLocaleString(),
|
||||||
|
finishedAt: finishedAt?.toLocaleString(),
|
||||||
|
usedTime: finishedAt ? formatTime(finishedAt - createdAt) : '',
|
||||||
|
commandCount: commands.length,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,11 +3,13 @@ import { Router } from 'express'
|
|||||||
import { homeController } from './controllers/index.js'
|
import { homeController } from './controllers/index.js'
|
||||||
import { userListController } from './controllers/users.js'
|
import { userListController } from './controllers/users.js'
|
||||||
import { commandListController } from './controllers/commands.js'
|
import { commandListController } from './controllers/commands.js'
|
||||||
|
import { sessionListController } from './controllers/sessions.js'
|
||||||
|
|
||||||
const router = Router()
|
const router = Router()
|
||||||
|
|
||||||
router.get('/', homeController)
|
router.get('/', homeController)
|
||||||
router.get('/users', userListController)
|
router.get('/users', userListController)
|
||||||
router.get('/commands', commandListController)
|
router.get('/commands', commandListController)
|
||||||
|
router.get('/sessions', sessionListController)
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<li><a href='/'>Home</a></li>
|
<li><a href='/'>Home</a></li>
|
||||||
<li><a href='/users'>Users</a></li>
|
<li><a href='/users'>Users</a></li>
|
||||||
<li><a href='/commands'>Commands</a></li>
|
<li><a href='/commands'>Commands</a></li>
|
||||||
|
<li><a href='/sessions'>Sessions</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{{{body}}}
|
{{{body}}}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<h1>Sessions</h1>
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>User</th>
|
||||||
|
<th>Quest</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Created At</th>
|
||||||
|
<th>Finished At</th>
|
||||||
|
<th>Used Time</th>
|
||||||
|
<th>Command Count</th>
|
||||||
|
</tr>
|
||||||
|
{{#each sessions}}
|
||||||
|
<tr>
|
||||||
|
<td>{{user}}</td>
|
||||||
|
<td>{{quest}}</td>
|
||||||
|
<td>{{status}}</td>
|
||||||
|
<td>{{createdAt}}</td>
|
||||||
|
<td>{{finishedAt}}</td>
|
||||||
|
<td>{{usedTime}}</td>
|
||||||
|
<td>{{commandCount}}</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
Reference in new issue
Block a user