diff --git a/app.js b/app.js index 8e9dd77..9bd6875 100644 --- a/app.js +++ b/app.js @@ -38,6 +38,7 @@ async function initDatabase() { // For any collection, init here users = await getCollection(db, "users"); + plans = await getCollection(db, "plans"); } /*** ROUTINGS ***/ @@ -76,8 +77,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 fe7c97d..db53450 100644 --- a/src/auth/authentication.js +++ b/src/auth/authentication.js @@ -42,6 +42,7 @@ module.exports = (users) => { console.log("User logged in successfully"); console.log("User email: " + req.body.email); req.session.authenticated = true; + req.session.userId = user._id; req.session.email = req.body.email; req.session.errMessage = ""; res.redirect("/home"); @@ -86,6 +87,7 @@ module.exports = (users) => { req.session.authenticated = true; req.session.email = req.body.email; + req.session.userId = results.insertedId; req.session.errMessage = ""; res.status(status.Ok); diff --git a/src/router/user.js b/src/router/user.js index dd8eaf6..dfd022d 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -1,7 +1,7 @@ const status = require("../util/statuses"); const joi = require("joi"); -module.exports = (middleware, users) => { +module.exports = (middleware, users, plans) => { const router = require("express").Router(); router.use(middleware); @@ -16,11 +16,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); @@ -43,7 +110,7 @@ module.exports = (middleware, users) => { }); router.post('/questionnaire', (req, res) => { - console.log("Questionnaire POST body:", req.body); + // console.log("Questionnaire POST body:", req.body); const questionnaireSchema = joi.object({ dob: joi.date().required(), 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") %>
<%= plan.description %>