- added a persistent 12 hour / 24 hour segmented control under the sidebar’s Time preferences.

Updated:
[public/index.php](/Users/tyemeclifford/Documents/GH/weather/public/index.php)
[public/assets/js/app.js](/Users/tyemeclifford/Documents/GH/weather/public/assets/js/app.js)
[public/assets/css/styles.css](/Users/tyemeclifford/Documents/GH/weather/public/assets/css/styles.css)
[README.md](/Users/tyemeclifford/Documents/GH/weather/README.md)
This commit is contained in:
Ty Clifford
2026-06-30 19:56:36 -04:00
parent c69d2b147b
commit 181efee0e6
4 changed files with 61 additions and 3 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ A PHP, SQLite, HTML5, and JavaScript weather dashboard that uses public weather
- RainViewer radar tiles on an interactive Leaflet map.
- Local SQLite API cache with a five minute weather refresh window.
- Hourly and daily archive snapshots with search and JSON detail export.
- Cookie-backed display preferences, map layer toggles, dark/light theme, and import/export.
- Cookie-backed display preferences, map layer toggles, 12/24 hour time format, dark/light theme, and import/export.
- Current-date history facts comparing the projection to the same date last year.
## Run
+25
View File
@@ -302,6 +302,31 @@ body.light .status-line {
accent-color: var(--pink);
}
.segmented {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
min-height: var(--control-h);
overflow: hidden;
border: 1px solid var(--line);
border-radius: var(--radius);
}
.segmented button {
min-height: var(--control-h);
border: 0;
border-radius: 0;
background: transparent;
color: var(--muted);
padding: 0 10px;
}
.segmented button[aria-pressed="true"] {
background: linear-gradient(135deg, rgba(57, 168, 255, 0.28), rgba(255, 90, 165, 0.24));
color: var(--text);
font-weight: 800;
}
.control-actions {
display: grid;
gap: 10px;
+27 -2
View File
@@ -3,6 +3,7 @@
const DEFAULT_PREFS = {
theme: "dark",
timeFormat: "12",
locationQuery: "New York, NY",
sections: {
current: true,
@@ -110,6 +111,17 @@
$("refreshButton").addEventListener("click", () => loadWeather(true));
$("themeButton").addEventListener("click", toggleTheme);
document.querySelectorAll("[data-time-format]").forEach((button) => {
button.addEventListener("click", () => {
state.prefs.timeFormat = button.dataset.timeFormat === "24" ? "24" : "12";
savePrefs();
applyPreferences();
if (state.dashboard) {
renderDashboard();
renderArchives();
}
});
});
$("exportPrefs").addEventListener("click", exportPreferences);
$("importPrefsButton").addEventListener("click", () => $("importPrefsFile").click());
$("importPrefsFile").addEventListener("change", importPreferences);
@@ -635,11 +647,17 @@
function applyPreferences() {
document.body.classList.toggle("light", state.prefs.theme === "light");
$("themeLabel").textContent = state.prefs.theme === "light" ? "Dark" : "Light";
state.prefs.timeFormat = state.prefs.timeFormat === "24" ? "24" : "12";
document.querySelectorAll("[data-pref]").forEach((input) => {
input.checked = Boolean(getPath(state.prefs, input.dataset.pref));
});
document.querySelectorAll("[data-time-format]").forEach((button) => {
const isActive = button.dataset.timeFormat === state.prefs.timeFormat;
button.setAttribute("aria-pressed", isActive ? "true" : "false");
});
Object.entries(state.prefs.sections).forEach(([name, visible]) => {
document.querySelectorAll(`[data-section="${name}"]`).forEach((section) => {
section.classList.toggle("is-hidden", !visible);
@@ -827,7 +845,8 @@
month: "short",
day: "numeric",
hour: "numeric",
minute: "2-digit"
minute: "2-digit",
hour12: useTwelveHourClock()
}).format(date);
}
@@ -841,10 +860,16 @@
}
return new Intl.DateTimeFormat(undefined, {
weekday: "short",
hour: "numeric"
hour: "numeric",
minute: "2-digit",
hour12: useTwelveHourClock()
}).format(date);
}
function useTwelveHourClock() {
return state.prefs.timeFormat !== "24";
}
function formatDay(value) {
if (!value) {
return "--";
+8
View File
@@ -87,6 +87,14 @@ declare(strict_types=1);
<label><input type="checkbox" data-pref="metrics.pollen"> Pollen</label>
</div>
<div class="control-group">
<h3>Time</h3>
<div class="segmented" role="group" aria-label="Time format">
<button type="button" data-time-format="12" aria-pressed="true">12 hour</button>
<button type="button" data-time-format="24" aria-pressed="false">24 hour</button>
</div>
</div>
<div class="control-actions">
<button type="button" id="exportPrefs">
<i data-lucide="download"></i>