@@ -1154,6 +1188,7 @@ function goToTab(tabName) {
if (tabName === 'switches') searchSwitches();
if (tabName === 'news') loadNews();
if (tabName === 'blog') loadBlogDrafts();
+ if (tabName === 'finder') document.getElementById('finder-switch-input').focus();
}
document.querySelectorAll('.tab').forEach(function(tab) {
@@ -2320,6 +2355,125 @@ function pollBlogLlm(id, attempt) {
// Hot topics loaded dynamically via hot-topics.js
+// ══════════════════════════════════════════════════════
+// FINDER — Switch → Transceiver
+// ══════════════════════════════════════════════════════
+
+function finderQuick(model) {
+ document.getElementById('finder-switch-input').value = model;
+ runFinder();
+}
+
+async function runFinder() {
+ var model = (document.getElementById('finder-switch-input').value || '').trim();
+ var speed = document.getElementById('finder-speed-filter').value;
+ var results = document.getElementById('finder-results');
+ if (!model) { results.innerHTML = '
Enter a switch model to search.
'; return; }
+
+ results.innerHTML = '
Searching compatibility database...
';
+
+ var url = '/api/finder?switch=' + encodeURIComponent(model) + (speed ? '&speed=' + speed : '');
+ try {
+ var data = await api(url);
+
+ if (data.error) {
+ results.innerHTML = '
Not found: ' + data.error +
+ (data.suggestion ? '
' + data.suggestion + '' : '') + '
';
+ return;
+ }
+
+ var sw = data.switch;
+ var transceivers = data.compatible_transceivers || [];
+ var total = data.total || 0;
+
+ // Switch info header
+ var swHtml = '
' +
+ (sw.image_url ? '

' : '') +
+ '
' +
+ '
' + sw.vendor + ' ' + sw.model + '
' +
+ '
' +
+ (sw.series ? sw.series + ' · ' : '') +
+ 'Max speed: ' + (sw.max_speed_gbps || '?') + 'G' +
+ '
' +
+ '
' +
+ '
' +
+ '' + total + ' compatible transceivers' +
+ '
' +
+ '
';
+
+ if (transceivers.length === 0) {
+ results.innerHTML = swHtml + '
No compatible transceivers found for this switch. Try removing the speed filter.
';
+ return;
+ }
+
+ // Group by speed class
+ var bySpeed = {};
+ for (var t of transceivers) {
+ var key = t.speed_gbps + 'G ' + t.form_factor;
+ if (!bySpeed[key]) bySpeed[key] = [];
+ bySpeed[key].push(t);
+ }
+
+ var speedColors = { 800: '#c1121f', 400: '#FF8100', 100: '#e6a800', 25: '#2d6a4f', 10: '#888' };
+
+ var tcvrHtml = Object.entries(bySpeed).sort(function(a, b) {
+ return parseInt(b[0]) - parseInt(a[0]);
+ }).map(function(entry) {
+ var speedClass = entry[0];
+ var items = entry[1];
+ var speedGbps = items[0].speed_gbps;
+ var color = speedColors[speedGbps] || '#888';
+
+ var cards = items.slice(0, 12).map(function(t) {
+ var isFlexoptix = (t.vendor || '').toUpperCase() === 'FLEXOPTIX';
+ var hasPrice = t.price != null;
+ var priceHtml = hasPrice
+ ? '
' + (t.currency || 'EUR') + ' ' + parseFloat(t.price).toFixed(2) + ''
+ : '
Price on request';
+ var stockHtml = t.stock === 'in_stock' ? '
● In Stock'
+ : t.stock === 'limited' ? '
● Limited'
+ : '';
+ var partNum = t.part_number || t.slug || t.id;
+
+ return '
' +
+ '
' +
+ '
' +
+ (isFlexoptix ? 'FLEXOPTIX' : '') +
+ '' + (t.vendor || '') + '
' +
+ '' + partNum + '
' +
+ '' +
+ (t.reach || '') + (t.fiber_type ? ' · ' + t.fiber_type : '') +
+ (t.connector ? ' · ' + t.connector : '') +
+ '' +
+ '
' +
+ '
' +
+ priceHtml + '
' + stockHtml +
+ '
' +
+ '
' +
+ (t.buy_url ? '
Buy at Flexoptix →' : '') +
+ '
';
+ }).join('');
+
+ return '
' +
+ '
' +
+ speedClass + ' (' + items.length + ' options)' +
+ '
' +
+ '
' + cards + '
' +
+ '
';
+ }).join('');
+
+ results.innerHTML = swHtml +
+ '
' +
+ 'Showing ' + Math.min(transceivers.length, total) + ' of ' + total + ' compatible transceivers · ' +
+ 'Orange border = Flexoptix product' +
+ '
' +
+ tcvrHtml;
+
+ } catch(e) {
+ results.innerHTML = '
Error: ' + e.message + '
';
+ }
+}
+
async function loadBlogDrafts() {