diff --git a/app.js b/app.js index 9e5e519..0310bf1 100644 --- a/app.js +++ b/app.js @@ -39,6 +39,7 @@ async function initDatabase() { // For any collection, init here users = await getCollection(db, "users"); + plans = await getCollection(db, "plans"); } /*** ROUTINGS ***/ @@ -88,8 +89,8 @@ initDatabase().then(() => { app.use(require("./src/auth/authentication")(users)); // Import middleware & apply to user routes - const middleware = require("./src/auth/middleware")(users); - app.use(require('./src/router/user')(middleware, users)); + const middleware = require("./src/auth/middleware")(users, plans); + app.use(require('./src/router/user')(middleware, users, plans)); // 404 handler app.get('/*splat', (req, res) => { diff --git a/src/auth/authentication.js b/src/auth/authentication.js index b71fa12..261b5a4 100644 --- a/src/auth/authentication.js +++ b/src/auth/authentication.js @@ -40,6 +40,7 @@ module.exports = (users) => { } req.session.authenticated = true; + req.session.userId = user._id; req.session.email = req.body.email; req.session.errMessage = ""; res.redirect("/home"); @@ -84,6 +85,7 @@ module.exports = (users) => { req.session.authenticated = true; req.session.email = req.body.email; + req.session.userId = results.insertedId; req.session.errMessage = ""; return res.status(status.Ok).redirect("/home"); diff --git a/src/router/user.js b/src/router/user.js index 407aca9..9daa7cb 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -3,7 +3,7 @@ const bcrypt = require('bcrypt'); const joi = require("joi"); const salt = 12; -module.exports = (middleware, users) => { +module.exports = (middleware, users, plans) => { const router = require("express").Router(); router.use(middleware); @@ -18,11 +18,78 @@ module.exports = (middleware, users) => { return res.status(status.Ok); }); - router.get('/plans', (req, res) => { - res.render('plans', { user: req.user }); - return res.status(status.Ok); + router.get('/plans', async (req, res) => { + if (!req.session.email) { + return res.status(status.Unauthorized).redirect('/login'); + } + + try { + + // console.log(req.user.email); + const userPlans = await plans.find({userEmail: req.user.email }).toArray(); + // console.log(userPlans); + res.render('plans', { + user: req.user, + plans: userPlans + }); + + } catch (err) { + console.error("Error fetching plans:", err); + req.session.errMessage = "Could not load your plans. Please try again."; + res.status(status.InternalServerError).redirect('/home'); + } }); + router.get('/newPlan', (req, res) => { + const errMessage = req.session.errMessage; + req.session.errMessage = ""; + res.render('newPlan', { user: req.user, errMessage: errMessage }); + }); + + router.post('/newPlan', async (req, res) => { + if (!req.session.email) { + return res.status(status.Unauthorized).redirect('/login'); + } + + const planSchema = joi.object({ + name: joi.string().min(3).max(100).required(), + retirementAge: joi.number().min(18).max(120).required(), + retirementExpenses: joi.number().min(0).required(), + retirementAssets: joi.number().min(0).required(), + retirementLiabilities: joi.number().min(0).required(), + }); + + const validationOptions = { convert: true, abortEarly: false }; + const { error, value } = planSchema.validate(req.body, validationOptions); + + if (error) { + console.error("Plan validation error:", error.details); + req.session.errMessage = "Invalid input: " + error.details.map(d => d.message.replace(/"/g, '')).join(', '); + res.status(status.BadRequest).redirect("/newPlan"); + return; + } + const newPlan = { + userEmail: req.user.email, + name: value.name, + retirementAge: value.retirementAge, + retirementExpenses: value.retirementExpenses, + retirementAssets: value.retirementAssets, + retirementLiabilities: value.retirementLiabilities, + progress: "0%" + }; + + try{ + await plans.insertOne(newPlan); + req.session.errMessage = ""; + res.redirect('/plans'); + } + catch(err){ + console.error("Error saving plan:", err); + req.session.errMessage = "An error occurred while saving your plan. Please try again."; + res.status(status.InternalServerError).redirect("/newPlan"); + } + }); + router.get('/more', (req, res) => { res.render('more', { user: req.user }); return res.status(status.Ok); @@ -45,6 +112,8 @@ module.exports = (middleware, users) => { }); router.post('/questionnaire', (req, res) => { + // console.log("Questionnaire POST body:", req.body); + const questionnaireSchema = joi.object({ dob: joi.date().required(), education: joi.string().valid('primary', 'secondary', 'tertiary', 'postgraduate').required(), @@ -53,10 +122,6 @@ module.exports = (middleware, users) => { expenses: joi.number().min(0).required(), assets: joi.number().min(0).required(), liabilities: joi.number().min(0).required(), - retirementAge: joi.number().min(18).max(120).required(), - retirementExpenses: joi.number().min(0).required(), - retirementAssets: joi.number().min(0).required(), - retirementLiabilities: joi.number().min(0).required(), }); const validationOptions = { convert: true, abortEarly: false }; @@ -81,10 +146,6 @@ module.exports = (middleware, users) => { expenses: value.expenses, assets: value.assets, liabilities: value.liabilities, - retirementAge: value.retirementAge, - retirementExpenses: value.retirementExpenses, - retirementAssets: value.retirementAssets, - retirementLiabilities: value.retirementLiabilities, } } ).then((result) => { diff --git a/src/views/newPlan.ejs b/src/views/newPlan.ejs new file mode 100644 index 0000000..40b409b --- /dev/null +++ b/src/views/newPlan.ejs @@ -0,0 +1,40 @@ +<%- include("./partials/fileHeader") %> +<%- include("./partials/header") %> + + + Welcome: <%= user.email %> + + Financial Questionnaire + + + Plan Name + + + + Desired Retirement Age + + + + + Estimated Monthly Retirement Expenses + + + + + Estimated Retirement Assets + + + + + Estimated Retirement Liabilities + + + + + Save Plan + + + + + +<%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/plans.ejs b/src/views/plans.ejs index 7f6e699..10a6ca1 100644 --- a/src/views/plans.ejs +++ b/src/views/plans.ejs @@ -1,8 +1,23 @@ <%- include("./partials/fileHeader") %> <%- include("./partials/header") %> - - The Plans Page + + Welcome: <%= user.email %> + + My Retirement Plans + New Plan + + <% plans.forEach(plan => { %> + + <%= plan.name %> + + + + <%= plan.description %> + + <% }) %> + + <%- include("./partials/navBar") %> diff --git a/src/views/questionnaire.ejs b/src/views/questionnaire.ejs index 10a1b29..c023058 100644 --- a/src/views/questionnaire.ejs +++ b/src/views/questionnaire.ejs @@ -60,26 +60,6 @@ Liabilities - - - Desired Retirement Age - - - - - Estimated Monthly Retirement Expenses - - - - - Estimated Retirement Assets - - - - - Estimated Retirement Liabilities - - Submit Questionnaire
<%= plan.description %>