import { useEffect, useState } from 'react' import { Link, useNavigate, useParams } from 'react-router-dom' import { ArrowLeft } from 'lucide-react' import { InvoiceDraftFields } from '../components/InvoiceDraftFields' import { isEmptyRichText, RichTextEditor } from '../components/RichTextEditor' import { useToast } from '../context/ToastContext' import { useT } from '../i18n/useT' import { ApiError, isAbortError } from '../lib/api' import { createInvoiceTemplate, getInvoiceTemplate, listInvoiceItemTemplates, updateInvoiceTemplate, } from '../services/invoiceService' import type { InvoiceItemTemplate } from '../types/invoice' import { buildAccountsPayload, buildKeyPointsPayload, buildTemplateItemsPayload, draftsFromInvoiceTemplate, emptyDraftItem, type DraftAccount, type DraftKeyPoint, type DraftLineItem, } from '../utils/invoiceDraft' import pageStyles from '../components/PageContent.module.css' import formStyles from '../components/InvoiceForm.module.css' import tableStyles from './InvoicesPage.module.css' export function InvoiceTemplateEditorPage() { const { templateId } = useParams() const isEdit = Boolean(templateId) const navigate = useNavigate() const { showToast } = useToast() const t = useT() const [itemTemplates, setItemTemplates] = useState([]) const [loading, setLoading] = useState(isEdit) const [error, setError] = useState('') const [name, setName] = useState('') const [topText, setTopText] = useState('') const [items, setItems] = useState([emptyDraftItem()]) const [keyPoints, setKeyPoints] = useState([]) const [accounts, setAccounts] = useState([]) const [selectedItemTemplateId, setSelectedItemTemplateId] = useState('') const [submitting, setSubmitting] = useState(false) const [formError, setFormError] = useState('') useEffect(() => { const controller = new AbortController() async function load() { setLoading(true) setError('') try { const itemsRes = await listInvoiceItemTemplates(controller.signal) setItemTemplates(itemsRes.items.filter((i) => i.isActive)) if (templateId) { const template = await getInvoiceTemplate(templateId, controller.signal) const drafts = draftsFromInvoiceTemplate(template) setName(drafts.name) setTopText(drafts.topText) setItems(drafts.items) setKeyPoints(drafts.keyPoints) setAccounts(drafts.accounts) } } catch (err) { if (isAbortError(err)) return setError(err instanceof ApiError ? err.message : t('invoiceTemplateEditor.loadError')) } finally { setLoading(false) } } void load() return () => controller.abort() // eslint-disable-next-line react-hooks/exhaustive-deps }, [templateId]) async function handleSave() { setFormError('') if (!name.trim()) { setFormError(t('invoiceTemplateEditor.nameRequired')) return } let lineItems try { lineItems = buildTemplateItemsPayload(items, t) } catch (err) { setFormError(err instanceof Error ? err.message : t('invoiceTemplateEditor.saveError')) return } const payload = { name: name.trim(), topText: isEmptyRichText(topText) ? undefined : topText, items: lineItems, keyPoints: buildKeyPointsPayload(keyPoints), accounts: buildAccountsPayload(accounts), } setSubmitting(true) try { if (templateId) { await updateInvoiceTemplate(templateId, payload) showToast(t('invoiceTemplateEditor.updated'), 'success') } else { await createInvoiceTemplate(payload) showToast(t('invoiceTemplateEditor.created'), 'success') } navigate('/invoices/templates') } catch (err) { setFormError(err instanceof ApiError ? err.message : t('invoiceTemplateEditor.saveError')) } finally { setSubmitting(false) } } return (
{t('invoiceTemplateEditor.backToTemplates')}

{isEdit ? t('invoiceTemplateEditor.editTitle') : t('invoiceTemplateEditor.addTitle')}

{t('invoiceTemplateEditor.subtitle')}

{error ?

{error}

: null} {loading ?

{t('invoiceTemplateEditor.loading')}

: null} {!loading ? (
setName(e.target.value)} placeholder={t('invoiceTemplateEditor.namePlaceholder')} />
{formError ?

{formError}

: null}
) : null}
) }