diff --git a/.env.sample b/.env.sample index b2e280a..1eccfbf 100644 --- a/.env.sample +++ b/.env.sample @@ -445,3 +445,8 @@ # When true, all sections start expanded. When false, all sections start collapsed. # Default: true # BK_STATISTICS_DEFAULT_EXPANDED=false + +# Optional: Enable dark mode by default +# When true, the application starts in dark mode. +# Default: false +# BK_DARK_MODE=true diff --git a/bricktracker/config.py b/bricktracker/config.py index 7026295..94e681c 100644 --- a/bricktracker/config.py +++ b/bricktracker/config.py @@ -96,4 +96,5 @@ CONFIG: Final[list[dict[str, Any]]] = [ {'n': 'WISHES_DEFAULT_ORDER', 'd': '"bricktracker_wishes"."rowid" DESC'}, {'n': 'STATISTICS_SHOW_CHARTS', 'd': True, 'c': bool}, {'n': 'STATISTICS_DEFAULT_EXPANDED', 'd': True, 'c': bool}, + {'n': 'DARK_MODE', 'c': bool}, ] diff --git a/bricktracker/config_manager.py b/bricktracker/config_manager.py index 475a3c7..d5d1298 100644 --- a/bricktracker/config_manager.py +++ b/bricktracker/config_manager.py @@ -53,6 +53,7 @@ LIVE_CHANGEABLE_VARS: Final[List[str]] = [ 'BK_REBRICKABLE_PAGE_SIZE', 'BK_STATISTICS_SHOW_CHARTS', 'BK_STATISTICS_DEFAULT_EXPANDED', + 'BK_DARK_MODE', # Default ordering and formatting 'BK_INSTRUCTIONS_ALLOWED_EXTENSIONS', 'BK_MINIFIGURES_DEFAULT_ORDER', @@ -322,6 +323,7 @@ class ConfigManager: 'BK_HIDE_SPARE_PARTS': 'Hide spare parts from parts lists (spare parts must still be in database)', 'BK_USE_REMOTE_IMAGES': 'Use remote images from Rebrickable CDN instead of local', 'BK_STATISTICS_SHOW_CHARTS': 'Show collection growth charts on statistics page', - 'BK_STATISTICS_DEFAULT_EXPANDED': 'Expand all statistics sections by default' + 'BK_STATISTICS_DEFAULT_EXPANDED': 'Expand all statistics sections by default', + 'BK_DARK_MODE': 'Enable dark mode theme' } return help_text.get(var_name, 'No help available for this variable') \ No newline at end of file diff --git a/static/scripts/statistics.js b/static/scripts/statistics.js index f51c4bf..df2ca3a 100644 --- a/static/scripts/statistics.js +++ b/static/scripts/statistics.js @@ -11,6 +11,11 @@ document.addEventListener('DOMContentLoaded', function() { // Debug: Log chart data to console console.log('Chart Data:', window.chartData); + // Get current theme colors + const isDarkMode = document.documentElement.getAttribute('data-bs-theme') === 'dark'; + const textColor = isDarkMode ? '#f8f9fa' : '#212529'; + const gridColor = isDarkMode ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'; + // Common chart configuration const commonConfig = { type: 'line', @@ -25,20 +30,30 @@ document.addEventListener('DOMContentLoaded', function() { x: { title: { display: true, - text: 'Release Year' + text: 'Release Year', + color: textColor + }, + ticks: { + color: textColor }, grid: { - display: false + display: false, + color: gridColor } }, y: { beginAtZero: true, title: { display: true, - text: 'Count' + text: 'Count', + color: textColor }, ticks: { - precision: 0 + precision: 0, + color: textColor + }, + grid: { + color: gridColor } } }, @@ -110,7 +125,8 @@ document.addEventListener('DOMContentLoaded', function() { ...commonConfig.options.scales.y, title: { display: true, - text: 'Parts Count' + text: 'Parts Count', + color: textColor } } } @@ -143,7 +159,8 @@ document.addEventListener('DOMContentLoaded', function() { ...commonConfig.options.scales.y, title: { display: true, - text: 'Minifigures Count' + text: 'Minifigures Count', + color: textColor } } } diff --git a/static/styles.css b/static/styles.css index 90a9b7e..857c3c6 100644 --- a/static/styles.css +++ b/static/styles.css @@ -87,6 +87,11 @@ border-color: #6c757d; } +[data-bs-theme="dark"] .table th .dropdown-toggle:hover { + background-color: #2b3035; + border-color: #6c757d; +} + /* Style dropdown items */ .dropdown-menu .dropdown-header { font-size: 0.75rem; @@ -106,6 +111,11 @@ color: #212529; } +[data-bs-theme="dark"] .dropdown-menu .dropdown-item:hover { + background-color: #2b3035; + color: #fff; +} + .dropdown-menu .dropdown-item i { width: 1.25rem; text-align: center; @@ -117,6 +127,11 @@ --th-bg:#fff !important; } +[data-bs-theme="dark"] .sortable { + --th-color: #fff !important; + --th-bg: #212529 !important; +} + .sortable thead th { font-weight: bold !important; } @@ -180,3 +195,80 @@ pointer-events: none; }/* Duplicate filter support */ .duplicate-filter-hidden { display: none !important; } + +/* Dark mode link and text fixes */ +[data-bs-theme="dark"] .text-reset { + color: var(--bs-body-color) !important; +} + +[data-bs-theme="dark"] a.text-reset:hover { + color: var(--bs-link-hover-color) !important; +} + +[data-bs-theme="dark"] .text-dark { + color: var(--bs-body-color) !important; +} + +/* Dark mode border fixes */ +[data-bs-theme="dark"] .border-black { + border-color: var(--bs-border-color) !important; +} + +/* Dark mode badge fixes */ +[data-bs-theme="dark"] .text-bg-light { + background-color: #343a40 !important; + color: #f8f9fa !important; +} + +[data-bs-theme="dark"] .bg-white { + background-color: #212529 !important; +} + +[data-bs-theme="dark"] .text-black { + color: #f8f9fa !important; +} + +/* Dark mode button fixes */ +[data-bs-theme="dark"] .btn-outline-dark { + border-color: #f8f9fa; + color: #f8f9fa; +} + +[data-bs-theme="dark"] .btn-outline-dark:hover { + background-color: #f8f9fa; + border-color: #f8f9fa; + color: #212529; +} + +[data-bs-theme="dark"] .btn-light { + background-color: #343a40; + border-color: #495057; + color: #f8f9fa; +} + +[data-bs-theme="dark"] .btn-light:hover { + background-color: #495057; + border-color: #6c757d; + color: #fff; +} + +/* Dark mode table fixes */ +[data-bs-theme="dark"] .table-light { + --bs-table-bg: #343a40; + --bs-table-color: #f8f9fa; +} + +/* Dark mode for card header links */ +[data-bs-theme="dark"] .text-decoration-none.text-dark { + color: var(--bs-body-color) !important; +} + +/* Dark mode table text fix - ensure all table text is visible */ +[data-bs-theme="dark"] .table { + --bs-table-color: var(--bs-body-color); +} + +[data-bs-theme="dark"] .table tbody td, +[data-bs-theme="dark"] .table tbody th { + color: var(--bs-body-color); +} diff --git a/templates/admin/configuration.html b/templates/admin/configuration.html index 99c65b0..f6f6fcd 100644 --- a/templates/admin/configuration.html +++ b/templates/admin/configuration.html @@ -508,6 +508,14 @@
Expand all statistics sections by default
+ +
+ + +
diff --git a/templates/base.html b/templates/base.html index b95433d..968f6ca 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,5 +1,5 @@ - +