"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { getWalletBalance, getWalletLogs } from "@/api/wallet"; import { Button } from "@/components/ui/button"; import { PlayerPanel } from "@/components/layout/player-panel"; import { WalletLogsBlock } from "@/features/wallet/wallet-logs-block"; import { dispatchWalletLogsRefresh } from "@/hooks/use-pending-wallet-reconcile"; import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency"; import { PLAYER_CURRENCY_CHANGE_EVENT } from "@/lib/player-currency-preference"; import { isCreditFundingPlayer } from "@/lib/player-funding-mode"; import { formatWalletClientError } from "@/lib/wallet-api-error"; import { getWalletLogsLastPage, type WalletLogsData } from "@/types/api/wallet-logs"; const WALLET_LOGS_PAGE_SIZE = 10; export function WalletLogsScreen() { const { activeCurrency: currency } = useActivePlayerCurrency(); const { t } = useTranslation("player"); const [logs, setLogs] = useState(null); const [filter, setFilter] = useState(""); const [loading, setLoading] = useState(true); const [logsLoading, setLogsLoading] = useState(false); const [loadingMore, setLoadingMore] = useState(false); const [error, setError] = useState(null); const [creditMode, setCreditMode] = useState(false); const loadMoreRef = useRef(null); const fetchPassRef = useRef(true); const load = useCallback(async (targetPage = 1, append = false) => { setError(null); if (append) { setLoadingMore(true); } else if (fetchPassRef.current) { setLoading(true); fetchPassRef.current = false; } else { setLogsLoading(true); } try { const balance = await getWalletBalance({ currency }); setCreditMode(isCreditFundingPlayer(balance)); const nextLogs = await getWalletLogs({ page: targetPage, size: WALLET_LOGS_PAGE_SIZE, type: filter || undefined, currency, }); setLogs((current) => append && current ? { ...nextLogs, items: [...current.items, ...nextLogs.items] } : nextLogs, ); dispatchWalletLogsRefresh(nextLogs.pending_reconcile ?? []); } catch (e) { setError(formatWalletClientError(e, t)); if (!append) { setLogs(null); } } finally { setLoading(false); setLogsLoading(false); setLoadingMore(false); } }, [currency, filter, t]); useEffect(() => { queueMicrotask(() => { void load(1, false); }); }, [currency, load]); useEffect(() => { const onCurrencyChange = () => void load(1, false); window.addEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onCurrencyChange); return () => window.removeEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onCurrencyChange); }, [load]); const hasMore = logs ? logs.page < getWalletLogsLastPage(logs) : false; const loadMore = useCallback(() => { if (!logs || !hasMore || loadingMore) return; void load(logs.page + 1, true); }, [hasMore, load, loadingMore, logs]); useEffect(() => { const target = loadMoreRef.current; if (!target || loading || logsLoading || loadingMore || !hasMore) return; const observer = new IntersectionObserver( ([entry]) => { if (entry?.isIntersecting) { loadMore(); } }, { rootMargin: "160px" }, ); observer.observe(target); return () => observer.disconnect(); }, [hasMore, loadMore, loading, loadingMore, logsLoading]); return (
{error ? (

{error}

) : null}
); }