diff --git a/public/css/style.css b/public/css/style.css index 8ca76ff..cdec535 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,39 +1,39 @@ /* Import Google Fonts for modern typography */ -@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); +@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } /* Body Styling */ body { - font-family: 'Poppins', sans-serif; - background-color: #f0f2f5; /* Light, soft background for a modern look */ - color: #333; - padding: 0; - display: flex; - flex-direction: column; - justify-content: start; - align-items: center; - min-height: 100vh; - padding-top: 60px; + font-family: "Poppins", sans-serif; + background-color: #f0f2f5; /* Light, soft background for a modern look */ + color: #333; + padding: 0; + display: flex; + flex-direction: column; + justify-content: start; + align-items: center; + min-height: 100vh; + padding-top: 60px; } -#main-header{ - font-size: 64px; - text-align: center; +#main-header { + font-size: 64px; + text-align: center; } /* Container Styling */ .container { - background-color: #fff; - border-radius: 8px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - padding: 30px; - width: 100%; - max-width: 900px; - margin: 20px; + background-color: #fff; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + padding: 30px; + width: 100%; + max-width: 900px; + margin: 20px; } /* Comparison Container Styling */ @@ -72,89 +72,92 @@ body { } /* Headings Styling */ -h1, h4 { - text-align: center; - color: #2C3E50; /* Darker shade for headings */ - font-weight: 600; - margin-bottom: 20px; +h1, +h4 { + text-align: center; + color: #2c3e50; /* Darker shade for headings */ + font-weight: 600; + margin-bottom: 20px; } /* Form Labels */ label { - display: block; - margin-bottom: 10px; - font-weight: 500; - color: #7F8C8D; + display: block; + margin-bottom: 10px; + font-weight: 500; + color: #7f8c8d; } /* Input Fields and Select Elements */ -input[type="text"], select { - width: 50%; - padding: 14px; - margin-bottom: 20px; - border-radius: 8px; - border: 1px solid #BDC3C7; - font-size: 16px; - background-color: #ECF0F1; - transition: all 0.3s ease; +input[type="text"], +select { + width: 50%; + padding: 14px; + margin-bottom: 20px; + border-radius: 8px; + border: 1px solid #bdc3c7; + font-size: 16px; + background-color: #ecf0f1; + transition: all 0.3s ease; } -input[type="text"]:focus, select:focus { - border-color: #4CAF50; - outline: none; - box-shadow: 0 0 8px rgba(76, 175, 80, 0.4); +input[type="text"]:focus, +select:focus { + border-color: #4caf50; + outline: none; + box-shadow: 0 0 8px rgba(76, 175, 80, 0.4); } /* Button Styling */ button { - width: 30%; - padding: 14px; - background-color: #4CAF50; - color: white; - border: none; - border-radius: 8px; - font-size: 16px; - font-weight: 600; - cursor: pointer; - transition: transform 0.3s ease, background-color 0.3s ease; + width: 30%; + padding: 14px; + background-color: #4caf50; + color: white; + border: none; + border-radius: 8px; + font-size: 16px; + font-weight: 600; + cursor: pointer; + transition: transform 0.3s ease, background-color 0.3s ease; } button:hover { - background-color: #388E3C; - transform: translateY(-4px); + background-color: #388e3c; + transform: translateY(-4px); } button:disabled { - background-color: #BDC3C7; - cursor: not-allowed; + background-color: #bdc3c7; + cursor: not-allowed; } /* API Response Box */ #responseBox { - background-color: #F9F9F9; - content:"The response .."; - border-radius: 8px; - border: 1px solid #BDC3C7; - padding: 20px; - margin-bottom: 30px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); - min-height: 50px; - min-width:300px; - text-align: center; - overflow: auto; + background-color: #f9f9f9; + content: "The response .."; + border-radius: 8px; + border: 1px solid #bdc3c7; + padding: 20px; + margin-bottom: 30px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + min-height: 50px; + min-width: 300px; + text-align: center; + overflow: auto; } /* Code Samples Styling */ pre { - background-color: #2C3E50; - color: #ECF0F1; - padding: 20px; - border-radius: 8px; - font-size: 14px; - line-height: 1.6; - overflow-x: auto; - white-space: pre-wrap; - word-wrap: break-word; + background-color: #2c3e50; + color: #ecf0f1; + padding: 20px; + border-radius: 8px; + font-size: 14px; + line-height: 1.6; + overflow-x: auto; + white-space: pre-wrap; + word-wrap: break-word; } /* Encouragement */ @@ -175,121 +178,190 @@ pre { /* Navbar Styling */ #navbar { - width: 100%; - background-color: #2C3E50; - padding: 15px 0; - position: fixed; - top: 0; - left: 0; - z-index: 1000; - display: flex; - justify-content: center; + width: 100%; + background-color: #2c3e50; + padding: 15px 0; + position: fixed; + top: 0; + left: 0; + z-index: 1000; + display: flex; + justify-content: center; } #navbar ul { - list-style: none; - display: flex; - gap: 20px; - padding: 0; - margin: 0; + list-style: none; + display: flex; + gap: 20px; + padding: 0; + margin: 0; } #navbar ul li { - display: inline; + display: inline; } #navbar ul li a { - text-decoration: none; - color: white; - font-size: 16px; - font-weight: 500; - padding: 10px 15px; - transition: 0.3s; + text-decoration: none; + color: white; + font-size: 16px; + font-weight: 500; + padding: 10px 15px; + transition: 0.3s; } #navbar ul li a:hover { - background-color: #4CAF50; - border-radius: 5px; + background-color: #4caf50; + border-radius: 5px; } /* Adjust body to avoid content being hidden under navbar */ body { - padding-top: 60px; + padding-top: 60px; } /* Footer Styling */ footer a { - color: #fff; - text-decoration: none; - font-weight: 600; + color: #fff; + text-decoration: none; + font-weight: 600; } footer:hover { - transform: translateY(-4px); + transform: translateY(-4px); } /* Contact Box */ .contact-box { - text-align: center; + text-align: center; } .contact-box ul { - list-style-position: inside; - display: inline-block; - text-align: left; - padding: 0; + list-style-position: inside; + display: inline-block; + text-align: left; + padding: 0; } .contact-box h3 { - margin-top: 32px; + margin-top: 32px; } .contact-box p:first-of-type { - font-size: 18px; - font-weight: 600; - margin-bottom: 16px; + font-size: 18px; + font-weight: 600; + margin-bottom: 16px; } /* Responsive Design */ @media (max-width: 768px) { - .container { - padding: 20px; - width: 100%; - } - - .comparison-box-parrent { - flex-direction: column; - align-items: center; - } - .comparison-container { - flex-direction: column; - align-items: center; - } - .comparison-box { - width: 100%; - margin-bottom: 20px; - } - - input[type="text"], select, button { - width: 100%; - } - - footer { - position: relative; - bottom: 0; - right: 0; - padding: 15px; - border-radius: 0; - } + .container { + padding: 20px; + width: 100%; + } + + .comparison-box-parrent { + flex-direction: column; + align-items: center; + } + .comparison-container { + flex-direction: column; + align-items: center; + } + .comparison-box { + width: 100%; + margin-bottom: 20px; + } + + input[type="text"], + select, + button { + width: 100%; + } + + footer { + position: relative; + bottom: 0; + right: 0; + padding: 15px; + border-radius: 0; + } } @media (max-width: 480px) { - h1 { - font-size: 26px; - } + h1 { + font-size: 26px; + } + + h4 { + font-size: 18px; + } - h4 { - font-size: 18px; - } + input[type="text"], + select, + button { + font-size: 14px; + } +} +.search-results { + width: 50%; + max-height: 200px; + overflow-y: auto; + border: 1px solid #bdc3c7; + border-radius: 8px; + margin-top: 8px; + padding-left: 8px; + display: none; +} + +@media (max-width: 768px) { + .search-results { + width: 100%; + } +} +.search-results-item { + margin: 10px; + cursor: pointer; +} + +.search-input-container { + position: relative; + width: 50%; + max-width: 100%; +} + +.search-input-container input[type="text"] { + width: 100%; + padding-right: 60px; + box-sizing: border-box; +} + +@media (max-width: 768px) { + .search-input-container { + width: 100%; + } +} + +.clear-icon, +.dropdown-icon { + position: absolute; + top: 35%; + transform: translateY(-50%); + cursor: pointer; + font-size: 15px; + color: #999; + padding: 0 4px; + border-radius: 100%; + background-color: transparent; +} + +.clear-icon:hover, +.dropdown-icon:hover { + background-color: #e0e3e5; +} + +.clear-icon { + right: 34px; + display: none; +} - input[type="text"], select, button { - font-size: 14px; - } +.dropdown-icon { + right: 10px; } diff --git a/public/js/script.js b/public/js/script.js index 984206a..bd8eded 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1,6 +1,32 @@ +const operations = [ + { value: "onlyNumbers", label: "Only Numbers" }, + { value: "onlyLetters", label: "Only Letters" }, + { value: "onlySpecialCharacters", label: "Only Special Characters" }, + { value: "isEmailAddress", label: "Is Email Address" }, + { value: "isPhoneNumber", label: "Is Phone Number" }, + { value: "trim", label: "Trim" }, + { value: "isInteger", label: "Is Integer" }, + { value: "isAlphaNumeric", label: "Is Alpha Numeric" }, + { value: "isHexadecimal", label: "Is Hexadecimal" }, + { value: "isDecimal", label: "Is Decimal" }, + { value: "isLowercase", label: "Is Lowercase" }, + { value: "isDate", label: "Is Date" }, + { value: "isAllCaps", label: "Is AllCaps" }, + { value: "isUrl", label: "Is Url" }, + { value: "isBinaryString", label: "Is Binary String" }, + { value: "isBoolean", label: "Is Boolean" }, + { value: "isCountry", label: "Is Country" }, + { value: "isValidStateCode", label: "Is Valid State Code" }, +]; + async function getResponse() { - const inputString = document.querySelector("#inputString").value; - const endpoint = document.querySelector('select[name="endpoint"]').value; + const inputString = document.querySelector("#inputString")?.value; + const endpoint = document.querySelector("#selectedOperation")?.value; + + if (!endpoint) { + alert("Please select an operation first"); + return; + } // Use window.location.origin to get the base URL const baseUrl = window.location.origin; @@ -9,8 +35,8 @@ async function getResponse() { const response = await fetch(`${baseUrl}/api/${endpoint}`, { method: "POST", body: JSON.stringify({ - inputString: inputString - }), + inputString: inputString, + }), headers: { "Content-Type": "application/json", }, @@ -31,3 +57,105 @@ function enableButton() { document.querySelector("#getResponseButton").disabled = inputString.length > 0 ? false : true; } + +function renderOperations(operations) { + const searchResults = document.querySelector("#searchResults"); + searchResults.innerHTML = ""; + searchResults.style.display = "block"; + + operations.forEach((operation) => { + const div = document.createElement("div"); + div.className = "search-results-item"; + div.textContent = operation.label; + div.onclick = () => selectOperation(operation); + searchResults.appendChild(div); + }); +} + +function toggleDropdown() { + const searchResults = document.querySelector("#searchResults"); + const dropdownIcon = document.querySelector("#dropdownToggle"); + const isVisible = searchResults.style.display === "block"; + + if (isVisible) { + searchResults.style.display = "none"; + dropdownIcon.textContent = "▼"; + } else { + renderOperations(operations); + searchResults.style.disabled = "block"; + dropdownIcon.textContent = "▲"; + } +} + +function searchOperations(showAll = false) { + const searchInput = document.querySelector("#operationSearch"); + const searchResults = document.querySelector("#searchResults"); + const dropdownIcon = document.querySelector("#dropdownToggle"); + const query = showAll ? "" : searchInput.value.toLowerCase(); + + const filteredOperations = operations.filter( + (operation) => + operation.label.toLowerCase().includes(query) || + operation.value.toLowerCase().includes(query) + ); + + renderOperations(filteredOperations); + searchResults.style.display = "block"; + dropdownIcon.textContent = "▲"; + + if (filteredOperations.length === 0) { + searchResults.style.display = "none"; + dropdownIcon.textContent = "▼"; + } +} + +document.querySelector("#operationSearch").addEventListener("click", () => { + searchOperations(true); +}); + +function clearSelection() { + const searchInput = document.querySelector("#operationSearch"); + const searchResults = document.querySelector("#searchResults"); + const selectedOperation = document.querySelector("#selectedOperation"); + const clearIcon = document.querySelector("#clearSearch"); + const dropdownIcon = document.querySelector("#dropdownToggle"); + + searchInput.value = ""; + renderOperations(operations); + selectedOperation.value = ""; + searchResults.style.display = "block"; + clearIcon.style.display = "none"; + dropdownIcon.textContent = "▲"; +} + +function selectOperation(operation) { + const searchInput = document.querySelector("#operationSearch"); + const searchResults = document.querySelector("#searchResults"); + const selectedOperation = document.querySelector("#selectedOperation"); + const clearIcon = document.querySelector("#clearSearch"); + const dropdownIcon = document.querySelector("#dropdownToggle"); + + searchInput.value = operation.label; + selectedOperation.value = operation.value; + searchResults.style.display = "none"; + clearIcon.style.display = "block"; + dropdownIcon.textContent = "▼"; +} + +document.addEventListener("click", (e) => { + const searchResults = document.querySelector("#searchResults"); + const operationSearch = document.querySelector("#operationSearch"); + const clearIcon = document.querySelector("#clearSearch"); + const dropdownIcon = document.querySelector("#dropdownToggle"); + + if ( + e.target !== operationSearch && + e.target !== clearIcon && + e.target !== dropdownIcon && + !searchResults.contains(e.taget) && + searchResults.style.display === "block" + ) { + searchResults.style.display = "none"; + dropdownIcon.textContent = "▼"; + } +}); diff --git a/views/pages/index.pug b/views/pages/index.pug index 264175f..064e9f3 100644 --- a/views/pages/index.pug +++ b/views/pages/index.pug @@ -11,26 +11,12 @@ block content label Select a simple operation to perform (all operations can be found on our docs page) br br - select(name='endpoint') - option(value='onlyNumbers') Only Numbers - option(value='onlyLetters') Only Letters - option(value='onlySpecialCharacters') Only Special Characters - option(value='isEmailAddress') Is Email Address - option(value='isPhoneNumber') Is Phone Number - option(Value='trim') Trim - option(value='isInteger') Is Integer - option(value='isAlphaNumeric') Is Alpha Numeric - option(value='isHexadecimal') Is Hexadecimal - option(value='isDecimal') Is Decimal - option(value='isLowercase') Is Lowercase - option(value='isDate') Is Date - option(value='isAllCaps') Is AllCaps - option(value='isUrl') Is Url - option(value='isBinaryString') Is Binary String - option(value='isBoolean') Is Boolean - option(value='isCountry') Is Country - option(value='isValidStateCode') Is Valid State Code - + .search-input-container + input(type="text" id="operationSearch" placeholder="Search operation..." onkeyup="searchOperations()") + span(class="clear-icon" id="clearSearch" onclick="clearSelection()") X + span(class="dropdown-icon" id="dropdownToggle" onclick="toggleDropdown()") ▼ + div(id="searchResults" class="search-results") + input(type="hidden" id="selectedOperation") br br button(onclick='getResponse()' id='getResponseButton' disabled='true') Get Response