Models & Routes

This commit is contained in:
ShiharaD
2025-09-01 15:33:46 +05:30
parent 8c6da127ef
commit 47fac5148e
5 changed files with 242 additions and 10 deletions

180
routes/reports.js Normal file
View File

@ -0,0 +1,180 @@
// routes/reports.js
const express = require('express');
require('dotenv').config();
const router = express.Router();
const nodemailer = require('nodemailer');
const GameSession = require('../models/GameSession');
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
}
});
router.post('/generate-report', async (req, res) => {
const { username, email } = req.body;
if (!username || !email) {
return res.status(400).json({
success: false,
message: 'Username and email are required'
});
}
try {
// Fetch all sessions for the user
const sessions = await GameSession.find({ username }).sort({ createdAt: -1 });
if (sessions.length === 0) {
return res.status(404).json({
success: false,
message: 'No session data found for this user'
});
}
// Generate report content
const report = generateReportContent(username, sessions);
// Email configuration
const mailOptions = {
from: 'shiharahimalshi@gmail.com',
to: email,
subject: `Game Session Report for ${username}`,
html: report
};
// Send email
await transporter.sendMail(mailOptions);
res.json({
success: true,
message: 'Report sent successfully to ' + email
});
} catch (err) {
console.error('Report generation error:', err);
res.status(500).json({
success: false,
message: 'Failed to generate report',
error: err.message
});
}
});
function generateReportContent(username, sessions) {
// Calculate statistics
const totalSessions = sessions.length;
const totalPlayTime = sessions.reduce((sum, session) => sum + session.durationSeconds, 0);
const averagePlayTime = Math.round(totalPlayTime / totalSessions);
const levelsPlayed = [...new Set(sessions.map(s => s.levelNumber))].sort((a, b) => a - b);
// Format play time
const formatTime = (seconds) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return `${hours}h ${minutes}m ${secs}s`;
};
// Generate professional report-style HTML
let html = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: 'Segoe UI', Arial, sans-serif; margin: 30px; background: #fff; color: #000; line-height: 1.6; }
.header { text-align: center; margin-bottom: 30px; }
.header h1 { margin: 0; font-size: 28px; font-weight: bold; }
.header h2 { margin: 5px 0; font-size: 20px; font-weight: normal; }
.header p { margin: 0; font-size: 14px; color: #555; }
.section { margin-bottom: 30px; }
.section h3 { border-bottom: 2px solid #333; padding-bottom: 5px; margin-bottom: 15px; font-size: 18px; }
.stat-item { margin: 6px 0; font-size: 15px; }
.level-container { display: flex; flex-wrap: wrap; gap: 20px; }
.level-card { flex: 1 1 200px; border: 1px solid #ddd; padding: 12px; border-radius: 6px; background: #f9f9f9; }
table { width: 100%; border-collapse: collapse; margin-top: 15px; font-size: 14px; }
th, td { border: 1px solid #ddd; padding: 10px; text-align: center; }
th { background: #f2f2f2; font-weight: bold; }
tr:nth-child(even) { background: #fafafa; }
.footer { text-align: center; margin-top: 40px; font-size: 13px; color: #555; }
</style>
</head>
<body>
<div class="header">
<h1>Game Session Report</h1>
<h2>Player: ${username}</h2>
<p>Generated on: ${new Date().toLocaleDateString()}</p>
</div>
<div class="section">
<h3>Overall Statistics</h3>
<div class="stat-item"><strong>Total Sessions:</strong> ${totalSessions}</div>
<div class="stat-item"><strong>Total Play Time:</strong> ${formatTime(totalPlayTime)}</div>
<div class="stat-item"><strong>Average Session Time:</strong> ${formatTime(averagePlayTime)}</div>
<div class="stat-item"><strong>Levels Played:</strong> ${levelsPlayed.join(', ')}</div>
</div>
<div class="section">
<h3>Level Statistics</h3>
<div class="level-container">`;
// Level-specific stats
levelsPlayed.forEach(level => {
const levelSessions = sessions.filter(s => s.levelNumber === level);
const levelTotalTime = levelSessions.reduce((sum, s) => sum + s.durationSeconds, 0);
const levelAvgTime = Math.round(levelTotalTime / levelSessions.length);
html += `
<div class="level-card">
<strong>Level ${level}</strong><br>
Sessions: ${levelSessions.length}<br>
Total Time: ${formatTime(levelTotalTime)}<br>
Average Time: ${formatTime(levelAvgTime)}
</div>`;
});
html += `
</div>
</div>
<div class="section">
<h3>Detailed Session History</h3>
<table>
<tr>
<th>Date</th>
<th>Level</th>
<th>Duration</th>
<th>Performance</th>
</tr>`;
sessions.forEach(session => {
const date = session.createdAt ? new Date(session.createdAt).toLocaleDateString() : 'N/A';
const performance = session.durationSeconds < averagePlayTime ? 'Above Average' : 'Average';
html += `
<tr>
<td>${date}</td>
<td>Level ${session.levelNumber}</td>
<td>${formatTime(session.durationSeconds)}</td>
<td>${performance}</td>
</tr>`;
});
html += `
</table>
</div>
<div class="footer">
<p>This report was generated automatically by the game system.</p>
</div>
</body>
</html>`;
return html;
}
module.exports = router;