Fix colour system

This commit is contained in:
2025-05-27 14:36:40 +02:00
parent 60582d4520
commit 0c745e7544
13 changed files with 120 additions and 100 deletions

View File

@@ -356,9 +356,15 @@ def init_routes(main_bp):
flash('Only administrators can update settings.', 'error') flash('Only administrators can update settings.', 'error')
return redirect(url_for('main.dashboard')) return redirect(url_for('main.dashboard'))
logger.debug(f"Form data: {request.form}")
logger.debug(f"CSRF token: {request.form.get('csrf_token')}")
primary_color = request.form.get('primary_color') primary_color = request.form.get('primary_color')
secondary_color = request.form.get('secondary_color') secondary_color = request.form.get('secondary_color')
logger.debug(f"Primary color: {primary_color}")
logger.debug(f"Secondary color: {secondary_color}")
if not primary_color or not secondary_color: if not primary_color or not secondary_color:
flash('Both primary and secondary colors are required.', 'error') flash('Both primary and secondary colors are required.', 'error')
return redirect(url_for('main.settings')) return redirect(url_for('main.settings'))
@@ -369,8 +375,10 @@ def init_routes(main_bp):
try: try:
db.session.commit() db.session.commit()
logger.debug("Colors updated successfully in database")
flash('Color settings updated successfully!', 'success') flash('Color settings updated successfully!', 'success')
except Exception as e: except Exception as e:
logger.error(f"Error updating colors: {str(e)}")
db.session.rollback() db.session.rollback()
flash('An error occurred while updating color settings.', 'error') flash('An error occurred while updating color settings.', 'error')
@@ -447,9 +455,17 @@ def init_routes(main_bp):
@main_bp.route('/dynamic-colors.css') @main_bp.route('/dynamic-colors.css')
def dynamic_colors(): def dynamic_colors():
site_settings = SiteSettings.get_settings() """Generate dynamic CSS variables based on site settings"""
logger.info(f"[Dynamic Colors] Request from: {request.referrer}")
# Calculate derived colors # Get colors from settings
site_settings = SiteSettings.get_settings()
primary_color = site_settings.primary_color
secondary_color = site_settings.secondary_color
logger.info(f"[Dynamic Colors] Current colors - Primary: {primary_color}, Secondary: {secondary_color}")
# Convert hex to RGB for opacity calculations
def hex_to_rgb(hex_color): def hex_to_rgb(hex_color):
hex_color = hex_color.lstrip('#') hex_color = hex_color.lstrip('#')
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4)) return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
@@ -457,60 +473,49 @@ def init_routes(main_bp):
def rgb_to_hex(rgb): def rgb_to_hex(rgb):
return '#{:02x}{:02x}{:02x}'.format(rgb[0], rgb[1], rgb[2]) return '#{:02x}{:02x}{:02x}'.format(rgb[0], rgb[1], rgb[2])
def lighten_color(hex_color, amount): def lighten_color(hex_color, amount=0.2):
rgb = hex_to_rgb(hex_color) rgb = hex_to_rgb(hex_color)
return rgb_to_hex(tuple(min(255, int(c + (255 - c) * amount)) for c in rgb)) rgb = tuple(min(255, int(c + (255 - c) * amount)) for c in rgb)
return rgb_to_hex(rgb)
# Calculate all color variants # Calculate derived colors
primary_light = lighten_color(site_settings.primary_color, 0.15) primary_rgb = hex_to_rgb(primary_color)
primary_bg_light = lighten_color(site_settings.primary_color, 0.9) secondary_rgb = hex_to_rgb(secondary_color)
primary_opacity_15 = site_settings.primary_color + '26'
secondary_light = lighten_color(site_settings.secondary_color, 0.15) # Lighten colors for hover states
secondary_bg_light = lighten_color(site_settings.secondary_color, 0.9) primary_light = lighten_color(primary_color, 0.2)
secondary_opacity_15 = site_settings.secondary_color + '26' secondary_light = lighten_color(secondary_color, 0.2)
# Calculate chart colors
primary_chart_light = lighten_color(site_settings.primary_color, 0.2)
primary_chart_lighter = lighten_color(site_settings.primary_color, 0.4)
primary_chart_lightest = lighten_color(site_settings.primary_color, 0.6)
primary_chart_pale = lighten_color(site_settings.primary_color, 0.8)
secondary_chart_light = lighten_color(site_settings.secondary_color, 0.2)
secondary_chart_lighter = lighten_color(site_settings.secondary_color, 0.4)
secondary_chart_lightest = lighten_color(site_settings.secondary_color, 0.6)
secondary_chart_pale = lighten_color(site_settings.secondary_color, 0.8)
# Generate CSS with opacity variables
css = f""" css = f"""
:root {{ :root {{
/* Primary Colors */ /* Primary Colors */
--primary-color: {site_settings.primary_color}; --primary-color: {primary_color};
--primary-light: {primary_light}; --primary-light: {primary_light};
--primary-bg-light: {primary_bg_light}; --primary-rgb: {primary_rgb[0]}, {primary_rgb[1]}, {primary_rgb[2]};
--primary-opacity-15: {primary_opacity_15}; --primary-opacity-8: rgba({primary_rgb[0]}, {primary_rgb[1]}, {primary_rgb[2]}, 0.08);
--primary-opacity-15: rgba({primary_rgb[0]}, {primary_rgb[1]}, {primary_rgb[2]}, 0.15);
--primary-opacity-25: rgba({primary_rgb[0]}, {primary_rgb[1]}, {primary_rgb[2]}, 0.25);
--primary-opacity-50: rgba({primary_rgb[0]}, {primary_rgb[1]}, {primary_rgb[2]}, 0.5);
/* Secondary Colors */ /* Secondary Colors */
--secondary-color: {site_settings.secondary_color}; --secondary-color: {secondary_color};
--secondary-light: {secondary_light}; --secondary-light: {secondary_light};
--secondary-bg-light: {secondary_bg_light}; --secondary-rgb: {secondary_rgb[0]}, {secondary_rgb[1]}, {secondary_rgb[2]};
--secondary-opacity-15: {secondary_opacity_15}; --secondary-opacity-8: rgba({secondary_rgb[0]}, {secondary_rgb[1]}, {secondary_rgb[2]}, 0.08);
--secondary-opacity-15: rgba({secondary_rgb[0]}, {secondary_rgb[1]}, {secondary_rgb[2]}, 0.15);
--secondary-opacity-25: rgba({secondary_rgb[0]}, {secondary_rgb[1]}, {secondary_rgb[2]}, 0.25);
--secondary-opacity-50: rgba({secondary_rgb[0]}, {secondary_rgb[1]}, {secondary_rgb[2]}, 0.5);
/* Chart Colors */ /* Chart Colors */
--chart-primary: {site_settings.primary_color}; --chart-color-1: {primary_color};
--chart-secondary: {site_settings.secondary_color}; --chart-color-2: {secondary_color};
--chart-warning: #ffd700; --chart-color-3: {lighten_color(primary_color, 0.4)};
--chart-color-4: {lighten_color(secondary_color, 0.4)};
/* Primary Chart Colors */
--chart-primary-light: {primary_chart_light};
--chart-primary-lighter: {primary_chart_lighter};
--chart-primary-lightest: {primary_chart_lightest};
--chart-primary-pale: {primary_chart_pale};
/* Secondary Chart Colors */
--chart-secondary-light: {secondary_chart_light};
--chart-secondary-lighter: {secondary_chart_lighter};
--chart-secondary-lightest: {secondary_chart_lightest};
--chart-secondary-pale: {secondary_chart_pale};
}} }}
""" """
logger.info(f"[Dynamic Colors] Generated CSS with primary color: {primary_color}")
logger.info(f"[Dynamic Colors] Cache version: {site_settings.updated_at.timestamp()}")
return Response(css, mimetype='text/css') return Response(css, mimetype='text/css')

