coming together

This commit is contained in:
HotSwapp
2025-08-13 18:53:35 -05:00
parent acc5155bf7
commit 5111079149
51 changed files with 14457 additions and 588 deletions

View File

@@ -277,7 +277,7 @@ function setAuthToken(token) {
// Page helpers
function isLoginPage() {
const path = window.location.pathname;
return path === '/login' || path === '/';
return path === '/login';
}
// Verify the current access token by hitting /api/auth/me
@@ -329,6 +329,14 @@ async function checkUserPermissions() {
const adminDivider = document.getElementById('admin-menu-divider');
if (adminItem) adminItem.classList.remove('hidden');
if (adminDivider) adminDivider.classList.remove('hidden');
const importDesktop = document.getElementById('nav-import-desktop');
const importMobile = document.getElementById('nav-import-mobile');
if (importDesktop) importDesktop.classList.remove('hidden');
if (importMobile) importMobile.classList.remove('hidden');
const flexibleDesktop = document.getElementById('nav-flexible-desktop');
const flexibleMobile = document.getElementById('nav-flexible-mobile');
if (flexibleDesktop) flexibleDesktop.classList.remove('hidden');
if (flexibleMobile) flexibleMobile.classList.remove('hidden');
}
const userDropdownName = document.querySelector('#userDropdown button span');
if (user.full_name && userDropdownName) {
@@ -555,6 +563,8 @@ function initializeDataTable(tableId, options = {}) {
const headers = table.querySelectorAll('th[data-sort]');
headers.forEach(header => {
header.classList.add('sortable-header');
header.classList.add('cursor-pointer');
header.classList.add('select-none');
header.addEventListener('click', () => sortTable(table, header));
});
@@ -577,10 +587,16 @@ function sortTable(table, header) {
// Remove sort classes from all headers
table.querySelectorAll('th').forEach(th => {
th.classList.remove('sort-asc', 'sort-desc');
const indicator = th.querySelector('.sort-indicator');
if (indicator) indicator.remove();
});
// Add sort class to current header
header.classList.add(isAscending ? 'sort-asc' : 'sort-desc');
const indicator = document.createElement('span');
indicator.className = 'sort-indicator ml-1 text-neutral-400';
indicator.textContent = isAscending ? '▲' : '▼';
header.appendChild(indicator);
rows.sort((a, b) => {
const aValue = a.children[columnIndex].textContent.trim();
@@ -669,7 +685,7 @@ function initializeSearch(searchInput, resultsContainer, searchFunction) {
try {
showLoading(resultsContainer, 'Searching...');
const results = await searchFunction(query);
displaySearchResults(resultsContainer, results);
displaySearchResults(resultsContainer, results, query);
} catch (error) {
resultsContainer.innerHTML = '<p class="text-danger">Search failed</p>';
}
@@ -677,18 +693,21 @@ function initializeSearch(searchInput, resultsContainer, searchFunction) {
});
}
function displaySearchResults(container, results) {
function displaySearchResults(container, results, query = '') {
if (!results || results.length === 0) {
container.innerHTML = '<p class="text-neutral-500">No results found</p>';
return;
}
const tokens = (window.highlightUtils && typeof window.highlightUtils.buildTokens === 'function')
? window.highlightUtils.buildTokens(query)
: [];
const resultsHtmlRaw = results.map(result => `
<div class="search-result p-2 border-bottom">
<div class="flex justify-between">
<div>
<strong>${result.title}</strong>
<small class="text-neutral-500 block">${result.description}</small>
<strong>${window.highlightUtils ? window.highlightUtils.highlight(result.title || '', tokens) : (result.title || '')}</strong>
<small class="text-neutral-500 block">${window.highlightUtils ? window.highlightUtils.highlight(result.description || '', tokens) : (result.description || '')}</small>
</div>
<span class="inline-block px-2 py-0.5 text-xs rounded bg-neutral-200 text-neutral-700">${result.type}</span>
</div>