From 2c5fa2121fe438033d8eb7c70d5a5da7f4258e75 Mon Sep 17 00:00:00 2001 From: core Date: Wed, 29 Oct 2025 12:41:25 -0400 Subject: [PATCH 1/5] feat: start implementing dark mode --- package-lock.json | 14 ++++ resources/assets/js/app.js | 1 + resources/assets/js/theme.js | 80 +++++++++++++++++++++ resources/assets/sass/_variables.scss | 1 + resources/assets/sass/app.scss | 13 ++-- resources/assets/sass/mix/dashboard.scss | 2 +- resources/assets/sass/mix/footer_white.scss | 2 +- resources/assets/sass/mix/roster.scss | 5 ++ resources/assets/sass/mix/sidebar.scss | 2 +- 9 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 resources/assets/js/theme.js diff --git a/package-lock.json b/package-lock.json index d02cdbc82..5d7622b14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -78,6 +78,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", "dev": true, + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", @@ -3440,6 +3441,7 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -3945,6 +3947,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3989,6 +3992,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4565,6 +4569,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -7068,6 +7073,7 @@ "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-7.0.1.tgz", "integrity": "sha512-33AmZ+xjZhg2JMCe+vDf6a9mzWukE7l+wAtesjE7KyteqqKjzxv7aVQeWnul1Ve26mWvEQqyPwl0OctNBfSR9w==", "dev": true, + "peer": true, "dependencies": { "file-type": "^12.0.0", "globby": "^10.0.0", @@ -8032,6 +8038,7 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -8785,6 +8792,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -9353,6 +9361,7 @@ "version": "6.0.16", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -9971,6 +9980,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz", "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==", "dev": true, + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -11123,6 +11133,7 @@ "version": "5.94.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", + "peer": true, "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -11169,6 +11180,7 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.2.0", @@ -11260,6 +11272,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -11372,6 +11385,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index 0965adf78..5be6a1051 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -6,3 +6,4 @@ require("./ckeditor.js"); require("./bootstrap.js"); require("./helpers.js"); +require("./theme.js"); diff --git a/resources/assets/js/theme.js b/resources/assets/js/theme.js new file mode 100644 index 000000000..18bc84944 --- /dev/null +++ b/resources/assets/js/theme.js @@ -0,0 +1,80 @@ +/*! + * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) + * Copyright 2011-2025 The Bootstrap Authors + * Licensed under the Creative Commons Attribution 3.0 Unported License. + */ + +(() => { + 'use strict' + + const getStoredTheme = () => localStorage.getItem('theme') + const setStoredTheme = theme => localStorage.setItem('theme', theme) + + const getPreferredTheme = () => { + const storedTheme = getStoredTheme() + if (storedTheme) { + return storedTheme + } + + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' + } + + const setTheme = theme => { + if (theme === 'auto') { + document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) + } else { + document.documentElement.setAttribute('data-bs-theme', theme) + } + } + + setTheme(getPreferredTheme()) + + const showActiveTheme = (theme, focus = false) => { + const themeSwitcher = document.querySelector('#bd-theme') + + if (!themeSwitcher) { + return + } + + const themeSwitcherText = document.querySelector('#bd-theme-text') + const activeThemeIcon = document.querySelector('.theme-icon-active use') + const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`) + const svgOfActiveBtn = btnToActive.querySelector('svg use').getAttribute('href') + + document.querySelectorAll('[data-bs-theme-value]').forEach(element => { + element.classList.remove('active') + element.setAttribute('aria-pressed', 'false') + }) + + btnToActive.classList.add('active') + btnToActive.setAttribute('aria-pressed', 'true') + activeThemeIcon.setAttribute('href', svgOfActiveBtn) + const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})` + themeSwitcher.setAttribute('aria-label', themeSwitcherLabel) + + if (focus) { + themeSwitcher.focus() + } + } + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { + const storedTheme = getStoredTheme() + if (storedTheme !== 'light' && storedTheme !== 'dark') { + setTheme(getPreferredTheme()) + } + }) + + window.addEventListener('DOMContentLoaded', () => { + showActiveTheme(getPreferredTheme()) + + document.querySelectorAll('[data-bs-theme-value]') + .forEach(toggle => { + toggle.addEventListener('click', () => { + const theme = toggle.getAttribute('data-bs-theme-value') + setStoredTheme(theme) + setTheme(theme) + showActiveTheme(theme, true) + }) + }) + }) +})() diff --git a/resources/assets/sass/_variables.scss b/resources/assets/sass/_variables.scss index 0e2bd9f95..2795da902 100644 --- a/resources/assets/sass/_variables.scss +++ b/resources/assets/sass/_variables.scss @@ -1,4 +1,5 @@ // Body + $body-bg: #f5f8fa; // Typography diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss index ddf990cc1..719bd1b4c 100644 --- a/resources/assets/sass/app.scss +++ b/resources/assets/sass/app.scss @@ -22,8 +22,8 @@ $font-family-base: "Hind Siliguri", sans-serif; html, body { - background-color: #fff; - color: black; + //background-color: #fff; + //color: black; --bs-body-font-family: "Hind Siliguri", sans-serif; --bs-body-font-size: 1rem; --bs-body-font-weight: 100; @@ -151,15 +151,16 @@ body { } .view-header { - background-color: #f0f0f0; + background-color: var(--bs-secondary-bg); } .tab-link { - color: black; +// color: black; } .item-black { - color: black; +// color: black; + color: var(--bs-body-color); } .bronze { @@ -168,6 +169,7 @@ body { div.bronze-bg { background-color: #c9ae5d; + color: rgb(33,37,41); } .pyrite { @@ -176,6 +178,7 @@ div.bronze-bg { div.pyrite-bg { background-color: #ffdf00; + color: rgb(33,37,41); } div.hours-danger, diff --git a/resources/assets/sass/mix/dashboard.scss b/resources/assets/sass/mix/dashboard.scss index 821c9d02b..77a4baa1a 100644 --- a/resources/assets/sass/mix/dashboard.scss +++ b/resources/assets/sass/mix/dashboard.scss @@ -63,7 +63,7 @@ input:checked + .slider:before { div.clocks div.card-body { text-align: center; - background-color: lightgrey; + background-color: var(--bs-tertiary-bg); } div.clocks iframe { diff --git a/resources/assets/sass/mix/footer_white.scss b/resources/assets/sass/mix/footer_white.scss index 1f47a3aaf..497911bdb 100644 --- a/resources/assets/sass/mix/footer_white.scss +++ b/resources/assets/sass/mix/footer_white.scss @@ -46,7 +46,7 @@ table.availability td.available { text-align: center; padding-top: 25px; padding-bottom: 25px; - background-color: #eee; + background-color: var(--bs-secondary-bg); } #myFooter .fa { diff --git a/resources/assets/sass/mix/roster.scss b/resources/assets/sass/mix/roster.scss index 1ae16b47f..32b08cab3 100644 --- a/resources/assets/sass/mix/roster.scss +++ b/resources/assets/sass/mix/roster.scss @@ -4,3 +4,8 @@ thead.sticky th { top: 0; box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.4); } + + +[data-bs-theme=dark] thead.sticky th { + background: var(--bs-secondary-bg); +} diff --git a/resources/assets/sass/mix/sidebar.scss b/resources/assets/sass/mix/sidebar.scss index 30be1f585..f519e6e66 100644 --- a/resources/assets/sass/mix/sidebar.scss +++ b/resources/assets/sass/mix/sidebar.scss @@ -11,7 +11,7 @@ font-size: 12px; } #pill-sidebar a.nav-link { - color: black; + color: var(--bs-body-color); font-size: 14px; } From c18b770f89676e6467997b02cc98bf88bd056e96 Mon Sep 17 00:00:00 2001 From: core Date: Thu, 30 Oct 2025 08:28:03 -0400 Subject: [PATCH 2/5] feat(darkmode): fix text colors across site --- .../dashboard/admin/incident_reports/index.blade.php | 4 ++-- .../views/dashboard/admin/roster/edit.blade.php | 6 +++--- .../views/dashboard/admin/roster/purge.blade.php | 2 +- .../views/dashboard/admin/scenery/index.blade.php | 2 +- .../views/dashboard/controllers/files.blade.php | 2 +- .../views/dashboard/controllers/roster.blade.php | 4 ++-- .../views/dashboard/training/ots-center.blade.php | 6 +++--- resources/views/dashboard/training/tickets.blade.php | 2 +- resources/views/inc/scenery_index.blade.php | 2 +- resources/views/inc/stats.blade.php | 2 +- resources/views/site/staff.blade.php | 12 ++++++------ 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/resources/views/dashboard/admin/incident_reports/index.blade.php b/resources/views/dashboard/admin/incident_reports/index.blade.php index 5b0db652e..cdc87e42c 100644 --- a/resources/views/dashboard/admin/incident_reports/index.blade.php +++ b/resources/views/dashboard/admin/incident_reports/index.blade.php @@ -10,10 +10,10 @@
diff --git a/resources/views/dashboard/admin/roster/edit.blade.php b/resources/views/dashboard/admin/roster/edit.blade.php index 96de3e3fe..1fe3ffe26 100644 --- a/resources/views/dashboard/admin/roster/edit.blade.php +++ b/resources/views/dashboard/admin/roster/edit.blade.php @@ -10,16 +10,16 @@
diff --git a/resources/views/dashboard/admin/roster/purge.blade.php b/resources/views/dashboard/admin/roster/purge.blade.php index b7e6c2f82..6d24ab113 100644 --- a/resources/views/dashboard/admin/roster/purge.blade.php +++ b/resources/views/dashboard/admin/roster/purge.blade.php @@ -36,7 +36,7 @@ @php ($active = ' active') @endif @endforeach @endforeach diff --git a/resources/views/dashboard/controllers/files.blade.php b/resources/views/dashboard/controllers/files.blade.php index 00a72412a..bb8faad53 100644 --- a/resources/views/dashboard/controllers/files.blade.php +++ b/resources/views/dashboard/controllers/files.blade.php @@ -35,7 +35,7 @@ @php ($activeMarker = ' active') @endif @php ($displayedTabs[] = strtolower($fileCategory)) @endforeach diff --git a/resources/views/dashboard/controllers/roster.blade.php b/resources/views/dashboard/controllers/roster.blade.php index 964809ce2..241d239ab 100644 --- a/resources/views/dashboard/controllers/roster.blade.php +++ b/resources/views/dashboard/controllers/roster.blade.php @@ -22,10 +22,10 @@ @endif @php diff --git a/resources/views/dashboard/training/ots-center.blade.php b/resources/views/dashboard/training/ots-center.blade.php index 92c389edb..a33739aa0 100644 --- a/resources/views/dashboard/training/ots-center.blade.php +++ b/resources/views/dashboard/training/ots-center.blade.php @@ -12,13 +12,13 @@
diff --git a/resources/views/dashboard/training/tickets.blade.php b/resources/views/dashboard/training/tickets.blade.php index 70a4654c3..edb3345be 100644 --- a/resources/views/dashboard/training/tickets.blade.php +++ b/resources/views/dashboard/training/tickets.blade.php @@ -72,7 +72,7 @@ @php ($active = ' active') @endif @endforeach diff --git a/resources/views/inc/scenery_index.blade.php b/resources/views/inc/scenery_index.blade.php index 9b1eac1c0..babce2aa8 100644 --- a/resources/views/inc/scenery_index.blade.php +++ b/resources/views/inc/scenery_index.blade.php @@ -27,7 +27,7 @@ @php ($active = ' active') @endif @endforeach diff --git a/resources/views/inc/stats.blade.php b/resources/views/inc/stats.blade.php index 1dd1177ce..497c5feb4 100644 --- a/resources/views/inc/stats.blade.php +++ b/resources/views/inc/stats.blade.php @@ -57,7 +57,7 @@ @php ($active = ' active') @endif @endforeach diff --git a/resources/views/site/staff.blade.php b/resources/views/site/staff.blade.php index 4db702d08..9c4a0b756 100644 --- a/resources/views/site/staff.blade.php +++ b/resources/views/site/staff.blade.php @@ -18,7 +18,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

The Air Traffic Manager is responsible to the Deputy Director - Air Traffic Services for the overall administration of the ARTCC. The ATM is responsible for appointing ARTCC staff members and delegation of authorities.

@@ -33,7 +33,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

The Deputy Air Traffic Manager reports to the Air Traffic Manager and acts as Air Traffic Manager in their absence. The Deputy Air Traffic Manager is jointly responsible for administration and accuracy of the roster including visiting controllers.

@@ -48,7 +48,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

The Training Administrator works with the Air Traffic Manager and Deputy Air Traffic Manager to build training programs, establish training procedures and recommend instructors and mentors. The Training Administrator works with Instructors and Mentors to develop knowledge and mentors to help develop teaching ability.

@@ -79,7 +79,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

Responsible to the Air Traffic Manager for the operation and maintenance of all IT services including, but not limited to, the Website, TeamSpeak and Email services and any other tasking as directed.

@@ -94,7 +94,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

The Events Coordinator is responsible to the Deputy Air Traffic Manager for the coordination, planning, dissemination and creation of events to neighboring facilities, virtual airlines, VATUSA and VATSIM.

@@ -124,7 +124,7 @@ {{ $s->full_name }} @endforeach @endif -   +  

The Facility Engineer is responsible to the Senior Staff for creation of sector files, radar client files, training scenarios, Letters of Agreement, Memorandums of Understanding, Standard Operating Procedures and other requests as directed and submission to the Air Traffic Manager for approval prior to dissemination.

From 19782e7afbd6a990b070fcf1ab35dd661755ea6b Mon Sep 17 00:00:00 2001 From: core Date: Thu, 30 Oct 2025 08:29:23 -0400 Subject: [PATCH 3/5] feat(darkmode): remove clocks from dashboard --- resources/views/dashboard/dashboard.blade.php | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/resources/views/dashboard/dashboard.blade.php b/resources/views/dashboard/dashboard.blade.php index 39b3306bf..ea9bc4a82 100644 --- a/resources/views/dashboard/dashboard.blade.php +++ b/resources/views/dashboard/dashboard.blade.php @@ -26,32 +26,6 @@
@endif -
-
-
-
Zulu/UTC Time Now:
- -
-
-
-
-
Eastern Time Now:
- -
-
-
-
-
Central Time Now:
- -
-
-
-
-
Pacific Time Now:
- -
-
-
@include('inc.notifications')

Controller Dashboard Quicklinks

From 0bd66fd3fc417763d8a18b346f7ff46e1f88d583 Mon Sep 17 00:00:00 2001 From: core Date: Thu, 30 Oct 2025 08:42:58 -0400 Subject: [PATCH 4/5] feat(darkmode): misc improvements/fixes --- resources/assets/sass/app.scss | 7 +++++++ resources/assets/sass/mix/sidebar.scss | 2 +- resources/views/inc/header.blade.php | 2 +- resources/views/inc/logo.blade.php | 11 ++++------- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss index 719bd1b4c..83bb6ed49 100644 --- a/resources/assets/sass/app.scss +++ b/resources/assets/sass/app.scss @@ -222,3 +222,10 @@ td.hours-success { a { text-decoration: none; } + +[data-bs-theme=dark] .logo-light { + display: none; +} +[data-bs-theme=light] .logo-dark { + display: none; +} diff --git a/resources/assets/sass/mix/sidebar.scss b/resources/assets/sass/mix/sidebar.scss index f519e6e66..65cdf1ee7 100644 --- a/resources/assets/sass/mix/sidebar.scss +++ b/resources/assets/sass/mix/sidebar.scss @@ -6,7 +6,7 @@ } #pill-sidebar button { - color: #606060; + color: var(--bs-secondary-color); font-weight: bold; font-size: 12px; } diff --git a/resources/views/inc/header.blade.php b/resources/views/inc/header.blade.php index 62efe0b21..31aab918f 100644 --- a/resources/views/inc/header.blade.php +++ b/resources/views/inc/header.blade.php @@ -1,6 +1,6 @@ @php ($header_type = (isset($type)) ? $type : 'internal') @if($header_type == 'external') - +
@isset($content) {!! $content !!} diff --git a/resources/views/inc/logo.blade.php b/resources/views/inc/logo.blade.php index a0f80c147..0b39e40c2 100644 --- a/resources/views/inc/logo.blade.php +++ b/resources/views/inc/logo.blade.php @@ -1,11 +1,5 @@ @php $logo_id = 'ztl_logo_'; - $logo_bg_color = 'white'; - if(isset($color)) { - if(in_array($color, ['white','black'])) { - $logo_bg_color = $color; - } - } @endphp @toggle('custom_theme_logo') @php @@ -30,4 +24,7 @@ @php ($logo_id = 'ztl_logo_santa-') @endif @endtoggle - \ No newline at end of file + + + + From 5c5785b328d651b7e8445bcc3043e2224696a952 Mon Sep 17 00:00:00 2001 From: core Date: Thu, 30 Oct 2025 08:52:13 -0400 Subject: [PATCH 5/5] feat(darkmode): fix tab headers --- resources/assets/sass/app.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss index 83bb6ed49..53aae4afb 100644 --- a/resources/assets/sass/app.scss +++ b/resources/assets/sass/app.scss @@ -229,3 +229,7 @@ a { [data-bs-theme=light] .logo-dark { display: none; } + +.tab-link { + color: var(--bs-secondary-color); +}