diff --git a/docs/app.js b/docs/app.js
index 47e3282..c93efcd 100644
--- a/docs/app.js
+++ b/docs/app.js
@@ -1,173 +1,263 @@
-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');
+/**
+ * @fileoverview Main application file for Debrid Services Comparison
+ * Handles data fetching, table generation, search functionality, and comparison features
+ */
- const adultHostsTableContainer = document.getElementById('adult-hosts-table-container');
- const adultHostSearchInput = document.getElementById('adult-host-search-input');
- const clearAdultHostSearchIcon = document.getElementById('clear-adult-host-search');
-
- const pricingSection = document.getElementById('pricing'); // Targeting the 'Pricing' section
-
- // Initially hide the comparison table container
- compareTableContainer.style.display = 'none';
-
- try {
- const [fileHostsResponse, adultHostsResponse, pricingResponse] = await Promise.all([
- fetch('./json/file-hosts.json'),
- fetch('./json/adult-hosts.json'),
- fetch('./json/pricing.json') // Fetching the pricing data
- ]);
- const fileHostsData = await fileHostsResponse.json();
- const adultHostsData = await adultHostsResponse.json();
- const pricingData = await pricingResponse.json(); // Parsed pricing data
-
- // Function to generate a table
- const generateTable = (data, tableId) => {
- const container = document.getElementById(tableId);
- let tableHTML = `
Service Name `;
- const providers = Object.keys(data[Object.keys(data)[0]]);
- providers.forEach(provider => {
- tableHTML += `${provider} `;
- });
- tableHTML += '';
-
- for (const host in data) {
- tableHTML += `${host} `;
- providers.forEach(provider => {
- const status = data[host][provider];
- const icon = status === 'yes' ? '✅' : '❌';
- tableHTML += `${icon} `;
- });
- tableHTML += ' ';
- }
- tableHTML += '
';
- container.innerHTML = tableHTML;
- };
-
- // Function to generate the pricing table
- const generatePricingTable = (pricingData) => {
- let tableHTML = 'Plans ';
- // Extract service names from the first plan object
- if (pricingData.plans && pricingData.plans.length > 0) {
- const services = Object.keys(pricingData.plans[0]).filter(key => key !== 'name');
- services.forEach(service => {
- tableHTML += `${service} `;
- });
- tableHTML += '';
-
- pricingData.plans.forEach(plan => {
- tableHTML += '';
- tableHTML += `${plan.name} `;
- services.forEach(service => {
- tableHTML += `${plan[service]} `;
- });
- tableHTML += ' ';
- });
-
- tableHTML += '
';
- pricingSection.innerHTML = tableHTML;
- } else {
- pricingSection.innerHTML = 'Error: Pricing data structure is incorrect.
';
- }
- };
-
- // 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 = 'Service Name ' + provider1 + ' ' + provider2 + ' ';
-
- for (const host in data) {
- const status1 = data[host][provider1];
- const status2 = data[host][provider2];
- const icon1 = status1 === 'yes' ? '✅' : '❌';
- const icon2 = status2 === 'yes' ? '✅' : '❌';
- tableHTML += `${host} ${icon1} ${icon2} `;
- }
-
- tableHTML += '
';
- compareTableContainer.innerHTML = `X ` + 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);
- generatePricingTable(pricingData); // Generate pricing table
-
- // 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.
';
- pricingSection.innerHTML = 'Error loading pricing data.
';
+// Class to handle table-related operations
+class TableManager {
+ /**
+ * @param {string} containerId - ID of the table container element
+ * @param {string} searchInputId - ID of the search input element
+ * @param {string} clearIconId - ID of the clear search icon element
+ */
+ constructor(containerId, searchInputId, clearIconId) {
+ this.container = document.getElementById(containerId);
+ this.searchInput = document.getElementById(searchInputId);
+ this.clearIcon = document.getElementById(clearIconId);
+ this.setupSearchFunctionality();
}
-});
\ No newline at end of file
+
+ /**
+ * Generates a table from provided data
+ * @param {Object} data - Table data object
+ * @returns {void}
+ */
+ generateTable(data) {
+ if (!data || Object.keys(data).length === 0) {
+ this.container.innerHTML = 'No data available.
';
+ return;
+ }
+
+ const providers = Object.keys(data[Object.keys(data)[0]]);
+ const tableHTML = `
+
+
+
+ Service Name
+ ${providers.map(provider => `${provider} `).join('')}
+
+
+
+ ${Object.entries(data).map(([host, providerData]) => `
+
+ ${host}
+ ${providers.map(provider => `
+
+ ${providerData[provider] === 'yes' ? '✅' : '❌'}
+
+ `).join('')}
+
+ `).join('')}
+
+
+ `;
+
+ this.container.innerHTML = tableHTML;
+ }
+
+ /**
+ * Sets up search functionality for the table
+ * @private
+ */
+ setupSearchFunctionality() {
+ this.searchInput?.addEventListener('input', () => {
+ const searchTerm = this.searchInput.value.toLowerCase();
+ const rows = this.container.querySelectorAll('table tbody tr');
+
+ this.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';
+ });
+ });
+
+ this.clearIcon?.addEventListener('click', () => {
+ this.searchInput.value = '';
+ this.clearIcon.style.display = 'none';
+ this.searchInput.dispatchEvent(new Event('input'));
+ });
+ }
+ }
+
+ // Class to handle comparison functionality
+ class ComparisonManager {
+ /**
+ * @param {string} containerId - ID of the comparison container
+ * @param {string} select1Id - ID of the first provider select element
+ * @param {string} select2Id - ID of the second provider select element
+ * @param {Object} data - Comparison data object
+ */
+ constructor(containerId, select1Id, select2Id, data) {
+ this.container = document.getElementById(containerId);
+ this.select1 = document.getElementById(select1Id);
+ this.select2 = document.getElementById(select2Id);
+ this.data = data;
+ this.setupEventListeners();
+ this.populateDropdowns();
+ }
+
+ /**
+ * Populates provider dropdowns with available options
+ * @private
+ */
+ populateDropdowns() {
+ const providers = Object.keys(this.data[Object.keys(this.data)[0]]);
+
+ [this.select1, this.select2].forEach(select => {
+ providers.forEach(provider => {
+ const option = document.createElement('option');
+ option.value = provider;
+ option.textContent = provider;
+ select.appendChild(option);
+ });
+ });
+ }
+
+ /**
+ * Generates comparison table for selected providers
+ * @private
+ */
+ generateCompareTable() {
+ const provider1 = this.select1.value;
+ const provider2 = this.select2.value;
+
+ if (!provider1 || !provider2) return;
+
+ const tableHTML = `
+ X
+
+
+
+ Service Name
+ ${provider1}
+ ${provider2}
+
+
+
+ ${Object.entries(this.data).map(([host, providerData]) => `
+
+ ${host}
+ ${providerData[provider1] === 'yes' ? '✅' : '❌'}
+ ${providerData[provider2] === 'yes' ? '✅' : '❌'}
+
+ `).join('')}
+
+
+ `;
+
+ this.container.innerHTML = tableHTML;
+ this.container.style.display = 'block';
+ this.setupCloseButton();
+ }
+
+ /**
+ * Sets up event listeners for comparison functionality
+ * @private
+ */
+ setupEventListeners() {
+ [this.select1, this.select2].forEach(select => {
+ select?.addEventListener('change', () => this.generateCompareTable());
+ });
+ }
+
+ /**
+ * Sets up close button functionality
+ * @private
+ */
+ setupCloseButton() {
+ document.getElementById('close-compare')?.addEventListener('click', () => {
+ this.container.style.display = 'none';
+ });
+ }
+ }
+
+ // Class to handle pricing table generation
+ class PricingManager {
+ /**
+ * @param {string} containerId - ID of the pricing section container
+ */
+ constructor(containerId) {
+ this.container = document.getElementById(containerId);
+ }
+
+ /**
+ * Generates pricing table from provided data
+ * @param {Object} data - Pricing data object
+ */
+ generatePricingTable(data) {
+ if (!data?.plans?.length) {
+ this.container.innerHTML = 'Error: Invalid pricing data structure.
';
+ return;
+ }
+
+ const services = Object.keys(data.plans[0]).filter(key => key !== 'name');
+ const tableHTML = `
+
+
+
+ Plans
+ ${services.map(service => `${service} `).join('')}
+
+
+
+ ${data.plans.map(plan => `
+
+ ${plan.name}
+ ${services.map(service => `${plan[service]} `).join('')}
+
+ `).join('')}
+
+
+ `;
+
+ this.container.innerHTML = tableHTML;
+ }
+ }
+
+ // Main application initialization
+ document.addEventListener('DOMContentLoaded', async () => {
+ // Initialize table managers
+ const fileHostsTable = new TableManager(
+ 'file-hosts-table-container',
+ 'host-search-input',
+ 'clear-host-search'
+ );
+
+ const adultHostsTable = new TableManager(
+ 'adult-hosts-table-container',
+ 'adult-host-search-input',
+ 'clear-adult-host-search'
+ );
+
+ const pricingManager = new PricingManager('pricing');
+
+ try {
+ // Fetch all required data concurrently
+ const [fileHostsData, adultHostsData, pricingData] = await Promise.all([
+ fetch('./json/file-hosts.json').then(res => res.json()),
+ fetch('./json/adult-hosts.json').then(res => res.json()),
+ fetch('./json/pricing.json').then(res => res.json())
+ ]);
+
+ // Generate tables and initialize comparison
+ fileHostsTable.generateTable(fileHostsData);
+ adultHostsTable.generateTable(adultHostsData);
+ pricingManager.generatePricingTable(pricingData);
+
+ // Initialize comparison manager
+ new ComparisonManager(
+ 'compare-table-container',
+ 'provider1',
+ 'provider2',
+ fileHostsData
+ );
+
+ } catch (error) {
+ console.error('Error initializing application:', error);
+ const errorMessage = 'Error loading data. Please try again later.
';
+ fileHostsTable.container.innerHTML = errorMessage;
+ adultHostsTable.container.innerHTML = errorMessage;
+ pricingManager.container.innerHTML = errorMessage;
+ }
+ });
\ No newline at end of file