Add responsive mobile layout and drawer menu

This commit is contained in:
MarcWieland
2026-07-27 00:11:10 +02:00
parent 4588468ed6
commit a405bfb91f
7 changed files with 389 additions and 156 deletions
+29 -27
View File
@@ -9,34 +9,36 @@ export const LiveOrdersTable: React.FC<LiveOrdersTableProps> = ({ orders }) => {
return (
<div className="content-card">
<h2 className="card-heading">Heutige Live-Aufträge (Dispatching)</h2>
<table className="orders-table">
<thead>
<tr>
<th>Kunde</th>
<th>Monteur</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{orders.map((order) => (
<tr key={order.id}>
<td style={{ fontWeight: 600, color: '#0f172a' }}>{order.customerName}</td>
<td style={{ color: '#334155' }}>{order.technicianName}</td>
<td>
<span
className={`badge ${
order.status === 'In Bearbeitung'
? 'badge-in-progress'
: 'badge-scheduled'
}`}
>
{order.status === 'Geplant' ? `Geplant (${order.startTime})` : order.status}
</span>
</td>
<div className="table-responsive">
<table className="orders-table">
<thead>
<tr>
<th>Kunde</th>
<th>Monteur</th>
<th>Status</th>
</tr>
))}
</tbody>
</table>
</thead>
<tbody>
{orders.map((order) => (
<tr key={order.id}>
<td style={{ fontWeight: 600, color: '#0f172a' }}>{order.customerName}</td>
<td style={{ color: '#334155' }}>{order.technicianName}</td>
<td>
<span
className={`badge ${
order.status === 'In Bearbeitung'
? 'badge-in-progress'
: 'badge-scheduled'
}`}
>
{order.status === 'Geplant' ? `Geplant (${order.startTime})` : order.status}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
+62 -29
View File
@@ -6,15 +6,23 @@ import {
Package,
Users,
Clock,
Database
Database,
X
} from 'lucide-react';
interface SidebarProps {
activeTab: string;
setActiveTab: (tab: string) => void;
isOpen: boolean;
onClose: () => void;
}
export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) => {
export const Sidebar: React.FC<SidebarProps> = ({
activeTab,
setActiveTab,
isOpen,
onClose
}) => {
const menuItems = [
{ id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard },
{ id: 'dispatching', label: 'Dispatching', icon: CalendarDays },
@@ -24,33 +32,58 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
{ id: 'supabase', label: 'Supabase Sync', icon: Database },
];
return (
<aside className="sidebar">
<div className="brand">
<Wrench className="brand-icon" size={24} />
<span>Handwerksfreund</span>
</div>
const handleSelect = (tabId: string) => {
setActiveTab(tabId);
onClose(); // Close mobile sidebar on selection
};
<nav>
<ul className="nav-list">
{menuItems.map((item) => {
const Icon = item.icon;
const isActive = activeTab === item.id;
return (
<li key={item.id}>
<button
className={`nav-item ${isActive ? 'active' : ''}`}
onClick={() => setActiveTab(item.id)}
style={{ width: '100%', background: 'none', border: 'none', textAlign: 'left' }}
>
<Icon className="icon" size={20} />
<span>{item.label}</span>
</button>
</li>
);
})}
</ul>
</nav>
</aside>
return (
<>
{/* Mobile Backdrop */}
{isOpen && (
<div
className="sidebar-backdrop"
onClick={onClose}
aria-hidden="true"
/>
)}
<aside className={`sidebar ${isOpen ? 'open' : ''}`}>
<div className="brand">
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
<Wrench className="brand-icon" size={24} />
<span>Handwerksfreund</span>
</div>
<button
className="mobile-close-btn"
onClick={onClose}
aria-label="Menü schließen"
>
<X size={24} />
</button>
</div>
<nav>
<ul className="nav-list">
{menuItems.map((item) => {
const Icon = item.icon;
const isActive = activeTab === item.id;
return (
<li key={item.id}>
<button
className={`nav-item ${isActive ? 'active' : ''}`}
onClick={() => handleSelect(item.id)}
>
<Icon className="icon" size={20} />
<span>{item.label}</span>
</button>
</li>
);
})}
</ul>
</nav>
</aside>
</>
);
};