feat: Complete mobile UI overhaul

Major mobile improvements:
- Sticky header with simplified controls
- Slide-out filter sidebar with overlay
- Bottom navigation bar (Home, Filter, New, Settings)
- Stacked toolbar layout
- Full-width modals sliding up from bottom
- Admin dropdown as bottom sheet
- Horizontal scrolling table with touch support
- 44px minimum touch targets throughout
- iOS zoom prevention on inputs
- Landscape mode optimizations

CSS changes:
- Rewrote all mobile styles with correct class names
- Added mobile bottom nav styles
- Fixed toolbar-left, toolbar-center, toolbar-right
- Fixed user-header-left, user-header-right

JS changes:
- initMobileSidebar now creates bottom nav
- Removed style.display = 'none' (CSS handles visibility)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 10:48:32 -05:00
parent efa1b81a62
commit d073add6a6
5 changed files with 514 additions and 230 deletions

View File

@@ -54,13 +54,11 @@ function closeMobileSidebar() {
document.body.style.overflow = '';
}
// Initialize mobile sidebar elements
// Initialize mobile elements
function initMobileSidebar() {
const sidebar = document.getElementById('dashboardSidebar');
const dashboardMain = document.querySelector('.dashboard-main');
if (!sidebar || !dashboardMain) return;
// Create overlay if it doesn't exist
if (!document.getElementById('mobileSidebarOverlay')) {
const overlay = document.createElement('div');
@@ -70,26 +68,50 @@ function initMobileSidebar() {
document.body.appendChild(overlay);
}
// Create mobile filter toggle button if it doesn't exist
if (!document.getElementById('mobileFilterToggle')) {
// Create mobile filter toggle button
if (dashboardMain && !document.getElementById('mobileFilterToggle')) {
const toggleBtn = document.createElement('button');
toggleBtn.id = 'mobileFilterToggle';
toggleBtn.className = 'mobile-filter-toggle';
toggleBtn.innerHTML = '<span>☰</span> Filters & Options';
toggleBtn.innerHTML = ' Filters & Search Options';
toggleBtn.onclick = openMobileSidebar;
toggleBtn.style.display = 'none'; // Hidden by default, shown via CSS media query
dashboardMain.insertBefore(toggleBtn, dashboardMain.firstChild);
}
// Create close button inside sidebar if it doesn't exist
if (!sidebar.querySelector('.mobile-sidebar-close')) {
// Create close button inside sidebar
if (sidebar && !sidebar.querySelector('.mobile-sidebar-close')) {
const closeBtn = document.createElement('button');
closeBtn.className = 'mobile-sidebar-close';
closeBtn.innerHTML = '×';
closeBtn.onclick = closeMobileSidebar;
closeBtn.style.display = 'none'; // Hidden by default, shown via CSS media query
sidebar.insertBefore(closeBtn, sidebar.firstChild);
}
// Create mobile bottom navigation
if (!document.getElementById('mobileBottomNav')) {
const nav = document.createElement('nav');
nav.id = 'mobileBottomNav';
nav.className = 'mobile-bottom-nav';
nav.innerHTML = `
<a href="/">
<span class="nav-icon">🏠</span>
<span>Home</span>
</a>
<button type="button" onclick="openMobileSidebar()">
<span class="nav-icon">🔍</span>
<span>Filter</span>
</button>
<a href="/ticket/create">
<span class="nav-icon"></span>
<span>New</span>
</a>
<button type="button" onclick="if(typeof openSettingsModal==='function')openSettingsModal()">
<span class="nav-icon">⚙️</span>
<span>Settings</span>
</button>
`;
document.body.appendChild(nav);
}
}
// Restore sidebar state on page load