From 47fac5148e4d01bcd2e800c15f6aab33121e2036 Mon Sep 17 00:00:00 2001 From: ShiharaD <105881361+IT21304842@users.noreply.github.com> Date: Mon, 1 Sep 2025 15:33:46 +0530 Subject: [PATCH] Models & Routes --- GameSession.js => models/GameSession.js | 20 +-- User.js => models/User.js | 0 routes/auth.js | 30 ++++ routes/game.js | 22 +++ routes/reports.js | 180 ++++++++++++++++++++++++ 5 files changed, 242 insertions(+), 10 deletions(-) rename GameSession.js => models/GameSession.js (97%) rename User.js => models/User.js (100%) create mode 100644 routes/auth.js create mode 100644 routes/game.js create mode 100644 routes/reports.js diff --git a/GameSession.js b/models/GameSession.js similarity index 97% rename from GameSession.js rename to models/GameSession.js index f54f512..67a224c 100644 --- a/GameSession.js +++ b/models/GameSession.js @@ -1,10 +1,10 @@ -const mongoose = require('mongoose'); - -const gameSessionSchema = new mongoose.Schema({ - username: { type: String, required: true }, // can be ObjectId if you prefer - levelNumber: { type: Number, required: true }, - durationSeconds: { type: Number, required: true }, - playedAt: { type: Date, default: Date.now } -}); - -module.exports = mongoose.model('GameSession', gameSessionSchema); +const mongoose = require('mongoose'); + +const gameSessionSchema = new mongoose.Schema({ + username: { type: String, required: true }, // can be ObjectId if you prefer + levelNumber: { type: Number, required: true }, + durationSeconds: { type: Number, required: true }, + playedAt: { type: Date, default: Date.now } +}); + +module.exports = mongoose.model('GameSession', gameSessionSchema); diff --git a/User.js b/models/User.js similarity index 100% rename from User.js rename to models/User.js diff --git a/routes/auth.js b/routes/auth.js new file mode 100644 index 0000000..d8addf4 --- /dev/null +++ b/routes/auth.js @@ -0,0 +1,30 @@ +const express = require('express'); +const router = express.Router(); +const bcrypt = require('bcryptjs'); +const User = require('../models/User'); + +router.post('/register', async (req, res) => { + const { username, password } = req.body; + const hash = await bcrypt.hash(password, 10); + try { + const newUser = new User({ username, password: hash }); + await newUser.save(); + res.status(201).json({ success: true, message: 'User created' }); + } catch (err) { + res.status(400).json({ success: false, message: 'User exists or error' }); + } +}); + + +router.post('/login', async (req, res) => { + const { username, password } = req.body; + const user = await User.findOne({ username }); + if (!user) return res.status(400).json({ success: false, message: 'Invalid credentials' }); + + const isMatch = await bcrypt.compare(password, user.password); + if (!isMatch) return res.status(400).json({ success: false, message: 'Invalid credentials' }); + + res.json({ success: true, message: 'Login successful' }); +}); + +module.exports = router; diff --git a/routes/game.js b/routes/game.js new file mode 100644 index 0000000..de2f3b3 --- /dev/null +++ b/routes/game.js @@ -0,0 +1,22 @@ +// routes/game.js +const express = require('express'); +const router = express.Router(); +const GameSession = require('../models/GameSession'); + +router.post('/save-session', async (req, res) => { + const { username, levelNumber, durationSeconds } = req.body; + + if (!username || !levelNumber || !durationSeconds) { + return res.status(400).json({ success: false, message: 'Missing data' }); + } + + try { + const session = new GameSession({ username, levelNumber, durationSeconds }); + await session.save(); + res.json({ success: true, message: 'Session saved' }); + } catch (err) { + res.status(500).json({ success: false, message: 'Server error', error: err.message }); + } +}); + +module.exports = router; diff --git a/routes/reports.js b/routes/reports.js new file mode 100644 index 0000000..d799c9c --- /dev/null +++ b/routes/reports.js @@ -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 = ` + + +
+ + + +Generated on: ${new Date().toLocaleDateString()}
+Date | +Level | +Duration | +Performance | +
---|---|---|---|
${date} | +Level ${session.levelNumber} | +${formatTime(session.durationSeconds)} | +${performance} | +