Initial commit: SREBOT website (Express/EJS + i18n) - extracted from SREBOT monorepo
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
// Universal Header Search Functionality
|
||||
let headerSearchTimeout;
|
||||
|
||||
async function headerSearchPlayers() {
|
||||
const searchTerm = document.getElementById('headerPlayerSearch').value.trim();
|
||||
const resultsDiv = document.getElementById('headerSearchResults');
|
||||
|
||||
// Clear previous timeout
|
||||
clearTimeout(headerSearchTimeout);
|
||||
|
||||
if (searchTerm.length < 2) {
|
||||
resultsDiv.classList.remove('show');
|
||||
return;
|
||||
}
|
||||
|
||||
// Debounce search (increased to 500ms for better performance)
|
||||
headerSearchTimeout = setTimeout(async () => {
|
||||
try {
|
||||
const response = await window.apiClient.searchPlayers(searchTerm);
|
||||
displayHeaderSearchResults(response.results, resultsDiv);
|
||||
} catch (error) {
|
||||
console.error('Search error:', error);
|
||||
resultsDiv.innerHTML = '<div class="header-search-result-item">' + (window.__t ? __t('js.searchError') : 'Search error. Please try again.') + '</div>';
|
||||
resultsDiv.classList.add('show');
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function displayHeaderSearchResults(players, resultsDiv) {
|
||||
if (!players || players.length === 0) {
|
||||
resultsDiv.innerHTML = '<div class="header-search-result-item">' + (window.__t ? __t('js.noPlayersFound') : 'No players found') + '</div>';
|
||||
} else {
|
||||
resultsDiv.innerHTML = players.slice(0, 8).map(player => {
|
||||
const squadronTag = player.squadron_name ? `<span class="player-squadron" style="font-family: 'skyquakesymbols', 'Inter', sans-serif !important; color: rgba(255, 255, 255, 0.4); font-size: 0.85rem; margin-right: 0.4rem;">${escapeHtml(player.squadron_name)}</span>` : '';
|
||||
return `
|
||||
<div class="header-search-result-item" onclick="navigateToPlayer(${player.uid})">
|
||||
<div class="header-result-name">${squadronTag}${escapeHtml(player.nick)}</div>
|
||||
<div class="header-result-stats">${formatHeaderNumber(player.total_kills || 0)} ${window.__t ? __t('js.killsSuffix') : 'kills'} • ${(player.win_rate || 0).toFixed(1)}% ${window.__t ? __t('js.winRateSuffix') : 'win rate'}</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
resultsDiv.classList.add('show');
|
||||
}
|
||||
|
||||
function navigateToPlayer(uid) {
|
||||
window.location.href = `/players/${uid}`;
|
||||
}
|
||||
|
||||
function hideHeaderSearchResults() {
|
||||
const el = document.getElementById('headerSearchResults');
|
||||
if (el) el.classList.remove('show');
|
||||
}
|
||||
|
||||
function handleHeaderKeydown(event) {
|
||||
if (event.key === 'Escape') {
|
||||
hideHeaderSearchResults();
|
||||
document.getElementById('headerPlayerSearch').blur();
|
||||
}
|
||||
}
|
||||
|
||||
function formatHeaderNumber(num) {
|
||||
if (num >= 1000000) {
|
||||
return (num / 1000000).toFixed(1) + 'M';
|
||||
} else if (num >= 1000) {
|
||||
return (num / 1000).toFixed(1) + 'K';
|
||||
}
|
||||
return num.toString();
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// Hide search results when clicking outside
|
||||
document.addEventListener('click', function(event) {
|
||||
if (!event.target.closest('.nav-search')) {
|
||||
hideHeaderSearchResults();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user