style: run prettier on entire codebase

This commit is contained in:
BOHA
2026-03-24 19:59:14 +01:00
parent 872be42107
commit 3c167cf5c4
148 changed files with 26740 additions and 13990 deletions

View File

@@ -1,109 +1,169 @@
import { useAlert } from '../context/AlertContext'
import { useAuth } from '../context/AuthContext'
import Forbidden from '../components/Forbidden'
import { motion } from 'framer-motion'
import ConfirmModal from '../components/ConfirmModal'
import AdminDatePicker from '../components/AdminDatePicker'
import BulkAttendanceModal from '../components/BulkAttendanceModal'
import ShiftFormModal from '../components/ShiftFormModal'
import AttendanceShiftTable from '../components/AttendanceShiftTable'
import useModalLock from '../hooks/useModalLock'
import useAttendanceAdmin from '../hooks/useAttendanceAdmin'
import FormField from '../components/FormField'
import { formatMinutes } from '../utils/attendanceHelpers'
import { useAlert } from "../context/AlertContext";
import { useAuth } from "../context/AuthContext";
import Forbidden from "../components/Forbidden";
import { motion } from "framer-motion";
import ConfirmModal from "../components/ConfirmModal";
import AdminDatePicker from "../components/AdminDatePicker";
import BulkAttendanceModal from "../components/BulkAttendanceModal";
import ShiftFormModal from "../components/ShiftFormModal";
import AttendanceShiftTable from "../components/AttendanceShiftTable";
import useModalLock from "../hooks/useModalLock";
import useAttendanceAdmin from "../hooks/useAttendanceAdmin";
import FormField from "../components/FormField";
import { formatMinutes } from "../utils/attendanceHelpers";
interface UserTotalData {
name: string
minutes: number
working: boolean
vacation_hours: number
sick_hours: number
holiday_hours: number
unpaid_hours: number
fund: number | null
worked_hours: number
covered: number
missing: number
overtime: number
name: string;
minutes: number;
working: boolean;
vacation_hours: number;
sick_hours: number;
holiday_hours: number;
unpaid_hours: number;
fund: number | null;
worked_hours: number;
covered: number;
missing: number;
overtime: number;
}
function getFundBarBackground(data: UserTotalData) {
if (data.overtime > 0) return 'linear-gradient(135deg, var(--warning), #d97706)'
if (data.covered >= (data.fund ?? 0)) return 'linear-gradient(135deg, var(--success), #059669)'
return 'var(--gradient)'
if (data.overtime > 0)
return "linear-gradient(135deg, var(--warning), #d97706)";
if (data.covered >= (data.fund ?? 0))
return "linear-gradient(135deg, var(--success), #059669)";
return "var(--gradient)";
}
export default function AttendanceAdmin() {
const alert = useAlert()
const { hasPermission } = useAuth()
const alert = useAlert();
const { hasPermission } = useAuth();
const {
loading, month, setMonth,
filterUserId, setFilterUserId,
data, hasData,
showBulkModal, setShowBulkModal,
bulkSubmitting, bulkForm, setBulkForm,
showCreateModal, setShowCreateModal,
createForm, setCreateForm,
showEditModal, setShowEditModal,
editingRecord, editForm, setEditForm,
deleteConfirm, setDeleteConfirm,
loading,
month,
setMonth,
filterUserId,
setFilterUserId,
data,
hasData,
showBulkModal,
setShowBulkModal,
bulkSubmitting,
bulkForm,
setBulkForm,
showCreateModal,
setShowCreateModal,
createForm,
setCreateForm,
showEditModal,
setShowEditModal,
editingRecord,
editForm,
setEditForm,
deleteConfirm,
setDeleteConfirm,
projectList,
createProjectLogs, setCreateProjectLogs,
editProjectLogs, setEditProjectLogs,
openCreateModal, handleCreateShiftDateChange, handleCreateSubmit,
openBulkModal, toggleBulkUser, toggleAllBulkUsers, handleBulkSubmit,
openEditModal, handleEditSubmit,
handleDelete, handlePrint
} = useAttendanceAdmin({ alert })
createProjectLogs,
setCreateProjectLogs,
editProjectLogs,
setEditProjectLogs,
openCreateModal,
handleCreateShiftDateChange,
handleCreateSubmit,
openBulkModal,
toggleBulkUser,
toggleAllBulkUsers,
handleBulkSubmit,
openEditModal,
handleEditSubmit,
handleDelete,
handlePrint,
} = useAttendanceAdmin({ alert });
useModalLock(showBulkModal)
useModalLock(showEditModal)
useModalLock(showCreateModal)
useModalLock(showBulkModal);
useModalLock(showEditModal);
useModalLock(showCreateModal);
if (!hasPermission('attendance.admin')) return <Forbidden />
if (!hasPermission("attendance.admin")) return <Forbidden />;
// Show skeleton only on initial load (no data yet), not on filter changes
const isInitialLoad = loading && data.records.length === 0 && Object.keys(data.user_totals).length === 0
const isInitialLoad =
loading &&
data.records.length === 0 &&
Object.keys(data.user_totals).length === 0;
if (isInitialLoad) {
return (
<div className="admin-skeleton" style={{ padding: 0, gap: '1.5rem' }}>
<div className="admin-skeleton-row" style={{ justifyContent: 'space-between' }}>
<div className="admin-skeleton" style={{ padding: 0, gap: "1.5rem" }}>
<div
className="admin-skeleton-row"
style={{ justifyContent: "space-between" }}
>
<div>
<div className="admin-skeleton-line h-8" style={{ width: '200px', marginBottom: '0.5rem' }} />
<div
className="admin-skeleton-line h-8"
style={{ width: "200px", marginBottom: "0.5rem" }}
/>
</div>
<div className="admin-skeleton-row" style={{ gap: '0.5rem' }}>
<div className="admin-skeleton-line h-10" style={{ width: '120px', borderRadius: '8px' }} />
<div className="admin-skeleton-line h-10" style={{ width: '120px', borderRadius: '8px' }} />
<div className="admin-skeleton-line h-10" style={{ width: '140px', borderRadius: '8px' }} />
<div className="admin-skeleton-row" style={{ gap: "0.5rem" }}>
<div
className="admin-skeleton-line h-10"
style={{ width: "120px", borderRadius: "8px" }}
/>
<div
className="admin-skeleton-line h-10"
style={{ width: "120px", borderRadius: "8px" }}
/>
<div
className="admin-skeleton-line h-10"
style={{ width: "140px", borderRadius: "8px" }}
/>
</div>
</div>
<div className="admin-card">
<div className="admin-skeleton" style={{ gap: '0.75rem', padding: '1rem' }}>
<div
className="admin-skeleton"
style={{ gap: "0.75rem", padding: "1rem" }}
>
<div className="admin-skeleton-row">
<div className="admin-skeleton-line h-10" style={{ flex: 1, borderRadius: '8px' }} />
<div className="admin-skeleton-line h-10" style={{ flex: 1, borderRadius: '8px' }} />
<div
className="admin-skeleton-line h-10"
style={{ flex: 1, borderRadius: "8px" }}
/>
<div
className="admin-skeleton-line h-10"
style={{ flex: 1, borderRadius: "8px" }}
/>
</div>
</div>
</div>
<div className="admin-grid admin-grid-3">
{[0, 1, 2].map(i => (
{[0, 1, 2].map((i) => (
<div key={i} className="admin-card">
<div className="admin-card-body">
<div className="admin-skeleton" style={{ gap: '0.75rem' }}>
<div className="admin-skeleton" style={{ gap: "0.75rem" }}>
<div className="admin-skeleton-line w-1/2" />
<div className="admin-skeleton-line h-8" style={{ width: '80px' }} />
<div className="admin-skeleton-line w-1/3" style={{ height: '10px' }} />
<div className="admin-skeleton-line w-full" style={{ height: '4px' }} />
<div
className="admin-skeleton-line h-8"
style={{ width: "80px" }}
/>
<div
className="admin-skeleton-line w-1/3"
style={{ height: "10px" }}
/>
<div
className="admin-skeleton-line w-full"
style={{ height: "4px" }}
/>
</div>
</div>
</div>
))}
</div>
<div className="admin-card">
<div className="admin-skeleton" style={{ gap: '1.25rem' }}>
{[0, 1, 2, 3, 4].map(i => (
<div className="admin-skeleton" style={{ gap: "1.25rem" }}>
{[0, 1, 2, 3, 4].map((i) => (
<div key={i} className="admin-skeleton-row">
<div className="admin-skeleton-line w-1/4" />
<div className="admin-skeleton-line w-1/3" />
@@ -113,7 +173,7 @@ export default function AttendanceAdmin() {
</div>
</div>
</div>
)
);
}
return (
@@ -134,7 +194,15 @@ export default function AttendanceAdmin() {
className="admin-btn admin-btn-secondary"
title="Tisk docházky"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ marginRight: '0.5rem' }}>
<svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
style={{ marginRight: "0.5rem" }}
>
<polyline points="6 9 6 2 18 2 18 9" />
<path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2" />
<rect x="6" y="14" width="12" height="8" />
@@ -152,7 +220,14 @@ export default function AttendanceAdmin() {
onClick={openCreateModal}
className="admin-btn admin-btn-primary"
>
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
>
<line x1="12" y1="5" x2="12" y2="19" />
<line x1="5" y1="12" x2="19" y2="12" />
</svg>
@@ -185,7 +260,9 @@ export default function AttendanceAdmin() {
>
<option value="">Všichni</option>
{data.users.map((user) => (
<option key={user.id} value={user.id}>{user.name}</option>
<option key={user.id} value={user.id}>
{user.name}
</option>
))}
</select>
</FormField>
@@ -202,68 +279,110 @@ export default function AttendanceAdmin() {
transition={{ duration: 0.25, delay: 0.09 }}
>
{Object.entries(data.user_totals).map(([uid, userData]) => {
const ut = userData as UserTotalData
const ut = userData as UserTotalData;
return (
<div key={uid} className="admin-card">
<div className="admin-card-body">
<div className="flex-row gap-2 mb-2">
<span style={{ fontWeight: 600 }}>{ut.name}</span>
<span className={`attendance-working-badge ${ut.working ? 'working' : 'finished'}`}>
{ut.working ? '\u2713' : '\u2717'}
<span
className={`attendance-working-badge ${ut.working ? "working" : "finished"}`}
>
{ut.working ? "\u2713" : "\u2717"}
</span>
</div>
<div className="admin-stat-value">{formatMinutes(ut.minutes)}</div>
<div className="admin-stat-value">
{formatMinutes(ut.minutes)}
</div>
<div className="admin-stat-label">odpracováno</div>
<div style={{ marginTop: '0.5rem', display: 'flex', flexWrap: 'wrap', gap: '0.25rem' }}>
<div
style={{
marginTop: "0.5rem",
display: "flex",
flexWrap: "wrap",
gap: "0.25rem",
}}
>
{ut.vacation_hours > 0 && (
<span className="attendance-leave-badge badge-vacation">Dov: {ut.vacation_hours}h</span>
<span className="attendance-leave-badge badge-vacation">
Dov: {ut.vacation_hours}h
</span>
)}
{ut.sick_hours > 0 && (
<span className="attendance-leave-badge badge-sick">Nem: {ut.sick_hours}h</span>
<span className="attendance-leave-badge badge-sick">
Nem: {ut.sick_hours}h
</span>
)}
{ut.holiday_hours > 0 && (
<span className="attendance-leave-badge badge-holiday">Sv: {ut.holiday_hours}h</span>
<span className="attendance-leave-badge badge-holiday">
Sv: {ut.holiday_hours}h
</span>
)}
{ut.unpaid_hours > 0 && (
<span className="attendance-leave-badge badge-unpaid">Nep: {ut.unpaid_hours}h</span>
<span className="attendance-leave-badge badge-unpaid">
Nep: {ut.unpaid_hours}h
</span>
)}
</div>
{ut.fund !== null && (
<div className="mt-2">
<div className="text-secondary" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: '0.8rem' }}>
<span>Fond: {ut.worked_hours}h / {ut.fund}h</span>
<div
className="text-secondary"
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
fontSize: "0.8rem",
}}
>
<span>
Fond: {ut.worked_hours}h / {ut.fund}h
</span>
{ut.overtime > 0 && (
<span className="text-warning fw-600">+{ut.overtime}h</span>
<span className="text-warning fw-600">
+{ut.overtime}h
</span>
)}
{ut.overtime <= 0 && ut.missing > 0 && (
<span className="text-danger fw-600">-{ut.missing}h</span>
<span className="text-danger fw-600">
-{ut.missing}h
</span>
)}
</div>
<div style={{
marginTop: '0.375rem',
height: '4px',
background: 'var(--bg-tertiary)',
borderRadius: '2px',
overflow: 'hidden'
}}>
<div style={{
height: '100%',
width: `${Math.min(100, (ut.covered / (ut.fund || 1)) * 100)}%`,
background: getFundBarBackground(ut),
borderRadius: '2px',
transition: 'width 0.3s ease'
}} />
<div
style={{
marginTop: "0.375rem",
height: "4px",
background: "var(--bg-tertiary)",
borderRadius: "2px",
overflow: "hidden",
}}
>
<div
style={{
height: "100%",
width: `${Math.min(100, (ut.covered / (ut.fund || 1)) * 100)}%`,
background: getFundBarBackground(ut),
borderRadius: "2px",
transition: "width 0.3s ease",
}}
/>
</div>
</div>
)}
{data.leave_balances[uid] && (
<div className="text-secondary" style={{ marginTop: '0.5rem', fontSize: '0.8rem' }}>
Zbývá dovolené: {data.leave_balances[uid].vacation_remaining.toFixed(1)}h / {data.leave_balances[uid].vacation_total}h
<div
className="text-secondary"
style={{ marginTop: "0.5rem", fontSize: "0.8rem" }}
>
Zbývá dovolené:{" "}
{data.leave_balances[uid].vacation_remaining.toFixed(1)}h
/ {data.leave_balances[uid].vacation_total}h
</div>
)}
</div>
</div>
)
);
})}
</motion.div>
)}
@@ -337,5 +456,5 @@ export default function AttendanceAdmin() {
confirmVariant="danger"
/>
</div>
)
);
}