style: run prettier on entire codebase
This commit is contained in:
@@ -1,93 +1,123 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
formatDate, formatDatetime, formatTime,
|
||||
calculateWorkMinutes, formatMinutes,
|
||||
getLeaveTypeName, getLeaveTypeBadgeClass
|
||||
} from '../utils/attendanceHelpers'
|
||||
formatDate,
|
||||
formatDatetime,
|
||||
formatTime,
|
||||
calculateWorkMinutes,
|
||||
formatMinutes,
|
||||
getLeaveTypeName,
|
||||
getLeaveTypeBadgeClass,
|
||||
} from "../utils/attendanceHelpers";
|
||||
|
||||
interface ProjectLog {
|
||||
id?: number
|
||||
project_id?: number
|
||||
project_name?: string
|
||||
started_at?: string
|
||||
ended_at?: string | null
|
||||
hours?: string | number | null
|
||||
minutes?: string | number | null
|
||||
id?: number;
|
||||
project_id?: number;
|
||||
project_name?: string;
|
||||
started_at?: string;
|
||||
ended_at?: string | null;
|
||||
hours?: string | number | null;
|
||||
minutes?: string | number | null;
|
||||
}
|
||||
|
||||
interface AttendanceRecord {
|
||||
id: number
|
||||
shift_date: string
|
||||
user_name: string
|
||||
leave_type?: string
|
||||
leave_hours?: number
|
||||
arrival_time?: string | null
|
||||
departure_time?: string | null
|
||||
break_start?: string | null
|
||||
break_end?: string | null
|
||||
arrival_lat?: number | string | null
|
||||
arrival_lng?: number | string | null
|
||||
departure_lat?: number | string | null
|
||||
departure_lng?: number | string | null
|
||||
project_name?: string
|
||||
project_logs?: ProjectLog[]
|
||||
notes?: string | null
|
||||
id: number;
|
||||
shift_date: string;
|
||||
user_name: string;
|
||||
leave_type?: string;
|
||||
leave_hours?: number;
|
||||
arrival_time?: string | null;
|
||||
departure_time?: string | null;
|
||||
break_start?: string | null;
|
||||
break_end?: string | null;
|
||||
arrival_lat?: number | string | null;
|
||||
arrival_lng?: number | string | null;
|
||||
departure_lat?: number | string | null;
|
||||
departure_lng?: number | string | null;
|
||||
project_name?: string;
|
||||
project_logs?: ProjectLog[];
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
interface AttendanceShiftTableProps {
|
||||
records: AttendanceRecord[]
|
||||
onEdit: (record: AttendanceRecord) => void
|
||||
onDelete: (record: AttendanceRecord) => void
|
||||
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)}`
|
||||
return `${formatTime(record.break_start)} - ${formatTime(record.break_end)}`;
|
||||
}
|
||||
if (record.break_start) {
|
||||
return `${formatTime(record.break_start)} - ?`
|
||||
return `${formatTime(record.break_start)} - ?`;
|
||||
}
|
||||
return '\u2014'
|
||||
return "\u2014";
|
||||
}
|
||||
|
||||
function renderProjectCell(record: AttendanceRecord): React.ReactNode {
|
||||
if (record.project_logs && record.project_logs.length > 0) {
|
||||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.125rem' }}>
|
||||
<div
|
||||
style={{ display: "flex", flexDirection: "column", gap: "0.125rem" }}
|
||||
>
|
||||
{record.project_logs.map((log, i) => {
|
||||
let h: number, m: number, isActive = false
|
||||
let h: number,
|
||||
m: number,
|
||||
isActive = false;
|
||||
if (log.hours !== null && log.hours !== undefined) {
|
||||
h = parseInt(String(log.hours)) || 0
|
||||
m = parseInt(String(log.minutes)) || 0
|
||||
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 mins = Math.floor((end.getTime() - new Date(log.started_at!).getTime()) / 60000)
|
||||
h = Math.floor(mins / 60)
|
||||
m = mins % 60
|
||||
isActive = !log.ended_at;
|
||||
const end = log.ended_at ? new Date(log.ended_at) : new Date();
|
||||
const mins = Math.floor(
|
||||
(end.getTime() - new Date(log.started_at!).getTime()) / 60000,
|
||||
);
|
||||
h = Math.floor(mins / 60);
|
||||
m = mins % 60;
|
||||
}
|
||||
return (
|
||||
<span key={log.id || i} className="admin-badge" style={{ fontSize: '0.7rem', display: 'inline-block', background: isActive ? 'var(--accent-light)' : undefined }}>
|
||||
{log.project_name || `#${log.project_id}`} ({h}:{String(m).padStart(2, '0')}h{isActive ? ' \u25B8' : ''})
|
||||
<span
|
||||
key={log.id || i}
|
||||
className="admin-badge"
|
||||
style={{
|
||||
fontSize: "0.7rem",
|
||||
display: "inline-block",
|
||||
background: isActive ? "var(--accent-light)" : undefined,
|
||||
}}
|
||||
>
|
||||
{log.project_name || `#${log.project_id}`} ({h}:
|
||||
{String(m).padStart(2, "0")}h{isActive ? " \u25B8" : ""})
|
||||
</span>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
if (record.project_name) {
|
||||
return <span className="admin-badge admin-badge-wrap" style={{ fontSize: '0.75rem' }}>{record.project_name}</span>
|
||||
return (
|
||||
<span
|
||||
className="admin-badge admin-badge-wrap"
|
||||
style={{ fontSize: "0.75rem" }}
|
||||
>
|
||||
{record.project_name}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return '\u2014'
|
||||
return "\u2014";
|
||||
}
|
||||
|
||||
export default function AttendanceShiftTable({ records, onEdit, onDelete }: AttendanceShiftTableProps) {
|
||||
export default function AttendanceShiftTable({
|
||||
records,
|
||||
onEdit,
|
||||
onDelete,
|
||||
}: AttendanceShiftTableProps) {
|
||||
if (records.length === 0) {
|
||||
return (
|
||||
<div className="admin-empty-state">
|
||||
<p>Za tento měsíc nejsou žádné záznamy.</p>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -110,40 +140,65 @@ export default function AttendanceShiftTable({ records, onEdit, onDelete }: Atte
|
||||
</thead>
|
||||
<tbody>
|
||||
{records.map((record) => {
|
||||
const leaveType = record.leave_type || 'work'
|
||||
const isLeave = leaveType !== 'work'
|
||||
const leaveType = record.leave_type || "work";
|
||||
const isLeave = leaveType !== "work";
|
||||
const workMinutes = isLeave
|
||||
? (Number(record.leave_hours) || 8) * 60
|
||||
: calculateWorkMinutes(record)
|
||||
const hasLocation = (record.arrival_lat && record.arrival_lng) || (record.departure_lat && record.departure_lng)
|
||||
: calculateWorkMinutes(record);
|
||||
const hasLocation =
|
||||
(record.arrival_lat && record.arrival_lng) ||
|
||||
(record.departure_lat && record.departure_lng);
|
||||
|
||||
return (
|
||||
<tr key={record.id}>
|
||||
<td className="admin-mono">{formatDate(record.shift_date)}</td>
|
||||
<td>{record.user_name}</td>
|
||||
<td>
|
||||
<span className={`attendance-leave-badge ${getLeaveTypeBadgeClass(leaveType)}`}>
|
||||
<span
|
||||
className={`attendance-leave-badge ${getLeaveTypeBadgeClass(leaveType)}`}
|
||||
>
|
||||
{getLeaveTypeName(leaveType)}
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">{isLeave ? '\u2014' : formatDatetime(record.arrival_time)}</td>
|
||||
<td className="admin-mono">
|
||||
{isLeave ? '\u2014' : formatBreak(record)}
|
||||
{isLeave ? "\u2014" : formatDatetime(record.arrival_time)}
|
||||
</td>
|
||||
<td className="admin-mono">{isLeave ? '\u2014' : formatDatetime(record.departure_time)}</td>
|
||||
<td className="admin-mono">{workMinutes > 0 ? `${formatMinutes(workMinutes)} h` : '\u2014'}</td>
|
||||
<td>
|
||||
{renderProjectCell(record)}
|
||||
<td className="admin-mono">
|
||||
{isLeave ? "\u2014" : formatBreak(record)}
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{isLeave ? "\u2014" : formatDatetime(record.departure_time)}
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{workMinutes > 0
|
||||
? `${formatMinutes(workMinutes)} h`
|
||||
: "\u2014"}
|
||||
</td>
|
||||
<td>{renderProjectCell(record)}</td>
|
||||
<td>
|
||||
{hasLocation ? (
|
||||
<Link to={`/attendance/location/${record.id}`} className="attendance-gps-link" title="Zobrazit polohu" aria-label="Zobrazit polohu">
|
||||
{'\uD83D\uDCCD'}
|
||||
<Link
|
||||
to={`/attendance/location/${record.id}`}
|
||||
className="attendance-gps-link"
|
||||
title="Zobrazit polohu"
|
||||
aria-label="Zobrazit polohu"
|
||||
>
|
||||
{"\uD83D\uDCCD"}
|
||||
</Link>
|
||||
) : '\u2014'}
|
||||
) : (
|
||||
"\u2014"
|
||||
)}
|
||||
</td>
|
||||
<td style={{ maxWidth: '100px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={record.notes || ''}>
|
||||
{record.notes || ''}
|
||||
<td
|
||||
style={{
|
||||
maxWidth: "100px",
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
}}
|
||||
title={record.notes || ""}
|
||||
>
|
||||
{record.notes || ""}
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
@@ -153,7 +208,14 @@ export default function AttendanceShiftTable({ records, onEdit, onDelete }: Atte
|
||||
title="Upravit"
|
||||
aria-label="Upravit"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
|
||||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
|
||||
</svg>
|
||||
@@ -164,7 +226,14 @@ export default function AttendanceShiftTable({ records, onEdit, onDelete }: Atte
|
||||
title="Smazat"
|
||||
aria-label="Smazat"
|
||||
>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<polyline points="3 6 5 6 21 6" />
|
||||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
|
||||
</svg>
|
||||
@@ -172,10 +241,10 @@ export default function AttendanceShiftTable({ records, onEdit, onDelete }: Atte
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user