From f28132e4b8be81b98500dc47e067e9e7f15c9b86 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 13:29:44 -0400 Subject: [PATCH 01/22] splitting into components --- css/02_new_initiatives.css | 9 ---- css/common.css | 10 ++-- index.html | 40 ++++++++++++---- js/archive/start_from_save_main.js | 13 +++++ js/components/header/header.css | 9 ++++ js/components/header/header.js | 3 ++ js/components/prompt/prompt.css | 12 +++++ js/components/prompt/prompt.js | 3 ++ .../components/welcome/welcome.css | 1 - js/components/welcome/welcome.js | 7 +++ js/init.js | 13 ++++- js/pages/00_welcome/main.js | 17 +++---- js/pages/02_new_initiatives/main.js | 48 +++---------------- js/pages/02_new_initiatives/main_archive.js | 44 +++++++++++++++++ .../02_new_initiatives/new_inits_helpers.js | 35 ++++++++++++++ pages/02_new_initiatives.html | 7 ++- 16 files changed, 189 insertions(+), 82 deletions(-) create mode 100644 js/archive/start_from_save_main.js create mode 100644 js/components/header/header.css create mode 100644 js/components/header/header.js create mode 100644 js/components/prompt/prompt.css create mode 100644 js/components/prompt/prompt.js rename css/00_welcome.css => js/components/welcome/welcome.css (92%) create mode 100644 js/components/welcome/welcome.js create mode 100644 js/pages/02_new_initiatives/main_archive.js create mode 100644 js/pages/02_new_initiatives/new_inits_helpers.js diff --git a/css/02_new_initiatives.css b/css/02_new_initiatives.css index 32a3752..f56b4a4 100644 --- a/css/02_new_initiatives.css +++ b/css/02_new_initiatives.css @@ -13,12 +13,3 @@ .btn.btn-submit:hover { color: black; } - -#initiative-table-div { - display: none; - /* text-align: center; */ -} - -#initial-questions { - text-align: center; -} diff --git a/css/common.css b/css/common.css index b446866..5e49392 100644 --- a/css/common.css +++ b/css/common.css @@ -19,14 +19,10 @@ /* Every page */ -h1 { - text-align: center; -} +/* start by hiding everything */ +#welcome-page{display: none;} -h2 { - color: var(--citygreen); - text-align: center; -} +#prompt-div{display: none;} body { margin-top: 20px; diff --git a/index.html b/index.html index 03fb7f3..e2a8b8b 100644 --- a/index.html +++ b/index.html @@ -7,63 +7,83 @@ - + - + + + + + + +

FY2026 Budget Form

+




- - + - + - + - + - + - + -
+
+

Do you have any new initiatives for FY26?

