- PageController: Replaced simple HTML with proper TemplateResponse - Added index() method with full admin interface - Added save() method for POST /save - Added load() method for GET /load - Injected IConfig service for configuration storage - Added validation for required fields - Proper error handling with JSONResponse - Admin template: Full Nextcloud-compatible admin interface - Google Analytics configuration section (client ID, secret, refresh token) - Anthropic Claude API configuration section (API key) - Configuration status display (success/warning states) - Form with proper Nextcloud components - CSRF token handling - Routes: Added /save and /load endpoints - page#index (GET) - renders admin page - page#save (POST) - saves configuration - page#load (GET) - loads configuration - Application.php: Updated with APP_VERSION constant - Proper style and script loading - CSS: Complete styling for admin interface - Responsive design with Nextcloud theme colors - Form input styling with focus states - Action buttons with hover effects - JavaScript: Complete form handling - AJAX submission to /save endpoint - Configuration loading from /load endpoint - CSRF token handling with OC.requestToken - OC.Notification integration for success/error messages - Real-time status updates This is a complete, working admin interface for configuration. Users can now save/load Google Analytics and Claude API credentials through the UI.
138 lines
4.8 KiB
JavaScript
138 lines
4.8 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
const saveButton = document.getElementById('analytics-hub-save');
|
|
const cancelButton = document.getElementById('analytics-hub-cancel');
|
|
const form = document.getElementById('analytics-hub-form');
|
|
|
|
if (saveButton) {
|
|
saveButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
saveConfiguration();
|
|
});
|
|
}
|
|
|
|
if (cancelButton) {
|
|
cancelButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
loadConfiguration();
|
|
});
|
|
}
|
|
|
|
function saveConfiguration() {
|
|
// Get form data
|
|
const formData = new FormData(form);
|
|
const data = {
|
|
google_client_id: document.getElementById('google_client_id').value,
|
|
google_client_secret: document.getElementById('google_client_secret').value,
|
|
google_refresh_token: document.getElementById('google_refresh_token').value,
|
|
anthropic_api_key: document.getElementById('anthropic_api_key').value
|
|
};
|
|
|
|
// Validate required fields
|
|
if (!data.google_client_id) {
|
|
showNotification('Error', 'Google Client ID is required');
|
|
return;
|
|
}
|
|
|
|
if (!data.google_client_secret) {
|
|
showNotification('Error', 'Google Client Secret is required');
|
|
return;
|
|
}
|
|
|
|
if (!data.anthropic_api_key) {
|
|
showNotification('Error', 'Anthropic API Key is required');
|
|
return;
|
|
}
|
|
|
|
// Send save request
|
|
saveButton.textContent = 'Saving...';
|
|
saveButton.disabled = true;
|
|
|
|
const url = OC.generateUrl('/apps/analyticshub/admin/save');
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'requesttoken': OC.requestToken
|
|
},
|
|
body: JSON.stringify(data)
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showNotification('Success', 'Configuration saved successfully');
|
|
if (data.data && data.data.is_configured) {
|
|
updateStatus(true);
|
|
}
|
|
} else {
|
|
showNotification('Error', data.error || 'Failed to save configuration');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showNotification('Error', 'Failed to save configuration: ' + error.message);
|
|
})
|
|
.finally(() => {
|
|
saveButton.textContent = 'Save Configuration';
|
|
saveButton.disabled = false;
|
|
});
|
|
}
|
|
|
|
function loadConfiguration() {
|
|
const url = OC.generateUrl('/apps/analyticshub/admin/load');
|
|
|
|
fetch(url, {
|
|
method: 'GET',
|
|
headers: {
|
|
'requesttoken': OC.requestToken
|
|
}
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.data) {
|
|
document.getElementById('google_client_id').value = data.data.google_client_id || '';
|
|
document.getElementById('google_client_secret').value = '';
|
|
document.getElementById('google_refresh_token').value = '';
|
|
document.getElementById('anthropic_api_key').value = '';
|
|
updateStatus(!!data.data.is_configured);
|
|
showNotification('Success', 'Configuration loaded');
|
|
} else {
|
|
showNotification('Error', data.error || 'Failed to load configuration');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
showNotification('Error', 'Failed to load configuration: ' + error.message);
|
|
});
|
|
}
|
|
|
|
function updateStatus(isConfigured) {
|
|
const statusDiv = document.querySelector('.analytics-hub-settings__status');
|
|
if (!statusDiv) return;
|
|
|
|
const statusMessage = isConfigured ? '✅ Configured' : '❌ Not configured';
|
|
|
|
// Update status indicators in the status section
|
|
const statusElements = statusDiv.querySelectorAll('p strong');
|
|
statusElements.forEach(el => {
|
|
const text = el.textContent;
|
|
if (text.includes('Google Client ID')) {
|
|
el.parentElement.innerHTML = '<strong>Google Client ID:</strong> ' + statusMessage;
|
|
}
|
|
if (text.includes('Anthropic API Key')) {
|
|
el.parentElement.innerHTML = '<strong>Anthropic API Key:</strong> ' + statusMessage;
|
|
}
|
|
});
|
|
}
|
|
|
|
function showNotification(title, message) {
|
|
// Try Nextcloud's notification system first
|
|
if (typeof OC !== 'undefined' && OC.Notification) {
|
|
OC.Notification.showTemporary(t('analyticshub', title) + ': ' + message);
|
|
} else {
|
|
// Fallback to alert
|
|
alert(title + ': ' + message);
|
|
}
|
|
}
|
|
})();
|