import { useState, useEffect, useCallback, useRef } from 'react' import { useAlert } from '../context/AlertContext' import { useAuth } from '../context/AuthContext' import { motion, AnimatePresence } from 'framer-motion' import ConfirmModal from '../components/ConfirmModal' import FormField from '../components/FormField' import Forbidden from '../components/Forbidden' import RichEditor from '../components/RichEditor' import useModalLock from '../hooks/useModalLock' import apiFetch from '../utils/api' const API_BASE = '/api/admin' export default function OffersTemplates() { const { hasPermission } = useAuth() const [activeTab, setActiveTab] = useState('items') if (!hasPermission('offers.settings')) return return (

Šablony

Šablony položek a rozsahu projektu

{activeTab === 'items' ? : }
) } // --- Item Templates Tab --- function ItemTemplatesTab() { const alert = useAlert() const [loading, setLoading] = useState(true) const [templates, setTemplates] = useState([]) const [showModal, setShowModal] = useState(false) const [editingTemplate, setEditingTemplate] = useState(null) const [saving, setSaving] = useState(false) const [form, setForm] = useState({ name: '', description: '', default_price: 0, category: '' }) const [deleteConfirm, setDeleteConfirm] = useState({ show: false, template: null }) const [deleting, setDeleting] = useState(false) useModalLock(showModal) const fetchData = useCallback(async () => { try { const response = await apiFetch(`${API_BASE}/offers-templates.php?action=items`) if (response.status === 401) return const result = await response.json() if (result.success) { setTemplates(result.data.templates) } } catch { alert.error('Nepodařilo se načíst šablony') } finally { setLoading(false) } }, [alert]) useEffect(() => { fetchData() }, [fetchData]) const openCreate = () => { setEditingTemplate(null) setForm({ name: '', description: '', default_price: 0, category: '' }) setShowModal(true) } const openEdit = (t) => { setEditingTemplate(t) setForm({ name: t.name || '', description: t.description || '', default_price: t.default_price || 0, category: t.category || '' }) setShowModal(true) } const handleSubmit = async () => { if (!form.name.trim()) { alert.error('Název šablony je povinný') return } setSaving(true) try { const body = editingTemplate ? { ...form, id: editingTemplate.id } : form const response = await apiFetch(`${API_BASE}/offers-templates.php?action=item`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) const result = await response.json() if (result.success) { setShowModal(false) await new Promise(r => setTimeout(r, 300)) alert.success(result.message) fetchData() } else { alert.error(result.error) } } catch { alert.error('Chyba připojení') } finally { setSaving(false) } } const handleDelete = async () => { if (!deleteConfirm.template) return setDeleting(true) try { const response = await apiFetch(`${API_BASE}/offers-templates.php?action=item&id=${deleteConfirm.template.id}`, { method: 'DELETE' }) const result = await response.json() if (result.success) { setDeleteConfirm({ show: false, template: null }) alert.success(result.message) fetchData() } else { alert.error(result.error) } } catch { alert.error('Chyba připojení') } finally { setDeleting(false) } } if (loading) { return (
{[0, 1, 2, 3, 4].map(i => (
))}
) } return ( <>

Šablony položek ({templates.length})

{templates.length === 0 ? (

Zatím žádné šablony položek.

) : (
{templates.map((t) => ( ))}
Název Popis Cena Kategorie Akce
{t.name} {t.description || '—'} {Number(t.default_price).toFixed(2)} {t.category || '—'}
)}
{/* Item Template Modal */} {showModal && (
setShowModal(false)} />

{editingTemplate ? 'Upravit šablonu' : 'Nová šablona položky'}

setForm(p => ({ ...p, name: e.target.value }))} className="admin-form-input" />