From a98f3fa2f5e5239e119edd657290f9cc7d3d9d35 Mon Sep 17 00:00:00 2001 From: Sam sunder Date: Wed, 31 May 2023 18:35:02 +0530 Subject: [PATCH 01/10] Added settings in settings page and added search link to navbar --- .../static/colorschemes/catppuccin-mocha.css | 2 + public/static/settings.js | 173 +++++++++++++ public/static/themes/simple.css | 233 +++++++++++++++--- public/templates/navbar.html | 1 + public/templates/settings.html | 85 ++++++- 5 files changed, 462 insertions(+), 32 deletions(-) create mode 100644 public/static/settings.js diff --git a/public/static/colorschemes/catppuccin-mocha.css b/public/static/colorschemes/catppuccin-mocha.css index d2c1075..6432155 100644 --- a/public/static/colorschemes/catppuccin-mocha.css +++ b/public/static/colorschemes/catppuccin-mocha.css @@ -2,8 +2,10 @@ --bg: #1e1e2e; --fg: #cdd6f4; --1: #45475a; + --1_1: #4f5169; --2: #f38ba8; --3: #a6e3a1; + --3_1: #7ce073; --4: #f9e2af; --5: #89b4fa; --6: #f5c2e7; diff --git a/public/static/settings.js b/public/static/settings.js new file mode 100644 index 0000000..0af04bf --- /dev/null +++ b/public/static/settings.js @@ -0,0 +1,173 @@ +function toggleSelectOptions(elem, state) { + elem.classList.remove("invalid"); + try { elem.parentElement.querySelector('.errTxt').remove();} catch (error) {} + let options = elem.querySelector('.options'); + const pos = elem.getBoundingClientRect(); + const windowWidth = document.getElementsByTagName("body")[0].clientHeight; + if(pos.y + 250 > windowWidth) { + options.style.bottom = '40px'; + } else { options.style.bottom = null } + options.style.display = state != 'close' ? getComputedStyle(options).display == 'none' ? 'block': 'none' : 'none'; +} + +let selectElements = document.querySelectorAll('.custom-select'); +Array.from(selectElements).forEach(element => { + element.childNodes[0].nodeValue = (element.hasAttribute('data-multiple') ? element.getAttribute('data-placeholder') : element.getAttribute('data-default')); + element.addEventListener('click', (e) => {if (e.target === element) toggleSelectOptions(element)}); + element.addEventListener('focusout', (e) => {if (e.target === element) toggleSelectOptions(element, 'close')}); +}); + +function removeSelectOption(elem, optionId) { + let option = document.querySelector('#'+optionId); + let selectDiv = option.closest('.custom-select'); + let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); + elem.parentElement.remove(); + option.removeAttribute('selected'); + option.querySelector('svg').remove(); + input.value = input.value.replace(option.getAttribute('data-value') ? option.getAttribute('data-value') + "," : '', ''); +} + +function multiSelectClickHandler(elem) { + let selectDiv = elem.closest('.custom-select'); + let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); + if (!elem.hasAttribute('selected')) { + document.querySelector('#'+elem.closest(".custom-select").getAttribute("data-showDivId")).innerHTML += + `${elem.innerText}   + + + + + `; + elem.setAttribute('selected', ''); + elem.innerHTML = `${elem.innerText} + + ` + + // Code where value in inserted into input + input.value += elem.getAttribute('data-value') ? elem.getAttribute('data-value') + "," : ''; + } else { + // similar to removeSelectOption method + document.querySelector('#'+elem.getAttribute('id')+'-selected').remove(); + elem.removeAttribute('selected'); + elem.querySelector('svg').remove(); + + input.value = input.value.replace(elem.getAttribute('data-value') ? elem.getAttribute('data-value') + "," : '', ''); + } + +} + +function singleSelectClickHandler(elem) { + let selectDiv = elem.closest('.custom-select'); + let selectedOption = selectDiv.querySelector('span[selected]'); + let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`); + if (!elem.hasAttribute('selected')) { + if (selectedOption != null) { + selectedOption.removeAttribute('selected'); + selectedOption.querySelector('svg').remove(); + } + elem.setAttribute('selected', ''); + elem.innerHTML = `${elem.innerText} + + ` + // Code where value is inserted to input + input.value = elem.getAttribute('data-value') ? elem.getAttribute('data-value') : ''; + selectDiv.childNodes[0].nodeValue = elem.innerText; + } else { + elem.removeAttribute('selected'); + elem.querySelector('svg').remove(); + selectDiv.childNodes[0].nodeValue = selectDiv.getAttribute('data-default'); + + input.value = ""; + } + selectDiv.blur(); +} + +let multiSelectOptions = document.querySelectorAll('.custom-select[data-multiple="1"]>.options span'); +for (let i = 0; i < multiSelectOptions.length; i++) { + multiSelectOptions[i].addEventListener('click', () => {multiSelectClickHandler(multiSelectOptions[i])}); + multiSelectOptions[i].setAttribute('id', 'option-'+i.toString()); +} + +let singleSelectOptions = document.querySelectorAll('.custom-select:not([data-multiple="1"])>.options span'); +for (let i = 0; i < singleSelectOptions.length; i++) { + singleSelectOptions[i].addEventListener('click', () => {singleSelectClickHandler(singleSelectOptions[i])}); + singleSelectOptions[i].setAttribute('id', 'option-'+i.toString()); +} + +function selectAllHandler(elem) { + let options = elem.parentElement.querySelectorAll('.custom-select[data-multiple="1"]>.options span'); + Array.from(options).forEach((option) => { + try { + let selectedShownElem = document.getElementById(option.getAttribute('id')+'-selected'); + removeSelectOption(selectedShownElem.querySelector('span'), option.getAttribute('id')) + } catch (err) {} + if (elem.innerText == 'select all') { option.click() }; + }); + elem.innerText = elem.innerText == 'select all' ? 'deselect all' : 'select all' +} + + +// On settings form submit +function submitSettings() { + let form = document.settings; + document.querySelectorAll('.errTxt').forEach(e => e.remove()); + for(let i = 0; i < form.elements.length; i++) { + let input = form.elements[i]; + if (input.value == "" && input.hasAttribute('required')) { + let elem = input.parentElement.querySelector('[takeInput]') + let errTxt = document.createElement('p') + errTxt.classList.add('errTxt') + errTxt.innerText = 'This setting can\'t be empty!!' + elem.classList.add('invalid'); + elem.parentElement.insertBefore(errTxt, elem); + } + } + return false; +} + +document.querySelectorAll('.settings-sidebar .set-name').forEach(filter => { + let target = filter.getAttribute('data-detailId'); + filter.addEventListener('click', () => { + try {document.querySelector('.set-name.active').classList.remove('active');} catch(e){} + filter.classList.add('active'); + if (target == 'all') { + document.querySelectorAll('.set-item').forEach((elem) => { + elem.style.display = 'block'; + }) + return; + } + document.querySelectorAll('.set-item[data-id="'+target+'"]').forEach((elem) => { + elem.style.display = 'block' + }) + document.querySelectorAll('.set-item:not([data-id="'+target+'"])').forEach((elem) => { + elem.style.display = 'none' + }) + }) +}) + +function fadeOut(element) { + var op = 1; // initial opacity + var timer = setInterval(function () { + if (op <= 0.1){ + clearInterval(timer); + element.style.display = 'none'; + element.classList.add('fade'); + } + element.style.opacity = op; + element.style.filter = 'alpha(opacity=' + op * 100 + ")"; + op -= op * 0.1; + }, 50); +} + +function fadeIn(element) { + var op = 0.1; // initial opacity + element.style.display = 'block'; + var timer = setInterval(function () { + if (op >= 1){ + clearInterval(timer); + } + element.style.opacity = op; + element.style.filter = 'alpha(opacity=' + op * 100 + ")"; + op += op * 0.1; + }, 10); +} diff --git a/public/static/themes/simple.css b/public/static/themes/simple.css index 17962d0..61776ae 100644 --- a/public/static/themes/simple.css +++ b/public/static/themes/simple.css @@ -263,41 +263,212 @@ footer { /* Styles for the about page */ - .about-container article{ - font-size: 1.5rem; - color:var(--fg); - padding-bottom: 10px; - } +.about-container article{ + font-size: 1.5rem; + color:var(--fg); + padding-bottom: 10px; +} - .about-container article h1{ - color: var(--2); - font-size: 2.8rem; - } +.about-container article h1{ + color: var(--2); + font-size: 2.8rem; +} - .about-container article div{ - padding-bottom: 15px; - } +.about-container article div{ + padding-bottom: 15px; +} - .about-container a{ - color:var(--3); - } +.about-container a{ + color:var(--3); +} - .about-container article h2{ - color: var(--3); - font-size: 1.8rem; - padding-bottom: 10px; - } +.about-container article h2{ + color: var(--3); + font-size: 1.8rem; + padding-bottom: 10px; +} - .about-container p{ - color:var(--fg); - font-size: 1.6rem; - padding-bottom: 10px; - } +.about-container p{ + color:var(--fg); + font-size: 1.6rem; + padding-bottom: 10px; +} - .about-container h3{ - font-size: 1.5rem; - } +.about-container h3{ + font-size: 1.5rem; +} - .about-container { - width: 80%; - } +.about-container { + width: 80%; +} + +.settings { + margin: 2rem; + width: 80%; + height: 100%; + color: var(--fg); +} + +.settings h1 { + color: var(--2); + font-size: 2.5rem; +} + + +.settings hr { + border-color: var(--3); + margin: .3rem 0 1rem 0; +} + +.settings-view { + display: flex; + flex: 1 0 auto; +} + +.settings-sidebar { + width: 25%; + height: 100%; +} + +.settings-sidebar .set-name { + cursor: pointer; + font-size: 2rem; + display: block; + margin-right: .5rem; + margin-left: -.7rem; + padding: .7rem; + border-radius: 5px; + font-weight: bold; +} + +.settings-sidebar .set-name:hover, .settings-sidebar .set-name.active { + background-color: var(--1_1); +} + +.settings-detail { + border-left: 1.5px solid var(--3); + padding-left: 3rem; + margin-top: .7rem; +} + +.settings-detail .set-item { + margin: 2rem 0; + margin-top: 0; +} + +.settings-detail .set-name { + font-size: 2rem; + font-weight: bold; + color: var(--4) +} + +.settings-detail .set-desc { + font-size: 1.5rem; + margin-bottom: .5rem; +} + +.custom-select, .options { + font-size: 1.5rem; + background-color: var(--bg); + width: 250px; + padding: 1rem 1.7rem; + border-radius: 7px; +} + +.custom-select { + position: relative; + vertical-align: middle; + margin: .7rem 0; +} + +.custom-select.invalid { + border: 1px solid red; +} + +.custom-select svg { + float: right; +} + +.options { + display: none; + position: absolute; + left: 0; + margin-top: 1.3rem; + width: 100%; + padding: .7rem 1rem; + cursor: pointer; + z-index: 3; + max-height: 15rem; + overflow-y: auto; +} + +.options span { + display: block; + padding: 1rem; + width: 100%; + border-radius: 5px; + vertical-align: middle; +} + +.options span:hover { + background-color: var(--1_1); +} + +.selected-multiple-option { + padding: .8rem; + border-radius: 5px; + background-color: var(--bg); + margin: .5rem .3rem; +} + +.selected-multiple-option svg { + width: 1.3rem; + height: 1.3rem; + vertical-align: middle; + margin-bottom: .5rem; + cursor: pointer; +} + +.select-multiple-show { + margin: 1rem 0; + font-size: 1.5rem; +} + +.underlined-text { + font-size: 1.7rem; + cursor: pointer; + margin-bottom: .5rem; + display: block; +} + +.settings .submit-btn { + padding: 1rem 2rem; + font-size: 1.5rem; + background: var(--3); + color: var(--bg); + border-radius: .5rem; + border: 1px solid transparent; + font-weight: bold; + transition: background .5s ease-in; + cursor: pointer; +} + +.settings .submit-btn:hover { + border: 1px solid var(--bg); + background: var(--3_1); + box-shadow: 0px 0px 2px 2px var(--fg); +} + +.settings .submit-btn:active { + outline: none; + border: 2px solid var(--bg); +} + +.errTxt { + color: white; + background: red; + padding: .5rem; + border-radius: 5px; + font-size: 1.3rem; + width: max-content; +} \ No newline at end of file diff --git a/public/templates/navbar.html b/public/templates/navbar.html index f5f581f..87d6550 100644 --- a/public/templates/navbar.html +++ b/public/templates/navbar.html @@ -1,5 +1,6 @@