Files
eatme/frontend/src/pages/EmployeeApp.tsx
Michal Pemcak fffcb73ea4 Initial commit: EatMe attendance tracker
Google-SSO PWA for bistro employee clock-in/out, admin employee
management, and stats with CSV export. Express + SQLite backend,
React + Zustand frontend in the light-mono-tui design language.
Multi-stage Dockerfile, compose.yaml for image-based deploys, nginx
reverse-proxy template, and an OKF documentation bundle in docs/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-16 18:41:11 +02:00

62 lines
2.0 KiB
TypeScript

import { useEffect } from 'react';
import useAttendanceStore from '../store/attendanceStore';
import { ClockControls } from '../components/ClockControls';
import { StatusBadge } from '../components/StatusBadge';
import { StatsSummary } from '../components/StatsSummary';
import { SessionList } from '../components/SessionList';
export function EmployeeApp() {
const status = useAttendanceStore((s) => s.status);
const busy = useAttendanceStore((s) => s.busy);
const error = useAttendanceStore((s) => s.error);
const live = useAttendanceStore((s) => s.live);
const load = useAttendanceStore((s) => s.load);
const recordEvent = useAttendanceStore((s) => s.recordEvent);
const startPolling = useAttendanceStore((s) => s.startPolling);
const stopPolling = useAttendanceStore((s) => s.stopPolling);
useEffect(() => {
load();
}, [load]);
useEffect(() => {
if (status === null || status === 'clocked_out') {
stopPolling();
return;
}
startPolling();
return () => stopPolling();
}, [status, startPolling, stopPolling]);
if (!status || !live) {
return <div className="empty-line">&gt; načítám</div>;
}
return (
<>
<div className="panel">
<p className="panel-title">Docházka</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', marginBottom: '1rem' }}>
<StatusBadge status={status} />
</div>
<ClockControls status={status} busy={busy} onAction={recordEvent} />
{error && <div className="login-error">{error}</div>}
</div>
<div className="panel">
<p className="panel-title">Statistiky &middot; tento měsíc</p>
<StatsSummary
totalWorkedMs={live.totalWorkedMs}
totalBreakMs={live.totalBreakMs}
shiftCount={live.shiftCount}
/>
</div>
<div className="panel">
<p className="panel-title">Směny</p>
<SessionList sessions={live.sessions} />
</div>
</>
);
}