import { Link } from "react-router-dom";
import {
formatDate,
formatDatetime,
formatTime,
calculateWorkMinutes,
formatMinutes,
getLeaveTypeName,
getLeaveTypeBadgeClass,
} from "../utils/attendanceHelpers";
import type { AttendanceRecord as HookAttendanceRecord } from "../hooks/useAttendanceAdmin";
interface AttendanceRecord extends HookAttendanceRecord {
arrival_lat?: number | string | null;
arrival_lng?: number | string | null;
departure_lat?: number | string | null;
departure_lng?: number | string | null;
}
interface AttendanceShiftTableProps {
records: AttendanceRecord[];
onEdit: (record: AttendanceRecord) => void;
onDelete: (record: AttendanceRecord) => void;
}
function formatBreak(record: AttendanceRecord): string {
if (record.break_start && record.break_end) {
return `${formatTime(record.break_start)} - ${formatTime(record.break_end)}`;
}
if (record.break_start) {
return `${formatTime(record.break_start)} - ?`;
}
return "—";
}
function renderProjectCell(record: AttendanceRecord): React.ReactNode {
if (record.project_logs && record.project_logs.length > 0) {
return (
{record.project_logs.map((log, i) => {
let h: number,
m: number,
isActive = false;
let durationValid = true;
if (log.hours !== null && log.hours !== undefined) {
h = parseInt(String(log.hours)) || 0;
m = parseInt(String(log.minutes)) || 0;
} else {
isActive = !log.ended_at;
const end = log.ended_at ? new Date(log.ended_at) : new Date();
const start = log.started_at ? new Date(log.started_at) : null;
if (start && !isNaN(start.getTime()) && !isNaN(end.getTime())) {
const mins = Math.max(
0,
Math.floor((end.getTime() - start.getTime()) / 60000),
);
h = Math.floor(mins / 60);
m = mins % 60;
} else {
durationValid = false;
h = 0;
m = 0;
}
}
return (
{log.project_name || `#${log.project_id}`}{" "}
{durationValid
? `(${h}:${String(m).padStart(2, "0")}h${isActive ? " ▸" : ""})`
: "—"}
);
})}
);
}
if (record.project_name) {
return (
{record.project_name}
);
}
return "—";
}
export default function AttendanceShiftTable({
records,
onEdit,
onDelete,
}: AttendanceShiftTableProps) {
if (records.length === 0) {
return (
Za tento měsíc nejsou žádné záznamy.
);
}
return (
| Datum |
Zaměstnanec |
Typ |
Příchod |
Pauza |
Odchod |
Hodiny |
Projekt |
GPS |
Poznámka |
Akce |
{records.map((record) => {
const leaveType = record.leave_type || "work";
const isLeave = leaveType !== "work";
const workMinutes = isLeave
? (record.leave_hours != null ? Number(record.leave_hours) : 8) *
60
: calculateWorkMinutes({
...record,
notes: record.notes ?? undefined,
});
const hasLocation =
(record.arrival_lat && record.arrival_lng) ||
(record.departure_lat && record.departure_lng);
return (
| {formatDate(record.shift_date)} |
{record.user_name} |
{getLeaveTypeName(leaveType)}
|
{isLeave ? "—" : formatDatetime(record.arrival_time)}
|
{isLeave ? "—" : formatBreak(record)}
|
{isLeave ? "—" : formatDatetime(record.departure_time)}
|
{workMinutes > 0 ? `${formatMinutes(workMinutes)} h` : "—"}
|
{renderProjectCell(record)} |
{hasLocation ? (
{"📍"}
) : (
"—"
)}
|
{record.notes || ""}
|
|
);
})}
);
}