feat: Rechnungen, Dokumente und Preview im Ticket buendeln

- InvoiceNinja-Rechnungen pro Kunde/Ticket anzeigen, verknuepfen und aus
  Ticket heraus erstellen (integrationsApi, useInvoices, InvoicePanel)
- Paperless-ngx: Ticket-Uploads automatisch synchronisieren und Kunden-/
  Ticket-Dokumente durchsuchen/anzeigen (DocumentsPanel, FileUploadModal)
- Projekt-/Preview-Karte mit Status, Provisioning und letztem Commit
- Einheitliches Ticket-Detail mit Tabs (Details/Arbeitsblaetter/Rechnungen/
  Dokumente/Projekt) + zugehoerige Styles

Aufruf des Integrations-Backends same-origin per Appwrite-JWT.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Webklar DeployandCursor committed 2026-06-17 09:13:35 +00:00
1 parent 8abf11ad18
commit 8f6927fbb0
8 files changed
+862 -186

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
import { useState, useEffect, useCallback } from 'react'
import { integrationsApi } from '../lib/integrationsApi'
/**
* Laedt die InvoiceNinja-Rechnungen eines verknuepften Clients.
* clientId = customers.invoiceNinjaClientId (oder null -> nichts laden).
*/
export function useInvoices(clientId) {
const [invoices, setInvoices] = useState([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const fetchInvoices = useCallback(async () => {
if (!clientId) {
setInvoices([])
return
}
setLoading(true)
setError(null)
try {
const data = await integrationsApi.listInvoices(clientId)
setInvoices(data.invoices || [])
} catch (err) {
setError(err.message)
setInvoices([])
} finally {
setLoading(false)
}
}, [clientId])
useEffect(() => {
fetchInvoices()
}, [fetchInvoices])
const createInvoice = useCallback(
async (payload) => {
try {
const data = await integrationsApi.createInvoice(payload)
await fetchInvoices()
return { success: true, invoice: data.invoice }
} catch (err) {
return { success: false, error: err.message }
}
},
[fetchInvoices]
)
return { invoices, loading, error, refresh: fetchInvoices, createInvoice }
}