This commit is contained in:
MarcWieland
2026-07-26 23:57:23 +02:00
commit 8b613ec0bc
6300 changed files with 1257646 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
import React from 'react';
import { ScheduleItem } from '../types';
interface LiveOrdersTableProps {
orders: ScheduleItem[];
}
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>
</tr>
))}
</tbody>
</table>
</div>
);
};
+56
View File
@@ -0,0 +1,56 @@
import React from 'react';
import {
Wrench,
LayoutDashboard,
CalendarDays,
Package,
Users,
Clock,
Database
} from 'lucide-react';
interface SidebarProps {
activeTab: string;
setActiveTab: (tab: string) => void;
}
export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) => {
const menuItems = [
{ id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard },
{ id: 'dispatching', label: 'Dispatching', icon: CalendarDays },
{ id: 'lager', label: 'Lager & Teile', icon: Package },
{ id: 'monteure', label: 'Monteure', icon: Users },
{ id: 'zeiterfassung', label: 'Zeiterfassung', icon: Clock },
{ id: 'supabase', label: 'Supabase Sync', icon: Database },
];
return (
<aside className="sidebar">
<div className="brand">
<Wrench className="brand-icon" size={24} />
<span>Handwerksfreund</span>
</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={() => 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>
);
};
+16
View File
@@ -0,0 +1,16 @@
import React from 'react';
interface StatCardProps {
label: string;
value: string;
isWarning?: boolean;
}
export const StatCard: React.FC<StatCardProps> = ({ label, value, isWarning }) => {
return (
<div className="kpi-card">
<span className="kpi-label">{label}</span>
<span className={`kpi-value ${isWarning ? 'warning' : ''}`}>{value}</span>
</div>
);
};
+37
View File
@@ -0,0 +1,37 @@
import React from 'react';
import { SystemStatus } from '../types';
interface SystemStatusCardProps {
status: SystemStatus | null;
}
export const SystemStatusCard: React.FC<SystemStatusCardProps> = ({ status }) => {
const host = status?.host || 'supabase.marc-wieland.de';
const latency = status?.latencyMs ?? 18;
return (
<div className="content-card">
<h2 className="card-heading">Supabase System-Status</h2>
<p className="status-panel-description">
Datenbank-Verbindung und Realtime-Sync laufen stabil.
</p>
<div className="status-details-box">
<div className="status-item">
<span className="status-key">DB Host:</span>
<span className="status-val">{host}</span>
</div>
<div className="status-item">
<span className="status-key">Latency:</span>
<span className="status-val">{latency}ms</span>
</div>
<div className="status-item">
<span className="status-key">Letzter Sync:</span>
<span className="status-val">Vor wenigen Sekunden</span>
</div>
</div>
</div>
);
};