diff --git a/src/public/scripts/calcExchange.js b/src/public/scripts/calcExchange.js deleted file mode 100644 index 29956e8..0000000 --- a/src/public/scripts/calcExchange.js +++ /dev/null @@ -1,3 +0,0 @@ -let rate = document.getElementsByClassName("countryButton").value; - -document.getElementById("exchange").innerHTML \ No newline at end of file diff --git a/src/public/scripts/dollarFormat.js b/src/public/scripts/dollarFormat.js index a22f2c5..e962411 100644 --- a/src/public/scripts/dollarFormat.js +++ b/src/public/scripts/dollarFormat.js @@ -1,12 +1,12 @@ + /** * Function takes in a number and formats it to currency - * @param {integer} - * @returns nuber formatted in currency + * @param {number} value + * @returns {string} number formatted in currency */ - document.addEventListener("DOMContentLoaded", () => { const number = document.querySelectorAll(".planGoal"); - number.forEach(value => { + number.forEach((value) => { num = parseFloat(value.textContent); if (num >= 999999) { value.textContent = "$" + (num /= 1000000) + "M"; diff --git a/src/public/scripts/editPlanModals.js b/src/public/scripts/editPlanModals.js new file mode 100644 index 0000000..55f9909 --- /dev/null +++ b/src/public/scripts/editPlanModals.js @@ -0,0 +1,65 @@ +// Basic client-side form submission handler to process JSON response +document.addEventListener('DOMContentLoaded', () => { + const form = document.getElementById('editPlanForm'); + const errorMessagesDiv = document.getElementById('formErrorMessages'); + + // Store initial form values + const initialValues = { + name: form.name.value, + retirementAge: form.retirementAge.value, + retirementExpenses: form.retirementExpenses.value, + retirementAssets: form.retirementAssets.value, + retirementLiabilities: form.retirementLiabilities.value + }; + + const resetButton = document.getElementById('resetButton'); + resetButton.addEventListener('click', function() { + form.name.value = initialValues.name; + form.retirementAge.value = initialValues.retirementAge; + form.retirementExpenses.value = initialValues.retirementExpenses; + form.retirementAssets.value = initialValues.retirementAssets; + form.retirementLiabilities.value = initialValues.retirementLiabilities; + if (errorMessagesDiv) { + errorMessagesDiv.style.display = 'none'; // Hide error message on reset + errorMessagesDiv.textContent = ''; + } + }); + + if (form) { + form.addEventListener('submit', async function(event) { + event.preventDefault(); // Prevent traditional form submission + errorMessagesDiv.textContent = ''; + errorMessagesDiv.style.display = 'none'; + + const formData = new FormData(form); + const data = {}; + formData.forEach((value, key) => { + data[key] = value; + }); + + try { + const response = await fetch(form.action, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }); + + const result = await response.json(); + + if (response.ok && result.success) { + // alert('Plan updated successfully!'); // Optional: show an alert + window.location.href = `/plans/<%= plan._id %>`; // Redirect to plan detail page + } else { + errorMessagesDiv.textContent = result.message || 'An error occurred while updating the plan.'; + errorMessagesDiv.style.display = 'block'; + } + } catch (error) { + console.error('Error submitting form:', error); + errorMessagesDiv.textContent = 'A network error occurred. Please try again.'; + errorMessagesDiv.style.display = 'block'; + } + }); + } +}); \ No newline at end of file diff --git a/src/public/scripts/footer.js b/src/public/scripts/footer.js index e63f58a..03e9328 100644 --- a/src/public/scripts/footer.js +++ b/src/public/scripts/footer.js @@ -13,6 +13,7 @@ if(page !== "login" && page !== "signup" && page !== "forgotPassword" && page != factButton.addEventListener("click", () => { factMenu.classList.toggle("hidden"); }); + factSubmitButton.addEventListener("click", () => { fetch("/fact", { method: "POST", diff --git a/src/public/scripts/geolocation.js b/src/public/scripts/geolocation.js index 94c9c66..15d4bbb 100644 --- a/src/public/scripts/geolocation.js +++ b/src/public/scripts/geolocation.js @@ -1,9 +1,17 @@ +/** + * getLocation gets the geolocation of user on page load. + */ function getLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(getLatestExchange, error); } } +/** + * update the currency exchange rate dropdown + * or display error + * @param {object} data + */ function update(data) { if (data.data.message != "error") { document.getElementById("loading").style = "display: none"; @@ -48,6 +56,10 @@ function update(data) { } } +/** + * switchButton changes the selected exchange rate icon + * @param {element} clickedButton + */ function switchButton(clickedButton) { document.getElementById("dropdown-country-button").value = clickedButton.value; updateExchange(document.getElementById("dropdown-country-button").value); @@ -60,10 +72,18 @@ function switchButton(clickedButton) { `; } +/** + * updateExchange updates the exchange rate + * @param {number} exRate + */ function updateExchange(exRate) { document.getElementById("exchange").innerHTML = "$1.00 = $" +`${(1 * exRate).toFixed(2)}`; } +/** + * getLatestExchange gets rates from API from a given location. + * @param {object} position coordinates + */ async function getLatestExchange(position) { let lat = position.coords.latitude; let lon = position.coords.longitude; @@ -73,6 +93,10 @@ async function getLatestExchange(position) { update(data); } +/** + * error displays error message + * @param {string} err + */ function error(err) { const data = { data: { diff --git a/src/public/scripts/planManager.js b/src/public/scripts/planManager.js index a1d4bec..9f0b1ac 100644 --- a/src/public/scripts/planManager.js +++ b/src/public/scripts/planManager.js @@ -1,3 +1,7 @@ +/** + * editPlan redirect + * @param {string} planId + */ function editPlan(planId) { if (planId) { window.location.href = `/plans/${planId}/edit`; @@ -7,6 +11,10 @@ function editPlan(planId) { } } +/** + * deletePlan handler + * @param {string} planId + */ async function deletePlan(planId) { if (!planId) { console.error('deletePlan called without a planId'); @@ -36,4 +44,4 @@ async function deletePlan(planId) { alert('An error occurred while trying to delete the plan. Please check the console for details and ensure the server is running.'); } } -} \ No newline at end of file +} diff --git a/src/public/scripts/planModals.js b/src/public/scripts/planModals.js new file mode 100644 index 0000000..07a8dbe --- /dev/null +++ b/src/public/scripts/planModals.js @@ -0,0 +1,78 @@ +document.addEventListener('DOMContentLoaded', () => { + const openModalBtn = document.getElementById('openNewPlanModalBtn'); + const newPlanDialog = document.getElementById('newPlanDialog'); + const newPlanForm = document.getElementById('newPlanForm'); + const submitNewPlanBtn = document.getElementById('submitNewPlanBtn'); + const newPlanError = document.getElementById('newPlanError'); + const resetNewPlanFormBtn = document.getElementById('resetNewPlanFormBtn'); + + openModalBtn.addEventListener('click', () => { + newPlanDialog.showModal(); + // Error reset is now handled by 'close' event, but good to clear on open too + newPlanError.style.display = 'none'; + newPlanError.textContent = ''; + }); + + // Handles form reset and error clearing when dialog is closed by any means (Esc, Cancel button, backdrop click, successful submit) + newPlanDialog.addEventListener('close', () => { + newPlanForm.reset(); + newPlanError.style.display = 'none'; + newPlanError.textContent = ''; + }); + + // Close dialog if user clicks on the backdrop + newPlanDialog.addEventListener('click', (event) => { + if (event.target === newPlanDialog) { + newPlanDialog.close(); // This will trigger the 'close' event listener above + } + }); + + resetNewPlanFormBtn.addEventListener('click', () => { + newPlanForm.reset(); + newPlanError.style.display = 'none'; + newPlanError.textContent = ''; + }); + + newPlanForm.addEventListener('submit', async (event) => { + event.preventDefault(); + submitNewPlanBtn.disabled = true; + submitNewPlanBtn.textContent = 'Saving...'; + newPlanError.style.display = 'none'; + + const formData = new FormData(newPlanForm); + const data = Object.fromEntries(formData.entries()); + + try { + const response = await fetch('/newPlan', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }); + + if (response.ok) { + const result = await response.json(); + if (result.success) { + newPlanDialog.close(); // This will trigger the 'close' event listener + window.location.reload(); // Reload to see the new plan + } else { + newPlanError.textContent = result.message || 'Failed to create plan. Please try again.'; + newPlanError.style.display = 'block'; + } + } else { + const errorData = await response.json(); + newPlanError.textContent = errorData.message || `Error: ${response.status} - ${response.statusText}`; + newPlanError.style.display = 'block'; + } + } catch (error) { + console.error('Error submitting new plan:', error); + newPlanError.textContent = 'An unexpected error occurred. Please try again.'; + newPlanError.style.display = 'block'; + } + finally { + submitNewPlanBtn.disabled = false; + submitNewPlanBtn.textContent = 'Save Plan'; + } + }); +}); \ No newline at end of file diff --git a/src/views/editPlan.ejs b/src/views/editPlan.ejs index 63ae3a7..44862c7 100644 --- a/src/views/editPlan.ejs +++ b/src/views/editPlan.ejs @@ -55,73 +55,7 @@ - + <%- include('./partials/navBar') %> <%- include('./partials/scriptLoader') %> diff --git a/src/views/plans.ejs b/src/views/plans.ejs index fa48b64..1f47031 100644 --- a/src/views/plans.ejs +++ b/src/views/plans.ejs @@ -65,84 +65,5 @@ <%- include("./partials/navBar") %> <%- include("./partials/scriptLoader") %> - + <%- include("./partials/footer") %>