Reachy-Mini-FAQ / script.js
Anne-Charlotte's picture
Rename Script.js to script.js
c2efa62 verified
/**
* Reachy Mini FAQ - Interactive Script
* Handles product selection via tabs, search filtering, and FAQ interactions
*/
(function() {
'use strict';
// ========================================
// DOM Elements
// ========================================
const productTabs = document.querySelectorAll('.product-tab');
const faqContainer = document.getElementById('faq-container');
const searchInput = document.getElementById('search-input');
const faqSections = document.getElementById('faq-sections');
const footerYear = document.getElementById('footer-year');
// ========================================
// State
// ========================================
let currentProduct = 'beta';
// ========================================
// Product Data
// ========================================
const productInfo = {
beta: { name: 'Reachy Mini Beta', color: 'beta' },
lite: { name: 'Reachy Mini Lite', color: 'lite' },
wireless: { name: 'Reachy Mini Wireless', color: 'wireless' }
};
// ========================================
// Initialize
// ========================================
function init() {
// Set current year in footer
if (footerYear) {
footerYear.textContent = new Date().getFullYear();
}
// Attach event listeners
attachEventListeners();
// Check for URL hash to auto-select product
checkUrlHash();
}
// ========================================
// Event Listeners
// ========================================
function attachEventListeners() {
// Product tabs
productTabs.forEach(tab => {
tab.addEventListener('click', () => {
selectProduct(tab.dataset.product);
});
});
// Search functionality
if (searchInput) {
searchInput.addEventListener('input', debounce(handleSearch, 200));
// Clear search on Escape
searchInput.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
searchInput.value = '';
handleSearch();
searchInput.blur();
}
});
}
// Handle browser back/forward
window.addEventListener('popstate', checkUrlHash);
}
// ========================================
// Product Selection
// ========================================
function selectProduct(productId) {
if (!productInfo[productId]) return;
currentProduct = productId;
// Update URL hash
history.replaceState({ product: productId }, '', `#${productId}`);
// Update active state in tabs
productTabs.forEach(tab => {
tab.classList.toggle('active', tab.dataset.product === productId);
});
// Filter content for product (placeholder for future differentiation)
filterContentForProduct(productId);
}
function checkUrlHash() {
const hash = window.location.hash.slice(1);
if (hash && productInfo[hash]) {
selectProduct(hash);
} else {
selectProduct('beta');
}
}
// ========================================
// Content Filtering (for future use)
// ========================================
function filterContentForProduct(productId) {
// Placeholder: In the future, this function can show/hide
// product-specific FAQ items based on data attributes
// For now, all products show the same content
const allFaqItems = faqSections.querySelectorAll('.faq-item');
allFaqItems.forEach(item => {
// Example future logic:
// const products = item.dataset.products?.split(',') || ['all'];
// item.style.display = products.includes('all') || products.includes(productId) ? '' : 'none';
item.style.display = '';
});
}
// ========================================
// Search Functionality
// ========================================
function handleSearch() {
const query = searchInput.value.toLowerCase().trim();
const faqItems = faqSections.querySelectorAll('.faq-item');
const sections = faqSections.querySelectorAll('.faq-section');
const subsections = faqSections.querySelectorAll('.subsection');
if (!query) {
// Show all items
faqItems.forEach(item => {
item.style.display = '';
item.removeAttribute('open');
});
sections.forEach(section => section.style.display = '');
subsections.forEach(sub => sub.style.display = '');
return;
}
// Filter items
faqItems.forEach(item => {
const question = item.querySelector('.question')?.textContent.toLowerCase() || '';
const answer = item.querySelector('.answer')?.textContent.toLowerCase() || '';
const tags = Array.from(item.querySelectorAll('.tag'))
.map(tag => tag.textContent.toLowerCase())
.join(' ');
const matches = question.includes(query) ||
answer.includes(query) ||
tags.includes(query);
item.style.display = matches ? '' : 'none';
// Auto-expand matching items
if (matches && query.length > 2) {
item.setAttribute('open', '');
}
});
// Hide empty subsections
subsections.forEach(sub => {
const visibleItems = sub.querySelectorAll('.faq-item:not([style*="display: none"])');
sub.style.display = visibleItems.length > 0 ? '' : 'none';
});
// Hide empty sections
sections.forEach(section => {
const visibleItems = section.querySelectorAll('.faq-item:not([style*="display: none"])');
section.style.display = visibleItems.length > 0 ? '' : 'none';
});
}
// ========================================
// Utilities
// ========================================
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// ========================================
// Keyboard Navigation
// ========================================
document.addEventListener('keydown', (e) => {
// Press '/' to focus search
if (e.key === '/' && !e.ctrlKey && !e.metaKey) {
if (document.activeElement !== searchInput) {
e.preventDefault();
searchInput?.focus();
}
}
});
// ========================================
// Initialize on DOM Ready
// ========================================
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();