diff --git a/app.js b/app.js new file mode 100644 index 0000000..ec4d361 --- /dev/null +++ b/app.js @@ -0,0 +1,67 @@ +// ==UserScript== +// @name Free Competitors 2.0 +// @namespace https://suod.madiator.com +// @description Script to search and display software and recommendations +// @license AGPLv3 +// ==/UserScript== + +function searchSoftware() { + const query = document.getElementById('searchBox').value; + + // Clear previous results and recommendations + document.getElementById('results').innerHTML = ''; + document.getElementById('recommendations').innerHTML = ''; + + fetch(`/software/${query}`) + .then(response => response.json()) + .then(data => displayResults([data])) + .catch(error => console.error('Error:', error)); + + fetch(`/recommendations?q=${query}`) + .then(response => response.json()) + .then(data => displayRecommendations(data)) + .catch(error => console.error('Error:', error)); +} + +function displayResults(data) { + const resultsSection = document.getElementById('results'); + resultsSection.innerHTML = ''; + data.forEach(software => { + const softwareDiv = document.createElement('div'); + softwareDiv.classList.add('software'); + softwareDiv.innerHTML = ` +

${software.names[0]} logo ${software.names[0]}

+

${software.comment}

+

Platforms: ${software.platforms?.join(', ') ?? 'Unknown'}

+

Licenses: ${software.licenses?.join(', ') ?? 'Unknown'}

+

Interfaces: ${software.interface?.join(', ') ?? 'Unknown'}

+

Programming Languages: ${software.languages?.join(', ') ?? 'Unknown'}

+

Issues: ${software.issues?.join(', ') ?? 'None'}

+ Website + Wikipedia + `; + resultsSection.appendChild(softwareDiv); + }); +} + +function displayRecommendations(data) { + const recommendationsSection = document.getElementById('recommendations'); + recommendationsSection.innerHTML = ''; + data.forEach(({software, score}) => { + const softwareDiv = document.createElement('div'); + softwareDiv.classList.add('software'); + softwareDiv.innerHTML = ` +

${software.names[0]} logo ${software.names[0]}

+

Score: ${score}

+

${software.comment}

+

Platforms: ${software.platforms?.join(', ') ?? 'Unknown'}

+

Licenses: ${software.licenses?.join(', ') ?? 'Unknown'}

+

Interfaces: ${software.interface?.join(', ') ?? 'Unknown'}

+

Programming Languages: ${software.languages?.join(', ') ?? 'Unknown'}

+

Issues: ${software.issues?.join(', ') ?? 'None'}

+ Website + Wikipedia + `; + recommendationsSection.appendChild(softwareDiv); + }); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..60eaf85 --- /dev/null +++ b/index.html @@ -0,0 +1,28 @@ + + + + + + Free Competitors + + + +
+

Free Competitors

+
+
+
+ + +
+
+
+
+

Recommendations:

+
+
+
+
+ + + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..62b419c --- /dev/null +++ b/styles.css @@ -0,0 +1,118 @@ +body { + font-family: 'Arial', sans-serif; + background-color: #121212; + color: #e0e0e0; + margin: 0; + padding: 0; + box-sizing: border-box; +} + +header { + background-color: #4CAF50; + color: white; + padding: 1em; + text-align: center; +} + +main { + padding: 2em; + max-width: 1200px; + margin: auto; +} + +#search-section { + text-align: center; + margin-bottom: 2em; +} + +#searchBox { + width: 70%; + padding: 0.7em; + font-size: 1em; + border: none; + border-radius: 5px; + margin-right: 10px; +} + +button { + padding: 0.7em 1.5em; + font-size: 1em; + background-color: #4CAF50; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s; +} + +button:hover { + background-color: #45a049; +} + +.content { + display: flex; + gap: 20px; +} + +#results { + flex: 0 0 25%; +} + +.recommendations-container { + flex: 1; +} + +#recommendations { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; + align-items: start; +} + +.software { + background-color: #1e1e1e; + border: 1px solid #333; + border-radius: 10px; + padding: 1em; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + transition: transform 0.2s; + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 200px; /* Adjust this value to ensure consistent height */ +} + +.software:hover { + transform: translateY(-5px); +} + +.software h2 { + margin-top: 0; + display: flex; + align-items: center; +} + +.software img { + max-width: 50px; + max-height: 50px; + margin-right: 15px; +} + +.software p { + margin: 0.5em 0; +} + +.software a { + display: inline-block; + margin: 5px 5px 0 0; + padding: 0.5em 1em; + color: white; + background-color: #4CAF50; + border-radius: 5px; + text-decoration: none; + transition: background-color 0.3s; +} + +.software a:hover { + background-color: #45a049; +} \ No newline at end of file