feat: Add timezone setting in preferences + clickable logo

- Add timezone dropdown to settings modal with common timezones
- Save/load timezone preference per user
- Apply user's timezone preference after authentication
- Override system default with user preference if set
- Make dashboard logo clickable (returns to default filters)
- Show current timezone in settings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 21:54:04 -05:00
parent 8b4ef2a7f5
commit c32e9c871b
3 changed files with 47 additions and 1 deletions

View File

@@ -45,6 +45,13 @@ function applyPreferences() {
document.body.classList.add(`table-${density}`); document.body.classList.add(`table-${density}`);
} }
// Timezone - use server default if not set
const timezone = userPreferences.timezone || window.APP_TIMEZONE || 'America/New_York';
const timezoneSelect = document.getElementById('userTimezone');
if (timezoneSelect) {
timezoneSelect.value = timezone;
}
// Notifications // Notifications
const notificationsCheckbox = document.getElementById('notificationsEnabled'); const notificationsCheckbox = document.getElementById('notificationsEnabled');
if (notificationsCheckbox) { if (notificationsCheckbox) {
@@ -71,6 +78,7 @@ async function saveSettings() {
default_status_filters: Array.from(document.querySelectorAll('[name="defaultFilters"]:checked')) default_status_filters: Array.from(document.querySelectorAll('[name="defaultFilters"]:checked'))
.map(cb => cb.value).join(','), .map(cb => cb.value).join(','),
table_density: document.getElementById('tableDensity').value, table_density: document.getElementById('tableDensity').value,
timezone: document.getElementById('userTimezone').value,
notifications_enabled: document.getElementById('notificationsEnabled').checked ? '1' : '0', notifications_enabled: document.getElementById('notificationsEnabled').checked ? '1' : '0',
sound_effects: document.getElementById('soundEffects').checked ? '1' : '0', sound_effects: document.getElementById('soundEffects').checked ? '1' : '0',
toast_duration: document.getElementById('toastDuration').value toast_duration: document.getElementById('toastDuration').value

View File

@@ -36,6 +36,21 @@ if (!str_starts_with($requestPath, '/api/')) {
// Initialize audit log model // Initialize audit log model
$GLOBALS['auditLog'] = new AuditLogModel($conn); $GLOBALS['auditLog'] = new AuditLogModel($conn);
// Check if user has a timezone preference and apply it
if ($currentUser && isset($currentUser['user_id'])) {
require_once 'models/UserPreferencesModel.php';
$prefsModel = new UserPreferencesModel($conn);
$userTimezone = $prefsModel->getPreference($currentUser['user_id'], 'timezone', null);
if ($userTimezone) {
// Override system timezone with user preference
date_default_timezone_set($userTimezone);
$GLOBALS['config']['TIMEZONE'] = $userTimezone;
$now = new DateTime('now', new DateTimeZone($userTimezone));
$GLOBALS['config']['TIMEZONE_OFFSET'] = $now->getOffset() / 60;
$GLOBALS['config']['TIMEZONE_ABBREV'] = $now->format('T');
}
}
} }
// Simple router // Simple router

View File

@@ -77,7 +77,7 @@
</script> </script>
<div class="user-header"> <div class="user-header">
<div class="user-header-left"> <div class="user-header-left">
<span class="app-title">🎫 Tinker Tickets</span> <a href="/" class="app-title" style="text-decoration: none; color: inherit;">🎫 Tinker Tickets</a>
</div> </div>
<div class="user-header-right"> <div class="user-header-right">
<?php if (isset($GLOBALS['currentUser'])): ?> <?php if (isset($GLOBALS['currentUser'])): ?>
@@ -484,6 +484,29 @@
<option value="comfortable">Comfortable</option> <option value="comfortable">Comfortable</option>
</select> </select>
</div> </div>
<div class="setting-row">
<label for="userTimezone">Timezone:</label>
<select id="userTimezone" class="setting-select">
<option value="America/New_York">Eastern (EST/EDT)</option>
<option value="America/Chicago">Central (CST/CDT)</option>
<option value="America/Denver">Mountain (MST/MDT)</option>
<option value="America/Los_Angeles">Pacific (PST/PDT)</option>
<option value="America/Anchorage">Alaska (AKST/AKDT)</option>
<option value="Pacific/Honolulu">Hawaii (HST)</option>
<option value="UTC">UTC</option>
<option value="Europe/London">London (GMT/BST)</option>
<option value="Europe/Paris">Paris (CET/CEST)</option>
<option value="Europe/Berlin">Berlin (CET/CEST)</option>
<option value="Asia/Tokyo">Tokyo (JST)</option>
<option value="Asia/Shanghai">Shanghai (CST)</option>
<option value="Asia/Kolkata">India (IST)</option>
<option value="Australia/Sydney">Sydney (AEST/AEDT)</option>
</select>
<small style="color: var(--text-muted); margin-top: 0.25rem; display: block;">
Current: <?php echo $GLOBALS['config']['TIMEZONE_ABBREV']; ?> (<?php echo $GLOBALS['config']['TIMEZONE']; ?>)
</small>
</div>
</div> </div>
<!-- Notifications --> <!-- Notifications -->