created space for more settings
This commit is contained in:
108
static/css/settings.css
Normal file
108
static/css/settings.css
Normal file
@@ -0,0 +1,108 @@
|
||||
/* TEST - This should make all nav links bright red */
|
||||
.card-header-tabs .nav-link {
|
||||
color: var(--text-muted);
|
||||
background: var(--bg-light);
|
||||
border: none;
|
||||
padding: 0.75rem 1.25rem;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
margin-right: 0.5rem;
|
||||
border-radius: 0.375rem 0.375rem 0 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--bs-nav-link-color: var(--text-muted) !important;
|
||||
--bs-nav-link-hover-color: var(--primary-color) !important;
|
||||
--bs-nav-link-disabled-color: var(--text-muted) !important;
|
||||
--bs-nav-link-active-color: var(--primary-color) !important;
|
||||
}
|
||||
|
||||
/* Override base nav-link styles */
|
||||
.card-header-tabs .nav-link,
|
||||
.card-header-tabs .nav-link:focus,
|
||||
.card-header-tabs .nav-link:hover,
|
||||
.card-header-tabs .nav-link.active,
|
||||
.card-header-tabs .nav-item.show .nav-link {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link:hover,
|
||||
.card-header-tabs .nav-link:focus,
|
||||
.card-header-tabs .nav-link.active,
|
||||
.card-header-tabs .nav-item.show .nav-link {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link:hover {
|
||||
color: var(--primary-color);
|
||||
background: var(--primary-bg-light);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link.active {
|
||||
color: var(--primary-color);
|
||||
background: var(--white);
|
||||
border: none;
|
||||
border-bottom: 2px solid var(--primary-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link i {
|
||||
width: 1.25rem;
|
||||
text-align: center;
|
||||
color: var(--primary-color);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link.active i {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
padding: 1rem;
|
||||
background: var(--bg-light);
|
||||
}
|
||||
|
||||
.card-header-tabs {
|
||||
margin: -0.5rem -1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 1.5rem;
|
||||
background: var(--white);
|
||||
border-radius: 0 0 0.375rem 0.375rem;
|
||||
}
|
||||
|
||||
/* Override Bootstrap's default tab colors */
|
||||
.card-header-tabs .nav-link:focus,
|
||||
.card-header-tabs .nav-link:hover {
|
||||
border-color: transparent;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.card-header-tabs .nav-link.active,
|
||||
.card-header-tabs .nav-item.show .nav-link {
|
||||
background-color: var(--white);
|
||||
border-color: transparent transparent var(--primary-color);
|
||||
}
|
||||
|
||||
/* Override Bootstrap's default text colors */
|
||||
.nav-tabs .nav-link,
|
||||
.nav-tabs .nav-link:focus,
|
||||
.nav-tabs .nav-link:hover,
|
||||
.nav-tabs .nav-link.active,
|
||||
.nav-tabs .nav-item.show .nav-link {
|
||||
color: var(--text-muted) !important;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link:hover,
|
||||
.nav-tabs .nav-link.active,
|
||||
.nav-tabs .nav-item.show .nav-link {
|
||||
color: var(--primary-color) !important;
|
||||
}
|
||||
138
static/js/settings.js
Normal file
138
static/js/settings.js
Normal file
@@ -0,0 +1,138 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const primaryColorInput = document.getElementById('primaryColor');
|
||||
const secondaryColorInput = document.getElementById('secondaryColor');
|
||||
|
||||
// Color manipulation functions
|
||||
function hexToRgb(hex) {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16)
|
||||
} : null;
|
||||
}
|
||||
|
||||
function rgbToHex(r, g, b) {
|
||||
return '#' + [r, g, b].map(x => {
|
||||
const hex = x.toString(16);
|
||||
return hex.length === 1 ? '0' + hex : hex;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function lightenColor(color, amount) {
|
||||
const rgb = hexToRgb(color);
|
||||
if (!rgb) return color;
|
||||
|
||||
return rgbToHex(
|
||||
Math.min(255, Math.round(rgb.r + (255 - rgb.r) * amount)),
|
||||
Math.min(255, Math.round(rgb.g + (255 - rgb.g) * amount)),
|
||||
Math.min(255, Math.round(rgb.b + (255 - rgb.b) * amount))
|
||||
);
|
||||
}
|
||||
|
||||
function darkenColor(color, amount) {
|
||||
const rgb = hexToRgb(color);
|
||||
if (!rgb) return color;
|
||||
|
||||
return rgbToHex(
|
||||
Math.max(0, Math.round(rgb.r * (1 - amount))),
|
||||
Math.max(0, Math.round(rgb.g * (1 - amount))),
|
||||
Math.max(0, Math.round(rgb.b * (1 - amount)))
|
||||
);
|
||||
}
|
||||
|
||||
function updateAllColors(color, isPrimary) {
|
||||
const prefix = isPrimary ? 'primary' : 'secondary';
|
||||
|
||||
// Calculate derived colors
|
||||
const lightColor = lightenColor(color, 0.15);
|
||||
const bgLightColor = lightenColor(color, 0.9);
|
||||
const opacity15 = color + '26'; // 15% opacity in hex
|
||||
|
||||
// Calculate chart colors
|
||||
const chartColors = {
|
||||
base: color,
|
||||
light: lightenColor(color, 0.2),
|
||||
lighter: lightenColor(color, 0.4),
|
||||
lightest: lightenColor(color, 0.6),
|
||||
pale: lightenColor(color, 0.8)
|
||||
};
|
||||
|
||||
// Update CSS variables for the entire website
|
||||
document.documentElement.style.setProperty(`--${prefix}-color`, color);
|
||||
document.documentElement.style.setProperty(`--${prefix}-light`, lightColor);
|
||||
document.documentElement.style.setProperty(`--${prefix}-bg-light`, bgLightColor);
|
||||
document.documentElement.style.setProperty(`--${prefix}-opacity-15`, opacity15);
|
||||
|
||||
// Update chart color variables
|
||||
document.documentElement.style.setProperty(`--chart-${prefix}`, chartColors.base);
|
||||
document.documentElement.style.setProperty(`--chart-${prefix}-light`, chartColors.light);
|
||||
document.documentElement.style.setProperty(`--chart-${prefix}-lighter`, chartColors.lighter);
|
||||
document.documentElement.style.setProperty(`--chart-${prefix}-lightest`, chartColors.lightest);
|
||||
document.documentElement.style.setProperty(`--chart-${prefix}-pale`, chartColors.pale);
|
||||
|
||||
// Update derived colors in the preview section
|
||||
const derivedColorsSection = document.getElementById(`${prefix}DerivedColors`);
|
||||
if (derivedColorsSection) {
|
||||
const previews = derivedColorsSection.querySelectorAll('.color-preview');
|
||||
previews.forEach(preview => {
|
||||
const colorType = preview.getAttribute('data-color-type');
|
||||
let previewColor;
|
||||
switch (colorType) {
|
||||
case 'base':
|
||||
previewColor = color;
|
||||
break;
|
||||
case 'light':
|
||||
previewColor = lightColor;
|
||||
break;
|
||||
case 'bg-light':
|
||||
previewColor = bgLightColor;
|
||||
break;
|
||||
case 'opacity':
|
||||
previewColor = opacity15;
|
||||
break;
|
||||
}
|
||||
preview.style.backgroundColor = previewColor;
|
||||
});
|
||||
}
|
||||
|
||||
// Update the color input value
|
||||
if (isPrimary) {
|
||||
primaryColorInput.value = color;
|
||||
} else {
|
||||
secondaryColorInput.value = color;
|
||||
}
|
||||
}
|
||||
|
||||
// Event listeners for color inputs
|
||||
primaryColorInput.addEventListener('change', () => {
|
||||
updateAllColors(primaryColorInput.value, true);
|
||||
});
|
||||
|
||||
secondaryColorInput.addEventListener('change', () => {
|
||||
updateAllColors(secondaryColorInput.value, false);
|
||||
});
|
||||
|
||||
// Also listen for input events for real-time updates
|
||||
primaryColorInput.addEventListener('input', () => {
|
||||
updateAllColors(primaryColorInput.value, true);
|
||||
});
|
||||
|
||||
secondaryColorInput.addEventListener('input', () => {
|
||||
updateAllColors(secondaryColorInput.value, false);
|
||||
});
|
||||
|
||||
// Initialize colors from database values
|
||||
function initializeColors() {
|
||||
// Reset inputs to original database values
|
||||
primaryColorInput.value = primaryColorInput.dataset.originalValue;
|
||||
secondaryColorInput.value = secondaryColorInput.dataset.originalValue;
|
||||
|
||||
// Update all color previews
|
||||
updateAllColors(primaryColorInput.value, true);
|
||||
updateAllColors(secondaryColorInput.value, false);
|
||||
}
|
||||
|
||||
// Initialize colors when the page loads
|
||||
initializeColors();
|
||||
});
|
||||
Reference in New Issue
Block a user