From ac66323a78ac1cb3f54953cac0a89b37c2db7a92 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 11:02:10 -0700 Subject: [PATCH 1/9] fix/remove deprecated page --- about.html | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 about.html diff --git a/about.html b/about.html deleted file mode 100644 index 7c27b52..0000000 --- a/about.html +++ /dev/null @@ -1,12 +0,0 @@ - - - Team Name: BBY-14 - Team Members: - - - From c4a90ceb15a6d19adfdc9e051f5602d68a52207b Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 11:14:22 -0700 Subject: [PATCH 2/9] fix/.env example + delete .vscode folder --- .env.example | 9 ++++++--- .vscode/settings.json | 4 ---- app.js | 8 ++++---- 3 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.env.example b/.env.example index 518df8a..255daf9 100755 --- a/.env.example +++ b/.env.example @@ -1,4 +1,7 @@ -mongoURI='mongodb://localhost:27017/' -database='nameOfDatabase' +MONGO_URI='mongodb://localhost:27017/' +DATABASE='nameOfDatabase' PORT=8000 -secret='123456789' \ No newline at end of file +SECRET='123456789' +GEOLOCATION_API='api_key' +EMAIL_USER=mail@example.com +EMAIL_PASS='password' diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c8a7ed4..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "editor.fontFamily": "Monocraft", - "editor.fontLigatures": true -} \ No newline at end of file diff --git a/app.js b/app.js index 466d093..d2fce68 100644 --- a/app.js +++ b/app.js @@ -9,9 +9,9 @@ require('dotenv').config(); const app = express(); const port = process.env.PORT || 3000; -const mongoURI = process.env.mongoURI; -const database = process.env.database; // Database name -const secret = process.env.secret || "123-secret-xyz"; +const mongoURI = process.env.MONGO_URI; +const database = process.env.DATABASE; // Database name +const secret = process.env.SECRET || "123-secret-xyz"; /*** Sessions ***/ app.use(session({ @@ -36,7 +36,7 @@ let users; let assets; let plans; async function initDatabase() { - const db = await connectMongo(mongoURI, database); + const db = connectMongo(mongoURI, database); // For any collection, init here users = await getCollection(db, "users"); From 345cbd2bf2dda6406a0236120492144b475fa1f1 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 18:09:22 -0700 Subject: [PATCH 3/9] fix/database not awaited --- app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index d2fce68..aaf8166 100644 --- a/app.js +++ b/app.js @@ -36,8 +36,8 @@ let users; let assets; let plans; async function initDatabase() { - const db = connectMongo(mongoURI, database); - + const db = await connectMongo(mongoURI, database); + // For any collection, init here users = await getCollection(db, "users"); assets = await getCollection(db, "assets"); From ed06b8731d12aa681bab88fc6bc750197242385e Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 18:13:06 -0700 Subject: [PATCH 4/9] fix/404 not found handling --- app.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app.js b/app.js index aaf8166..b976e9a 100644 --- a/app.js +++ b/app.js @@ -73,6 +73,13 @@ app.get('/aboutUs', (req, res) => { return res.status(status.Ok); }); +// 404 handler - keep the actual notFound route please +// REALLY DONT DELETE THIS +app.get('/notFound', (req, res) => { + res.render('notFound'); + return res.status(status.NotFound); +}); + // Initialize database and start app initDatabase().then(() => { console.log("Successfully connected to MongoDB"); From 5763f03288a63a9cf41d87e06ff120628a5c4a53 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 18:14:22 -0700 Subject: [PATCH 5/9] fix/geolocation api key --- src/public/scripts/geolocation.js | 2 +- src/router/user.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/public/scripts/geolocation.js b/src/public/scripts/geolocation.js index 26f2e1a..51096a6 100644 --- a/src/public/scripts/geolocation.js +++ b/src/public/scripts/geolocation.js @@ -38,7 +38,7 @@ function update(data) { dropdown.appendChild(listItem); }); - console.log(data); + // console.log(data); } function switchButton(clickedButton) { diff --git a/src/router/user.js b/src/router/user.js index 42134cd..740bc59 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -505,7 +505,7 @@ module.exports = (middleware, users, plans, assets) => { }); router.get("/exRates/:lat/:lon", async (req, res) => { if (!req.session.geoData.country) { - const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${req.params.lat},${req.params.lon}&result_type=country&key=${process.env.geolocation_api}`); + const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${req.params.lat},${req.params.lon}&result_type=country&key=${process.env.GEOLOCATION_API}`); const data = await response.json(); country = data.results[0].formatted_address; From 9c0c5604410873eb7fd04de0843b646623aa2373 Mon Sep 17 00:00:00 2001 From: nicoagostini Date: Thu, 8 May 2025 20:09:22 -0700 Subject: [PATCH 6/9] Progress bar calculations added, displaying and updating the database --- src/router/user.js | 35 ++++++++++++++++++++++++------- src/util/calculations.js | 45 ++++++++++++++++++++++++++++++++++++++++ src/views/planDetail.ejs | 8 +++---- src/views/plans.ejs | 2 +- 4 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 src/util/calculations.js diff --git a/src/router/user.js b/src/router/user.js index 740bc59..084ea03 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -1,4 +1,5 @@ const getRates = require("../util/exchangeRate"); +const { calculatePlanProgress, updatePlanProgressInDB } = require("../util/calculations"); const status = require("../util/statuses"); const ObjectId = require('mongodb').ObjectId; const session = require("express-session"); @@ -89,11 +90,21 @@ module.exports = (middleware, users, plans, assets) => { router.get('/plans', async (req, res) => { try { // console.log(new ObjectId(req.session.user._id)); - const userPlans = await plans.find({userId: new ObjectId(req.session.user._id) }).toArray(); - // console.log(userPlans); + const userPlansFromDB = await plans.find({userId: new ObjectId(req.session.user._id) }).toArray(); + // console.log(userPlansFromDB); + + // Use a for...of loop for proper async/await behavior in series for updates + for (const plan of userPlansFromDB) { + const percentage = await calculatePlanProgress(plan, assets, req.session.user._id); + await updatePlanProgressInDB(plan._id, percentage, plans); // Pass the 'plans' collection + } + + // Re-fetch plans to get updated progress for rendering + const updatedUserPlans = await plans.find({ userId: new ObjectId(req.session.user._id) }).toArray(); + res.render('plans', { user: req.session.user, - plans: userPlans, + plans: updatedUserPlans, // Send the most up-to-date plans geoData: req.session.geoData }); } catch (err) { @@ -107,7 +118,8 @@ module.exports = (middleware, users, plans, assets) => { try { const planId = req.params.id; - + let userAssets = await assets.find({ userId: new ObjectId(req.session.user._id) }).toArray(); + if (!ObjectId.isValid(planId)) { req.session.errMessage = "Invalid plan ID format."; @@ -122,10 +134,19 @@ module.exports = (middleware, users, plans, assets) => { return res.status(status.NotFound).redirect('/plans'); } // console.log("Found plan:", plan); + + // The plan.progress should be up-to-date from the database as it was updated in the /plans route + // or when assets/plans are modified. If an immediate recalculation for this specific view is absolutely needed, + // (e.g., if assets were modified without an immediate plan progress update elsewhere), + // you could do it here: + // const currentProgress = await calculatePlanProgress(plan, assets, req.session.user._id); + // plan.progress = currentProgress; // This would only update the 'plan' object for this render, not in DB + res.render('planDetail', { user: req.session.user, - plan: plan, - geoData: req.session.geoData + plan: plan, // This plan object will have the progress from the database + geoData: req.session.geoData, + assets: userAssets, }); } catch (err) { @@ -174,7 +195,7 @@ module.exports = (middleware, users, plans, assets) => { retirementExpenses: value.retirementExpenses, retirementAssets: value.retirementAssets, retirementLiabilities: value.retirementLiabilities, - progress: "0%" + progress: "0" }; try{ diff --git a/src/util/calculations.js b/src/util/calculations.js new file mode 100644 index 0000000..25f5d33 --- /dev/null +++ b/src/util/calculations.js @@ -0,0 +1,45 @@ +const ObjectId = require('mongodb').ObjectId; + +async function calculatePlanProgress(plans, assets, userId) { + if (!plans || typeof plans.retirementAssets === 'undefined') { + console.error("Invalid plan document provided to calculatePlanProgress:", plans); + return 0; + } + if (!assets || typeof assets.find !== 'function') { + console.error("Invalid assetsCollection provided to calculatePlanProgress"); + return 0; + } + + try { + const userAssets = await assets.find({ userId: new ObjectId(userId) }).toArray(); + const totalUserAssetValue = userAssets.reduce((total, asset) => total + asset.value, 0); + let percentage = 0; + + if (plans.retirementAssets > 0) { + percentage = (totalUserAssetValue / plans.retirementAssets) * 100; + } + return percentage; + } catch (err) { + console.error("Error in calculatePlanProgress:", err); + return 0; + } +} + +async function updatePlanProgressInDB(planId, percentage, plans) { + if (!plans || typeof plans.updateOne !== 'function') { + console.error("Error with the plans collection"); + return; + } + if (typeof percentage !== 'number' || isNaN(percentage)) { + console.error(`Error with the percentage: ${percentage}`); + return; + } + + try { + await plans.updateOne({ _id: new ObjectId(planId) }, { $set: { progress: parseFloat(percentage.toFixed(2)) } }); + } catch (err) { + console.error("Error in updatePlanProgressInDB:", err); + } +} + +module.exports = { calculatePlanProgress, updatePlanProgressInDB }; \ No newline at end of file diff --git a/src/views/planDetail.ejs b/src/views/planDetail.ejs index 8b430f1..49c34f9 100644 --- a/src/views/planDetail.ejs +++ b/src/views/planDetail.ejs @@ -12,10 +12,10 @@
Progress - <%= plan.progress %> + <%= plan.progress %>%
-
+
@@ -25,11 +25,11 @@
-