+
+ + + + +
+ + + \ No newline at end of file diff --git a/js/archive/start_from_save_main.js b/js/archive/start_from_save_main.js new file mode 100644 index 0000000..362a86c --- /dev/null +++ b/js/archive/start_from_save_main.js @@ -0,0 +1,13 @@ +document.addEventListener('DOMContentLoaded', function () { + + // If starting over, reset storage + document.getElementById('start-over-btn').addEventListener('click', function(event){ + localStorage.setItem("employeeTableData", ""); + }); + + // Show start from saved data button only if there is saved data + if (localStorage.getItem("employeeTableData")) { + document.getElementById('load-saved-data-btn').style.display = "block" + } + +}); \ No newline at end of file diff --git a/js/components/header/header.css b/js/components/header/header.css new file mode 100644 index 0000000..ccd9d76 --- /dev/null +++ b/js/components/header/header.css @@ -0,0 +1,9 @@ + +h1 { + text-align: center; +} + +h2 { + color: var(--citygreen); + text-align: center; +} \ No newline at end of file diff --git a/js/components/header/header.js b/js/components/header/header.js new file mode 100644 index 0000000..d8e0e6f --- /dev/null +++ b/js/components/header/header.js @@ -0,0 +1,3 @@ +export function updateSubtitle(subtitle){ + document.getElementById("subtitle").textContent = subtitle; +} \ No newline at end of file diff --git a/js/components/prompt/prompt.css b/js/components/prompt/prompt.css new file mode 100644 index 0000000..3a82f0b --- /dev/null +++ b/js/components/prompt/prompt.css @@ -0,0 +1,12 @@ +#prompt-div { + display: none; + text-align: center; +} + +#prompt { + text-align: center; +} + +.btn.btn-yes { background-color: var(--green);} +.btn.btn-no {background-color: var(--orange);} +.btn.btn-yes, .btn.btn-no{ font-size: 1.5em;} \ No newline at end of file diff --git a/js/components/prompt/prompt.js b/js/components/prompt/prompt.js new file mode 100644 index 0000000..1c9588b --- /dev/null +++ b/js/components/prompt/prompt.js @@ -0,0 +1,3 @@ +export function showPrompt(){ + document.getElementById("prompt-div").style.display = "block"; +} \ No newline at end of file diff --git a/css/00_welcome.css b/js/components/welcome/welcome.css similarity index 92% rename from css/00_welcome.css rename to js/components/welcome/welcome.css index 87fa6b5..23b5108 100644 --- a/css/00_welcome.css +++ b/js/components/welcome/welcome.css @@ -24,6 +24,5 @@ display: flex; justify-content: center; /* Center horizontally */ align-items: center; /* Center vertically */ - /* height: 100vh; Take up full viewport height */ flex-wrap: wrap; } \ No newline at end of file diff --git a/js/components/welcome/welcome.js b/js/components/welcome/welcome.js new file mode 100644 index 0000000..eebfb33 --- /dev/null +++ b/js/components/welcome/welcome.js @@ -0,0 +1,7 @@ +// Hide and unhide welcome buttons +export function unhideWelcomeButtons(){ + document.getElementById("welcome-page").style.display = "flex"; +} +export function hideWelcomeButtons(){ + document.getElementById("welcome-page").style.display = "none"; +} diff --git a/js/init.js b/js/init.js index d928e40..69c1c3c 100644 --- a/js/init.js +++ b/js/init.js @@ -7,4 +7,15 @@ let target = 2000000; let baseline_revenue = 0; let supp_revenue = 0; let supp_total = personnel_supp - supp_revenue; -let baseline_total = personnel_baseline - baseline_revenue; \ No newline at end of file +let baseline_total = personnel_baseline - baseline_revenue; + +// import functions +import { initializeWelcomePage } from './pages/00_welcome/main.js'; +import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' + +document.addEventListener('DOMContentLoaded', function () { + + initializeWelcomePage(); + document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) + +}); \ No newline at end of file diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index 362a86c..6cffc10 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -1,13 +1,10 @@ -document.addEventListener('DOMContentLoaded', function () { +import { updateSubtitle } from '../../components/header/header.js' +import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' - // If starting over, reset storage - document.getElementById('start-over-btn').addEventListener('click', function(event){ - localStorage.setItem("employeeTableData", ""); - }); +export function initializeWelcomePage(){ - // Show start from saved data button only if there is saved data - if (localStorage.getItem("employeeTableData")) { - document.getElementById('load-saved-data-btn').style.display = "block" - } + updateSubtitle("Welcome"); + unhideWelcomeButtons(); -}); \ No newline at end of file + +} \ No newline at end of file diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index 4292a14..574da52 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -1,44 +1,8 @@ +import { hideWelcomeButtons } from '../../components/welcome/welcome.js' +import { showPrompt } from '../../components/prompt/prompt.js' -document.addEventListener('DOMContentLoaded', function () { - - document.getElementById('new-init-form').addEventListener('submit', function(event) { - handleFormSubmissions(event); - }); - -}); - -// process new initiative submission -function handleFormSubmissions(event){ - event.preventDefault(); // Prevent the default form submission - - // get values from form - var name = document.getElementById('init-name').value; - var explanation = document.getElementById('init-explanation').value; - var request = document.getElementById('init-request').value; - - var table = document.getElementById('initiative-table'); - - // Insert a row at the end of the table - var newRow = table.insertRow(table.rows.length); - - // Insert cells in the row - var cell1 = newRow.insertCell(0); - var cell2 = newRow.insertCell(1); - var cell3 = newRow.insertCell(2); - - // Add some text to the new cells - cell1.innerHTML = name; - cell2.innerHTML = explanation; - cell3.innerHTML = formatCurrency(request); - cell3.classList.add('cost'); - - // Clear the form for the next entries - document.getElementById('new-init-form').reset(); - - //show table - document.getElementById('initiative-table-div').style.display = "block"; - - // hide modal and Y/N questions - $('#new-init-modal').modal('hide'); - document.getElementById('initial-questions').style.display = 'none'; +// Set up links to different pages +export function loadNewInitiatives() { + hideWelcomeButtons(); + showPrompt(); } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/main_archive.js b/js/pages/02_new_initiatives/main_archive.js new file mode 100644 index 0000000..4292a14 --- /dev/null +++ b/js/pages/02_new_initiatives/main_archive.js @@ -0,0 +1,44 @@ + +document.addEventListener('DOMContentLoaded', function () { + + document.getElementById('new-init-form').addEventListener('submit', function(event) { + handleFormSubmissions(event); + }); + +}); + +// process new initiative submission +function handleFormSubmissions(event){ + event.preventDefault(); // Prevent the default form submission + + // get values from form + var name = document.getElementById('init-name').value; + var explanation = document.getElementById('init-explanation').value; + var request = document.getElementById('init-request').value; + + var table = document.getElementById('initiative-table'); + + // Insert a row at the end of the table + var newRow = table.insertRow(table.rows.length); + + // Insert cells in the row + var cell1 = newRow.insertCell(0); + var cell2 = newRow.insertCell(1); + var cell3 = newRow.insertCell(2); + + // Add some text to the new cells + cell1.innerHTML = name; + cell2.innerHTML = explanation; + cell3.innerHTML = formatCurrency(request); + cell3.classList.add('cost'); + + // Clear the form for the next entries + document.getElementById('new-init-form').reset(); + + //show table + document.getElementById('initiative-table-div').style.display = "block"; + + // hide modal and Y/N questions + $('#new-init-modal').modal('hide'); + document.getElementById('initial-questions').style.display = 'none'; +} \ No newline at end of file diff --git a/js/pages/02_new_initiatives/new_inits_helpers.js b/js/pages/02_new_initiatives/new_inits_helpers.js new file mode 100644 index 0000000..e127208 --- /dev/null +++ b/js/pages/02_new_initiatives/new_inits_helpers.js @@ -0,0 +1,35 @@ +// process new initiative submission +function handleFormSubmissions(event){ + event.preventDefault(); // Prevent the default form submission + + // get values from form + var name = document.getElementById('init-name').value; + var explanation = document.getElementById('init-explanation').value; + var request = document.getElementById('init-request').value; + + var table = document.getElementById('initiative-table'); + + // Insert a row at the end of the table + var newRow = table.insertRow(table.rows.length); + + // Insert cells in the row + var cell1 = newRow.insertCell(0); + var cell2 = newRow.insertCell(1); + var cell3 = newRow.insertCell(2); + + // Add some text to the new cells + cell1.innerHTML = name; + cell2.innerHTML = explanation; + cell3.innerHTML = formatCurrency(request); + cell3.classList.add('cost'); + + // Clear the form for the next entries + document.getElementById('new-init-form').reset(); + + //show table + document.getElementById('initiative-table-div').style.display = "block"; + + // hide modal and Y/N questions + $('#new-init-modal').modal('hide'); + document.getElementById('initial-questions').style.display = 'none'; +} \ No newline at end of file diff --git a/pages/02_new_initiatives.html b/pages/02_new_initiatives.html index b0fdcb8..91027c8 100644 --- a/pages/02_new_initiatives.html +++ b/pages/02_new_initiatives.html @@ -25,13 +25,16 @@

FY2026 Budget Form

-

New Initiatives

+

New Initiatives




-
+ + + +
From 1e3770d64b8dc3c26a33eea6d8d5a51b63c13605 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 14:29:14 -0400 Subject: [PATCH 02/22] moving code to components --- index.html | 57 ++++++++++++++++--- js/components/modal-form/modal-form.css | 0 js/components/modal-form/modal-form.js | 7 +++ js/components/prompt/prompt.css | 6 +- js/components/prompt/prompt.js | 9 +++ js/init.js | 14 ++++- js/pages/00_welcome/main.js | 2 + .../{new_inits_helpers.js => helpers.js} | 5 +- js/pages/02_new_initiatives/main.js | 20 ++++++- js/pages/02_new_initiatives/main_archive.js | 44 -------------- js/utils/storage-handlers.js | 10 ++++ js/utils/utils.js | 14 +---- 12 files changed, 118 insertions(+), 70 deletions(-) create mode 100644 js/components/modal-form/modal-form.css create mode 100644 js/components/modal-form/modal-form.js rename js/pages/02_new_initiatives/{new_inits_helpers.js => helpers.js} (89%) delete mode 100644 js/pages/02_new_initiatives/main_archive.js diff --git a/index.html b/index.html index e2a8b8b..05531d3 100644 --- a/index.html +++ b/index.html @@ -32,6 +32,7 @@



+ +
-

Do you have any new initiatives for FY26?

+


- + - +
+ + + \ No newline at end of file diff --git a/js/components/modal-form/modal-form.css b/js/components/modal-form/modal-form.css new file mode 100644 index 0000000..e69de29 diff --git a/js/components/modal-form/modal-form.js b/js/components/modal-form/modal-form.js new file mode 100644 index 0000000..52021f6 --- /dev/null +++ b/js/components/modal-form/modal-form.js @@ -0,0 +1,7 @@ +export function hideModal(modal_id) { + $('#' + modal_id).modal('hide'); +} + +export function showModal(modal_id) { + $('#' + modal_id).modal('show'); +} \ No newline at end of file diff --git a/js/components/prompt/prompt.css b/js/components/prompt/prompt.css index 3a82f0b..0633c92 100644 --- a/js/components/prompt/prompt.css +++ b/js/components/prompt/prompt.css @@ -7,6 +7,6 @@ text-align: center; } -.btn.btn-yes { background-color: var(--green);} -.btn.btn-no {background-color: var(--orange);} -.btn.btn-yes, .btn.btn-no{ font-size: 1.5em;} \ No newline at end of file +#option1 { background-color: var(--green);} +#option2 {background-color: var(--orange);} +#option1, #option2 { font-size: 1.5em; } \ No newline at end of file diff --git a/js/components/prompt/prompt.js b/js/components/prompt/prompt.js index 1c9588b..7743dec 100644 --- a/js/components/prompt/prompt.js +++ b/js/components/prompt/prompt.js @@ -1,3 +1,12 @@ export function showPrompt(){ document.getElementById("prompt-div").style.display = "block"; +} + +export function updatePrompt(prompt){ + document.getElementById('prompt').textContent = prompt; +} + +export function updatePromptButtons(option1, option2){ + document.getElementById('option1').textContent = option1; + document.getElementById('option2').textContent = option2; } \ No newline at end of file diff --git a/js/init.js b/js/init.js index 69c1c3c..295e5fe 100644 --- a/js/init.js +++ b/js/init.js @@ -9,13 +9,23 @@ let supp_revenue = 0; let supp_total = personnel_supp - supp_revenue; let baseline_total = personnel_baseline - baseline_revenue; +// page state +var page_state = 'welcome'; + // import functions import { initializeWelcomePage } from './pages/00_welcome/main.js'; import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' +import { loadPageState } from './utils/storage-handlers.js' document.addEventListener('DOMContentLoaded', function () { - initializeWelcomePage(); - document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) + loadPageState(); + console.log(page_state); + + if (page_state == 'welcome' ){ + initializeWelcomePage(); + } else if (page_state == 'new-inits'){ + loadNewInitiatives(); + } }); \ No newline at end of file diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index 6cffc10..b58c375 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -1,10 +1,12 @@ import { updateSubtitle } from '../../components/header/header.js' import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' +import { loadNewInitiatives } from '../02_new_initiatives/main.js' export function initializeWelcomePage(){ updateSubtitle("Welcome"); unhideWelcomeButtons(); + document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/new_inits_helpers.js b/js/pages/02_new_initiatives/helpers.js similarity index 89% rename from js/pages/02_new_initiatives/new_inits_helpers.js rename to js/pages/02_new_initiatives/helpers.js index e127208..8388964 100644 --- a/js/pages/02_new_initiatives/new_inits_helpers.js +++ b/js/pages/02_new_initiatives/helpers.js @@ -1,5 +1,8 @@ // process new initiative submission -function handleFormSubmissions(event){ + +// todo: parameterize so that it loads a table based on just the entries from the form + +export function handleFormSubmissions(event){ event.preventDefault(); // Prevent the default form submission // get values from form diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index 574da52..c61a1e5 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -1,8 +1,26 @@ import { hideWelcomeButtons } from '../../components/welcome/welcome.js' -import { showPrompt } from '../../components/prompt/prompt.js' +import { showPrompt, updatePrompt, updatePromptButtons } from '../../components/prompt/prompt.js' +import { handleFormSubmissions } from './helpers.js' +import { updatePageState } from '../../utils/storage-handlers.js' // Set up links to different pages export function loadNewInitiatives() { + + //update page state + updatePageState('new-inits'); + + // load text + updatePrompt('Do you have any new initiatives for FY26?'); + updatePromptButtons('Yes', 'No'); + + // prepare page view hideWelcomeButtons(); showPrompt(); + + // initialize form + + // initialize form submission + document.getElementById('form-modal').addEventListener('submit', function(event) { + handleFormSubmissions(event); + }); } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/main_archive.js b/js/pages/02_new_initiatives/main_archive.js deleted file mode 100644 index 4292a14..0000000 --- a/js/pages/02_new_initiatives/main_archive.js +++ /dev/null @@ -1,44 +0,0 @@ - -document.addEventListener('DOMContentLoaded', function () { - - document.getElementById('new-init-form').addEventListener('submit', function(event) { - handleFormSubmissions(event); - }); - -}); - -// process new initiative submission -function handleFormSubmissions(event){ - event.preventDefault(); // Prevent the default form submission - - // get values from form - var name = document.getElementById('init-name').value; - var explanation = document.getElementById('init-explanation').value; - var request = document.getElementById('init-request').value; - - var table = document.getElementById('initiative-table'); - - // Insert a row at the end of the table - var newRow = table.insertRow(table.rows.length); - - // Insert cells in the row - var cell1 = newRow.insertCell(0); - var cell2 = newRow.insertCell(1); - var cell3 = newRow.insertCell(2); - - // Add some text to the new cells - cell1.innerHTML = name; - cell2.innerHTML = explanation; - cell3.innerHTML = formatCurrency(request); - cell3.classList.add('cost'); - - // Clear the form for the next entries - document.getElementById('new-init-form').reset(); - - //show table - document.getElementById('initiative-table-div').style.display = "block"; - - // hide modal and Y/N questions - $('#new-init-modal').modal('hide'); - document.getElementById('initial-questions').style.display = 'none'; -} \ No newline at end of file diff --git a/js/utils/storage-handlers.js b/js/utils/storage-handlers.js index d427424..62a0c98 100644 --- a/js/utils/storage-handlers.js +++ b/js/utils/storage-handlers.js @@ -82,4 +82,14 @@ function loadCounters(){ personnel_baseline = parseInt(localStorage.getItem('personnel_baseline'), 10); personnel_supp = parseInt(localStorage.getItem('personnel_supp'), 10); updateDisplay(); +} + +// save page state +export function updatePageState(page){ + localStorage.setItem('page_state', page); +} + +// load page state +export function loadPageState(page){ + var page_state = localStorage.getItem('page_state'); } \ No newline at end of file diff --git a/js/utils/utils.js b/js/utils/utils.js index 2bde4c7..57aed89 100644 --- a/js/utils/utils.js +++ b/js/utils/utils.js @@ -47,17 +47,6 @@ function updateDisplay() { * of the element and passed through an optional formatting function before being * displayed in the cell. An optional callback can be triggered after the update * to perform additional actions. - * - * @param {HTMLElement} cell - The DOM element representing the cell to be made editable. - * @param {string} attribute - The attribute name of the cell where the value will be stored. - * @param {function} [formatValueCallback] - Optional. A function to format the value - * before displaying it in the cell. The function must accept a string and return - * a formatted string. - * @param {function} [updateCallback] - Optional. A function to be called after the cell - * value has been updated. Use this to trigger any additional side effects or updates - * to related data or UI elements. - * @param {function} [validate] - Optional. A function to validate input and return an error - * message if relevant. */ function createEditableCell(cell, attribute = 'value', formatValueCallback, updateCallback, validate) { // Add a click event to the cell to make it editable @@ -141,4 +130,5 @@ function validateNumber(input){ return "Field only accepts numbers"; }; return ""; -} \ No newline at end of file +} + From fead6cec83adf316fb95414b0ced6e9ece66707b Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 14:58:05 -0400 Subject: [PATCH 03/22] updated page state --- {pages/archive => archive}/index.html | 0 {pages/archive => archive}/personnel.html | 0 .../start_from_save_main.js | 0 css/common.css | 16 ------------ index.html | 17 ++++++++++++- js/components/nav_buttons/nav_buttons.css | 12 +++++++++ js/components/nav_buttons/nav_buttons.js | 0 js/init.js | 25 +++++++++++-------- js/pages/00_welcome/main.js | 6 +++++ js/pages/02_new_initiatives/main.js | 6 ++++- js/utils/storage-handlers.js | 2 +- 11 files changed, 54 insertions(+), 30 deletions(-) rename {pages/archive => archive}/index.html (100%) rename {pages/archive => archive}/personnel.html (100%) rename {js/archive => archive}/start_from_save_main.js (100%) create mode 100644 js/components/nav_buttons/nav_buttons.css create mode 100644 js/components/nav_buttons/nav_buttons.js diff --git a/pages/archive/index.html b/archive/index.html similarity index 100% rename from pages/archive/index.html rename to archive/index.html diff --git a/pages/archive/personnel.html b/archive/personnel.html similarity index 100% rename from pages/archive/personnel.html rename to archive/personnel.html diff --git a/js/archive/start_from_save_main.js b/archive/start_from_save_main.js similarity index 100% rename from js/archive/start_from_save_main.js rename to archive/start_from_save_main.js diff --git a/css/common.css b/css/common.css index 5e49392..a288a0d 100644 --- a/css/common.css +++ b/css/common.css @@ -96,22 +96,6 @@ tr td { .btn-carryover {background-color: var(--green);} .btn-add { background-color: var(--spiritgreen);} -/* Go to next page */ - -.new-row{ - margin: 20px; - text-align: center; -} -.next-button-row { - text-align: right; -} -.btn-next, .btn-last { - background-color: var(--blue); -} -.btn-next:hover, .btn-last:hover { - background-color: var(--yellow); -} - /* textbox width in table */ input { width: 100%; diff --git a/index.html b/index.html index 05531d3..0457a26 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,7 @@ + @@ -125,8 +126,22 @@
- + + + \ No newline at end of file diff --git a/js/components/nav_buttons/nav_buttons.css b/js/components/nav_buttons/nav_buttons.css new file mode 100644 index 0000000..8560007 --- /dev/null +++ b/js/components/nav_buttons/nav_buttons.css @@ -0,0 +1,12 @@ +#nav-btns { + margin: 20px; + text-align: center; +} + +#btn-next, #btn-last { + background-color: var(--blue); +} + +#btn-next:hover, #btn-last:hover { + background-color: var(--yellow); +} \ No newline at end of file diff --git a/js/components/nav_buttons/nav_buttons.js b/js/components/nav_buttons/nav_buttons.js new file mode 100644 index 0000000..e69de29 diff --git a/js/init.js b/js/init.js index 295e5fe..3fb5219 100644 --- a/js/init.js +++ b/js/init.js @@ -1,3 +1,8 @@ +// import functions +import { initializeWelcomePage } from './pages/00_welcome/main.js'; +import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' +import { loadPageState, updatePageState } from './utils/storage-handlers.js' + // running tallies of total spend let personnel_supp = 0; let personnel_baseline = 0; @@ -11,21 +16,19 @@ let baseline_total = personnel_baseline - baseline_revenue; // page state var page_state = 'welcome'; - -// import functions -import { initializeWelcomePage } from './pages/00_welcome/main.js'; -import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' -import { loadPageState } from './utils/storage-handlers.js' +// updatePageState(page_state); document.addEventListener('DOMContentLoaded', function () { - loadPageState(); + page_state = loadPageState(); console.log(page_state); - - if (page_state == 'welcome' ){ - initializeWelcomePage(); - } else if (page_state == 'new-inits'){ - loadNewInitiatives(); + + switch (page_state){ + case 'welcome': + initializeWelcomePage(); + case 'new-inits': + loadNewInitiatives(); } + }); \ No newline at end of file diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index b58c375..e38527b 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -1,12 +1,18 @@ import { updateSubtitle } from '../../components/header/header.js' import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' import { loadNewInitiatives } from '../02_new_initiatives/main.js' +import { updatePageState } from '../../utils/storage-handlers.js' export function initializeWelcomePage(){ + // record page state + updatePageState('welcome'); + + // page set up updateSubtitle("Welcome"); unhideWelcomeButtons(); + // initialize links in buttons document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index c61a1e5..80bbfbf 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -1,7 +1,8 @@ import { hideWelcomeButtons } from '../../components/welcome/welcome.js' import { showPrompt, updatePrompt, updatePromptButtons } from '../../components/prompt/prompt.js' import { handleFormSubmissions } from './helpers.js' -import { updatePageState } from '../../utils/storage-handlers.js' +import { updatePageState, loadPageState } from '../../utils/storage-handlers.js' +import { initializeWelcomePage } from '../00_welcome/main.js' // Set up links to different pages export function loadNewInitiatives() { @@ -23,4 +24,7 @@ export function loadNewInitiatives() { document.getElementById('form-modal').addEventListener('submit', function(event) { handleFormSubmissions(event); }); + + // initialize buttons + docuement.getElementById('btn-last').addEventListener('click', initializeWelcomePage); } \ No newline at end of file diff --git a/js/utils/storage-handlers.js b/js/utils/storage-handlers.js index 62a0c98..e72bb50 100644 --- a/js/utils/storage-handlers.js +++ b/js/utils/storage-handlers.js @@ -91,5 +91,5 @@ export function updatePageState(page){ // load page state export function loadPageState(page){ - var page_state = localStorage.getItem('page_state'); + return localStorage.getItem('page_state'); } \ No newline at end of file From 453c209bb23ef6475c1e14584577353e9588d894 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 16:14:07 -0400 Subject: [PATCH 04/22] updated page state --- .../modal-form.css => modal_form/modal_form.css} | 0 .../{modal-form/modal-form.js => modal_form/modal_form.js} | 0 js/components/nav_buttons/nav_buttons.js | 7 +++++++ js/components/prompt/prompt.js | 7 ++++++- js/pages/00_welcome/main.js | 5 +++++ js/pages/02_new_initiatives/main.js | 4 +++- 6 files changed, 21 insertions(+), 2 deletions(-) rename js/components/{modal-form/modal-form.css => modal_form/modal_form.css} (100%) rename js/components/{modal-form/modal-form.js => modal_form/modal_form.js} (100%) diff --git a/js/components/modal-form/modal-form.css b/js/components/modal_form/modal_form.css similarity index 100% rename from js/components/modal-form/modal-form.css rename to js/components/modal_form/modal_form.css diff --git a/js/components/modal-form/modal-form.js b/js/components/modal_form/modal_form.js similarity index 100% rename from js/components/modal-form/modal-form.js rename to js/components/modal_form/modal_form.js diff --git a/js/components/nav_buttons/nav_buttons.js b/js/components/nav_buttons/nav_buttons.js index e69de29..fb4bfb0 100644 --- a/js/components/nav_buttons/nav_buttons.js +++ b/js/components/nav_buttons/nav_buttons.js @@ -0,0 +1,7 @@ +export function hideNavButtons() { + document.getElementById('nav-btns').style.display = 'none'; +} + +export function showNavButtons() { + document.getElementById('nav-btns').style.display = 'block'; +} \ No newline at end of file diff --git a/js/components/prompt/prompt.js b/js/components/prompt/prompt.js index 7743dec..bfdc7dc 100644 --- a/js/components/prompt/prompt.js +++ b/js/components/prompt/prompt.js @@ -2,6 +2,11 @@ export function showPrompt(){ document.getElementById("prompt-div").style.display = "block"; } +export function hidePrompt(){ + document.getElementById('prompt-div').style.display = 'none'; +} + + export function updatePrompt(prompt){ document.getElementById('prompt').textContent = prompt; } @@ -9,4 +14,4 @@ export function updatePrompt(prompt){ export function updatePromptButtons(option1, option2){ document.getElementById('option1').textContent = option1; document.getElementById('option2').textContent = option2; -} \ No newline at end of file +} diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index e38527b..7c0bd99 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -2,6 +2,8 @@ import { updateSubtitle } from '../../components/header/header.js' import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' import { loadNewInitiatives } from '../02_new_initiatives/main.js' import { updatePageState } from '../../utils/storage-handlers.js' +import { hidePrompt } from '../../components/prompt/prompt.js' +import { hideNavButtons } from '../../components/nav_buttons/nav_buttons.js' export function initializeWelcomePage(){ @@ -11,6 +13,9 @@ export function initializeWelcomePage(){ // page set up updateSubtitle("Welcome"); unhideWelcomeButtons(); + // todo + hidePrompt(); + hideNavButtons(); // initialize links in buttons document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index 80bbfbf..33145d4 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -3,6 +3,7 @@ import { showPrompt, updatePrompt, updatePromptButtons } from '../../components/ import { handleFormSubmissions } from './helpers.js' import { updatePageState, loadPageState } from '../../utils/storage-handlers.js' import { initializeWelcomePage } from '../00_welcome/main.js' +import { showNavButtons } from '../../components/nav_buttons/nav_buttons.js' // Set up links to different pages export function loadNewInitiatives() { @@ -17,6 +18,7 @@ export function loadNewInitiatives() { // prepare page view hideWelcomeButtons(); showPrompt(); + showNavButtons(); // initialize form @@ -26,5 +28,5 @@ export function loadNewInitiatives() { }); // initialize buttons - docuement.getElementById('btn-last').addEventListener('click', initializeWelcomePage); + document.getElementById('btn-last').addEventListener('click', initializeWelcomePage); } \ No newline at end of file From 1fe7adc9bf88cabdaba2049a3b284c4fc4d6ac37 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 16:32:28 -0400 Subject: [PATCH 05/22] fixed switch in init.js --- js/init.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/init.js b/js/init.js index 3fb5219..d21f734 100644 --- a/js/init.js +++ b/js/init.js @@ -16,7 +16,6 @@ let baseline_total = personnel_baseline - baseline_revenue; // page state var page_state = 'welcome'; -// updatePageState(page_state); document.addEventListener('DOMContentLoaded', function () { @@ -26,8 +25,10 @@ document.addEventListener('DOMContentLoaded', function () { switch (page_state){ case 'welcome': initializeWelcomePage(); + break; case 'new-inits': loadNewInitiatives(); + break; } From e4e916cc8e40a0dd19f1d6ccf41d5be529fae9a5 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 16:40:04 -0400 Subject: [PATCH 06/22] fixed default page --- js/init.js | 6 +----- js/utils/storage-handlers.js | 3 ++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/js/init.js b/js/init.js index d21f734..388a099 100644 --- a/js/init.js +++ b/js/init.js @@ -14,13 +14,9 @@ let supp_revenue = 0; let supp_total = personnel_supp - supp_revenue; let baseline_total = personnel_baseline - baseline_revenue; -// page state -var page_state = 'welcome'; - document.addEventListener('DOMContentLoaded', function () { - page_state = loadPageState(); - console.log(page_state); + var page_state = loadPageState(); switch (page_state){ case 'welcome': diff --git a/js/utils/storage-handlers.js b/js/utils/storage-handlers.js index e72bb50..c5587e8 100644 --- a/js/utils/storage-handlers.js +++ b/js/utils/storage-handlers.js @@ -91,5 +91,6 @@ export function updatePageState(page){ // load page state export function loadPageState(page){ - return localStorage.getItem('page_state'); + const pageState = localStorage.getItem('page_state'); + return pageState !== null ? pageState : 'welcome'; } \ No newline at end of file From 42da8a3811a2a7242a60f8d09548b312034129a0 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 13 Jun 2024 16:49:07 -0400 Subject: [PATCH 07/22] updated welcome main.js --- js/pages/00_welcome/main.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index 7c0bd99..a31c368 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -13,7 +13,6 @@ export function initializeWelcomePage(){ // page set up updateSubtitle("Welcome"); unhideWelcomeButtons(); - // todo hidePrompt(); hideNavButtons(); From 73a4374f5c85313c670dabbfb3a48a324c938578 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Fri, 14 Jun 2024 11:03:13 -0400 Subject: [PATCH 08/22] first 3 pages roughly working after refactoring --- index.html | 2 -- js/components/modal_form/modal_form.js | 6 +++++ js/components/nav_buttons/nav_buttons.js | 6 +++++ js/components/prompt/prompt.js | 4 +++ js/init.js | 3 +++ js/pages/00_welcome/main.js | 2 +- js/pages/02_new_initiatives/main.js | 22 +++++++++++------ js/pages/03_revenue/main.js | 31 ++++++++++++++++++++++++ 8 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 js/pages/03_revenue/main.js diff --git a/index.html b/index.html index 0457a26..743a563 100644 --- a/index.html +++ b/index.html @@ -77,9 +77,7 @@


- - diff --git a/js/components/modal_form/modal_form.js b/js/components/modal_form/modal_form.js index 52021f6..cc402cc 100644 --- a/js/components/modal_form/modal_form.js +++ b/js/components/modal_form/modal_form.js @@ -4,4 +4,10 @@ export function hideModal(modal_id) { export function showModal(modal_id) { $('#' + modal_id).modal('show'); +} + +export function addModalLink(button_id, modal_id){ + document.getElementById(button_id).addEventListener('click', function() { + showModal(modal_id); + }); } \ No newline at end of file diff --git a/js/components/nav_buttons/nav_buttons.js b/js/components/nav_buttons/nav_buttons.js index fb4bfb0..c14da8d 100644 --- a/js/components/nav_buttons/nav_buttons.js +++ b/js/components/nav_buttons/nav_buttons.js @@ -4,4 +4,10 @@ export function hideNavButtons() { export function showNavButtons() { document.getElementById('nav-btns').style.display = 'block'; +} + +// imputs next and last should be functions to render the appropriate pages +export function updateNavButtonLinks(last, next){ + document.getElementById('btn-last').addEventListener('click', last); + document.getElementById('btn-next').addEventListener('click', next); } \ No newline at end of file diff --git a/js/components/prompt/prompt.js b/js/components/prompt/prompt.js index bfdc7dc..e6faa74 100644 --- a/js/components/prompt/prompt.js +++ b/js/components/prompt/prompt.js @@ -15,3 +15,7 @@ export function updatePromptButtons(option1, option2){ document.getElementById('option1').textContent = option1; document.getElementById('option2').textContent = option2; } + +export function addPromptButtonAction(button_id, action_fn){ + document.getElementById(button_id).addEventListener('click', action_fn); +} \ No newline at end of file diff --git a/js/init.js b/js/init.js index 388a099..9fb17f1 100644 --- a/js/init.js +++ b/js/init.js @@ -1,6 +1,7 @@ // import functions import { initializeWelcomePage } from './pages/00_welcome/main.js'; import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' +import { loadRevenuePage } from './pages/03_revenue/main.js' import { loadPageState, updatePageState } from './utils/storage-handlers.js' // running tallies of total spend @@ -25,6 +26,8 @@ document.addEventListener('DOMContentLoaded', function () { case 'new-inits': loadNewInitiatives(); break; + case 'revenue': + loadRevenuePage(); } diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index a31c368..f1d3921 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -9,7 +9,7 @@ export function initializeWelcomePage(){ // record page state updatePageState('welcome'); - + // page set up updateSubtitle("Welcome"); unhideWelcomeButtons(); diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index 33145d4..7089530 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -1,17 +1,21 @@ import { hideWelcomeButtons } from '../../components/welcome/welcome.js' -import { showPrompt, updatePrompt, updatePromptButtons } from '../../components/prompt/prompt.js' +import { updateSubtitle } from '../../components/header/header.js' +import { showPrompt, updatePrompt, updatePromptButtons, addPromptButtonAction } from '../../components/prompt/prompt.js' import { handleFormSubmissions } from './helpers.js' -import { updatePageState, loadPageState } from '../../utils/storage-handlers.js' +import { updatePageState } from '../../utils/storage-handlers.js' import { initializeWelcomePage } from '../00_welcome/main.js' -import { showNavButtons } from '../../components/nav_buttons/nav_buttons.js' +import { showNavButtons, updateNavButtonLinks } from '../../components/nav_buttons/nav_buttons.js' +import { loadRevenuePage } from '../03_revenue/main.js' +import { addModalLink } from '../../components/modal_form/modal_form.js' -// Set up links to different pages +// set up page and initialize all buttons export function loadNewInitiatives() { //update page state updatePageState('new-inits'); // load text + updateSubtitle('New Initiatives'); updatePrompt('Do you have any new initiatives for FY26?'); updatePromptButtons('Yes', 'No'); @@ -20,13 +24,17 @@ export function loadNewInitiatives() { showPrompt(); showNavButtons(); - // initialize form + // initialize modal + addModalLink('option1', 'form-modal'); // initialize form submission document.getElementById('form-modal').addEventListener('submit', function(event) { handleFormSubmissions(event); }); + + // initialize nav buttons fn(last, next) + updateNavButtonLinks(initializeWelcomePage, loadRevenuePage); - // initialize buttons - document.getElementById('btn-last').addEventListener('click', initializeWelcomePage); + // clicking 'No' will also take us to the next page + addPromptButtonAction('option2', loadRevenuePage); } \ No newline at end of file diff --git a/js/pages/03_revenue/main.js b/js/pages/03_revenue/main.js new file mode 100644 index 0000000..c77189b --- /dev/null +++ b/js/pages/03_revenue/main.js @@ -0,0 +1,31 @@ +import { updatePageState } from '../../utils/storage-handlers.js' +import { hideWelcomeButtons } from '../../components/welcome/welcome.js' +import { updateSubtitle } from '../../components/header/header.js' +import { showPrompt, updatePrompt, updatePromptButtons, addPromptButtonAction } from '../../components/prompt/prompt.js' +import { showNavButtons, updateNavButtonLinks } from '../../components/nav_buttons/nav_buttons.js' +import { loadNewInitiatives } from '../02_new_initiatives/main.js' + + +export function loadRevenuePage() { + + //update page state + updatePageState('revenue'); + + // prepare page view + hideWelcomeButtons(); + showPrompt(); + showNavButtons(); + + // update page text + updateSubtitle('Revenue Projections'); + // TODO: update to make dynamic + updatePrompt('Your revenue projection for FY26 is $0'); + updatePromptButtons('Confirm and continue.', "This doesn't look right"); + + // initialize nav buttons fn(last, next) + updateNavButtonLinks(loadNewInitiatives, loadNewInitiatives); + + // clicking 'confirm and continue' will also take us to the next page + addPromptButtonAction('option1', loadNewInitiatives); + +} \ No newline at end of file From 89e11c6ae6c4d3f5253efdcba2f9083be68d766f Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Mon, 17 Jun 2024 10:05:09 -0400 Subject: [PATCH 09/22] added form and modal components with custom fns --- css/common.css | 12 +- index.html | 34 +----- js/components/form/form.js | 105 ++++++++++++++++++ .../modal_form.css => modal/modal.css} | 0 .../modal_form.js => modal/modal.js} | 4 + js/pages/02_new_initiatives/helpers.js | 8 +- js/pages/02_new_initiatives/main.js | 11 +- 7 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 js/components/form/form.js rename js/components/{modal_form/modal_form.css => modal/modal.css} (100%) rename js/components/{modal_form/modal_form.js => modal/modal.js} (74%) diff --git a/css/common.css b/css/common.css index a288a0d..809f127 100644 --- a/css/common.css +++ b/css/common.css @@ -21,7 +21,6 @@ /* start by hiding everything */ #welcome-page{display: none;} - #prompt-div{display: none;} body { @@ -72,6 +71,12 @@ tr td { border-bottom: 1px solid black; } +/* textbox width in table */ +input { + width: 100%; +} + + /* Action buttons */ .action-btns { @@ -96,11 +101,6 @@ tr td { .btn-carryover {background-color: var(--green);} .btn-add { background-color: var(--spiritgreen);} -/* textbox width in table */ -input { - width: 100%; -} - .error-message { color: red; } diff --git a/index.html b/index.html index 743a563..7bc389c 100644 --- a/index.html +++ b/index.html @@ -14,6 +14,7 @@ + @@ -82,45 +83,18 @@

- diff --git a/js/components/form/form.css b/js/components/form/form.css new file mode 100644 index 0000000..b432df0 --- /dev/null +++ b/js/components/form/form.css @@ -0,0 +1,12 @@ +textarea {height: 100px; width: 100%;} + +textarea, input { + margin-bottom: 20px; +} + +.btn-submit { + margin-top: 20px; + width: 60%; + margin-left: 20%; + background-color: var(--spiritgreen); +} \ No newline at end of file diff --git a/js/components/form/form.js b/js/components/form/form.js index e2cf2ea..bea938d 100644 --- a/js/components/form/form.js +++ b/js/components/form/form.js @@ -1,8 +1,10 @@ // function to add questions to forms -function appendFormElement(type, label, inputType, inputId, required, cost = false) { +// type is 'input' or 'textarea' +// inputType is for validation ('number' or 'text', etc) +function appendFormElement(type, label, inputId, required, inputType, form_id = 'new-form', cost = false) { // change if we want forms elsewhere - const form = document.getElementById('form-in-modal'); + const form = document.getElementById(form_id); // create outer wrapper for element const wrapper = document.createElement('div'); @@ -39,21 +41,21 @@ function appendFormElement(type, label, inputType, inputId, required, cost = fal // Individual functions for each type of input. -export function addTextInput(label, inputId, required = false, cost = false) { - appendFormElement('input', label, inputId, required, 'text'); +export function addTextInput(label, inputId, required = false, form_id = 'new-form', cost = false) { + appendFormElement('input', label, inputId, required, 'text', form_id); } -export function addNumericInput(label, inputId, required = false, cost = true) { - appendFormElement('input', label, inputId, required, 'number'); +export function addNumericInput(label, inputId, required = false, form_id = 'new-form', cost = true) { + appendFormElement('input', label, inputId, required, 'number', form_id); } -export function addTextarea(label, inputId, required = false, cost = false) { - appendFormElement('textarea', label, inputId, required); +export function addTextarea(label, inputId, required = false, form_id = 'new-form', cost = false) { + appendFormElement('textarea', label, inputId, required, form_id); } -export function addSubmitButtonToForm() { +export function addSubmitButtonToForm(form_id = 'new-form') { // Find the form by its ID - const form = document.getElementById('form-in-modal'); + const form = document.getElementById(form_id); // Create the container `div` for the button const buttonContainer = document.createElement('div'); @@ -64,7 +66,7 @@ export function addSubmitButtonToForm() { submitInput.className = 'btn btn-submit'; // Use appropriate class for your design submitInput.type = 'submit'; submitInput.value = 'Submit'; - + // Append the submit input to the container buttonContainer.appendChild(submitInput); @@ -102,4 +104,17 @@ function fetchAllReponsesOnSubmission(event) { form.reset(); return formDataArray; +} + +export function addForm(element_id = 'modal-body', form_id = 'new-form') { + + const target_elem = document.getElementById(element_id); + + // create form + const form = document.createElement('form'); + form.setAttribute('id', form_id); + + // Append the form to the modal body + target_elem.appendChild(form); + } \ No newline at end of file diff --git a/js/components/modal/modal.js b/js/components/modal/modal.js index 10f03c1..7f0275f 100644 --- a/js/components/modal/modal.js +++ b/js/components/modal/modal.js @@ -14,4 +14,9 @@ export function addModalLink(button_id, modal_id){ export function updateModalTitle(title){ document.getElementById('modal-title').textContent = title; +} + +export function clearModal(){ + updateModalTitle(''); + document.getElementById('modal-body').innerHTML = ''; } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index c41ef23..2bab944 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -6,8 +6,8 @@ import { updatePageState } from '../../utils/storage-handlers.js' import { initializeWelcomePage } from '../00_welcome/main.js' import { showNavButtons, updateNavButtonLinks } from '../../components/nav_buttons/nav_buttons.js' import { loadRevenuePage } from '../03_revenue/main.js' -import { addModalLink, updateModalTitle } from '../../components/modal/modal.js' -import { addTextarea, addTextInput, addNumericInput, addSubmitButtonToForm } from '../../components/form/form.js' +import { addModalLink, updateModalTitle, clearModal } from '../../components/modal/modal.js' +import { addTextarea, addTextInput, addNumericInput, addSubmitButtonToForm, addForm } from '../../components/form/form.js' // set up page and initialize all buttons export function loadNewInitiatives() { @@ -27,19 +27,24 @@ export function loadNewInitiatives() { // initialize modal addModalLink('option1', 'main-modal'); + clearModal(); updateModalTitle('New initiative'); + + // set up form + addForm(); addTextInput('Initiative Name:', 'Initiative Name', true); //add required field + addTextarea('Explain why this initiative is neccessary and describe its potential impact.', 'Explanation', true); + addNumericInput('Roughly how additional money would this initiative require?', 'Cost', true); addSubmitButtonToForm(); - // initialize form submission - document.getElementById('main-modal').addEventListener('submit', function(event) { - handleFormSubmissions(event); - }); + // document.getElementById('main-modal').addEventListener('submit', function(event) { + // handleFormSubmissions(event); + // }); // initialize nav buttons fn(last, next) updateNavButtonLinks(initializeWelcomePage, loadRevenuePage); - // clicking 'No' will also take us to the next page + // clicking 'No' (no new initiatives) will also take us to the next page addPromptButtonAction('option2', loadRevenuePage); } \ No newline at end of file From 45de04f0c979915185044f768fe2d09f1f64033a Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Mon, 17 Jun 2024 14:42:02 -0400 Subject: [PATCH 11/22] basic table construction for page 2 --- css/common.css | 30 +----- index.html | 150 +++++++++++++++++----------- js/components/form/form.js | 12 +-- js/components/sidebar/sidebar.js | 10 ++ js/components/table/table.css | 26 +++++ js/components/table/table.js | 55 ++++++++++ js/pages/00_welcome/main.js | 2 + js/pages/02_new_initiatives/main.js | 21 +++- 8 files changed, 204 insertions(+), 102 deletions(-) create mode 100644 js/components/sidebar/sidebar.js create mode 100644 js/components/table/table.css create mode 100644 js/components/table/table.js diff --git a/css/common.css b/css/common.css index 809f127..fabcbb8 100644 --- a/css/common.css +++ b/css/common.css @@ -30,7 +30,7 @@ body { /* Button styling */ .btn { - cursor:pointer; + cursor: pointer; padding: 10px; margin-top: 5px; border-radius: 10px; @@ -49,34 +49,6 @@ body { color: var(--yellow); } -/* Table generics */ - -.table-container { - margin-top: 20px; -} - -thead > tr > th { - text-align: left; -} - -th { - background-color: var(--lightGray); -} - -tr { - border-width: 2px; -} - -tr td { - border-bottom: 1px solid black; -} - -/* textbox width in table */ -input { - width: 100%; -} - - /* Action buttons */ .action-btns { diff --git a/index.html b/index.html index d40ff33..305dcbf 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,7 @@ + @@ -35,55 +36,99 @@



- - +
+
+ + + - -
-

-
- - +
+ + - +
+ +
+
+ +
+
+
diff --git a/js/components/nav_buttons/nav_buttons.js b/js/components/nav_buttons/nav_buttons.js index c14da8d..f8895ad 100644 --- a/js/components/nav_buttons/nav_buttons.js +++ b/js/components/nav_buttons/nav_buttons.js @@ -1,3 +1,14 @@ + +import { initializeWelcomePage } from '../../pages/00_welcome/main.js'; +import { loadNewInitiatives } from '../../pages/02_new_initiatives/main.js' +import { loadRevenuePage } from '../../pages/03_revenue/main.js' +import { loadPageState } from '../../utils/storage-handlers.js' + + +let pages = {'welcome' : initializeWelcomePage, + 'new-inits' : loadNewInitiatives, + 'revenue' : loadRevenuePage } + export function hideNavButtons() { document.getElementById('nav-btns').style.display = 'none'; } @@ -7,7 +18,45 @@ export function showNavButtons() { } // imputs next and last should be functions to render the appropriate pages -export function updateNavButtonLinks(last, next){ - document.getElementById('btn-last').addEventListener('click', last); - document.getElementById('btn-next').addEventListener('click', next); +export function updateNavButtonLinks(page_state){ + // initialize last button + const last_btn = document.getElementById('btn-last'); + last_btn.addEventListener('click', lastPage); + // initialize next button + const next_btn = document.getElementById('btn-next'); + last_btn.addEventListener('click', nextPage); +} + +function nextPage(page_state){ + + var page_state = loadPageState(); + const keys = Object.keys(pages); + + // Find the index of the current key + const currentIndex = keys.indexOf(page_state); + + // Check if there is a next key + if (currentIndex >= 0 && currentIndex < keys.length - 1) { + // Get the next key + const nextKey = keys[currentIndex + 1]; + const nextFn = pages[nextKey]; + nextFn(); + } +} + +function lastPage(){ + + var page_state = loadPageState(); + const keys = Object.keys(pages); + + // Find the index of the current key + const currentIndex = keys.indexOf(page_state); + + // Check if there is a next key + if (currentIndex >= 1) { + // Get the next key + const lastKey = keys[currentIndex - 1]; + const lastFn = pages[lastKey]; + lastFn(); + } } \ No newline at end of file diff --git a/js/components/table/table.css b/js/components/table/table.css index dc2899c..f50d196 100644 --- a/js/components/table/table.css +++ b/js/components/table/table.css @@ -29,4 +29,15 @@ input { margin: auto; } +/* Add new row button */ +.btn-add { + background-color: var(--spiritgreen); + margin-top: 20px; +} +#add-btn-div { + display: flex; + justify-content: center; /* Aligns horizontally */ + align-items: center; /* Aligns vertically */ + width: 100%; +} \ No newline at end of file diff --git a/js/components/table/table.js b/js/components/table/table.js index 9c0add5..14c4cd1 100644 --- a/js/components/table/table.js +++ b/js/components/table/table.js @@ -57,12 +57,29 @@ export function adjustTableWidth(table_id, width_pct){ export function clearTable(table_id){ const table = document.getElementById(table_id); table.querySelector('thead').innerHTML = ''; - table.querySelector('tbody').innerHTML = ''; + table.querySelector('tbody'). + innerHTML = ''; } +// Add button functions +export function hideAddButton(){ + document.getElementById('add-btn').style.display = 'none'; +} + +export function showAddButton(){ + document.getElementById('add-btn').style.display = 'block'; +} + +export function updateAddButtonText(text){ + document.getElementById('add-btn').textContent = text; +} + +// Show and hide table + export function hideTable(table_id){ const table = document.getElementById(table_id); table.style.display = 'none'; + hideAddButton(); } export function showTable(table_id){ diff --git a/js/init.js b/js/init.js index 9fb17f1..c0a7668 100644 --- a/js/init.js +++ b/js/init.js @@ -2,7 +2,8 @@ import { initializeWelcomePage } from './pages/00_welcome/main.js'; import { loadNewInitiatives } from './pages/02_new_initiatives/main.js' import { loadRevenuePage } from './pages/03_revenue/main.js' -import { loadPageState, updatePageState } from './utils/storage-handlers.js' +import { loadPageState } from './utils/storage-handlers.js' +import { updateNavButtonLinks } from './components/nav_buttons/nav_buttons.js'; // running tallies of total spend let personnel_supp = 0; @@ -18,6 +19,7 @@ let baseline_total = personnel_baseline - baseline_revenue; document.addEventListener('DOMContentLoaded', function () { var page_state = loadPageState(); + updateNavButtonLinks(); switch (page_state){ case 'welcome': diff --git a/js/pages/00_welcome/helpers.js b/js/pages/00_welcome/helpers.js new file mode 100644 index 0000000..37847b8 --- /dev/null +++ b/js/pages/00_welcome/helpers.js @@ -0,0 +1,23 @@ + +import { hidePrompt } from '../../components/prompt/prompt.js' +import { hideNavButtons } from '../../components/nav_buttons/nav_buttons.js' +import { hideSideBar } from '../../components/sidebar/sidebar.js' +import { hideTable } from '../../components/table/table.js' +import { updateSubtitle } from '../../components/header/header.js' +import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' +import { loadNewInitiatives } from '../02_new_initiatives/main.js' + +export function initializePageView(){ + // page set up + hideTable('main-table'); + hideSideBar(); + updateSubtitle("Welcome"); + unhideWelcomeButtons(); + hidePrompt(); + hideNavButtons(); +} + +export function addLinks(){ + // initialize links in buttons + document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) +} diff --git a/js/pages/00_welcome/main.js b/js/pages/00_welcome/main.js index a831a14..401addc 100644 --- a/js/pages/00_welcome/main.js +++ b/js/pages/00_welcome/main.js @@ -1,26 +1,11 @@ -import { updateSubtitle } from '../../components/header/header.js' -import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' -import { loadNewInitiatives } from '../02_new_initiatives/main.js' + import { updatePageState } from '../../utils/storage-handlers.js' -import { hidePrompt } from '../../components/prompt/prompt.js' -import { hideNavButtons } from '../../components/nav_buttons/nav_buttons.js' -import { hideSideBar } from '../../components/sidebar/sidebar.js' -import { hideTable } from '../../components/table/table.js' +import { initializePageView, addLinks } from './helpers.js' export function initializeWelcomePage(){ - // record page state updatePageState('welcome'); - - // page set up - hideTable('main-table'); - hideSideBar(); - updateSubtitle("Welcome"); - unhideWelcomeButtons(); - hidePrompt(); - hideNavButtons(); - - // initialize links in buttons - document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) + initializePageView(); + addLinks(); } \ No newline at end of file diff --git a/js/pages/02_new_initiatives/helpers.js b/js/pages/02_new_initiatives/helpers.js index c15f0ac..1f2d0de 100644 --- a/js/pages/02_new_initiatives/helpers.js +++ b/js/pages/02_new_initiatives/helpers.js @@ -1,44 +1,76 @@ -// Add form question -// +import { hideWelcomeButtons } from '../../components/welcome/welcome.js' +import { updateSubtitle } from '../../components/header/header.js' +import { hidePrompt, showPrompt, updatePrompt, updatePromptButtons, addPromptButtonAction } from '../../components/prompt/prompt.js' +import { initializeWelcomePage } from '../00_welcome/main.js' +import { showNavButtons, updateNavButtonLinks } from '../../components/nav_buttons/nav_buttons.js' +import { loadRevenuePage } from '../03_revenue/main.js' +import { addModalLink, updateModalTitle, clearModal, hideModal } from '../../components/modal/modal.js' +import { fetchAllResponses, addTextarea, addTextInput, addNumericInput, addSubmitButtonToForm, addForm } from '../../components/form/form.js' +import { adjustTableWidth, hideTable, clearTable, updateAddButtonText, addNewRow, showTable, showAddButton } from '../../components/table/table.js' +import { hideSideBar } from '../../components/sidebar/sidebar.js' +export function initializePageView() { + // Load text + updateSubtitle('New Initiatives'); + updatePrompt('Do you have any new initiatives for FY26?'); + updatePromptButtons('Yes', 'No'); + // Prepare page view + hideWelcomeButtons(); + showNavButtons(); + hideSideBar(); + showPrompt(); + hideTable('main-table'); +} -// process new initiative submission - -// todo: parameterize so that it loads a table based on just the entries from the form +export function setUpModal() { + // Initialize modal + clearModal(); + addModalLink('option1', 'main-modal'); + updateModalTitle('New initiative'); + addModalLink('add-btn', 'main-modal'); +} -export function handleFormSubmissions(event){ - event.preventDefault(); // Prevent the default form submission +export function setUpForm() { + // Set up form + addForm(); + addTextInput('Initiative Name:', 'Initiative Name', true); // Add required field + addTextarea('Explain why this initiative is necessary and describe its potential impact.', 'Explanation', true); + addNumericInput('Roughly how additional money would this initiative require?', 'Cost', true); + addSubmitButtonToForm(); + // Initialize form submission to table data + handleFormSubmissions(); +} - // get values from form - var name = document.getElementById('init-name').value; - var explanation = document.getElementById('init-explanation').value; - var request = document.getElementById('init-request').value; +export function setUpTable() { + // Set up table + clearTable('main-table'); + adjustTableWidth('main-table', '70%'); + updateAddButtonText('Add another new initiative'); +} - var table = document.getElementById('initiative-table'); +export function handleNavigation() { + // clicking 'No' (no new initiatives) will also take us to the next page + addPromptButtonAction('option2', loadRevenuePage); +} - // Insert a row at the end of the table - var newRow = table.insertRow(table.rows.length); - - // Insert cells in the row - var cell1 = newRow.insertCell(0); - var cell2 = newRow.insertCell(1); - var cell3 = newRow.insertCell(2); +export function handleFormSubmissions(event){ + // initialize form submission + const modal = document.getElementById('main-modal'); + modal.addEventListener('submit', function(event) { + // get answers from form, hide form, show answers in table + const responses = fetchAllResponses(event); - // Add some text to the new cells - cell1.innerHTML = name; - cell2.innerHTML = explanation; - cell3.innerHTML = formatCurrency(request); - cell3.classList.add('cost'); + // change page view + hideModal('main-modal'); + hidePrompt(); - // Clear the form for the next entries - document.getElementById('new-init-form').reset(); - - //show table - document.getElementById('initiative-table-div').style.display = "block"; - - // hide modal and Y/N questions - $('#new-init-modal').modal('hide'); - document.getElementById('initial-questions').style.display = 'none'; + // add data to table + addNewRow('main-table', responses); + showTable('main-table'); + showAddButton(); + // TODO: save table data + // TODO: edit cost to show currency correctly + }); } diff --git a/js/pages/02_new_initiatives/main.js b/js/pages/02_new_initiatives/main.js index 8eca40f..63d636b 100644 --- a/js/pages/02_new_initiatives/main.js +++ b/js/pages/02_new_initiatives/main.js @@ -1,70 +1,14 @@ -import { hideWelcomeButtons } from '../../components/welcome/welcome.js' -import { updateSubtitle } from '../../components/header/header.js' -import { showPrompt, updatePrompt, updatePromptButtons, addPromptButtonAction, hidePrompt } from '../../components/prompt/prompt.js' -import { handleFormSubmissions } from './helpers.js' + +import { initializePageView, setUpModal, setUpForm, setUpTable, handleNavigation } from './helpers.js' import { updatePageState } from '../../utils/storage-handlers.js' -import { initializeWelcomePage } from '../00_welcome/main.js' -import { showNavButtons, updateNavButtonLinks } from '../../components/nav_buttons/nav_buttons.js' -import { loadRevenuePage } from '../03_revenue/main.js' -import { addModalLink, updateModalTitle, clearModal, hideModal } from '../../components/modal/modal.js' -import { addTextarea, addTextInput, addNumericInput, addSubmitButtonToForm, addForm, fetchAllResponses } from '../../components/form/form.js' -import { addNewRow, adjustTableWidth, hideTable, clearTable, showTable } from '../../components/table/table.js' -import { hideSideBar } from '../../components/sidebar/sidebar.js' + // set up page and initialize all buttons export function loadNewInitiatives() { - - //update page state updatePageState('new-inits'); - - // load text - updateSubtitle('New Initiatives'); - updatePrompt('Do you have any new initiatives for FY26?'); - updatePromptButtons('Yes', 'No'); - - // prepare page view - hideWelcomeButtons(); - hideSideBar(); - showPrompt(); - showNavButtons(); - hideTable('main-table'); - - // initialize modal - addModalLink('option1', 'main-modal'); - clearModal(); - updateModalTitle('New initiative'); - - // set up form - addForm(); - addTextInput('Initiative Name:', 'Initiative Name', true); //add required field - addTextarea('Explain why this initiative is neccessary and describe its potential impact.', 'Explanation', true); - addNumericInput('Roughly how additional money would this initiative require?', 'Cost', true); - addSubmitButtonToForm(); - - // set up table and initialize form submission to table data - clearTable('main-table'); - adjustTableWidth('main-table', '70%'); - - // initialize form submission - const modal = document.getElementById('main-modal'); - modal.addEventListener('submit', function(event) { - // get answers from form, hide form, show answers in table - const responses = fetchAllResponses(event); - - // change page view - hideModal('main-modal'); - hidePrompt(); - - // add data to table - addNewRow('main-table', responses); - showTable('main-table'); - // TODO: save table data - // TODO: edit cost to show currency correctly - }); - - // initialize nav buttons fn(last, next) - updateNavButtonLinks(initializeWelcomePage, loadRevenuePage); - - // clicking 'No' (no new initiatives) will also take us to the next page - addPromptButtonAction('option2', loadRevenuePage); -} \ No newline at end of file + initializePageView(); + setUpModal(); + setUpForm(); + setUpTable(); + handleNavigation(); +} diff --git a/js/pages/03_revenue/main.js b/js/pages/03_revenue/main.js index c77189b..7da0d87 100644 --- a/js/pages/03_revenue/main.js +++ b/js/pages/03_revenue/main.js @@ -22,9 +22,6 @@ export function loadRevenuePage() { updatePrompt('Your revenue projection for FY26 is $0'); updatePromptButtons('Confirm and continue.', "This doesn't look right"); - // initialize nav buttons fn(last, next) - updateNavButtonLinks(loadNewInitiatives, loadNewInitiatives); - // clicking 'confirm and continue' will also take us to the next page addPromptButtonAction('option1', loadNewInitiatives); From 7846a5ad00388b13e77c3f0c37a516a77573a689 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Tue, 18 Jun 2024 10:11:56 -0400 Subject: [PATCH 14/22] fixed naV BUTTONS. added some sample json data. --- css/common.css | 5 +- data/law_dept_sample/personnel_data.json | 35 +++++++++++++ data/law_dept_sample/services.json | 1 + data/law_dept_sample/strings.json | 39 ++++++++++++++ index.html | 11 +++- js/components/nav_buttons/nav_buttons.js | 8 +-- js/components/prompt/prompt.js | 8 +++ js/components/sidebar/sidebar.css | 4 ++ js/components/table/table.css | 1 + js/init.js | 11 ++-- js/pages/02_new_initiatives/helpers.js | 3 +- js/pages/03_revenue/main.js | 6 ++- js/pages/04_personnel/main.js | 65 ++++++++++-------------- js/pages/04_personnel/main_archived.js | 47 +++++++++++++++++ js/utils/data-handlers.js | 42 +++++++++++++++ 15 files changed, 233 insertions(+), 53 deletions(-) create mode 100644 data/law_dept_sample/personnel_data.json create mode 100644 data/law_dept_sample/services.json create mode 100644 data/law_dept_sample/strings.json create mode 100644 js/components/sidebar/sidebar.css create mode 100644 js/pages/04_personnel/main_archived.js create mode 100644 js/utils/data-handlers.js diff --git a/css/common.css b/css/common.css index cf6db90..0e80c16 100644 --- a/css/common.css +++ b/css/common.css @@ -40,10 +40,7 @@ body { /* Sidebar */ -#sidebar { - background-color: lightgrey; - /* min-height: 100vh; Full height of viewport */ - } + #supp-total { color: var(--yellow); diff --git a/data/law_dept_sample/personnel_data.json b/data/law_dept_sample/personnel_data.json new file mode 100644 index 0000000..2533bee --- /dev/null +++ b/data/law_dept_sample/personnel_data.json @@ -0,0 +1,35 @@ +[ + { + "Job Name": "Deputy Counsel", + "Account String": "1000-29320-320010", + "Service": "", + "Current FTEs (FY25)": 1, + "Baseline FTEs": 0, + "Supplemental FTEs": 0, + "Average FY25 Salary": "$150,000", + "Total Cost (Baseline)": "$ -", + "Total Cost (Supplementary)": "$ -" + }, + { + "Job Name": "Legal Secretary", + "Account String": "1000-29320-320010", + "Service": "", + "Current FTEs (FY25)": 5, + "Baseline FTEs": 0, + "Supplemental FTEs": 0, + "Average FY25 Salary": "$55,000", + "Total Cost (Baseline)": "$ -", + "Total Cost (Supplementary)": "$ -" + }, + { + "Job Name": "Assistant Counsel", + "Account String": "1000-29320-320010", + "Service": "", + "Current FTEs (FY25)": 10, + "Baseline FTEs": 0, + "Supplemental FTEs": 0, + "Average FY25 Salary": "$80,000", + "Total Cost (Baseline)": "$ -", + "Total Cost (Supplementary)": "$ -" + } +] \ No newline at end of file diff --git a/data/law_dept_sample/services.json b/data/law_dept_sample/services.json new file mode 100644 index 0000000..b57f101 --- /dev/null +++ b/data/law_dept_sample/services.json @@ -0,0 +1 @@ +["Appeals", "FOIA", "Lobbying"] \ No newline at end of file diff --git a/data/law_dept_sample/strings.json b/data/law_dept_sample/strings.json new file mode 100644 index 0000000..955a422 --- /dev/null +++ b/data/law_dept_sample/strings.json @@ -0,0 +1,39 @@ +{ + "1000" : { + "label" : "General Fund", + "appropriations" : { + "29320" : { + "label" : "Efficient and Innovative Operations Support", + "cost centers" : { + "320010" : { "label" : "Law Administration" }, + "321111" : { "label" : "Law Department Grants" } + } + } + } + }, + + "2119" : { + "label" : "FY2020 MIDC Grant", + "appropriations" : { + "21206" : { + "label" : "2023 Michigan Indigent Defense Commission", + "cost centers" : { + "320010" : { "label" : "Law Administration" }, + "321111" : { "label" : "Law Department Grants" } + } + } + } + }, + + "2490" : { + "label" : "Construction Code Fund", + "appropriations" : { + "25130" : { + "label" : "BSEED Safe Buildings", + "cost centers" : { + "320010" : { "label" : "Law Administration" } + } + } + } + } +} \ No newline at end of file diff --git a/index.html b/index.html index 3ccdfdc..ae8e30b 100644 --- a/index.html +++ b/index.html @@ -17,6 +17,7 @@ + @@ -131,7 +132,15 @@

-
-
- - - diff --git a/js/components/sidebar/sidebar.js b/js/components/sidebar/sidebar.js index c2b2efa..8527f87 100644 --- a/js/components/sidebar/sidebar.js +++ b/js/components/sidebar/sidebar.js @@ -1,10 +1,11 @@ export function hideSideBar(){ - document.getElementById('sidebar-panel').className = ''; + document.getElementById('sidebar-panel').style.display = 'none'; document.getElementById('main-panel').className = 'col-md-12'; } export function showSideBar(){ document.getElementById('sidebar-panel').className = 'col-md-2'; + document.getElementById('sidebar-panel').style.display = 'block'; document.getElementById('main-panel').className = 'col-md-10'; } diff --git a/js/components/table/table.js b/js/components/table/table.js index 14c4cd1..0c35596 100644 --- a/js/components/table/table.js +++ b/js/components/table/table.js @@ -85,4 +85,53 @@ export function hideTable(table_id){ export function showTable(table_id){ const table = document.getElementById(table_id); table.style.display = 'table'; +} + +// position is index at which new column will be inserted +export function addCol(tableId, position, htmlContent = '', headerTitle = '') { + // Get the table element by its ID + let table = document.getElementById(tableId); + + if (!table) { + console.error(`Table with ID ${tableId} not found.`); + return; + } + + // Validate position + let maxPosition = table.rows[0].cells.length; + if (position < 0 || position > maxPosition) { + console.error(`Position ${position} is out of bounds.`); + return; + } + + // Insert the header if provided + let thead = table.tHead; + if (headerTitle && thead) { + let th = document.createElement('th'); + th.innerHTML = headerTitle; // Use innerHTML to insert HTML content + thead.rows[0].insertBefore(th, thead.rows[0].cells[position]); + } + + // Insert new cells into each row of the table body + let tbody = table.tBodies[0]; + if (tbody) { + for (let i = 0; i < tbody.rows.length; i++) { + let row = tbody.rows[i]; + let td = document.createElement('td'); + td.innerHTML = htmlContent; // Use innerHTML to insert HTML content + row.insertBefore(td, row.cells[position]); + } + } +} + +function ncols(tableId){ + const table = document.getElementById(tableId); + // Ensure that the row exists before counting the columns + return table.rows[0].cells.length; +} + +export function addColToEnd(tableId, htmlContents = [], headerTitle = ''){ + // count columns and add new column to the end + const position = ncols(tableId); + addCol(tableId, position, htmlContents, headerTitle); } \ No newline at end of file diff --git a/js/pages/00_welcome/helpers.js b/js/pages/00_welcome/helpers.js index 37847b8..1313f4c 100644 --- a/js/pages/00_welcome/helpers.js +++ b/js/pages/00_welcome/helpers.js @@ -6,6 +6,8 @@ import { hideTable } from '../../components/table/table.js' import { updateSubtitle } from '../../components/header/header.js' import { unhideWelcomeButtons } from '../../components/welcome/welcome.js' import { loadNewInitiatives } from '../02_new_initiatives/main.js' +import { loadRevenuePage } from '../03_revenue/main.js' +import { loadPersonnelPage } from '../04_personnel/main.js' export function initializePageView(){ // page set up @@ -20,4 +22,7 @@ export function initializePageView(){ export function addLinks(){ // initialize links in buttons document.getElementById('step-initiatives').addEventListener('click', loadNewInitiatives) + document.getElementById('step-revenue').addEventListener('click', loadRevenuePage) + document.getElementById('step-personnel').addEventListener('click', loadPersonnelPage) + } diff --git a/js/pages/04_personnel/main.js b/js/pages/04_personnel/main.js index 1e51c16..d43b469 100644 --- a/js/pages/04_personnel/main.js +++ b/js/pages/04_personnel/main.js @@ -7,7 +7,7 @@ import { hidePromptButtons, showPrompt, updatePrompt } from "../../components/pr import { showNavButtons } from "../../components/nav_buttons/nav_buttons.js"; import { updateSubtitle } from "../../components/header/header.js"; import { loadJSONIntoTable } from "../../utils/data-handlers.js"; -import { showTable } from "../../components/table/table.js"; +import { addCol, addColToEnd, showTable } from "../../components/table/table.js"; import { showSideBar } from "../../components/sidebar/sidebar.js"; export function loadPersonnelPage(){ @@ -19,16 +19,26 @@ export function loadPersonnelPage(){ hideWelcomeButtons(); showPrompt(); showNavButtons(); + showSideBar(); + hidePromptButtons(); // update page text updateSubtitle('Personnel'); // TODO: update to make dynamic updatePrompt('For each job in your department, select the service and request the number of baseline and supplemental FTEs.'); - hidePromptButtons(); - - // initialize table - loadJSONIntoTable('../../../data/law_dept_sample/personnel_data.json', 'main-table'); - showTable('main-table'); - showSideBar(); + + + // Initialize table + loadJSONIntoTable('../../../data/law_dept_sample/personnel_data.json', 'main-table') + .then(() => { + showTable('main-table'); + addCol('main-table', 2, '', 'Service'); + addColToEnd('main-table', '$ -', 'Total Cost (Baseline)'); + addColToEnd('main-table', '$ -', 'Total Cost (Supplementary)'); + }) + .catch(error => { + console.error('An error occurred during table initialization:', error); + }); + } \ No newline at end of file diff --git a/js/utils/data-handlers.js b/js/utils/data-handlers.js index cf2a505..4d00f1f 100644 --- a/js/utils/data-handlers.js +++ b/js/utils/data-handlers.js @@ -1,6 +1,11 @@ export function loadJSONIntoTable(jsonFilePath, tableId) { - fetch(jsonFilePath) - .then(response => response.json()) + return fetch(jsonFilePath) + .then(response => { + if (!response.ok) { + throw new Error('Network response was not ok'); + } + return response.json(); + }) .then(data => { if(Array.isArray(data)) { const table = document.getElementById(tableId); From 4eef5c4c4ae3d1e482be56a97e164a067f198c53 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Tue, 18 Jun 2024 14:59:55 -0400 Subject: [PATCH 16/22] getting through personnel modularization --- data/law_dept_sample/personnel_data.json | 6 +- index.html | 10 ++- js/components/table/table.css | 8 ++ js/components/table/table.js | 72 ++++++++++++++++++ js/pages/04_personnel/main.js | 94 ++++++++++++++++++++++-- js/utils/utils.js | 2 +- 6 files changed, 179 insertions(+), 13 deletions(-) diff --git a/data/law_dept_sample/personnel_data.json b/data/law_dept_sample/personnel_data.json index 23a3ed3..becc1ce 100644 --- a/data/law_dept_sample/personnel_data.json +++ b/data/law_dept_sample/personnel_data.json @@ -5,7 +5,7 @@ "Current FTEs (FY25)": 1, "Baseline FTEs": 0, "Supplemental FTEs": 0, - "Average FY25 Salary": "$150,000" + "Current Average Salary": "150000" }, { "Job Name": "Legal Secretary", @@ -13,7 +13,7 @@ "Current FTEs (FY25)": 5, "Baseline FTEs": 0, "Supplemental FTEs": 0, - "Average FY25 Salary": "$55,000" + "Current Average Salary": "55000" }, { "Job Name": "Assistant Counsel", @@ -21,6 +21,6 @@ "Current FTEs (FY25)": 10, "Baseline FTEs": 0, "Supplemental FTEs": 0, - "Average FY25 Salary": "$80,000" + "Current Average Salary": "80000" } ] \ No newline at end of file diff --git a/index.html b/index.html index c7b20b0..272f9a3 100644 --- a/index.html +++ b/index.html @@ -94,10 +94,12 @@

- - - -
+ + + + +
+
diff --git a/js/components/table/table.css b/js/components/table/table.css index ad10867..2940c35 100644 --- a/js/components/table/table.css +++ b/js/components/table/table.css @@ -41,4 +41,12 @@ input { justify-content: center; /* Aligns horizontally */ align-items: center; /* Aligns vertically */ width: 100%; +} + +.btn-edit { + background-color: var(--spiritgreen); +} + +.active-editing { + background-color: var(--palegreen); } \ No newline at end of file diff --git a/js/components/table/table.js b/js/components/table/table.js index 0c35596..0c24707 100644 --- a/js/components/table/table.js +++ b/js/components/table/table.js @@ -1,3 +1,4 @@ +import { formatCurrency } from "../../utils/utils.js"; export function addTableHeaders(table_id, header_array){ @@ -134,4 +135,75 @@ export function addColToEnd(tableId, htmlContents = [], headerTitle = ''){ // count columns and add new column to the end const position = ncols(tableId); addCol(tableId, position, htmlContents, headerTitle); +} + +// functions for editing rows +function editButton() { + return '' +}; + +export function addEditCol(tableId){ + addColToEnd(tableId, editButton(), ' '); +} + +export function assignClassToColumn(tableId, headerName, className) { + // Get the table element by its ID + let table = document.getElementById(tableId); + + // Find the index of the column by its header name + const thead = table.tHead; + if (!thead || thead.rows.length === 0) { + console.error('The table header is not found or has no rows.'); + return; + } + + let headerCellIndex = -1; + const headerCells = thead.rows[0].cells; // Assuming the first row contains header cells () + for (let i = 0; i < headerCells.length; i++) { + if (headerCells[i].textContent.trim() === headerName) { + headerCellIndex = i; + break; + } + } + + if (headerCellIndex === -1) { + console.error(`No header found with name "${headerName}"`); + return; + } + + // Assign the class to each cell in the specified column index within the tbody + let tbody = table.tBodies[0]; + if (tbody) { + let bodyRows = tbody.rows; + for (let row of bodyRows) { + if (row.cells[headerCellIndex]) { + row.cells[headerCellIndex].classList.add(className); + } + } + } + } + +export function AddCostClass(tableId, headerName){ + assignClassToColumn(tableId, headerName, 'cost'); + + // Get all the cells with the specified class name + const cells = document.querySelectorAll(`.cost`); + + cells.forEach(cell => { + // Get the current text content of the cell and assign it to 'value' attribute + if (!cell.getAttribute('value')){ + const cellValue = cell.textContent.trim(); + cell.setAttribute('value', cellValue); + + // Now format the text content like currency and replace it in the cell + const formattedCurrency = formatCurrency(parseFloat(cellValue)); + cell.textContent = formattedCurrency; + } + + }); + +} + +export function updateCellValue(cell, newValue){ + pass; } \ No newline at end of file diff --git a/js/pages/04_personnel/main.js b/js/pages/04_personnel/main.js index d43b469..d98c5fa 100644 --- a/js/pages/04_personnel/main.js +++ b/js/pages/04_personnel/main.js @@ -7,7 +7,7 @@ import { hidePromptButtons, showPrompt, updatePrompt } from "../../components/pr import { showNavButtons } from "../../components/nav_buttons/nav_buttons.js"; import { updateSubtitle } from "../../components/header/header.js"; import { loadJSONIntoTable } from "../../utils/data-handlers.js"; -import { addCol, addColToEnd, showTable } from "../../components/table/table.js"; +import { AddCostClass, addCol, addColToEnd, addEditCol, adjustTableWidth, assignClassToColumn, showTable } from "../../components/table/table.js"; import { showSideBar } from "../../components/sidebar/sidebar.js"; export function loadPersonnelPage(){ @@ -21,24 +21,108 @@ export function loadPersonnelPage(){ showNavButtons(); showSideBar(); hidePromptButtons(); + adjustTableWidth('main-table', '90%'); // update page text updateSubtitle('Personnel'); - // TODO: update to make dynamic updatePrompt('For each job in your department, select the service and request the number of baseline and supplemental FTEs.'); + initializePersonnelTable(); + + + +} + +export function initializePersonnelTable(){ // Initialize table loadJSONIntoTable('../../../data/law_dept_sample/personnel_data.json', 'main-table') .then(() => { showTable('main-table'); - addCol('main-table', 2, '', 'Service'); - addColToEnd('main-table', '$ -', 'Total Cost (Baseline)'); - addColToEnd('main-table', '$ -', 'Total Cost (Supplementary)'); + addCol('main-table', 3, '', 'Service'); + addColToEnd('main-table', '0', 'Total Cost (Baseline)'); + addColToEnd('main-table', '0', 'Total Cost (Supplementary)'); + addEditCol('main-table'); + // assign cost classes + assignClassToColumn('main-table', 'Current Average Salary', 'avg-salary'); + AddCostClass('main-table', 'Current Average Salary'); + assignClassToColumn('main-table', 'Total Cost (Baseline)', 'total-baseline'); + AddCostClass('main-table', 'Total Cost (Baseline)'); + assignClassToColumn('main-table', 'Total Cost (Supplementary)', 'total-supp'); + AddCostClass('main-table', 'Total Cost (Supplementary)'); + // assign other classes + assignClassToColumn('main-table', 'Job Name', 'job-name'); + assignClassToColumn('main-table', 'Baseline FTEs', 'baseline-ftes'); + assignClassToColumn('main-table', 'Supplemental FTEs', 'supp-ftes'); + // manage edit buttons + handleRowEdit(); }) .catch(error => { console.error('An error occurred during table initialization:', error); + }); +} + +export function handleRowEdit(){ + // attach an event listener to each edit button in every row + var editButtons = document.getElementsByClassName('btn-edit'); + for (var i = 0; i < editButtons.length; i++) { + editButtons[i].addEventListener('click', function(event) { + // Determine what was clicked on within the table + var rowToEdit = event.target.closest('tr'); + // mark row as being edited + rowToEdit.classList.add('active-editing'); + + // turn relevant entries into textboxes + createEditableCell('baseline-ftes'); + createEditableCell('supp-ftes'); + // make acount string and service editable + + // hide edit buttons + + // create confirm button + // (elsewhere, attach confirmation listener to turn off edit class and show edits) }); + }; +} + + +function createEditableCell(cellClass, attribute = 'value'){ + // get cell + const cell = document.querySelector(`.active-editing td.${cellClass}`); + // Fetch the current attribute value of the cell or fall back to an empty string + var currentValue = cell.getAttribute(attribute) || ''; + // Create an input element to edit the value + var textbox = document.createElement('input'); + textbox.type = 'text'; + textbox.value = currentValue; + // Clear the current content and append the textbox to the cell + cell.innerHTML = ''; + cell.appendChild(textbox); + //cell.appendChild(feedback); +} + +function commitAndRestoreText() { + // Retrieve the entered value + var enteredValue = textbox.value; + // Set the attribute to the entered value + cell.setAttribute(attribute, enteredValue); + // validate text against validation criteria + let feedback_text = ''; + if (validate){ + feedback_text = validate(enteredValue); + } + // if there's an error, show it + if (feedback_text){ + feedback.textContent = feedback_text; + // otherwise, proceed + } else { + // Format and set the cell's text content + cell.textContent = formatValueCallback ? formatValueCallback(enteredValue) : enteredValue; + // If there is an update callback provided, call it + if (updateCallback) { + updateCallback(); + } + }; } \ No newline at end of file diff --git a/js/utils/utils.js b/js/utils/utils.js index 57aed89..352fa2e 100644 --- a/js/utils/utils.js +++ b/js/utils/utils.js @@ -1,5 +1,5 @@ // Function to format number as currency -const formatCurrency = (amount) => { +export const formatCurrency = (amount) => { var amount = parseFloat(amount); if (amount == NaN){ return "$ -" From 27150c406a6f6ff426848fdacec0152add5ff090 Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Tue, 18 Jun 2024 16:51:08 -0400 Subject: [PATCH 17/22] edited personnel page --- js/components/prompt/prompt.css | 2 ++ js/pages/04_personnel/main.js | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/js/components/prompt/prompt.css b/js/components/prompt/prompt.css index 0633c92..968f9eb 100644 --- a/js/components/prompt/prompt.css +++ b/js/components/prompt/prompt.css @@ -1,6 +1,8 @@ #prompt-div { display: none; text-align: center; + width: 60%; + margin-left: 20%; } #prompt { diff --git a/js/pages/04_personnel/main.js b/js/pages/04_personnel/main.js index d98c5fa..a1b275f 100644 --- a/js/pages/04_personnel/main.js +++ b/js/pages/04_personnel/main.js @@ -78,8 +78,14 @@ export function handleRowEdit(){ // make acount string and service editable // hide edit buttons - + var editButtons = document.getElementsByClassName('btn-edit'); + for (var i = 0; i < editButtons.length; i++) { + editButtons[i].style.display = 'none'; + } + // create confirm button + const confirmCell = rowToEdit.querySelector('.active-editing td:last-child'); + confirmCell.innerHTML = '' // (elsewhere, attach confirmation listener to turn off edit class and show edits) }); }; From 16ce22d3f592717bc833447c81d76ba9777f778e Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 20 Jun 2024 09:55:02 -0400 Subject: [PATCH 18/22] editing json path --- js/pages/04_personnel/main.js | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/js/pages/04_personnel/main.js b/js/pages/04_personnel/main.js index a1b275f..4efbfe0 100644 --- a/js/pages/04_personnel/main.js +++ b/js/pages/04_personnel/main.js @@ -36,7 +36,7 @@ export function loadPersonnelPage(){ export function initializePersonnelTable(){ // Initialize table - loadJSONIntoTable('../../../data/law_dept_sample/personnel_data.json', 'main-table') + loadJSONIntoTable('../../../../budget-request-demo/data/law_dept_sample/personnel_data.json', 'main-table') .then(() => { showTable('main-table'); addCol('main-table', 3, '', 'Service'); @@ -106,29 +106,3 @@ function createEditableCell(cellClass, attribute = 'value'){ cell.appendChild(textbox); //cell.appendChild(feedback); } - -function commitAndRestoreText() { - // Retrieve the entered value - var enteredValue = textbox.value; - // Set the attribute to the entered value - cell.setAttribute(attribute, enteredValue); - - // validate text against validation criteria - let feedback_text = ''; - if (validate){ - feedback_text = validate(enteredValue); - } - - // if there's an error, show it - if (feedback_text){ - feedback.textContent = feedback_text; - // otherwise, proceed - } else { - // Format and set the cell's text content - cell.textContent = formatValueCallback ? formatValueCallback(enteredValue) : enteredValue; - // If there is an update callback provided, call it - if (updateCallback) { - updateCallback(); - } - }; -} \ No newline at end of file From 64cb5858c4771db2bef0db626ba8374e856c4cef Mon Sep 17 00:00:00 2001 From: Katrina Wheelan Date: Thu, 20 Jun 2024 13:48:33 -0400 Subject: [PATCH 19/22] deleting extraneous files --- css/02_new_initiatives.css | 15 -- css/03_revenue.css | 3 - css/04_personnel.css | 28 -- css/common.css | 8 - index.html | 38 ++- js/components/sidebar/sidebar.css | 10 +- js/components/sidebar/sidebar.js | 42 +++ js/components/table/table.css | 4 + js/components/table/table.js | 4 +- js/pages/04_personnel/main.js | 93 ++++++- js/pages/04_personnel/rollup-helpers.js | 13 +- js/utils/utils.js | 22 -- pages/02_new_initiatives.html | 139 ---------- pages/03_revenue.html | 54 ---- pages/04.5_overtime.html | 208 --------------- pages/04_personnel.html | 335 ------------------------ 16 files changed, 184 insertions(+), 832 deletions(-) delete mode 100644 css/02_new_initiatives.css delete mode 100644 css/03_revenue.css delete mode 100644 css/04_personnel.css delete mode 100644 pages/02_new_initiatives.html delete mode 100644 pages/03_revenue.html delete mode 100644 pages/04.5_overtime.html delete mode 100644 pages/04_personnel.html diff --git a/css/02_new_initiatives.css b/css/02_new_initiatives.css deleted file mode 100644 index f56b4a4..0000000 --- a/css/02_new_initiatives.css +++ /dev/null @@ -1,15 +0,0 @@ -/* New initiative page */ - -.btn.btn-yes { background-color: var(--green);} -.btn.btn-no {background-color: var(--orange);} -.btn.btn-yes, .btn.btn-no{ font-size: 1.5em;} -.btn.btn-yes:hover, .btn.btn-no:hover {color: white;} - -#col-init-explanation{ width: 70%; } - -#init-explanation {height: 100px; width: 100%;} -#submit-btn-container {text-align: center;} -.btn.btn-submit {background-color: var(--spiritgreen); width: 50%; color:white;} -.btn.btn-submit:hover { - color: black; -} diff --git a/css/03_revenue.css b/css/03_revenue.css deleted file mode 100644 index 126ea53..0000000 --- a/css/03_revenue.css +++ /dev/null @@ -1,3 +0,0 @@ - -.btn.btn-yes { background-color: var(--green);} -.btn.btn-no {background-color: var(--orange);} \ No newline at end of file diff --git a/css/04_personnel.css b/css/04_personnel.css deleted file mode 100644 index 6981829..0000000 --- a/css/04_personnel.css +++ /dev/null @@ -1,28 +0,0 @@ -.btn-info { - border-radius: 0%; - background-color: var(--lightBlue); - margin-left: 10px; - color: black; -} - -.btn-edit { - background-color: var(--blue); - margin-left: 10px; -} - -.btn-see-calcs { - display: none; -} - -.icon-button { - background: none; - border: none; - padding: 0; - cursor: pointer; - font-size: 1.5em; - color: var(--blue); -} - -.icon-button:hover { - color: var(--orange); -} \ No newline at end of file diff --git a/css/common.css b/css/common.css index 0e80c16..2bb9994 100644 --- a/css/common.css +++ b/css/common.css @@ -38,14 +38,6 @@ body { color: white; } -/* Sidebar */ - - - -#supp-total { - color: var(--yellow); -} - /* Action buttons */ .action-btns { diff --git a/index.html b/index.html index 272f9a3..43a0d11 100644 --- a/index.html +++ b/index.html @@ -136,10 +136,44 @@


Baseline
-
+
+