Amba-Agent-App/lib/hooks/useTransactionDetail.ts
2026-01-16 00:22:35 +03:00

73 lines
2.1 KiB
TypeScript

import { useCallback, useEffect, useMemo, useRef } from 'react';
import type { Transaction } from '../services/transactionService';
import {
useTransactionStore,
type TransactionDetailCacheEntry,
} from '../stores/transactionStore';
import { useGlobalLoading } from './useGlobalLoading';
interface UseTransactionDetailReturn {
transaction: Transaction | null;
loading: boolean;
error: string | null;
refreshTransaction: () => Promise<void>;
}
const defaultEntry: TransactionDetailCacheEntry = {
transaction: null,
loading: false,
error: null,
};
export const useTransactionDetail = (
transactionId: string | null | undefined
): UseTransactionDetailReturn => {
const id = transactionId ?? null;
const lastIdRef = useRef<string | null>(null);
const ensureDetail = useTransactionStore((state) => state.ensureTransactionDetail);
const refreshDetail = useTransactionStore((state) => state.refreshTransactionDetail);
const removeDetail = useTransactionStore((state) => state.removeTransactionDetail);
const entry = useTransactionStore(
useCallback(
(state) => (id ? state.transactionDetails[id] ?? defaultEntry : defaultEntry),
[id]
)
);
const { withLoading } = useGlobalLoading();
useEffect(() => {
if (lastIdRef.current && lastIdRef.current !== id) {
removeDetail(lastIdRef.current);
}
lastIdRef.current = id;
}, [id, removeDetail]);
useEffect(() => {
if (!id) {
return;
}
ensureDetail(id);
}, [ensureDetail, id]);
const refreshTransaction = useCallback(async () => {
if (!id) {
return;
}
await withLoading(() => refreshDetail(id));
}, [id, refreshDetail, withLoading]);
return useMemo(
() => ({
transaction: id ? entry.transaction : null,
loading: id ? entry.loading : false,
error: id ? entry.error : null,
refreshTransaction,
}),
[entry.error, entry.loading, entry.transaction, id, refreshTransaction]
);
};