Add responsive mobile layout and drawer menu
This commit is contained in:
+25
-1
@@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { Menu, Wrench } from 'lucide-react';
|
||||||
import { Sidebar } from './components/Sidebar';
|
import { Sidebar } from './components/Sidebar';
|
||||||
import { DashboardView } from './views/DashboardView';
|
import { DashboardView } from './views/DashboardView';
|
||||||
import { DispatchingView } from './views/DispatchingView';
|
import { DispatchingView } from './views/DispatchingView';
|
||||||
@@ -9,6 +10,7 @@ import { SupabaseSyncView } from './views/SupabaseSyncView';
|
|||||||
|
|
||||||
export const App: React.FC = () => {
|
export const App: React.FC = () => {
|
||||||
const [activeTab, setActiveTab] = useState('dashboard');
|
const [activeTab, setActiveTab] = useState('dashboard');
|
||||||
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
|
|
||||||
const renderView = () => {
|
const renderView = () => {
|
||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
@@ -31,7 +33,29 @@ export const App: React.FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
<Sidebar activeTab={activeTab} setActiveTab={setActiveTab} />
|
{/* Mobile Header Bar */}
|
||||||
|
<header className="mobile-top-bar">
|
||||||
|
<button
|
||||||
|
className="mobile-hamburger-btn"
|
||||||
|
onClick={() => setMobileMenuOpen(true)}
|
||||||
|
aria-label="Menü öffnen"
|
||||||
|
>
|
||||||
|
<Menu size={24} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="mobile-brand">
|
||||||
|
<Wrench size={20} color="#38bdf8" />
|
||||||
|
<span>Handwerksfreund</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<Sidebar
|
||||||
|
activeTab={activeTab}
|
||||||
|
setActiveTab={setActiveTab}
|
||||||
|
isOpen={mobileMenuOpen}
|
||||||
|
onClose={() => setMobileMenuOpen(false)}
|
||||||
|
/>
|
||||||
|
|
||||||
<main className="main-content">
|
<main className="main-content">
|
||||||
{renderView()}
|
{renderView()}
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export const LiveOrdersTable: React.FC<LiveOrdersTableProps> = ({ orders }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="content-card">
|
<div className="content-card">
|
||||||
<h2 className="card-heading">Heutige Live-Aufträge (Dispatching)</h2>
|
<h2 className="card-heading">Heutige Live-Aufträge (Dispatching)</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
<table className="orders-table">
|
<table className="orders-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -38,5 +39,6 @@ export const LiveOrdersTable: React.FC<LiveOrdersTableProps> = ({ orders }) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,15 +6,23 @@ import {
|
|||||||
Package,
|
Package,
|
||||||
Users,
|
Users,
|
||||||
Clock,
|
Clock,
|
||||||
Database
|
Database,
|
||||||
|
X
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
activeTab: string;
|
activeTab: string;
|
||||||
setActiveTab: (tab: string) => void;
|
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 = [
|
const menuItems = [
|
||||||
{ id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard },
|
{ id: 'dashboard', label: 'Dashboard', icon: LayoutDashboard },
|
||||||
{ id: 'dispatching', label: 'Dispatching', icon: CalendarDays },
|
{ id: 'dispatching', label: 'Dispatching', icon: CalendarDays },
|
||||||
@@ -24,13 +32,38 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
|
|||||||
{ id: 'supabase', label: 'Supabase Sync', icon: Database },
|
{ id: 'supabase', label: 'Supabase Sync', icon: Database },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const handleSelect = (tabId: string) => {
|
||||||
|
setActiveTab(tabId);
|
||||||
|
onClose(); // Close mobile sidebar on selection
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className="sidebar">
|
<>
|
||||||
|
{/* Mobile Backdrop */}
|
||||||
|
{isOpen && (
|
||||||
|
<div
|
||||||
|
className="sidebar-backdrop"
|
||||||
|
onClick={onClose}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<aside className={`sidebar ${isOpen ? 'open' : ''}`}>
|
||||||
<div className="brand">
|
<div className="brand">
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||||
<Wrench className="brand-icon" size={24} />
|
<Wrench className="brand-icon" size={24} />
|
||||||
<span>Handwerksfreund</span>
|
<span>Handwerksfreund</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="mobile-close-btn"
|
||||||
|
onClick={onClose}
|
||||||
|
aria-label="Menü schließen"
|
||||||
|
>
|
||||||
|
<X size={24} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<ul className="nav-list">
|
<ul className="nav-list">
|
||||||
{menuItems.map((item) => {
|
{menuItems.map((item) => {
|
||||||
@@ -40,8 +73,7 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
|
|||||||
<li key={item.id}>
|
<li key={item.id}>
|
||||||
<button
|
<button
|
||||||
className={`nav-item ${isActive ? 'active' : ''}`}
|
className={`nav-item ${isActive ? 'active' : ''}`}
|
||||||
onClick={() => setActiveTab(item.id)}
|
onClick={() => handleSelect(item.id)}
|
||||||
style={{ width: '100%', background: 'none', border: 'none', textAlign: 'left' }}
|
|
||||||
>
|
>
|
||||||
<Icon className="icon" size={20} />
|
<Icon className="icon" size={20} />
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
@@ -52,5 +84,6 @@ export const Sidebar: React.FC<SidebarProps> = ({ activeTab, setActiveTab }) =>
|
|||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+171
-2
@@ -31,12 +31,62 @@ body {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-container {
|
.app-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile Top Navigation Bar (Hidden on Desktop) */
|
||||||
|
.mobile-top-bar {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: var(--bg-sidebar);
|
||||||
|
color: #ffffff;
|
||||||
|
padding: 14px 20px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 40;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-hamburger-btn {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #ffffff;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 6px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-hamburger-btn:hover {
|
||||||
|
background-color: var(--bg-sidebar-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-brand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar Backdrop for Mobile */
|
||||||
|
.sidebar-backdrop {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background-color: rgba(15, 23, 42, 0.6);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
z-index: 49;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sidebar Styles */
|
/* Sidebar Styles */
|
||||||
@@ -48,12 +98,14 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 24px 16px;
|
padding: 24px 16px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
z-index: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand {
|
.brand {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
justify-content: space-between;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -64,6 +116,21 @@ body {
|
|||||||
color: #38bdf8;
|
color: #38bdf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mobile-close-btn {
|
||||||
|
display: none;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #94a3b8;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-close-btn:hover {
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: var(--bg-sidebar-hover);
|
||||||
|
}
|
||||||
|
|
||||||
.nav-list {
|
.nav-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -83,6 +150,10 @@ body {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item:hover {
|
.nav-item:hover {
|
||||||
@@ -109,9 +180,10 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 32px;
|
gap: 32px;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Top Header */
|
/* Top Header Bar */
|
||||||
.header-bar {
|
.header-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -121,6 +193,8 @@ body {
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
@@ -137,6 +211,10 @@ body {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #10b981;
|
color: #10b981;
|
||||||
|
background-color: #f0fdf4;
|
||||||
|
padding: 6px 14px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 1px solid #bbf7d0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-dot {
|
.status-dot {
|
||||||
@@ -197,6 +275,7 @@ body {
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 28px;
|
padding: 28px;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-heading {
|
.card-heading {
|
||||||
@@ -206,11 +285,19 @@ body {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Table Container for Mobile Horizontal Scroll */
|
||||||
|
.table-responsive {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
/* Table Styles */
|
/* Table Styles */
|
||||||
.orders-table {
|
.orders-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
border-spacing: 0 12px;
|
border-spacing: 0 12px;
|
||||||
|
min-width: 500px; /* Ensures table readability on small screens */
|
||||||
}
|
}
|
||||||
|
|
||||||
.orders-table th {
|
.orders-table th {
|
||||||
@@ -219,6 +306,7 @@ body {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
padding: 0 16px 8px 16px;
|
padding: 0 16px 8px 16px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.orders-table td {
|
.orders-table td {
|
||||||
@@ -228,6 +316,7 @@ body {
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
border-top: 1px solid #f1f5f9;
|
border-top: 1px solid #f1f5f9;
|
||||||
border-bottom: 1px solid #f1f5f9;
|
border-bottom: 1px solid #f1f5f9;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.orders-table tr td:first-child {
|
.orders-table tr td:first-child {
|
||||||
@@ -278,6 +367,7 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-item {
|
.status-item {
|
||||||
@@ -298,11 +388,90 @@ body {
|
|||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Responsive Breakpoints
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Tablet & Mobile Layout (< 1024px) */
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.kpi-grid {
|
.kpi-grid {
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-grid {
|
.dashboard-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mobile Phone Layout (< 768px) */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.app-container {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-top-bar {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-backdrop {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
height: 100vh;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
box-shadow: 4px 0 24px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-close-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
padding: 20px 16px;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-bar {
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 1.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-card {
|
||||||
|
padding: 16px 18px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kpi-value {
|
||||||
|
font-size: 1.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-card {
|
||||||
|
padding: 20px 16px;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-heading {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CalendarDays, Plus, UserCheck } from 'lucide-react';
|
import { Plus, UserCheck } from 'lucide-react';
|
||||||
|
|
||||||
export const DispatchingView: React.FC = () => {
|
export const DispatchingView: React.FC = () => {
|
||||||
const scheduleData = [
|
const scheduleData = [
|
||||||
@@ -30,11 +30,12 @@ export const DispatchingView: React.FC = () => {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section className="content-card">
|
<section className="content-card">
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px', flexWrap: 'wrap', gap: '10px' }}>
|
||||||
<h2 className="card-heading" style={{ margin: 0 }}>Tagesdisposition (Heute)</h2>
|
<h2 className="card-heading" style={{ margin: 0 }}>Tagesdisposition (Heute)</h2>
|
||||||
<span style={{ fontSize: '0.9rem', color: '#64748b', fontWeight: 600 }}>10 Monteure im System</span>
|
<span style={{ fontSize: '0.9rem', color: '#64748b', fontWeight: 600 }}>10 Monteure im System</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="table-responsive">
|
||||||
<table className="orders-table">
|
<table className="orders-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -66,6 +67,7 @@ export const DispatchingView: React.FC = () => {
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Package, AlertTriangle } from 'lucide-react';
|
import { AlertTriangle } from 'lucide-react';
|
||||||
|
|
||||||
export const InventoryView: React.FC = () => {
|
export const InventoryView: React.FC = () => {
|
||||||
const parts = [
|
const parts = [
|
||||||
@@ -21,6 +21,7 @@ export const InventoryView: React.FC = () => {
|
|||||||
|
|
||||||
<section className="content-card">
|
<section className="content-card">
|
||||||
<h2 className="card-heading">Ersatzteilbestand & Bestellwarnungen</h2>
|
<h2 className="card-heading">Ersatzteilbestand & Bestellwarnungen</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
<table className="orders-table">
|
<table className="orders-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -56,6 +57,7 @@ export const InventoryView: React.FC = () => {
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Clock, CheckCircle } from 'lucide-react';
|
|
||||||
|
|
||||||
export const TimeTrackingView: React.FC = () => {
|
export const TimeTrackingView: React.FC = () => {
|
||||||
const timeEntries = [
|
const timeEntries = [
|
||||||
@@ -18,6 +17,7 @@ export const TimeTrackingView: React.FC = () => {
|
|||||||
|
|
||||||
<section className="content-card">
|
<section className="content-card">
|
||||||
<h2 className="card-heading">Erfasste Arbeitszeiten der Monteure</h2>
|
<h2 className="card-heading">Erfasste Arbeitszeiten der Monteure</h2>
|
||||||
|
<div className="table-responsive">
|
||||||
<table className="orders-table">
|
<table className="orders-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -48,6 +48,7 @@ export const TimeTrackingView: React.FC = () => {
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user