This commit is contained in:
Slipstream 2025-05-04 14:03:41 -06:00
parent c5772c7b4b
commit 427043f334
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD
3 changed files with 65 additions and 39 deletions

View File

@ -61,7 +61,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="nav-icon"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
AI Settings
</a>
<a href="#theme-settings" class="nav-item" data-section="theme-settings-section">
<a href="#theme-settings" class="nav-item" data-section="theme-settings-section" id="nav-theme-settings">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="nav-icon"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
Theme Settings
</a>

View File

@ -313,6 +313,11 @@ function showSection(sectionId) {
loadAiSettings();
}
// Load theme settings if needed
if (sectionId === 'theme-settings' && typeof loadThemeSettings === 'function' && typeof themeSettingsLoaded !== 'undefined' && !themeSettingsLoaded) {
loadThemeSettings();
}
// Load cog management if needed
if (sectionId === 'cog-management' && typeof loadGuildsForCogManagement === 'function' && typeof cogManagementLoaded !== 'undefined' && !cogManagementLoaded) {
loadGuildsForCogManagement();

View File

@ -3,9 +3,23 @@
* Handles theme customization for the dashboard
*/
// Flag to track if theme settings have been loaded
let themeSettingsLoaded = false;
// Initialize theme settings when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
initThemeSettings();
// Add event listener for theme settings tab
const navThemeSettings = document.getElementById('nav-theme-settings');
if (navThemeSettings) {
navThemeSettings.addEventListener('click', () => {
// Load theme settings if not already loaded
if (!themeSettingsLoaded) {
loadThemeSettings();
}
});
}
});
/**
@ -14,7 +28,7 @@ document.addEventListener('DOMContentLoaded', () => {
function initThemeSettings() {
// Get theme mode radio buttons
const themeModeRadios = document.querySelectorAll('input[name="theme_mode"]');
// Add event listeners to theme mode radio buttons
themeModeRadios.forEach(radio => {
radio.addEventListener('change', () => {
@ -33,13 +47,13 @@ function initThemeSettings() {
colorInputs.forEach(input => {
// Get the corresponding text input
const textInput = document.getElementById(`${input.id}-text`);
// Update text input when color input changes
input.addEventListener('input', () => {
textInput.value = input.value;
updateThemePreview();
});
// Update color input when text input changes
textInput.addEventListener('input', () => {
// Validate hex color format
@ -65,43 +79,50 @@ function initThemeSettings() {
// Add event listener to reset button
const resetButton = document.getElementById('reset-theme-settings-button');
resetButton.addEventListener('click', resetThemeSettings);
// Load theme settings from API
loadThemeSettings();
}
/**
* Load theme settings from API
*/
async function loadThemeSettings() {
// If theme settings are already loaded, don't fetch them again
if (themeSettingsLoaded) {
console.log('Theme settings already loaded, skipping API call');
return;
}
try {
// Show loading spinner
const themeSettingsForm = document.getElementById('theme-settings-form');
themeSettingsForm.innerHTML = '<div class="loading-spinner-container"><div class="loading-spinner"></div></div>';
// Fetch theme settings from API
console.log('Fetching theme settings from API');
const response = await fetch('/dashboard/api/settings');
if (!response.ok) {
throw new Error('Failed to load theme settings');
}
const data = await response.json();
// Mark theme settings as loaded
themeSettingsLoaded = true;
// Restore the form
themeSettingsForm.innerHTML = document.getElementById('theme-settings-template').innerHTML;
// Initialize event listeners again
initThemeSettings();
// Set theme settings values
if (data && data.theme) {
const theme = data.theme;
// Set theme mode
const themeModeRadio = document.querySelector(`input[name="theme_mode"][value="${theme.theme_mode}"]`);
if (themeModeRadio) {
themeModeRadio.checked = true;
// Show/hide custom theme settings
const customThemeSettings = document.getElementById('custom-theme-settings');
if (theme.theme_mode === 'custom') {
@ -110,33 +131,33 @@ async function loadThemeSettings() {
customThemeSettings.style.display = 'none';
}
}
// Set color values
if (theme.primary_color) {
document.getElementById('primary-color').value = theme.primary_color;
document.getElementById('primary-color-text').value = theme.primary_color;
}
if (theme.secondary_color) {
document.getElementById('secondary-color').value = theme.secondary_color;
document.getElementById('secondary-color-text').value = theme.secondary_color;
}
if (theme.accent_color) {
document.getElementById('accent-color').value = theme.accent_color;
document.getElementById('accent-color-text').value = theme.accent_color;
}
// Set font family
if (theme.font_family) {
document.getElementById('font-family').value = theme.font_family;
}
// Set custom CSS
if (theme.custom_css) {
document.getElementById('custom-css').value = theme.custom_css;
}
// Update preview
updateThemePreview();
}
@ -156,9 +177,9 @@ function updateThemePreview() {
const accentColor = document.getElementById('accent-color').value;
const fontFamily = document.getElementById('font-family').value;
const customCss = document.getElementById('custom-css').value;
const preview = document.getElementById('theme-preview');
// Apply theme mode
if (themeMode === 'dark') {
preview.classList.add('dark-mode');
@ -169,13 +190,13 @@ function updateThemePreview() {
} else if (themeMode === 'custom') {
preview.classList.remove('dark-mode');
preview.classList.add('custom-mode');
// Apply custom colors
preview.style.setProperty('--primary-color', primaryColor);
preview.style.setProperty('--secondary-color', secondaryColor);
preview.style.setProperty('--accent-color', accentColor);
preview.style.setProperty('--font-family', fontFamily);
// Apply custom CSS
const customStyleElement = document.getElementById('custom-theme-style');
if (customStyleElement) {
@ -196,14 +217,14 @@ async function saveThemeSettings() {
try {
const saveButton = document.getElementById('save-theme-settings-button');
saveButton.classList.add('btn-loading');
const themeMode = document.querySelector('input[name="theme_mode"]:checked').value;
const primaryColor = document.getElementById('primary-color').value;
const secondaryColor = document.getElementById('secondary-color').value;
const accentColor = document.getElementById('accent-color').value;
const fontFamily = document.getElementById('font-family').value;
const customCss = document.getElementById('custom-css').value;
// Create theme settings object
const themeSettings = {
theme_mode: themeMode,
@ -213,7 +234,7 @@ async function saveThemeSettings() {
font_family: fontFamily,
custom_css: customCss
};
// Send theme settings to API
const response = await fetch('/dashboard/api/settings', {
method: 'POST',
@ -226,29 +247,29 @@ async function saveThemeSettings() {
}
})
});
if (!response.ok) {
throw new Error('Failed to save theme settings');
}
// Show success message
const feedbackElement = document.getElementById('theme-settings-feedback');
feedbackElement.textContent = 'Theme settings saved successfully!';
feedbackElement.classList.add('text-success');
// Apply theme to the entire dashboard
applyThemeToDocument(themeSettings);
// Show toast notification
showToast('success', 'Success', 'Theme settings saved successfully!');
} catch (error) {
console.error('Error saving theme settings:', error);
// Show error message
const feedbackElement = document.getElementById('theme-settings-feedback');
feedbackElement.textContent = 'Failed to save theme settings. Please try again.';
feedbackElement.classList.add('text-danger');
// Show toast notification
showToast('error', 'Error', 'Failed to save theme settings');
} finally {
@ -264,10 +285,10 @@ async function saveThemeSettings() {
function resetThemeSettings() {
// Set theme mode to light
document.getElementById('theme-mode-light').checked = true;
// Hide custom theme settings
document.getElementById('custom-theme-settings').style.display = 'none';
// Reset color values
document.getElementById('primary-color').value = '#5865F2';
document.getElementById('primary-color-text').value = '#5865F2';
@ -275,16 +296,16 @@ function resetThemeSettings() {
document.getElementById('secondary-color-text').value = '#2D3748';
document.getElementById('accent-color').value = '#7289DA';
document.getElementById('accent-color-text').value = '#7289DA';
// Reset font family
document.getElementById('font-family').value = 'Inter, sans-serif';
// Reset custom CSS
document.getElementById('custom-css').value = '';
// Update preview
updateThemePreview();
// Show toast notification
showToast('info', 'Reset', 'Theme settings reset to defaults');
}
@ -304,13 +325,13 @@ function applyThemeToDocument(theme) {
} else if (theme.theme_mode === 'custom') {
document.body.classList.remove('dark-mode');
document.body.classList.add('custom-mode');
// Apply custom colors
document.documentElement.style.setProperty('--primary-color', theme.primary_color);
document.documentElement.style.setProperty('--secondary-color', theme.secondary_color);
document.documentElement.style.setProperty('--accent-color', theme.accent_color);
document.documentElement.style.setProperty('--font-family', theme.font_family);
// Apply custom CSS
const customStyleElement = document.getElementById('global-custom-theme-style');
if (customStyleElement) {