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?mine=1`); 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} />
); }