16 MOCK

+

<%= assets.length %>

-

$165,000 MOCK

+

<%= assets.reduce((total, asset) => total + asset.value, 0) %>

diff --git a/src/views/plans.ejs b/src/views/plans.ejs index ce7ca80..0b1b68b 100644 --- a/src/views/plans.ejs +++ b/src/views/plans.ejs @@ -11,7 +11,7 @@
<%= plan.name %>
-
+

<%= plan.description %>

From 42ea4ed8bc42b8aa8ef0090e43a5b84126b9da4f Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 21:39:07 -0700 Subject: [PATCH 7/9] fix/issue #13 --- src/views/dashboard.ejs | 14 ++------------ src/views/partials/footer.ejs | 12 +++++++++++- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/views/dashboard.ejs b/src/views/dashboard.ejs index 88ed427..11979d3 100644 --- a/src/views/dashboard.ejs +++ b/src/views/dashboard.ejs @@ -4,8 +4,8 @@
@@ -90,15 +90,5 @@
- - - - - - <%- include("./partials/navBar") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/partials/footer.ejs b/src/views/partials/footer.ejs index 110cbe0..89cc09b 100644 --- a/src/views/partials/footer.ejs +++ b/src/views/partials/footer.ejs @@ -6,5 +6,15 @@ + + + + + + - \ No newline at end of file + From 73a510252be06bf2982747a7ae174daedec486ca Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 8 May 2025 23:30:13 -0700 Subject: [PATCH 8/9] update+fix/asset icons + load geolocation scripts --- src/auth/middleware.js | 7 +-- src/public/scripts/assetManager.js | 59 +++++++++++++++++++-- src/public/svgs/icons/Bike.svg | 1 + src/public/svgs/icons/Book.svg | 1 + src/public/svgs/icons/Camera.svg | 1 + src/public/svgs/icons/Car.svg | 1 + src/public/svgs/icons/Coins.svg | 1 + src/public/svgs/icons/Console.svg | 1 + src/public/svgs/icons/Desktop.svg | 1 + src/public/svgs/icons/Device.svg | 1 + src/public/svgs/icons/Electronic.svg | 1 + src/public/svgs/icons/Home.svg | 1 + src/public/svgs/icons/Laptop.svg | 1 + src/public/svgs/icons/Money.svg | 1 + src/public/svgs/icons/Motorcycle.svg | 1 + src/public/svgs/icons/Other.svg | 1 + src/public/svgs/icons/Phone.svg | 1 + src/public/svgs/icons/Stock.svg | 1 + src/router/user.js | 18 +++++-- src/views/assets.ejs | 79 ++++++++++++++++++++++------ src/views/dashboard.ejs | 1 + src/views/more.ejs | 1 + src/views/newPlan.ejs | 2 + src/views/partials/footer.ejs | 9 ---- src/views/partials/scriptLoader.ejs | 8 +++ src/views/planDetail.ejs | 1 + src/views/plans.ejs | 1 + src/views/profile.ejs | 1 + src/views/questionnaire.ejs | 2 + 29 files changed, 170 insertions(+), 35 deletions(-) create mode 100644 src/public/svgs/icons/Bike.svg create mode 100644 src/public/svgs/icons/Book.svg create mode 100644 src/public/svgs/icons/Camera.svg create mode 100644 src/public/svgs/icons/Car.svg create mode 100644 src/public/svgs/icons/Coins.svg create mode 100644 src/public/svgs/icons/Console.svg create mode 100644 src/public/svgs/icons/Desktop.svg create mode 100644 src/public/svgs/icons/Device.svg create mode 100644 src/public/svgs/icons/Electronic.svg create mode 100644 src/public/svgs/icons/Home.svg create mode 100644 src/public/svgs/icons/Laptop.svg create mode 100644 src/public/svgs/icons/Money.svg create mode 100644 src/public/svgs/icons/Motorcycle.svg create mode 100644 src/public/svgs/icons/Other.svg create mode 100644 src/public/svgs/icons/Phone.svg create mode 100644 src/public/svgs/icons/Stock.svg create mode 100644 src/views/partials/scriptLoader.ejs diff --git a/src/auth/middleware.js b/src/auth/middleware.js index 3c12f61..5c24807 100644 --- a/src/auth/middleware.js +++ b/src/auth/middleware.js @@ -1,7 +1,7 @@ const status = require("../util/statuses"); const session = require("express-session"); -// Get all user routes names +// Get all names of user routes let userRouter = require("../router/user")((req, res, next) => next(), null, null, null); userRouter.stack.shift(); const userRoutes = userRouter.stack.map((layer) => layer.route.path.split("/")[1]); @@ -12,8 +12,9 @@ const userRoutes = userRouter.stack.map((layer) => layer.route.path.split("/")[1 */ const createMiddleware = (users) => { return async (req, res, next) => { - // Redirect not found pages to 404 page - if (!userRoutes.includes(req.url.split("/")[1])) { + // Check if incoming request route exists in user routes + // redirect to 404 if not + if (!userRoutes.includes(req.url.split("/")[1].split("?")[0])) { return res.status(status.NotFound).redirect("/notFound"); } diff --git a/src/public/scripts/assetManager.js b/src/public/scripts/assetManager.js index 86ddd08..16bbc37 100644 --- a/src/public/scripts/assetManager.js +++ b/src/public/scripts/assetManager.js @@ -8,6 +8,12 @@ const assetForms = [ * resetAll asset creation forms */ function resetAll() { + document.getElementById("dropdown-icon-button").innerHTML = ` + Other Other + + `; document.getElementById("create-other-asset-form").reset(); document.getElementById("create-saving-asset-form").reset(); document.getElementById("create-stock-asset-form").reset(); @@ -40,6 +46,7 @@ function resetRadio() { const assetKeys = { other: [ "name", + "dropdown-icon-button", "value", "description", "purchaseDate", @@ -59,8 +66,17 @@ const assetKeys = { /** * lockAsset prevents edits to asset view modal * @param {string} assetId + * @param {string} icon to defualt to */ -function lockAsset(assetId) { +function lockAsset(assetId, icon) { + let dropdown = document.getElementById(`dropdown-icon-button-${assetId}`); + if (dropdown) dropdown.innerHTML = ` + ${icon} ${icon} + + `; + document.getElementById(`${assetId}-form`).reset(); const type = document.getElementById(`type-${assetId}`).value; @@ -74,14 +90,15 @@ function lockAsset(assetId) { document.getElementById(`save-${assetId}`).classList.add("cursor-not-allowed"); document.getElementById(`edit-${assetId}`).innerHTML = "Edit"; - document.getElementById(`edit-${assetId}`).onclick = () => { unlockAsset(assetId) }; + document.getElementById(`edit-${assetId}`).onclick = () => { unlockAsset(assetId, icon) }; } /** * unlockAsset allows edits to asset view modal * @param {string} assetId + * @param {string} icon to defualt to */ -function unlockAsset(assetId) { +function unlockAsset(assetId, icon) { const type = document.getElementById(`type-${assetId}`).value; assetKeys[type].forEach((key) => { @@ -92,8 +109,40 @@ function unlockAsset(assetId) { document.getElementById(`save-${assetId}`).classList.remove("cursor-not-allowed"); document.getElementById(`save-${assetId}`).classList.add("cursor-pointer"); - document.getElementById(`edit-${assetId}`).innerHTML = "Cancel changes"; - document.getElementById(`edit-${assetId}`).onclick = () => { lockAsset(assetId) }; + document.getElementById(`edit-${assetId}`).innerHTML = "Cancel"; + document.getElementById(`edit-${assetId}`).onclick = () => { lockAsset(assetId, icon) }; +} + +/** + * autoOpenCreate checks if popup param + * in url to auto open create popup + */ +function autoOpenCreate() { + const query = window.location.search; + const params = new URLSearchParams(query); + + if (params.has("popup")) { + document.getElementById('create-asset-modal').showModal(); + } +} + +/** + * selectIcon updated selected icon while creating + * or modifying assets. + * @param {button element} selectedIcon + * @param {string} assetId + */ +function selectIcon(selectedIcon, assetId="") { + document.getElementById(`dropdown-icon-button${assetId != "" ? "-" : ""}${assetId}`).value = selectedIcon.value; + document.getElementById(`icon${assetId != "" ? "-" : ""}${assetId}`).value = selectedIcon.value + + document.getElementById(`dropdown-icon-button${assetId != "" ? "-" : ""}${assetId}`).innerHTML = selectedIcon.innerHTML + + ` + + `; } resetRadio(); +autoOpenCreate(); diff --git a/src/public/svgs/icons/Bike.svg b/src/public/svgs/icons/Bike.svg new file mode 100644 index 0000000..c31ed29 --- /dev/null +++ b/src/public/svgs/icons/Bike.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Book.svg b/src/public/svgs/icons/Book.svg new file mode 100644 index 0000000..d1cd59b --- /dev/null +++ b/src/public/svgs/icons/Book.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Camera.svg b/src/public/svgs/icons/Camera.svg new file mode 100644 index 0000000..4fda7d9 --- /dev/null +++ b/src/public/svgs/icons/Camera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Car.svg b/src/public/svgs/icons/Car.svg new file mode 100644 index 0000000..63014de --- /dev/null +++ b/src/public/svgs/icons/Car.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Coins.svg b/src/public/svgs/icons/Coins.svg new file mode 100644 index 0000000..17fee69 --- /dev/null +++ b/src/public/svgs/icons/Coins.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Console.svg b/src/public/svgs/icons/Console.svg new file mode 100644 index 0000000..932964d --- /dev/null +++ b/src/public/svgs/icons/Console.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Desktop.svg b/src/public/svgs/icons/Desktop.svg new file mode 100644 index 0000000..2ad4fbd --- /dev/null +++ b/src/public/svgs/icons/Desktop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Device.svg b/src/public/svgs/icons/Device.svg new file mode 100644 index 0000000..ea62d89 --- /dev/null +++ b/src/public/svgs/icons/Device.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Electronic.svg b/src/public/svgs/icons/Electronic.svg new file mode 100644 index 0000000..7f34f13 --- /dev/null +++ b/src/public/svgs/icons/Electronic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Home.svg b/src/public/svgs/icons/Home.svg new file mode 100644 index 0000000..230751a --- /dev/null +++ b/src/public/svgs/icons/Home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Laptop.svg b/src/public/svgs/icons/Laptop.svg new file mode 100644 index 0000000..eeb9595 --- /dev/null +++ b/src/public/svgs/icons/Laptop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Money.svg b/src/public/svgs/icons/Money.svg new file mode 100644 index 0000000..1476d84 --- /dev/null +++ b/src/public/svgs/icons/Money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Motorcycle.svg b/src/public/svgs/icons/Motorcycle.svg new file mode 100644 index 0000000..bd3776e --- /dev/null +++ b/src/public/svgs/icons/Motorcycle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Other.svg b/src/public/svgs/icons/Other.svg new file mode 100644 index 0000000..31bfd17 --- /dev/null +++ b/src/public/svgs/icons/Other.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Phone.svg b/src/public/svgs/icons/Phone.svg new file mode 100644 index 0000000..b34a759 --- /dev/null +++ b/src/public/svgs/icons/Phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/public/svgs/icons/Stock.svg b/src/public/svgs/icons/Stock.svg new file mode 100644 index 0000000..3caf5b6 --- /dev/null +++ b/src/public/svgs/icons/Stock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/router/user.js b/src/router/user.js index 084ea03..dc8b232 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -4,7 +4,9 @@ const status = require("../util/statuses"); const ObjectId = require('mongodb').ObjectId; const session = require("express-session"); const bcrypt = require("bcrypt"); +const path = require("path"); const joi = require("joi"); +const fs = require("fs"); const salt = 12; /** @@ -20,6 +22,7 @@ const getAssetSchema = (type) => { case "other": assetSchema = joi.object({ type: joi.string().valid("other", "stock", "saving").required(), + icon: joi.string().alphanum().required(), name: joi.string().alphanum().min(3).max(30).required(), value: joi.number().min(0).required(), purchaseDate: joi.date().required(), @@ -60,7 +63,11 @@ const getAssetSchema = (type) => { */ module.exports = (middleware, users, plans, assets) => { const router = require("express").Router(); - + + // Create list of icon filenames + let icons = fs.readdirSync(path.join(__dirname, "../public/svgs/icons")); + icons = icons.map((icon) => icon.split(".")[0]); + router.use(middleware); router.get('/home', async (req, res) => { @@ -83,7 +90,9 @@ module.exports = (middleware, users, plans, assets) => { user: req.session.user, errMessage: req.session.errMessage, assets: userAssets, - geoData: req.session.geoData }); + geoData: req.session.geoData, + icons: icons, + }); return res.status(status.Ok); }); @@ -388,6 +397,7 @@ module.exports = (middleware, users, plans, assets) => { newAsset.name = `${newAsset.ticker} Stock`; } newAsset.value = parseFloat(newAsset.value); + newAsset.icon = type == "stock" ? "Stock" : type == "saving" ? "Coins" : newAsset.icon; assets.insertOne(newAsset, (err, _) => { if (err) { @@ -433,7 +443,8 @@ module.exports = (middleware, users, plans, assets) => { update.name = `${update.ticker} Stock`; } update.value = parseFloat(update.value); - delete update.id + delete update.id; + delete update.userId; assets.updateOne( { "_id": new ObjectId(req.body.id) }, @@ -524,6 +535,7 @@ module.exports = (middleware, users, plans, assets) => { return res.status(status.InternalServerError).redirect("/profile"); }); }); + router.get("/exRates/:lat/:lon", async (req, res) => { if (!req.session.geoData.country) { const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${req.params.lat},${req.params.lon}&result_type=country&key=${process.env.GEOLOCATION_API}`); diff --git a/src/views/assets.ejs b/src/views/assets.ejs index cec34b0..0b6eae4 100644 --- a/src/views/assets.ejs +++ b/src/views/assets.ejs @@ -2,7 +2,6 @@ <%- include("./partials/header") %>
-
@@ -38,7 +37,31 @@
- + + + + +
+ + +
@@ -178,7 +201,9 @@ + +
+ <% } else { %> + + <% } %> + +

