From 0751029d51c89ecb2b840d312d43d08c0b1f0e03 Mon Sep 17 00:00:00 2001 From: fynks <75840152+fynks@users.noreply.github.com> Date: Thu, 16 Jan 2025 10:27:38 +0500 Subject: [PATCH] separated styles and js from main page --- docs/app.js | 140 ++++++++++++++++ docs/styles.css | 417 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 556 insertions(+), 1 deletion(-) create mode 100644 docs/app.js diff --git a/docs/app.js b/docs/app.js new file mode 100644 index 0000000..6375b24 --- /dev/null +++ b/docs/app.js @@ -0,0 +1,140 @@ + document.addEventListener('DOMContentLoaded', async () => { + const fileHostsTableContainer = document.getElementById('file-hosts-table-container'); + const hostSearchInput = document.getElementById('host-search-input'); + const clearHostSearchIcon = document.getElementById('clear-host-search'); + const provider1Select = document.getElementById('provider1'); + const provider2Select = document.getElementById('provider2'); + const compareTableContainer = document.getElementById('compare-table-container'); + const closeCompareButton = document.getElementById('close-compare'); + + const adultHostsTableContainer = document.getElementById('adult-hosts-table-container'); + const adultHostSearchInput = document.getElementById('adult-host-search-input'); + const clearAdultHostSearchIcon = document.getElementById('clear-adult-host-search'); + + // Initially hide the comparison table container + compareTableContainer.style.display = 'none'; + + try { + const [fileHostsResponse, adultHostsResponse] = await Promise.all([ + fetch('./json/file-hosts.json'), + fetch('./json/adult-hosts.json') + ]); + const fileHostsData = await fileHostsResponse.json(); + const adultHostsData = await adultHostsResponse.json(); + + // Function to generate a table + const generateTable = (data, tableId) => { + const container = document.getElementById(tableId); + let tableHTML = ``; + const providers = Object.keys(data[Object.keys(data)[0]]); + providers.forEach(provider => { + tableHTML += ``; + }); + tableHTML += ''; + + for (const host in data) { + tableHTML += ``; + providers.forEach(provider => { + const status = data[host][provider]; + const icon = status === 'yes' ? '✅' : '❌'; + tableHTML += ``; + }); + tableHTML += ''; + } + tableHTML += '
Service Name${provider}
${host}${icon}
'; + container.innerHTML = tableHTML; + }; + + // Function to populate provider dropdowns + const populateProviderDropdowns = (data) => { + const providers = Object.keys(data[Object.keys(data)[0]]); + providers.forEach(provider => { + const option1 = document.createElement('option'); + option1.value = provider; + option1.textContent = provider; + provider1Select.appendChild(option1); + + const option2 = document.createElement('option'); + option2.value = provider; + option2.textContent = provider; + provider2Select.appendChild(option2); + }); + }; + + // Function to generate the comparison table + const generateCompareTable = (data, provider1, provider2) => { + let tableHTML = ''; + + for (const host in data) { + const status1 = data[host][provider1]; + const status2 = data[host][provider2]; + const icon1 = status1 === 'yes' ? '✅' : '❌'; + const icon2 = status2 === 'yes' ? '✅' : '❌'; + tableHTML += ``; + } + + tableHTML += '
Service Name' + provider1 + '' + provider2 + '
${host}${icon1}${icon2}
'; + compareTableContainer.innerHTML = `` + tableHTML; + // Re-add the event listener for the close button after it's generated + document.getElementById('close-compare').addEventListener('click', () => { + compareTableContainer.style.display = 'none'; + }); + compareTableContainer.style.display = 'block'; + }; + + // Function for search functionality with clear icon visibility + const setupSearch = (searchInput, clearIcon, tableContainerId) => { + searchInput.addEventListener('input', () => { + const searchTerm = searchInput.value.toLowerCase(); + const rows = document.querySelectorAll(`#${tableContainerId} table tbody tr`); + if (!rows) return; + + // Show/hide clear icon based on input + clearIcon.style.display = searchTerm ? 'block' : 'none'; + + rows.forEach(row => { + const serviceName = row.querySelector('td:first-child').textContent.toLowerCase(); + row.style.display = serviceName.includes(searchTerm) ? '' : 'none'; + }); + }); + + clearIcon.addEventListener('click', () => { + searchInput.value = ''; + clearIcon.style.display = 'none'; + // Trigger the input event to refresh the table + searchInput.dispatchEvent(new Event('input')); + }); + }; + + // Initial table generation and dropdown population + generateTable(fileHostsData, 'file-hosts-table-container'); + generateTable(adultHostsData, 'adult-hosts-table-container'); + populateProviderDropdowns(fileHostsData); + + // Setup search for both tables + setupSearch(hostSearchInput, clearHostSearchIcon, 'file-hosts-table-container'); + setupSearch(adultHostSearchInput, clearAdultHostSearchIcon, 'adult-hosts-table-container'); + + // Comparison functionality + const handleCompare = () => { + const provider1 = provider1Select.value; + const provider2 = provider2Select.value; + if (provider1 && provider2) { + generateCompareTable(fileHostsData, provider1, provider2); + } + }; + + provider1Select.addEventListener('change', handleCompare); + provider2Select.addEventListener('change', handleCompare); + + // Close comparison functionality + closeCompareButton.addEventListener('click', () => { + compareTableContainer.style.display = 'none'; + }); + + } catch (error) { + console.error('Error fetching or parsing JSON:', error); + fileHostsTableContainer.innerHTML = '

Error loading file hosts data.

'; + adultHostsTableContainer.innerHTML = '

Error loading adult hosts data.

'; + } + }); \ No newline at end of file diff --git a/docs/styles.css b/docs/styles.css index c92e156..80cbee0 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -1 +1,416 @@ -:root{--primary:#2563eb;--text:#1f2937;--text-light:#6b7280;--bg:#ffffff;--bg-alt:#f8fafc;--border:#e2e8f0;--radius:.5rem;--shadow:0 1px 3px rgba(0,0,0,.1);--transition:all .2s ease;}body{font-family:-apple-system,BlinkMacSystemFont,'Inter',system-ui,sans-serif;line-height:1.7;max-width:1100px;margin:0 auto;padding:2rem;color:var(--text);background:var(--bg);}h1,h2,h3,h4{margin-top:2.5rem;margin-bottom:1.5rem;font-weight:600;line-height:1.3;color:var(--text);}h1{font-size:2.25rem}h2{font-size:1.875rem}h3{font-size:1.5rem}a{color:var(--primary);text-decoration:none;transition:var(--transition);}a:hover{opacity:.8;text-decoration:underline;}table{width:100%;border-collapse:separate;border-spacing:0;margin:2rem 0;font-size:.95rem;border:1px solid var(--border);border-radius:var(--radius);}th,td{padding:1rem;text-align:left;border-bottom:1px solid var(--border);}th{background-color:var(--primary);color:white;rgba(107,114,128,.507);font-weight:600;top:0;}tr:nth-child(even){background:var(--bg-alt);}tr:hover{background:rgba(37,99,235,.05);transition:var(--transition);}th:first-child{border-top-left-radius:var(--radius);}th:last-child{border-top-right-radius:var(--radius);}tr:last-child td:first-child{border-bottom-left-radius:var(--radius);}tr:last-child td:last-child{border-bottom-right-radius:var(--radius);}#search-container{margin:2rem 0;top:1rem;z-index:100;background:var(--bg);padding:1rem 0;}#search-input{width:90%;padding:.75rem 1rem;border:1px solid var(--border);border-radius:var(--radius);font-size:1rem;transition:var(--transition);margin:auto;}#search-input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px rgba(37,99,235,.1);}blockquote{margin:2rem 0;padding:1rem 1.5rem;border-left:4px solid var(--primary);background:var(--bg-alt);border-radius:0 var(--radius) var(--radius) 0;}code{background:var(--bg-alt);padding:.2em .4em;border-radius:var(--radius);font-size:.875em;font-family:ui-monospace,'Cascadia Code','Source Code Pro',Menlo,monospace;}@media (max-width:768px){body{padding:1rem}h1{font-size:1.875rem}h2{font-size:1.5rem}h3{font-size:1.25rem}table{border-radius:0;border-left:none;border-right:none}th,td{padding:.75rem;min-width:120px;font-size:.9rem}th{white-space:nowrap}} \ No newline at end of file +:root { + --primary: #2563eb; + --text: #1f2937; + --text-light: #6b7280; + --bg: #ffffff; + --bg-alt: #f8fafc; + --border: #e2e8f0; + --radius: 0.5rem; + --shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + --transition: all 0.2s ease; +} + +html { + scroll-behavior: smooth; +} + +/* Loading state */ +.loading { + text-align: center; + padding: 2rem; + color: var(--text-light); +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Inter', system-ui, sans-serif; + line-height: 1.7; + max-width: 1100px; + margin: 0 auto; + padding: 2rem; + color: var(--text); + background: var(--bg); +} + +/* Typography */ +h1, +h2, +h3, +h4 { + margin-top: 2.5rem; + margin-bottom: 1.5rem; + font-weight: 600; + line-height: 1.3; + color: var(--text); +} + +h1 { + font-size: 2.25rem; +} + +h2 { + font-size: 1.875rem; +} + +h3 { + font-size: 1.5rem; +} + +/* Links */ +a { + color: var(--primary); + text-decoration: none; + transition: var(--transition); +} + +a:hover { + opacity: 0.8; + text-decoration: underline; +} + +a[href^="http"]::after { + content: " ↗"; + font-size: 0.8em; + opacity: 1; + text-decoration: none; + display: inline-block; + transition: var(--transition); + color: var(--primary); +} + +/* Tables */ +table { + width: 100%; + border-collapse: collapse; + /* Changed from separate to collapse for better visual consistency */ + margin: 2rem 0; + font-size: 0.95rem; + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + /* Prevents border-radius from being clipped by cell backgrounds */ +} + +th, +td { + padding: 1rem; + text-align: left; + border-bottom: 1px solid var(--border); +} + +th { + background-color: var(--primary); + color: white; + font-weight: 600; + position: sticky; + /* For better header visibility on scroll */ + top: 0; + z-index: 1; + /* Ensure the sticky header is above the content */ +} + +/* Improve visual separation of header cells */ +th:not(:last-child) { + border-right: 1px solid var(--border); +} + +tr:nth-child(even) { + background: var(--bg-alt); +} + +tr:hover { + background: rgba(37, 99, 235, 0.05); + transition: var(--transition); +} + +/* Style the first and last cells of the header row */ +th:first-child { + border-top-left-radius: var(--radius); +} + +th:last-child { + border-top-right-radius: var(--radius); +} + +/* Style the first and last cells of the last data row */ +tr:last-child td:first-child { + border-bottom-left-radius: var(--radius); +} + +tr:last-child td:last-child { + border-bottom-right-radius: var(--radius); +} + +/* Search Container */ +#search-container, +#search-container-adult { + /* Apply styles to both search containers */ + margin: 2rem auto; + /* Center the search container */ + max-width: 1000px; + /* Limit the width for better layout */ + padding: 1rem; + + border-radius: var(--radius); + + + position: relative; + display: flex; + align-items: center; +} + +#host-search-input, +#adult-host-search-input { + /* Apply styles to both search inputs */ + width: 100%; + /* Make the input take full width of its container */ + padding: 0.75rem 1rem; + border: 1px solid var(--border); + border-radius: var(--radius); + font-size: 1rem; + transition: var(--transition); + box-sizing: border-box; + /* Include padding and border in the element's total width and height */ + +} + +#host-search-input:focus, +#adult-host-search-input:focus { + outline: none; + border-color: var(--primary); +} + +/* Blockquote */ +blockquote { + margin: 2rem 0; + padding: 1rem 2rem; + border-left: 4px solid var(--primary); + background: var(--bg-alt); + +} + +/* Code Blocks */ +code { + background: var(--bg-alt); + padding: 0.2em 0.4em; + border-radius: var(--radius); + font-size: 0.875em; + font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, monospace; +} + +/* Comparison Select Groups */ +#compare-container { + margin-top: 30px; + margin-bottom: 20px; + display: flex; + flex-direction: column; + /* Stack the select groups on smaller screens */ + align-items: center; + gap: 1rem; +} + +.compare-select-group { + display: flex; + gap: 0.5rem; + align-items: center; + width: 100%; + /* Take full width on smaller screens */ + max-width: 500px; + /* Limit width on larger screens */ + background: var(--bg-alt); + padding: 0.75rem; + border-radius: var(--radius); + border: 1px solid var(--border); + +} + +.compare-select-group label { + font-weight: 600; + flex-shrink: 0; + /* Prevent label from shrinking */ + min-width: 80px; + /* Ensure labels have some minimum width */ + text-align: right; + /* Align labels to the right */ +} + +.compare-select-group select { + padding: 0.6rem 1rem; + border: 1px solid var(--border); + border-radius: var(--radius); + font-size: 1rem; + appearance: none; + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + cursor: pointer; + flex-grow: 1; + box-sizing: border-box; + background-color: var(--bg); + background-position: right 8px center; + +} + +.compare-select-group select:hover { + border-color: var(--primary); +} + +.compare-select-group select:focus { + outline: none; + border-color: var(--primary); + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + body { + padding: 1rem; + } + + h1 { + font-size: 1.875rem; + } + + h2 { + font-size: 1.5rem; + } + + h3 { + font-size: 1.25rem; + } + + table { + border-radius: 0; + border-left: none; + border-right: none; + /* Enable horizontal scrolling for tables on small screens */ + display: block; + overflow-x: auto; + white-space: nowrap; + } + + th, + td { + padding: 0.75rem; + min-width: 120px; + font-size: 0.9rem; + } + + th { + white-space: nowrap; + } + + #search-container, + #search-container-adult { + margin-left: 0; + margin-right: 0; + border-radius: 0; + /* Remove border-radius on small screens for full-width feel */ + } + + #compare-container { + flex-direction: column; + /* Ensure select groups stack on smaller screens */ + align-items: stretch; + /* Make select groups take full width */ + } + + .compare-select-group { + flex-direction: column; + /* Stack label and select */ + align-items: stretch; + /* Make label and select take full width */ + } + + .compare-select-group label { + text-align: left; + /* Align label to the left when stacked */ + min-width: auto; + /* Allow label to take necessary width */ + } +} + +/* Clear icon button */ +.clear-icon { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + cursor: pointer; + font-size: 14px; + color: var(--text-light); + background: var(--bg-alt); + border: none; + border-radius: 50%; + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + transition: var(--transition); +} + +.clear-icon:hover { + background: var(--border); + color: var(--text); +} + +.search-input:not(:placeholder-shown)+.clear-icon { + opacity: 1; +} + +#compare-table-container { + position: relative; + margin-top: 2rem; + border: 1px solid var(--border); + border-radius: var(--radius); + padding: 1rem; +} + +#close-compare { + position: absolute; + top: -12px; + right: -12px; + background-color: var(--text); + color: white; + border: 2px solid var(--bg); + border-radius: 50%; + width: 24px; + height: 24px; + font-size: 12px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + opacity: 0.8; + transition: var(--transition); + box-shadow: var(--shadow); +} + +#close-compare:hover { + opacity: 1; + transform: scale(1.1); +} + + + +footer { + margin-top: 4rem; + padding: 2rem 0; + border-top: 1px solid var(--border); + text-align: center; + color: var(--text-light); +} + +/* Section transitions */ +main>* { + opacity: 0; + transform: translateY(20px); + animation: fadeIn 0.5s ease forwards; +} + +@keyframes fadeIn { + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file