This commit is contained in:
johnpccd 2025-05-24 15:36:14 +02:00
parent d193f05974
commit 3208307eaa
10 changed files with 193 additions and 39 deletions

View File

@ -46,7 +46,7 @@
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" onclick="showPage('api-keys')">
<a class="nav-link" href="#" onclick="showPage('apiKeys')">
<i class="fas fa-key me-1"></i>API Keys
</a>
</li>

View File

@ -11,9 +11,11 @@ class ApiClient {
}
getHeaders(includeContentType = true) {
const headers = {
'X-API-Key': this.apiKey
};
const headers = {};
if (this.apiKey) {
headers['X-API-Key'] = this.apiKey;
}
if (includeContentType) {
headers['Content-Type'] = 'application/json';
@ -25,8 +27,8 @@ class ApiClient {
async makeRequest(method, endpoint, data = null, isFormData = false) {
this.updateConfig();
if (!this.baseUrl || !this.apiKey) {
throw new Error('API not configured. Please set API base URL and key.');
if (!this.baseUrl) {
throw new Error('API not configured. Please set API base URL.');
}
const url = `${this.baseUrl}/api/v1${endpoint}`;

View File

@ -9,6 +9,7 @@ const app = {
// Initialize the application
document.addEventListener('DOMContentLoaded', () => {
console.log('App.js DOMContentLoaded fired');
console.log('SeReact Frontend v' + app.version + ' - Initializing...');
// Initialize configuration
@ -184,7 +185,7 @@ function handleRouteChange() {
const route = hash || 'home';
// Validate route
const validRoutes = ['home', 'config', 'images', 'search', 'teams', 'users', 'api-keys'];
const validRoutes = ['home', 'config', 'images', 'search', 'teams', 'users', 'apiKeys'];
if (validRoutes.includes(route)) {
showPage(route);
@ -248,7 +249,7 @@ function setupKeyboardShortcuts() {
// Number shortcuts for navigation
if (e.key >= '1' && e.key <= '6' && !e.ctrlKey && !e.metaKey && !e.altKey) {
const pages = ['home', 'images', 'search', 'teams', 'users', 'api-keys'];
const pages = ['home', 'images', 'search', 'teams', 'users', 'apiKeys'];
const pageIndex = parseInt(e.key) - 1;
if (pages[pageIndex]) {
e.preventDefault();
@ -279,7 +280,7 @@ function refreshCurrentPageData() {
case 'users':
loadUsers();
break;
case 'api-keys':
case 'apiKeys':
loadApiKeys();
break;
}

View File

@ -3,6 +3,11 @@ class Config {
constructor() {
this.apiBaseUrl = localStorage.getItem('apiBaseUrl') || 'http://localhost:8000';
this.apiKey = localStorage.getItem('apiKey') || '';
// Set default configuration if not already set
if (!localStorage.getItem('apiBaseUrl')) {
this.setApiBaseUrl('http://localhost:8000');
}
}
setApiBaseUrl(url) {
@ -24,7 +29,7 @@ class Config {
}
isConfigured() {
return this.apiBaseUrl && this.apiKey;
return this.apiBaseUrl; // Only require base URL, make API key optional for now
}
clear() {
@ -82,11 +87,6 @@ async function testConnection() {
return;
}
if (!apiKey) {
showAlert('API Key is required', 'danger');
return;
}
const testButton = document.querySelector('button[onclick="testConnection()"]');
const originalText = testButton.innerHTML;
testButton.innerHTML = '<span class="loading-spinner"></span> Testing...';
@ -105,7 +105,8 @@ async function testConnection() {
throw new Error(`Health check failed with status ${healthResponse.status}`);
}
// Test API authentication
// Test API authentication only if API key is provided
if (apiKey) {
const authResponse = await fetch(`${apiBaseUrl}/api/v1/teams`, {
method: 'GET',
headers: {
@ -122,11 +123,16 @@ async function testConnection() {
throw new Error(`API request failed with status ${authResponse.status}`);
}
showAlert('API connection successful! Backend is up and running.', 'success');
showAlert('API connection successful! Backend is up and running with authentication.', 'success');
} else {
showAlert('API connection successful! Backend is up and running (no authentication tested).', 'success');
}
// Save the working configuration
config.setApiBaseUrl(apiBaseUrl);
if (apiKey) {
config.setApiKey(apiKey);
}
// Update form values
document.getElementById('apiBaseUrl').value = apiBaseUrl;

View File

@ -2,6 +2,11 @@
// Load teams
async function loadTeams() {
console.log('loadTeams called');
console.log('Config check:', config.isConfigured());
console.log('API Base URL:', config.getApiBaseUrl());
console.log('API Key:', config.getApiKey() ? 'Set' : 'Not set');
if (!config.isConfigured()) {
showAlert('Please configure your API settings first.', 'warning');
return;
@ -11,11 +16,15 @@ async function loadTeams() {
container.innerHTML = '<div class="text-center"><div class="loading-spinner"></div> Loading teams...</div>';
try {
console.log('Making API request to get teams...');
const response = await apiClient.getTeams();
console.log('API response:', response);
// Handle structured response - extract teams array from response object
const teams = response.teams || response;
console.log('Teams data:', teams);
displayTeams(teams);
} catch (error) {
console.error('Error loading teams:', error);
handleApiError(error, 'loading teams');
container.innerHTML = '<div class="alert alert-danger">Failed to load teams</div>';
}

View File

@ -2,14 +2,18 @@
// Page navigation
function showPage(pageId) {
console.log('showPage called with pageId:', pageId);
// Hide all pages
const pages = document.querySelectorAll('.page');
console.log('Found pages:', pages.length);
pages.forEach(page => {
page.style.display = 'none';
});
// Show the selected page
const targetPage = document.getElementById(pageId + 'Page');
console.log('Target page element:', targetPage);
if (targetPage) {
targetPage.style.display = 'block';
@ -20,7 +24,10 @@ function showPage(pageId) {
updateNavActiveState(pageId);
// Load page data if needed
console.log('Loading page data for:', pageId);
loadPageData(pageId);
} else {
console.error('Target page not found:', pageId + 'Page');
}
}
@ -38,25 +45,34 @@ function updateNavActiveState(activePageId) {
// Load page-specific data
function loadPageData(pageId) {
console.log('loadPageData called with pageId:', pageId);
switch (pageId) {
case 'config':
console.log('Loading config page');
initializeConfigForm();
break;
case 'images':
console.log('Loading images page');
loadImages();
break;
case 'teams':
console.log('Loading teams page');
loadTeams();
break;
case 'users':
console.log('Loading users page');
loadUsers();
break;
case 'api-keys':
case 'apiKeys':
console.log('Loading apiKeys page');
loadApiKeys();
break;
case 'search':
console.log('Loading search page');
initializeSearchForm();
break;
default:
console.log('No specific loader for page:', pageId);
}
}
@ -266,6 +282,8 @@ window.addEventListener('hashchange', () => {
// Initialize page on load
document.addEventListener('DOMContentLoaded', () => {
console.log('UI.js DOMContentLoaded fired');
// Initialize tooltips and popovers
initializeTooltips();
initializePopovers();
@ -276,5 +294,25 @@ document.addEventListener('DOMContentLoaded', () => {
// Show initial page
const hash = window.location.hash.substring(1);
const initialPage = hash || 'home';
console.log('Initial page:', initialPage);
showPage(initialPage);
});
// Test function for debugging
function testPageNavigation() {
console.log('Testing page navigation...');
console.log('Available pages:', document.querySelectorAll('.page').length);
const pages = ['home', 'config', 'teams', 'users'];
pages.forEach(pageId => {
const pageElement = document.getElementById(pageId + 'Page');
console.log(`Page ${pageId}:`, pageElement ? 'Found' : 'NOT FOUND');
});
// Test showing teams page
console.log('Testing showPage("teams")...');
showPage('teams');
}
// Make test function available globally
window.testPageNavigation = testPageNavigation;

View File

@ -2,6 +2,11 @@
// Load users
async function loadUsers() {
console.log('loadUsers called');
console.log('Config check:', config.isConfigured());
console.log('API Base URL:', config.getApiBaseUrl());
console.log('API Key:', config.getApiKey() ? 'Set' : 'Not set');
if (!config.isConfigured()) {
showAlert('Please configure your API settings first.', 'warning');
return;
@ -11,11 +16,15 @@ async function loadUsers() {
container.innerHTML = '<div class="text-center"><div class="loading-spinner"></div> Loading users...</div>';
try {
console.log('Making API request to get users...');
const response = await apiClient.getUsers();
console.log('API response:', response);
// Handle structured response - extract users array from response object
const users = response.users || response;
console.log('Users data:', users);
displayUsers(users);
} catch (error) {
console.error('Error loading users:', error);
handleApiError(error, 'loading users');
container.innerHTML = '<div class="alert alert-danger">Failed to load users</div>';
}

View File

@ -11,7 +11,7 @@ import sys
from pathlib import Path
# Configuration
PORT = 8080
PORT = 8081
HOST = 'localhost'
class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):

92
client/test.html Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SeReact Test</title>
<style>
.page { display: none; padding: 20px; border: 1px solid #ccc; margin: 10px; }
.page.active { display: block; }
button { margin: 5px; padding: 10px; }
</style>
</head>
<body>
<h1>SeReact Navigation Test</h1>
<div>
<button onclick="showPage('home')">Home</button>
<button onclick="showPage('teams')">Teams</button>
<button onclick="showPage('users')">Users</button>
<button onclick="showPage('config')">Config</button>
<button onclick="testPageNavigation()">Test Navigation</button>
</div>
<div id="homePage" class="page">
<h2>Home Page</h2>
<p>This is the home page content.</p>
</div>
<div id="teamsPage" class="page">
<h2>Teams Page</h2>
<div id="teamsContainer">Teams will load here...</div>
</div>
<div id="usersPage" class="page">
<h2>Users Page</h2>
<div id="usersContainer">Users will load here...</div>
</div>
<div id="configPage" class="page">
<h2>Config Page</h2>
<p>Configuration settings go here.</p>
</div>
<div id="alertContainer"></div>
<script>
// Simple config mock
const config = {
isConfigured: () => true,
getApiBaseUrl: () => 'http://localhost:8000',
getApiKey: () => 'test-key'
};
// Simple API client mock
const apiClient = {
getTeams: () => Promise.resolve({teams: [{id: '1', name: 'Test Team', description: 'A test team', created_at: new Date().toISOString()}]}),
getUsers: () => Promise.resolve({users: [{id: '1', name: 'Test User', email: 'test@example.com', team_id: '1', is_admin: false, created_at: new Date().toISOString()}]})
};
// Mock functions
function showAlert(message, type) {
console.log(`Alert (${type}): ${message}`);
}
function handleApiError(error, context) {
console.error(`API Error ${context}:`, error);
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function formatDate(dateString) {
return new Date(dateString).toLocaleString();
}
</script>
<script src="js/ui.js"></script>
<script src="js/teams.js"></script>
<script src="js/users.js"></script>
<script>
// Initialize on load
document.addEventListener('DOMContentLoaded', () => {
console.log('Test page loaded');
showPage('home');
});
</script>
</body>
</html>

View File

@ -72,10 +72,7 @@ start_dev_server() {
fi
# Check if Python is available
if command -v python3 &> /dev/null; then
print_color $BLUE "🐍 Using Python development server"
python3 serve.py
elif command -v python &> /dev/null; then
if command -v python &> /dev/null; then
print_color $BLUE "🐍 Using Python development server"
python serve.py
else