fixing rolodex and search

This commit is contained in:
HotSwapp
2025-08-11 21:58:25 -05:00
parent 278eb7c5d4
commit c76b68d009
25 changed files with 1651 additions and 915 deletions

View File

@@ -54,12 +54,8 @@ async function saveThemePreference(theme) {
const token = localStorage.getItem('auth_token');
if (!token || isLoginPage()) return;
try {
await fetch('/api/auth/theme-preference', {
await window.http.wrappedFetch('/api/auth/theme-preference', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ theme_preference: theme })
});
} catch (error) {
@@ -88,9 +84,7 @@ async function loadUserThemePreference() {
const token = localStorage.getItem('auth_token');
if (!token || isLoginPage()) return;
try {
const response = await fetch('/api/auth/me', {
headers: { 'Authorization': `Bearer ${token}` }
});
const response = await window.http.wrappedFetch('/api/auth/me');
if (response.ok) {
const user = await response.json();
if (user.theme_preference) {
@@ -162,13 +156,8 @@ function validateField(field) {
function setupAPIHelpers() {
// Set up default headers for all API calls
window.apiHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
if (app.token) {
window.apiHeaders['Authorization'] = `Bearer ${app.token}`;
}
// Start proactive refresh scheduling when a token is present
if (app.token) {
@@ -197,7 +186,7 @@ async function apiCall(url, options = {}) {
};
try {
let response = await fetch(url, config);
let response = await window.http.wrappedFetch(url, config);
const updateCorrelationFromResponse = (resp) => {
try {
const cid = resp && resp.headers ? resp.headers.get('X-Correlation-ID') : null;
@@ -215,7 +204,7 @@ async function apiCall(url, options = {}) {
headers: { ...window.apiHeaders, ...options.headers },
...options
};
response = await fetch(url, retryConfig);
response = await window.http.wrappedFetch(url, retryConfig);
lastCorrelationId = updateCorrelationFromResponse(response);
} catch (_) {
// fall through to logout below
@@ -269,7 +258,6 @@ function setAuthTokens(accessToken, newRefreshToken = null) {
if (accessToken) {
app.token = accessToken;
localStorage.setItem('auth_token', accessToken);
window.apiHeaders['Authorization'] = `Bearer ${accessToken}`;
}
if (newRefreshToken) {
app.refreshToken = newRefreshToken;
@@ -297,9 +285,7 @@ async function checkTokenValidity() {
const token = localStorage.getItem('auth_token');
if (!token) return false;
try {
const response = await fetch('/api/auth/me', {
headers: { 'Authorization': `Bearer ${token}` }
});
const response = await window.http.wrappedFetch('/api/auth/me');
if (!response.ok) {
// Invalid token
return false;
@@ -334,9 +320,7 @@ async function checkUserPermissions() {
const token = localStorage.getItem('auth_token');
if (!token || isLoginPage()) return;
try {
const response = await fetch('/api/auth/me', {
headers: { 'Authorization': `Bearer ${token}` }
});
const response = await window.http.wrappedFetch('/api/auth/me');
if (response.ok) {
const user = await response.json();
app.user = user;
@@ -361,9 +345,7 @@ async function getInactivityWarningMinutes() {
const token = localStorage.getItem('auth_token');
if (!token) return 240;
try {
const resp = await fetch('/api/settings/inactivity_warning_minutes', {
headers: { 'Authorization': `Bearer ${token}` }
});
const resp = await window.http.wrappedFetch('/api/settings/inactivity_warning_minutes');
if (!resp.ok) return 240;
const data = await resp.json();
if (typeof data.minutes === 'number') return data.minutes;
@@ -512,9 +494,8 @@ async function logout(reason = null) {
const rtoken = localStorage.getItem('refresh_token');
try {
if (rtoken) {
await fetch('/api/auth/logout', {
await window.http.wrappedFetch('/api/auth/logout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refresh_token: rtoken })
});
}
@@ -531,7 +512,7 @@ async function logout(reason = null) {
app.user = null;
localStorage.removeItem('auth_token');
localStorage.removeItem('refresh_token');
delete window.apiHeaders['Authorization'];
// Authorization header is injected by fetch wrapper; nothing to clean here
if (reason) {
try { sessionStorage.setItem('logout_reason', reason); } catch (_) {}
@@ -702,7 +683,7 @@ function displaySearchResults(container, results) {
return;
}
const resultsHtml = results.map(result => `
const resultsHtmlRaw = results.map(result => `
<div class="search-result p-2 border-bottom">
<div class="flex justify-between">
<div>
@@ -713,8 +694,11 @@ function displaySearchResults(container, results) {
</div>
</div>
`).join('');
container.innerHTML = resultsHtml;
if (window.setSafeHTML) {
window.setSafeHTML(container, resultsHtmlRaw);
} else {
container.innerHTML = resultsHtmlRaw;
}
}
// Utility functions
@@ -814,13 +798,9 @@ function setupGlobalErrorHandlers() {
async function postClientError(payload) {
try {
const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' };
const token = (window.app && window.app.token) || localStorage.getItem('auth_token');
if (token) headers['Authorization'] = `Bearer ${token}`;
// Fire-and-forget; do not block UI
fetch('/api/documents/client-error', {
window.http.wrappedFetch('/api/documents/client-error', {
method: 'POST',
headers,
body: JSON.stringify(payload)
}).catch(() => {});
} catch (_) {
@@ -875,11 +855,10 @@ async function refreshToken() {
if (app.refreshInProgress) return; // Avoid parallel refreshes
app.refreshInProgress = true;
try {
const response = await fetch('/api/auth/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify({ refresh_token: app.refreshToken })
});
const response = await window.http.wrappedFetch('/api/auth/refresh', {
method: 'POST',
body: JSON.stringify({ refresh_token: app.refreshToken })
});
if (!response.ok) {
throw new Error('Refresh failed');
}