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

@@ -1113,15 +1113,7 @@ let currentUsers = [];
let currentSettings = [];
let userPagination = { page: 1, limit: 10 };
// Helper function for authenticated API calls
function getAuthHeaders() {
const token = localStorage.getItem('auth_token');
return {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
}
// Authorization and JSON headers are injected by window.http.wrappedFetch
// Check if current user has admin access
async function checkAdminAccess() {
const token = localStorage.getItem('auth_token');
@@ -1131,11 +1123,7 @@ async function checkAdminAccess() {
}
try {
const response = await fetch('/api/auth/me', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const response = await window.http.wrappedFetch('/api/auth/me');
if (!response.ok) {
window.location.href = '/login';
@@ -1245,9 +1233,7 @@ document.addEventListener('DOMContentLoaded', function() {
// System Health Functions
async function loadSystemHealth() {
try {
const response = await fetch('/api/admin/health', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/health');
const data = await response.json();
// Update status indicator
@@ -1300,9 +1286,7 @@ async function loadSystemHealth() {
async function loadSystemStats() {
try {
const response = await fetch('/api/admin/stats', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/stats');
const data = await response.json();
// Update dashboard cards
@@ -1346,9 +1330,7 @@ async function loadUsers() {
if (search) url += 'search=' + encodeURIComponent(search) + '&';
if (filter === 'active') url += 'active_only=true&';
const response = await fetch(url, {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch(url);
const users = await response.json();
currentUsers = users;
@@ -1408,9 +1390,7 @@ function showCreateUserModal() {
async function editUser(userId) {
try {
const response = await fetch('/api/admin/users/' + userId, {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/users/' + userId);
const user = await response.json();
document.getElementById('userModalTitle').textContent = 'Edit User';
@@ -1452,9 +1432,8 @@ async function saveUser() {
const url = isEdit ? '/api/admin/users/' + userId : '/api/admin/users';
const method = isEdit ? 'PUT' : 'POST';
const response = await fetch(url, {
const response = await window.http.wrappedFetch(url, {
method: method,
headers: getAuthHeaders(),
body: JSON.stringify(userData)
});
@@ -1490,9 +1469,8 @@ async function resetPassword() {
}
try {
const response = await fetch('/api/admin/users/' + userId + '/reset-password', {
const response = await window.http.wrappedFetch('/api/admin/users/' + userId + '/reset-password', {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify({
new_password: newPassword,
confirm_password: confirmPassword
@@ -1517,9 +1495,8 @@ async function deactivateUser(userId) {
if (!confirm('Are you sure you want to deactivate this user?')) return;
try {
const response = await fetch('/api/admin/users/' + userId, {
method: 'DELETE',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/users/' + userId, {
method: 'DELETE'
});
if (response.ok) {
@@ -1539,9 +1516,7 @@ async function deactivateUser(userId) {
// Settings Management Functions
async function loadSettings() {
try {
const response = await fetch('/api/admin/settings', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/settings');
const data = await response.json();
currentSettings = data.settings;
@@ -1592,9 +1567,7 @@ function showCreateSettingModal() {
async function editSetting(settingKey) {
try {
const response = await fetch('/api/admin/settings/' + encodeURIComponent(settingKey), {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/settings/' + encodeURIComponent(settingKey));
const setting = await response.json();
document.getElementById('settingModalTitle').textContent = 'Edit Setting';
@@ -1627,9 +1600,8 @@ async function saveSetting() {
const url = isEdit ? '/api/admin/settings/' + encodeURIComponent(settingKey) : '/api/admin/settings';
const method = isEdit ? 'PUT' : 'POST';
const response = await fetch(url, {
const response = await window.http.wrappedFetch(url, {
method: method,
headers: getAuthHeaders(),
body: JSON.stringify(isEdit ? {
setting_value: settingData.setting_value,
description: settingData.description
@@ -1688,9 +1660,8 @@ async function saveInactivitySetting() {
};
try {
const response = await fetch(url, {
const response = await window.http.wrappedFetch(url, {
method,
headers: getAuthHeaders(),
body: JSON.stringify(body)
});
if (!response.ok) throw new Error('Failed to save setting');
@@ -1708,9 +1679,8 @@ async function deleteSetting(settingKey) {
if (!confirm('Are you sure you want to delete this setting?')) return;
try {
const response = await fetch('/api/admin/settings/' + encodeURIComponent(settingKey), {
method: 'DELETE',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/settings/' + encodeURIComponent(settingKey), {
method: 'DELETE'
});
if (response.ok) {
@@ -1730,9 +1700,7 @@ async function deleteSetting(settingKey) {
// Maintenance Functions
async function loadLookupTables() {
try {
const response = await fetch('/api/admin/lookups/tables', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/lookups/tables');
const data = await response.json();
const element = document.getElementById('lookup-tables');
@@ -1756,9 +1724,8 @@ async function vacuumDatabase() {
if (!confirm('This will optimize the database. Continue?')) return;
try {
const response = await fetch('/api/admin/maintenance/vacuum', {
method: 'POST',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/maintenance/vacuum', {
method: 'POST'
});
const result = await response.json();
@@ -1779,9 +1746,8 @@ async function analyzeDatabase() {
if (!confirm('This will analyze database statistics. Continue?')) return;
try {
const response = await fetch('/api/admin/maintenance/analyze', {
method: 'POST',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/maintenance/analyze', {
method: 'POST'
});
const result = await response.json();
@@ -1818,9 +1784,7 @@ function addMaintenanceLog(operation, message) {
// Backup Functions
async function loadBackups() {
try {
const response = await fetch('/api/admin/backup/list', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/backup/list');
const data = await response.json();
const tbody = document.getElementById('backup-list');
@@ -1861,9 +1825,8 @@ async function createBackup() {
if (!confirm('Create a new database backup?')) return;
try {
const response = await fetch('/api/admin/backup/create', {
method: 'POST',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/backup/create', {
method: 'POST'
});
const result = await response.json();
@@ -1882,9 +1845,8 @@ async function createBackup() {
async function downloadBackup(filename) {
try {
const response = await fetch('/api/admin/backup/download', {
method: 'GET',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch('/api/admin/backup/download', {
method: 'GET'
});
if (!response.ok) {
@@ -1959,9 +1921,7 @@ async function loadIssues() {
if (categoryFilter) url += 'category=' + encodeURIComponent(categoryFilter) + '&';
if (assignedToMe) url += 'assigned_to_me=true&';
const response = await fetch(url, {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch(url);
if (!response.ok) {
throw new Error('Failed to load issues');
@@ -1981,9 +1941,7 @@ async function loadIssues() {
async function loadIssueStats() {
try {
const response = await fetch('/api/support/stats', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/support/stats');
if (!response.ok) {
throw new Error('Failed to load issue stats');
@@ -2082,9 +2040,7 @@ function filterIssues() {
async function viewIssue(issueId) {
try {
const response = await fetch('/api/support/tickets/' + issueId, {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/support/tickets/' + issueId);
if (!response.ok) {
throw new Error('Failed to load issue details');
@@ -2174,9 +2130,7 @@ async function viewIssue(issueId) {
async function loadUsersForAssignment() {
try {
if (allUsers.length === 0) {
const response = await fetch('/api/admin/users', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/admin/users');
allUsers = await response.json();
}
@@ -2235,9 +2189,8 @@ async function updateIssue() {
assigned_to: document.getElementById('updateAssignee').value || null
};
const response = await fetch('/api/support/tickets/' + window.currentIssueId, {
const response = await window.http.wrappedFetch('/api/support/tickets/' + window.currentIssueId, {
method: 'PUT',
headers: getAuthHeaders(),
body: JSON.stringify(updateData)
});
@@ -2273,9 +2226,8 @@ async function addResponse() {
}
try {
const response = await fetch('/api/support/tickets/' + window.currentIssueId + '/responses', {
const response = await window.http.wrappedFetch('/api/support/tickets/' + window.currentIssueId + '/responses', {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify({
message: message,
is_internal: isInternal
@@ -2307,9 +2259,7 @@ let importInProgress = false;
async function loadAvailableImportFiles() {
try {
const response = await fetch('/api/import/available-files', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/import/available-files');
if (!response.ok) throw new Error('Failed to load available files');
@@ -2351,9 +2301,7 @@ async function loadAvailableImportFiles() {
async function loadImportStatus() {
try {
const response = await fetch('/api/import/status', {
headers: getAuthHeaders()
});
const response = await window.http.wrappedFetch('/api/import/status');
if (!response.ok) throw new Error('Failed to load import status');
@@ -2431,15 +2379,13 @@ async function validateAdminFile() {
try {
showAdminProgress(true, 'Validating file...');
const response = await fetch(`/api/import/validate/${fileType}`, {
const response = await window.http.wrappedFetch(`/api/import/validate/${fileType}`, {
method: 'POST',
headers: getAuthHeaders(),
body: formData
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Validation failed');
throw await window.http.toError(response, 'Validation failed');
}
const result = await response.json();
@@ -2447,7 +2393,10 @@ async function validateAdminFile() {
} catch (error) {
console.error('Validation error:', error);
showAlert('Validation failed: ' + error.message, 'error');
const message = window.http && typeof window.http.formatAlert === 'function'
? window.http.formatAlert(error, 'Validation failed')
: 'Validation failed: ' + (error && error.message ? error.message : String(error));
showAlert(message, 'error');
} finally {
showAdminProgress(false);
}
@@ -2550,15 +2499,13 @@ async function handleAdminImport(event) {
try {
showAdminProgress(true, 'Importing data...');
const response = await fetch(`/api/import/upload/${fileType}`, {
const response = await window.http.wrappedFetch(`/api/import/upload/${fileType}`, {
method: 'POST',
headers: getAuthHeaders(),
body: formData
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Import failed');
throw await window.http.toError(response, 'Import failed');
}
const result = await response.json();
@@ -2572,7 +2519,10 @@ async function handleAdminImport(event) {
} catch (error) {
console.error('Import error:', error);
showAlert('Import failed: ' + error.message, 'error');
const message = window.http && typeof window.http.formatAlert === 'function'
? window.http.formatAlert(error, 'Import failed')
: 'Import failed: ' + (error && error.message ? error.message : String(error));
showAlert(message, 'error');
} finally {
importInProgress = false;
showAdminProgress(false);
@@ -2640,14 +2590,12 @@ async function clearAdminTable() {
}
try {
const response = await fetch(`/api/import/clear/${fileType}`, {
method: 'DELETE',
headers: getAuthHeaders()
const response = await window.http.wrappedFetch(`/api/import/clear/${fileType}`, {
method: 'DELETE'
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Clear operation failed');
throw await window.http.toError(response, 'Clear operation failed');
}
const result = await response.json();
@@ -2658,7 +2606,10 @@ async function clearAdminTable() {
} catch (error) {
console.error('Clear table error:', error);
showAlert('Clear operation failed: ' + error.message, 'error');
const message = window.http && typeof window.http.formatAlert === 'function'
? window.http.formatAlert(error, 'Clear operation failed')
: 'Clear operation failed: ' + (error && error.message ? error.message : String(error));
showAlert(message, 'error');
}
}