document.addEventListener('DOMContentLoaded', () => { // DOM Elements const searchForm = document.getElementById('searchForm'); const queryInput = document.getElementById('queryInput'); const searchBtn = document.getElementById('searchBtn'); const searchIcon = document.getElementById('searchIcon'); const loadingSpinner = document.getElementById('loadingSpinner'); const topKInput = document.getElementById('topKInput'); const topKValue = document.getElementById('topKValue'); const resultsContainer = document.getElementById('resultsContainer'); const errorMsg = document.getElementById('errorMsg'); const noResults = document.getElementById('noResults'); // Update Slider Value topKInput.addEventListener('input', (e) => { topKValue.textContent = e.target.value; }); // Form Submit searchForm.addEventListener('submit', async (e) => { e.preventDefault(); const query = queryInput.value.trim(); if (!query) return; const topK = parseInt(topKInput.value); // UI Loading State setLoading(true); hideElements([errorMsg, noResults]); resultsContainer.innerHTML = ''; try { const response = await fetch('/api/search', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query, top_k: topK }) }); if (!response.ok) { const contentType = response.headers.get("content-type"); if (contentType && contentType.includes("application/json")) { const errData = await response.json(); throw new Error(errData.detail || 'حدث خطأ أثناء الاتصال بالخادم'); } else { const text = await response.text(); console.error("Non-JSON Server Error:", text); if (response.status === 504 || response.status === 503) { throw new Error("تأخر الخادم في الاستجابة (جاري تهيئة مساحة HuggingFace). يرجى المحاولة مرة أخرى."); } throw new Error(`خطأ في الخادم (الكود ${response.status}) - يرجى الانتظار والمحاولة لاحقاً.`); } } const data = await response.json(); const results = data.results || []; if (results.length === 0) { noResults.classList.remove('hidden'); } else { renderResults(results); } } catch (error) { showError(error.message); } finally { setLoading(false); } }); function renderResults(results) { results.forEach((result, index) => { const delay = index * 0.15; // Staggered animation const card = document.createElement('div'); card.className = 'result-card'; card.style.animationDelay = `${delay}s`; // Topic badge (if exists) const topicHtml = result.topic && result.topic !== "nan" ? `${result.topic}` : ''; // Source URL link (if exists) const sourceHtml = result.source_url && result.source_url !== "nan" ? `🔗 المصدر` : ''; card.innerHTML = `
${result.title || 'حديث غير معنون'} ${topicHtml} ${sourceHtml} #${result.rank || (index + 1)}
${highlightQuery(result.text, queryInput.value)}
`; resultsContainer.appendChild(card); }); } // Basic highlighter for UX (optional enhancement) function highlightQuery(text, query) { if (!text) return ''; // Very basic escaping text to prevent XSS return text.replace(//g, ">"); } function setLoading(isLoading) { if (isLoading) { searchBtn.disabled = true; searchIcon.classList.add('hidden'); loadingSpinner.classList.remove('hidden'); } else { searchBtn.disabled = false; loadingSpinner.classList.add('hidden'); searchIcon.classList.remove('hidden'); } } function showError(message) { errorMsg.textContent = message; errorMsg.classList.remove('hidden'); } function hideElements(elements) { elements.forEach(el => el.classList.add('hidden')); } });