import { useState } from 'react' import { useAlert } from '../context/AlertContext' import { useAuth } from '../context/AuthContext' import { Link } from 'react-router-dom' import Forbidden from '../components/Forbidden' import { motion } from 'framer-motion' import ConfirmModal from '../components/ConfirmModal' import apiFetch from '../utils/api' import { formatDate, czechPlural } from '../utils/formatters' import SortIcon from '../components/SortIcon' import useTableSort from '../hooks/useTableSort' import useListData from '../hooks/useListData' import Pagination from '../components/Pagination' const API_BASE = '/api/admin' const STATUS_LABELS: Record = { aktivni: 'Aktivní', dokonceny: 'Dokončený', zruseny: 'Zrušený' } const STATUS_CLASSES: Record = { aktivni: 'admin-badge-project-aktivni', dokonceny: 'admin-badge-project-dokonceny', zruseny: 'admin-badge-project-zruseny' } interface Project { id: number project_number: string name: string customer_name: string responsible_user_name: string status: string start_date: string end_date: string order_id?: number order_number?: string } export default function Projects() { const alert = useAlert() const { hasPermission } = useAuth() const { sort, order, handleSort, activeSort } = useTableSort('project_number') const [search, setSearch] = useState('') const [page, setPage] = useState(1) const [deletingId, setDeletingId] = useState(null) const [deleteTarget, setDeleteTarget] = useState(null) const [deleteFiles, setDeleteFiles] = useState(false) const { items: projects, setItems: setProjects, loading, initialLoad, pagination } = useListData('projects', { search, sort, order, page, errorMsg: 'Nepodařilo se načíst projekty' }) if (!hasPermission('projects.view')) return const handleDelete = async () => { if (!deleteTarget) return setDeletingId(deleteTarget.id) try { const res = await apiFetch(`${API_BASE}/projects/${deleteTarget.id}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ delete_files: deleteFiles }), }) const data = await res.json() if (data.success) { alert.success(data.message || 'Projekt byl smazán') setProjects((prev: Project[]) => prev.filter(p => p.id !== deleteTarget.id)) } else { alert.error(data.error || 'Nepodařilo se smazat projekt') } } catch { alert.error('Chyba připojení') } finally { setDeletingId(null) setDeleteTarget(null) setDeleteFiles(false) } } if (initialLoad) { return (
{[0, 1, 2, 3, 4].map(i => (
))}
) } return (

Projekty

{pagination?.total ?? projects.length} {czechPlural(pagination?.total ?? projects.length, 'projekt', 'projekty', 'projektů')}

{hasPermission('projects.create') && ( Nový projekt )}
{ setSearch(e.target.value); setPage(1) }} className="admin-form-input" placeholder="Hledat podle čísla, názvu nebo zákazníka..." />
{projects.length === 0 ? (

Zatím nejsou žádné projekty.

Vytvořte první projekt tlačítkem výše nebo automaticky při vytvoření objednávky.

) : (
{(projects as Project[]).map((p) => ( ))}
handleSort('project_number')}> Číslo handleSort('name')}> Název Zákazník Zodpovědná osoba handleSort('status')}> Stav handleSort('start_date')}> Začátek handleSort('end_date')}> Konec Objednávka Akce
{p.project_number} {p.name || '—'} {p.customer_name || '—'} {p.responsible_user_name || '—'} {STATUS_LABELS[p.status] || p.status} {formatDate(p.start_date)} {formatDate(p.end_date)} {p.order_id ? ( {p.order_number} ) : '—'}
{!p.order_id && hasPermission('projects.create') && ( )}
)}
{ setDeleteTarget(null) setDeleteFiles(false) }} onConfirm={handleDelete} title="Smazat projekt" message={ <> Opravdu chcete smazat projekt {deleteTarget?.project_number}? } confirmText="Smazat" type="danger" loading={!!deletingId} />
) }