import { useState, useEffect, useCallback } from 'react' import { useAlert } from '../context/AlertContext' import { useAuth } from '../context/AuthContext' import { motion } from 'framer-motion' import Forbidden from '../components/Forbidden' import { formatDate, formatDatetime } from '../utils/attendanceHelpers' import apiFetch from '../utils/api' import ConfirmModal from '../components/ConfirmModal' const API_BASE = '/api/admin' const leaveTypeLabels: Record = { vacation: 'Dovolená', sick: 'Nemoc', unpaid: 'Neplacené volno' } const statusLabels: Record = { pending: 'Čeká na schválení', approved: 'Schváleno', rejected: 'Zamítnuto', cancelled: 'Zrušeno' } const statusClasses: Record = { pending: 'badge-pending', approved: 'badge-approved', rejected: 'badge-rejected', cancelled: 'badge-cancelled' } const leaveTypeClasses: Record = { vacation: 'badge-vacation', sick: 'badge-sick', unpaid: 'badge-unpaid' } interface LeaveRequest { id: number leave_type: string date_from: string date_to: string total_days: number total_hours: number status: string notes?: string reviewer_note?: string created_at: string } export default function LeaveRequests() { const alert = useAlert() const { hasPermission } = useAuth() const [loading, setLoading] = useState(true) const [requests, setRequests] = useState([]) const [cancelModal, setCancelModal] = useState<{ open: boolean; id: number | null }>({ open: false, id: null }) const [cancelling, setCancelling] = useState(false) const fetchRequests = useCallback(async () => { try { const response = await apiFetch(`${API_BASE}/leave-requests`) if (response.status === 401) return const result = await response.json() if (result.success) { setRequests(result.data) } } catch { alert.error('Nepodařilo se načíst žádosti') } finally { setLoading(false) } }, [alert]) useEffect(() => { fetchRequests() }, [fetchRequests]) if (!hasPermission('attendance.record')) return const handleCancel = async () => { setCancelling(true) try { const response = await apiFetch(`${API_BASE}/leave-requests/${cancelModal.id}`, { method: 'DELETE', }) if (response.status === 401) return const result = await response.json() if (result.success) { setCancelModal({ open: false, id: null }) await fetchRequests() alert.success(result.message) } else { alert.error(result.error) } } catch { alert.error('Chyba připojení') } finally { setCancelling(false) } } if (loading) { return (
{[0, 1, 2, 3, 4].map(i => (
))}
) } function renderNoteCell(req: LeaveRequest) { const truncate = (text: string) => text.length > 40 ? `${text.substring(0, 40)}...` : text if (req.status === 'rejected' && req.reviewer_note) { return ( {truncate(req.reviewer_note)} ) } if (req.notes) { return ( {truncate(req.notes)} ) } return } return (

Moje žádosti

Přehled žádostí o nepřítomnost

{requests.length === 0 ? (

Zatím nemáte žádné žádosti

Novou žádost můžete podat na stránce Docházka

) : (
{requests.map((req) => ( ))}
Typ Od Do Dny Hodiny Stav Poznámka Podáno
{leaveTypeLabels[req.leave_type] || req.leave_type} {formatDate(req.date_from)} {formatDate(req.date_to)} {req.total_days} {req.total_hours}h {statusLabels[req.status] || req.status} {renderNoteCell(req)} {formatDatetime(req.created_at)} {req.status === 'pending' && ( )}
)}
setCancelModal({ open: false, id: null })} onConfirm={handleCancel} title="Zrušit žádost" message="Opravdu chcete zrušit tuto žádost o nepřítomnost?" confirmText="Zrušit žádost" type="warning" loading={cancelling} />
) }