Finanzen: Rechnungen schreiben und verwalten, Buchungen zuordnen
Block 6 (Rechnungen: Filter, Altersgruppen, Aktionen, Dialog "Rechnung schreiben") und Block 7 (Buchungen mit Paging, Zuordnen-Dialog, bei Rechnungen zweistufig). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
18bc3012e0
commit
1feeb18c08
12 files changed
+2436
-8
No files matched your search
@@ -0,0 +1,49 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { getTransactions } from '../lib/financeApi'
|
||||
|
||||
const FALLBACK_ERROR = 'Die Buchungen konnten nicht geladen werden.'
|
||||
|
||||
/**
|
||||
* Lädt die gespeicherten Buchungen samt Zuordnungsvorschlägen (GET /buchungen, höchstens 1000, neueste zuerst).
|
||||
* `transactions` bleibt beim erneuten Laden stehen; `loaded` ist true, sobald einmal geladen wurde (auch leer);
|
||||
* `stripeFehler` ist der Hinweis des Servers, wenn Stripe die Vorschläge nicht liefern konnte. reload() wirft nie.
|
||||
*/
|
||||
export function useFinanceTransactions() {
|
||||
const [state, setState] = useState({ transactions: [], stripeFehler: '', loaded: false })
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState('')
|
||||
const aliveRef = useRef(true)
|
||||
const seqRef = useRef(0)
|
||||
|
||||
const reload = useCallback(async () => {
|
||||
// Nur die jüngste Anfrage zählt: eine langsame ältere darf neuere Daten nicht überschreiben
|
||||
const mine = ++seqRef.current
|
||||
const current = () => aliveRef.current && mine === seqRef.current
|
||||
setLoading(true)
|
||||
setError('')
|
||||
try {
|
||||
const data = await getTransactions()
|
||||
if (current()) {
|
||||
setState({
|
||||
transactions: Array.isArray(data?.buchungen) ? data.buchungen : [],
|
||||
stripeFehler: typeof data?.stripeFehler === 'string' ? data.stripeFehler : '',
|
||||
loaded: true,
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
if (current()) setError(err?.message || FALLBACK_ERROR)
|
||||
} finally {
|
||||
if (current()) setLoading(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
aliveRef.current = true
|
||||
reload()
|
||||
return () => {
|
||||
aliveRef.current = false
|
||||
}
|
||||
}, [reload])
|
||||
|
||||
return { ...state, loading, error, reload }
|
||||
}
|
||||
Reference in new issue
Block a user