<%= String(asset.type).charAt(0).toUpperCase() + String(asset.type).slice(1); %> Asset

+
+ <% if (asset.type != "stock") { %> @@ -328,16 +381,12 @@ <%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/dashboard.ejs b/src/views/dashboard.ejs index 11979d3..519832d 100644 --- a/src/views/dashboard.ejs +++ b/src/views/dashboard.ejs @@ -91,4 +91,5 @@
<%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/more.ejs b/src/views/more.ejs index 59e3acf..934700e 100644 --- a/src/views/more.ejs +++ b/src/views/more.ejs @@ -6,5 +6,6 @@ <%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/newPlan.ejs b/src/views/newPlan.ejs index a05dd1a..5370290 100644 --- a/src/views/newPlan.ejs +++ b/src/views/newPlan.ejs @@ -37,4 +37,6 @@ +<%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/partials/footer.ejs b/src/views/partials/footer.ejs index 89cc09b..9ee0b91 100644 --- a/src/views/partials/footer.ejs +++ b/src/views/partials/footer.ejs @@ -7,14 +7,5 @@ - - - - - diff --git a/src/views/partials/scriptLoader.ejs b/src/views/partials/scriptLoader.ejs new file mode 100644 index 0000000..afe997b --- /dev/null +++ b/src/views/partials/scriptLoader.ejs @@ -0,0 +1,8 @@ + + + + diff --git a/src/views/planDetail.ejs b/src/views/planDetail.ejs index 49c34f9..e75b46f 100644 --- a/src/views/planDetail.ejs +++ b/src/views/planDetail.ejs @@ -71,4 +71,5 @@ <%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> diff --git a/src/views/plans.ejs b/src/views/plans.ejs index 0b1b68b..5926a22 100644 --- a/src/views/plans.ejs +++ b/src/views/plans.ejs @@ -21,4 +21,5 @@ <%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> diff --git a/src/views/profile.ejs b/src/views/profile.ejs index b1a45f3..b8a8c3d 100644 --- a/src/views/profile.ejs +++ b/src/views/profile.ejs @@ -138,4 +138,5 @@ <%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file diff --git a/src/views/questionnaire.ejs b/src/views/questionnaire.ejs index 993a8c1..84420e6 100644 --- a/src/views/questionnaire.ejs +++ b/src/views/questionnaire.ejs @@ -68,4 +68,6 @@ +<%- include("./partials/navBar") %> +<%- include("./partials/scriptLoader") %> <%- include("./partials/footer") %> \ No newline at end of file From 540e191d27586f49ab8d74a9fb853e2e7213ee25 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Fri, 9 May 2025 09:49:14 -0700 Subject: [PATCH 9/9] refactor/remove debug statements --- src/auth/authentication.js | 2 +- src/public/scripts/geolocation.js | 2 -- src/router/user.js | 7 +------ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/auth/authentication.js b/src/auth/authentication.js index a540751..727f4e7 100644 --- a/src/auth/authentication.js +++ b/src/auth/authentication.js @@ -84,7 +84,7 @@ module.exports = (users) => { financialData: false, }).then((results, err) => { if (err) { - console.error(err); + console.error("Error creating user on signup: ", err); res.session.errMessage = "Internal server error"; return res.status(status.InternalServerError).redirect("/signup"); } diff --git a/src/public/scripts/geolocation.js b/src/public/scripts/geolocation.js index 51096a6..7fce450 100644 --- a/src/public/scripts/geolocation.js +++ b/src/public/scripts/geolocation.js @@ -37,8 +37,6 @@ function update(data) { dropdown.appendChild(listItem); }); - - // console.log(data); } function switchButton(clickedButton) { diff --git a/src/router/user.js b/src/router/user.js index dc8b232..8816990 100644 --- a/src/router/user.js +++ b/src/router/user.js @@ -98,9 +98,7 @@ module.exports = (middleware, users, plans, assets) => { router.get('/plans', async (req, res) => { try { - // console.log(new ObjectId(req.session.user._id)); const userPlansFromDB = await plans.find({userId: new ObjectId(req.session.user._id) }).toArray(); - // console.log(userPlansFromDB); // Use a for...of loop for proper async/await behavior in series for updates for (const plan of userPlansFromDB) { @@ -142,7 +140,6 @@ module.exports = (middleware, users, plans, assets) => { req.session.errMessage = "Plan not found or you do not have permission to view it."; return res.status(status.NotFound).redirect('/plans'); } - // console.log("Found plan:", plan); // The plan.progress should be up-to-date from the database as it was updated in the /plans route // or when assets/plans are modified. If an immediate recalculation for this specific view is absolutely needed, @@ -254,9 +251,7 @@ module.exports = (middleware, users, plans, assets) => { }); }); - router.post('/questionnaire', (req, res) => { - // console.log("Questionnaire POST body:", req.body); - + router.post('/questionnaire', (req, res) => { const questionnaireSchema = joi.object({ dob: joi.date().required(), education: joi.string().valid('primary', 'secondary', 'tertiary', 'postgraduate').required(),