View File

@@ -1,6 +1,3 @@
/* Import color variables */
@import 'colors.css';
body { body {
background-color: var(--bg-color); background-color: var(--bg-color);
} }

View File

@@ -1,6 +1,3 @@
/* Import color variables */
@import 'colors.css';
body { body {
background-color: var(--bg-color); background-color: var(--bg-color);
} }

View File

@@ -1,6 +1,3 @@
/* Import color variables */
@import 'colors.css';
/* Masonry Layout */ /* Masonry Layout */
.masonry { .masonry {
column-count: 1; column-count: 1;

View File

@@ -1,6 +1,3 @@
/* Import color variables */
@import 'colors.css';
.navbar { .navbar {
background-color: var(--primary-color) !important; background-color: var(--primary-color) !important;
} }

View File

@@ -1,6 +1,3 @@
/* Import color variables */
@import 'colors.css';
.btn-group .btn.active { .btn-group .btn.active {
background-color: var(--primary-bg-light) !important; background-color: var(--primary-bg-light) !important;
border-color: var(--primary-color) !important; border-color: var(--primary-color) !important;

View File

@@ -1,6 +1,7 @@
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const primaryColorInput = document.getElementById('primaryColor'); const primaryColorInput = document.getElementById('primaryColor');
const secondaryColorInput = document.getElementById('secondaryColor'); const secondaryColorInput = document.getElementById('secondaryColor');
const colorSettingsForm = document.getElementById('colorSettingsForm');
// Tab persistence // Tab persistence
const settingsTabs = document.querySelectorAll('#settingsTabs button[data-bs-toggle="tab"]'); const settingsTabs = document.querySelectorAll('#settingsTabs button[data-bs-toggle="tab"]');
@@ -163,15 +164,37 @@ document.addEventListener('DOMContentLoaded', function() {
// Initialize colors from database values // Initialize colors from database values
function initializeColors() { function initializeColors() {
// Reset inputs to original database values // Get the current computed CSS variable values
primaryColorInput.value = primaryColorInput.dataset.originalValue; const computedPrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim();
secondaryColorInput.value = secondaryColorInput.dataset.originalValue; const computedSecondaryColor = getComputedStyle(document.documentElement).getPropertyValue('--secondary-color').trim();
console.log('[Settings] Initializing colors:', {
primary: computedPrimaryColor,
secondary: computedSecondaryColor,
timestamp: new Date().toISOString()
});
// Update input values
primaryColorInput.value = computedPrimaryColor;
secondaryColorInput.value = computedSecondaryColor;
// Update all color previews // Update all color previews
updateAllColors(primaryColorInput.value, true); updateAllColors(computedPrimaryColor, true);
updateAllColors(secondaryColorInput.value, false); updateAllColors(computedSecondaryColor, false);
} }
// Initialize colors when the page loads // Initialize colors when the page loads
initializeColors(); initializeColors();
// Handle form submission
if (colorSettingsForm) {
colorSettingsForm.addEventListener('submit', function(e) {
console.log('[Settings] Form submitted with values:', {
primary: primaryColorInput.value,
secondary: secondaryColorInput.value,
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
timestamp: new Date().toISOString()
});
});
}
}); });

View File

@@ -8,7 +8,15 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='css/auth.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/auth.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}"> <link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}?v={{ site_settings.updated_at.timestamp() }}" onload="console.log('[CSS] Dynamic colors loaded with version:', '{{ site_settings.updated_at.timestamp() }}')">
<script>
console.log('[CSS] Base colors loaded');
document.addEventListener('DOMContentLoaded', function() {
console.log('[CSS] All CSS files loaded');
console.log('[CSS] Primary color:', getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim());
console.log('[CSS] Secondary color:', getComputedStyle(document.documentElement).getPropertyValue('--secondary-color').trim());
});
</script>
<style> <style>
body { body {
min-height: 100vh; min-height: 100vh;

View File

@@ -7,6 +7,16 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='css/auth.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/auth.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}?v={{ site_settings.updated_at.timestamp() }}" onload="console.log('[CSS] Dynamic colors loaded with version:', '{{ site_settings.updated_at.timestamp() }}')">
<script>
console.log('[CSS] Base colors loaded');
document.addEventListener('DOMContentLoaded', function() {
console.log('[CSS] All CSS files loaded');
console.log('[CSS] Primary color:', getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim());
console.log('[CSS] Secondary color:', getComputedStyle(document.documentElement).getPropertyValue('--secondary-color').trim());
});
</script>
</head> </head>
<body> <body>
<div class="container"> <div class="container">

View File

@@ -10,8 +10,17 @@
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link href="{{ url_for('static', filename='css/file-grid.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='css/file-grid.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/base.css') }}" rel="stylesheet"> <link href="{{ url_for('static', filename='css/base.css') }}" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/colors.css') }}">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}?v={{ site_settings.updated_at.timestamp() }}" onload="console.log('[CSS] Dynamic colors loaded with version:', '{{ site_settings.updated_at.timestamp() }}')">
{% block extra_css %}{% endblock %} {% block extra_css %}{% endblock %}
<script>
console.log('[CSS] Base colors loaded');
document.addEventListener('DOMContentLoaded', function() {
console.log('[CSS] All CSS files loaded');
console.log('[CSS] Primary color:', getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim());
console.log('[CSS] Secondary color:', getComputedStyle(document.documentElement).getPropertyValue('--secondary-color').trim());
});
</script>
</head> </head>
<body> <body>
<!-- Navigation --> <!-- Navigation -->

View File

@@ -5,7 +5,6 @@
{% block extra_css %} {% block extra_css %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/dashboard.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/dashboard.css') }}">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}">
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@@ -70,17 +69,11 @@ document.addEventListener('DOMContentLoaded', function() {
// Get all chart colors // Get all chart colors
const chartColors = { const chartColors = {
primary: getCssVar('--chart-primary'), color1: getCssVar('--chart-color-1'),
secondary: getCssVar('--chart-secondary'), color2: getCssVar('--chart-color-2'),
warning: getCssVar('--chart-warning'), color3: getCssVar('--chart-color-3'),
primaryLight: getCssVar('--chart-primary-light'), color4: getCssVar('--chart-color-4'),
primaryLighter: getCssVar('--chart-primary-lighter'), warning: getCssVar('--warning-color')
primaryLightest: getCssVar('--chart-primary-lightest'),
primaryPale: getCssVar('--chart-primary-pale'),
secondaryLight: getCssVar('--chart-secondary-light'),
secondaryLighter: getCssVar('--chart-secondary-lighter'),
secondaryLightest: getCssVar('--chart-secondary-lightest'),
secondaryPale: getCssVar('--chart-secondary-pale')
}; };
// Contact Status Chart // Contact Status Chart
@@ -92,7 +85,7 @@ document.addEventListener('DOMContentLoaded', function() {
labels: ['Active', 'Inactive'], labels: ['Active', 'Inactive'],
datasets: [{ datasets: [{
data: [{{ active_count }}, {{ inactive_count }}], data: [{{ active_count }}, {{ inactive_count }}],
backgroundColor: [chartColors.primary, chartColors.secondary], backgroundColor: [chartColors.color1, chartColors.color2],
borderWidth: 0, borderWidth: 0,
hoverOffset: 4 hoverOffset: 4
}] }]
@@ -119,7 +112,7 @@ document.addEventListener('DOMContentLoaded', function() {
labels: ['Starred', 'Unstarred'], labels: ['Starred', 'Unstarred'],
datasets: [{ datasets: [{
data: [{{ starred_count }}, {{ file_count - starred_count }}], data: [{{ starred_count }}, {{ file_count - starred_count }}],
backgroundColor: [chartColors.warning, chartColors.primary], backgroundColor: [chartColors.warning, chartColors.color1],
borderWidth: 0, borderWidth: 0,
hoverOffset: 4 hoverOffset: 4
}] }]
@@ -145,16 +138,10 @@ document.addEventListener('DOMContentLoaded', function() {
datasets: [{ datasets: [{
data: [{% for type in storage_by_type %}{{ type.total_size }}{% if not loop.last %}, {% endif %}{% endfor %}], data: [{% for type in storage_by_type %}{{ type.total_size }}{% if not loop.last %}, {% endif %}{% endfor %}],
backgroundColor: [ backgroundColor: [
chartColors.primary, chartColors.color1,
chartColors.primaryLight, chartColors.color2,
chartColors.primaryLighter, chartColors.color3,
chartColors.primaryLightest, chartColors.color4
chartColors.primaryPale,
chartColors.secondary,
chartColors.secondaryLight,
chartColors.secondaryLighter,
chartColors.secondaryLightest,
chartColors.secondaryPale
], ],
borderWidth: 0, borderWidth: 0,
hoverOffset: 4 hoverOffset: 4
@@ -185,16 +172,10 @@ document.addEventListener('DOMContentLoaded', function() {
datasets: [{ datasets: [{
data: [{% for type in trash_by_type %}{{ type.count }}{% if not loop.last %}, {% endif %}{% endfor %}], data: [{% for type in trash_by_type %}{{ type.count }}{% if not loop.last %}, {% endif %}{% endfor %}],
backgroundColor: [ backgroundColor: [
chartColors.primary, chartColors.color1,
chartColors.primaryLight, chartColors.color2,
chartColors.primaryLighter, chartColors.color3,
chartColors.primaryLightest, chartColors.color4
chartColors.primaryPale,
chartColors.secondary,
chartColors.secondaryLight,
chartColors.secondaryLighter,
chartColors.secondaryLightest,
chartColors.secondaryPale
], ],
borderWidth: 0, borderWidth: 0,
hoverOffset: 4 hoverOffset: 4

View File

@@ -5,7 +5,6 @@
{% block extra_css %} {% block extra_css %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/trash.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/trash.css') }}">
<link rel="stylesheet" href="{{ url_for('main.dynamic_colors') }}">
{% endblock %} {% endblock %}
{% block content %} {% block content %}