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..53aae4afb 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, @@ -219,3 +222,14 @@ td.hours-success { a { text-decoration: none; } + +[data-bs-theme=dark] .logo-light { + display: none; +} +[data-bs-theme=light] .logo-dark { + display: none; +} + +.tab-link { + color: var(--bs-secondary-color); +} 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..65cdf1ee7 100644 --- a/resources/assets/sass/mix/sidebar.scss +++ b/resources/assets/sass/mix/sidebar.scss @@ -6,12 +6,12 @@ } #pill-sidebar button { - color: #606060; + color: var(--bs-secondary-color); font-weight: bold; font-size: 12px; } #pill-sidebar a.nav-link { - color: black; + color: var(--bs-body-color); font-size: 14px; } 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/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

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/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 + + + + 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.