import { useState, useEffect, useMemo } from "react"; import { useNavigate, Link } from "react-router-dom"; import { useAlert } from "../context/AlertContext"; import { useAuth } from "../context/AuthContext"; import { motion } from "framer-motion"; import FormField from "../components/FormField"; import Forbidden from "../components/Forbidden"; import AdminDatePicker from "../components/AdminDatePicker"; import apiFetch from "../utils/api"; const API_BASE = "/api/admin"; interface Customer { id: number; name: string; company_id?: string; city?: string; } interface User { id: number; name: string; } interface ProjectForm { project_number: string; name: string; customer_id: number | null; customer_name: string; start_date: string; responsible_user_id: string; } export default function ProjectCreate() { const navigate = useNavigate(); const alert = useAlert(); const { hasPermission } = useAuth(); const [form, setForm] = useState({ project_number: "", name: "", customer_id: null, customer_name: "", start_date: new Date().toISOString().split("T")[0], responsible_user_id: "", }); const [users, setUsers] = useState([]); const [saving, setSaving] = useState(false); const [errors, setErrors] = useState>({}); const [loadingNumber, setLoadingNumber] = useState(true); // Customer selector state const [customers, setCustomers] = useState([]); const [customerSearch, setCustomerSearch] = useState(""); const [showCustomerDropdown, setShowCustomerDropdown] = useState(false); // Load initial data useEffect(() => { const load = async () => { try { const [numRes, custRes, usersRes] = await Promise.all([ apiFetch(`${API_BASE}/projects/next-number`), apiFetch(`${API_BASE}/customers`), apiFetch(`${API_BASE}/users`), ]); const numData = await numRes.json(); if (numData.success) { setForm((prev) => ({ ...prev, project_number: numData.data?.next_number || numData.data?.number || "", })); } const custData = await custRes.json(); if (custData.success) { setCustomers( Array.isArray(custData.data) ? custData.data : custData.data?.items || [], ); } const usersData = await usersRes.json(); if (usersData.success) { const rawUsers = Array.isArray(usersData.data) ? usersData.data : usersData.data?.items || []; setUsers( rawUsers.map((u: any) => ({ id: u.id, name: `${u.first_name || ""} ${u.last_name || ""}`.trim() || u.username, })), ); } } catch { alert.error("Chyba při načítání dat"); } finally { setLoadingNumber(false); } }; load(); }, [alert]); // Customer filtering const filteredCustomers = useMemo(() => { if (!customerSearch) return customers; const q = customerSearch.toLowerCase(); return customers.filter( (c) => (c.name || "").toLowerCase().includes(q) || (c.company_id || "").includes(customerSearch) || (c.city || "").toLowerCase().includes(q), ); }, [customers, customerSearch]); // Close dropdown on outside click useEffect(() => { const handleClickOutside = () => setShowCustomerDropdown(false); if (showCustomerDropdown) { document.addEventListener("click", handleClickOutside); return () => document.removeEventListener("click", handleClickOutside); } }, [showCustomerDropdown]); if (!hasPermission("projects.create")) return ; const selectCustomer = (customer: Customer) => { setForm((prev) => ({ ...prev, customer_id: customer.id, customer_name: customer.name, })); setErrors((prev) => ({ ...prev, customer_id: undefined })); setCustomerSearch(""); setShowCustomerDropdown(false); }; const clearCustomer = () => { setForm((prev) => ({ ...prev, customer_id: null, customer_name: "" })); }; const updateForm = (field: keyof ProjectForm, value: unknown) => { setForm((prev) => ({ ...prev, [field]: value })); setErrors((prev) => ({ ...prev, [field]: undefined })); }; const handleSave = async () => { const newErrors: Record = {}; if (!form.name.trim()) newErrors.name = "Název projektu je povinný"; if (!form.customer_id) newErrors.customer_id = "Vyberte zákazníka"; setErrors(newErrors); if (Object.keys(newErrors).length > 0) return; setSaving(true); try { const body = { name: form.name.trim(), customer_id: form.customer_id, start_date: form.start_date, responsible_user_id: form.responsible_user_id || null, }; const res = await apiFetch(`${API_BASE}/projects`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const data = await res.json(); if (data.success) { alert.success("Projekt byl vytvořen"); navigate(`/projects/${data.data.id}`); } else { alert.error(data.error || "Nepodařilo se vytvořit projekt"); } } catch { alert.error("Chyba připojení"); } finally { setSaving(false); } }; if (loadingNumber) { return (
{[0, 1, 2, 3].map((i) => (
))}
); } return (

Nový projekt

Ruční vytvoření projektu

Základní údaje

updateForm("name", e.target.value)} className="admin-form-input" placeholder="Název projektu" />
{form.customer_id ? (
{form.customer_name}
) : (
e.stopPropagation()} > { setCustomerSearch(e.target.value); setShowCustomerDropdown(true); }} onFocus={() => setShowCustomerDropdown(true)} className="admin-form-input" placeholder="Hledat zákazníka..." /> {showCustomerDropdown && (
{filteredCustomers.length === 0 ? (
Žádní zákazníci
) : ( filteredCustomers.slice(0, 20).map((c) => (
selectCustomer(c)} >
{c.name}
{c.city &&
{c.city}
}
)) )}
)}
)}
updateForm("start_date", val)} />
); }