135 lines
4.0 KiB
JavaScript
135 lines
4.0 KiB
JavaScript
// static/js/theme.js
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const themeSettingsForm = document.getElementById('theme-settings-form');
|
|
const colorInputs = themeSettingsForm
|
|
? themeSettingsForm.querySelectorAll('input[type="color"]')
|
|
: [];
|
|
|
|
// Function to apply theme settings to CSS variables
|
|
function applyTheme(theme) {
|
|
const root = document.documentElement;
|
|
if (theme.primary_color)
|
|
root.style.setProperty('--color-primary', theme.primary_color);
|
|
if (theme.secondary_color)
|
|
root.style.setProperty('--color-secondary', theme.secondary_color);
|
|
if (theme.accent_color)
|
|
root.style.setProperty('--color-accent', theme.accent_color);
|
|
if (theme.background_color)
|
|
root.style.setProperty('--color-background', theme.background_color);
|
|
if (theme.text_color)
|
|
root.style.setProperty('--color-text-primary', theme.text_color);
|
|
// Add other theme properties as needed
|
|
}
|
|
|
|
// Save theme to local storage
|
|
function saveTheme(theme) {
|
|
localStorage.setItem('user-theme', JSON.stringify(theme));
|
|
}
|
|
|
|
// Load theme from local storage
|
|
function loadTheme() {
|
|
const savedTheme = localStorage.getItem('user-theme');
|
|
return savedTheme ? JSON.parse(savedTheme) : null;
|
|
}
|
|
|
|
// Real-time preview for color inputs
|
|
colorInputs.forEach((input) => {
|
|
input.addEventListener('input', (event) => {
|
|
const cssVar = `--color-${event.target.id.replace('-', '_')}`;
|
|
document.documentElement.style.setProperty(cssVar, event.target.value);
|
|
});
|
|
});
|
|
|
|
const THEME_API_URL = '/api/settings/theme';
|
|
|
|
const normalizeTheme = (theme) => {
|
|
if (!theme || typeof theme !== 'object') {
|
|
return {};
|
|
}
|
|
const {
|
|
theme_name,
|
|
primary_color,
|
|
secondary_color,
|
|
accent_color,
|
|
background_color,
|
|
text_color,
|
|
} = theme;
|
|
return {
|
|
theme_name,
|
|
primary_color,
|
|
secondary_color,
|
|
accent_color,
|
|
background_color,
|
|
text_color,
|
|
};
|
|
};
|
|
|
|
if (themeSettingsForm) {
|
|
themeSettingsForm.addEventListener('submit', async (event) => {
|
|
event.preventDefault();
|
|
|
|
const formData = new FormData(themeSettingsForm);
|
|
const themeData = Object.fromEntries(formData.entries());
|
|
|
|
try {
|
|
const response = await fetch(THEME_API_URL, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify(themeData),
|
|
});
|
|
|
|
if (response.ok) {
|
|
const payload = await response.json();
|
|
const savedTheme = normalizeTheme(payload?.theme ?? themeData);
|
|
alert('Theme settings saved successfully!');
|
|
applyTheme(savedTheme);
|
|
saveTheme(savedTheme);
|
|
} else {
|
|
const errorData = await response.json();
|
|
alert(`Error saving theme settings: ${errorData.detail}`);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
alert('An error occurred while saving theme settings.');
|
|
}
|
|
});
|
|
}
|
|
|
|
// Load and apply theme on page load
|
|
const initialTheme = loadTheme();
|
|
if (initialTheme) {
|
|
applyTheme(initialTheme);
|
|
// Populate form fields if on the theme settings page
|
|
if (themeSettingsForm) {
|
|
for (const key in initialTheme) {
|
|
const input = themeSettingsForm.querySelector(
|
|
`#${key.replace('_', '-')}`
|
|
);
|
|
if (input) {
|
|
input.value = initialTheme[key];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// If no saved theme, load from backend (if available)
|
|
async function loadAndApplyThemeFromServer() {
|
|
try {
|
|
const response = await fetch(THEME_API_URL);
|
|
if (response.ok) {
|
|
const theme = normalizeTheme(await response.json());
|
|
applyTheme(theme);
|
|
saveTheme(theme); // Save to local storage for future use
|
|
} else {
|
|
console.error('Failed to load theme settings from server');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading theme settings from server:', error);
|
|
}
|
|
}
|
|
loadAndApplyThemeFromServer();
|
|
}
|
|
});
|