merge-requests/3333/head
danidfra 2025-04-01 18:05:07 -03:00
rodzic 21fc7c8ed9
commit 0c92375c42
4 zmienionych plików z 83 dodań i 81 usunięć

Wyświetl plik

@ -10,6 +10,7 @@ const messages = defineMessages({
title: { id: 'wallet.transactions', defaultMessage: 'Transactions' }, title: { id: 'wallet.transactions', defaultMessage: 'Transactions' },
more: { id: 'wallet.transactions.show_more', defaultMessage: 'Show More' }, more: { id: 'wallet.transactions.show_more', defaultMessage: 'Show More' },
loading: { id: 'wallet.loading', defaultMessage: 'Loading…' }, loading: { id: 'wallet.loading', defaultMessage: 'Loading…' },
noMoreTransactions: { id: 'wallet.transactions.no_more', defaultMessage: 'You reached the end of transactions' },
}); });
const WalletTransactions = () => { const WalletTransactions = () => {
@ -17,13 +18,15 @@ const WalletTransactions = () => {
const { isLoading, expandTransactions } = useTransactions(); const { isLoading, expandTransactions } = useTransactions();
const observerRef = useRef<HTMLDivElement | null>(null); const observerRef = useRef<HTMLDivElement | null>(null);
const [showSpinner, setShowSpinner] = useState(false); const [showSpinner, setShowSpinner] = useState(false);
const [hasMoreTransactions, setHasMoreTransactions] = useState(true);
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver( const observer = new IntersectionObserver(
([entry]) => { async ([entry]) => {
if (entry.isIntersecting) { if (entry.isIntersecting && !isLoading && hasMoreTransactions) {
setShowSpinner(true); setShowSpinner(true);
if (!isLoading) expandTransactions(); const hasMore = await expandTransactions();
setHasMoreTransactions(hasMore);
} }
}, },
{ rootMargin: '100px' }, { rootMargin: '100px' },
@ -34,13 +37,18 @@ const WalletTransactions = () => {
} }
return () => observer.disconnect(); return () => observer.disconnect();
}, [expandTransactions, isLoading]); }, [expandTransactions, isLoading, hasMoreTransactions]);
return ( return (
<Column label={intl.formatMessage(messages.title)}> <Column label={intl.formatMessage(messages.title)}>
<Transactions /> <Transactions />
<div className='flex w-full justify-center' ref={observerRef}> <div className='flex w-full justify-center' ref={observerRef}>
{showSpinner && isLoading && <Spinner />} {showSpinner && isLoading && <Spinner />}
{!hasMoreTransactions && (
<div className='py-4 text-center text-gray-600'>
{intl.formatMessage(messages.noMoreTransactions)}
</div>
)}
</div> </div>
</Column> </Column>
); );

Wyświetl plik

@ -44,85 +44,78 @@ const Wallet = () => {
return ( return (
<> <>
{isLoading ? {isLoading ? (
<Stack className='h-screen items-center justify-center'> <Stack className='h-screen items-center justify-center'>
<div className='rounded-lg border border-gray-200 p-10 dark:border-gray-700'> <Spinner size={50} withText={false} />
<Spinner size={50} withText={false} />
</div>
</Stack> </Stack>
: ) : (
( <Column label={intl.formatMessage(messages.wallet)} transparent withHeader={false} slim>
<Column label={intl.formatMessage(messages.wallet)} transparent withHeader={false} slim> <Card className='space-y-4 overflow-hidden'>
<Card className='space-y-4 overflow-hidden'> <CardHeader>
<CardHeader> <CardTitle title={intl.formatMessage(messages.wallet)} />
<CardTitle title={intl.formatMessage(messages.wallet)} /> </CardHeader>
</CardHeader>
{walletData ? ( {walletData ? (
<> <>
<CardBody> <CardBody>
<Stack <Stack
className='rounded-lg border border-gray-200 p-8 dark:border-gray-700' className='rounded-lg border border-gray-200 p-8 dark:border-gray-700'
alignItems='center' alignItems='center'
space={4} space={4}
>
<Balance />
</Stack>
</CardBody>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.transactions)} />
</CardHeader>
<CardBody>
<Transactions limit={4} />
{hasTransactions && <div className='mt-4 flex w-full justify-center'>
<Button
icon={moreIcon}
theme='primary'
to='/wallet/transactions'
className='px-6 font-medium'
> >
<Balance /> {intl.formatMessage(messages.more)}
</Stack> </Button>
</CardBody> </div>}
</CardBody>
<CardHeader> <CardHeader>
<CardTitle title={intl.formatMessage(messages.transactions)} /> <CardTitle title={intl.formatMessage(messages.management)} />
</CardHeader> </CardHeader>
<CardBody> <CardBody>
<Transactions limit={4} /> <List>
{hasTransactions && <div className='mt-4 flex w-full justify-center'> <ListItem label={intl.formatMessage(messages.mints)} to='/wallet/mints' />
<Button <ListItem label={intl.formatMessage(messages.relays)} to='/wallet/relays' />
icon={moreIcon} <ListItem label={intl.formatMessage(messages.payment)} >
theme='primary' <SelectDropdown
to='/wallet/transactions' className='max-w-[200px]'
className='px-6 font-medium' items={paymentMethods}
> defaultValue={method}
{intl.formatMessage(messages.more)} onChange={(event: React.ChangeEvent<HTMLSelectElement>) => {
</Button> changeMethod((event.target.value as 'cashu' | 'lightning'));
</div>} }}
</CardBody> />
</ListItem>
<CardHeader> </List>
<CardTitle title={intl.formatMessage(messages.management)} /> </CardBody>
</CardHeader> </>
) : (
<CardBody> <>
<List> <CardBody>
<ListItem label={intl.formatMessage(messages.mints)} to='/wallet/mints' /> <CreateWallet />
<ListItem label={intl.formatMessage(messages.relays)} to='/wallet/relays' /> </CardBody>
<ListItem label={intl.formatMessage(messages.payment)} > </>
<SelectDropdown )}
className='max-w-[200px]' </Card>
items={paymentMethods} </Column>
defaultValue={method} )}
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => {
changeMethod((event.target.value as 'cashu' | 'lightning'));
}}
/>
</ListItem>
</List>
</CardBody>
</>
)
:
<>
<CardBody>
<CreateWallet />
</CardBody>
</>
}
</Card>
</Column>
)
}
</> </>
); );
}; };

Wyświetl plik

@ -73,7 +73,7 @@ const useWalletStore = create<WalletState>((set) => ({
const useWallet = () => { const useWallet = () => {
const api = useApi(); const api = useApi();
const { wallet, setWallet, setAcceptsZapsCashu, hasFetchedWallet, setHasFetchedWallet } = useWalletStore(); const { wallet, setWallet, setAcceptsZapsCashu, hasFetchedWallet, setHasFetchedWallet } = useWalletStore();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(!hasFetchedWallet);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const createWallet = async (walletInfo: IWalletInfo) => { const createWallet = async (walletInfo: IWalletInfo) => {
@ -118,7 +118,6 @@ const useWallet = () => {
useEffect(() => { useEffect(() => {
if (!hasFetchedWallet) { if (!hasFetchedWallet) {
setHasFetchedWallet(true);
getWallet(false); getWallet(false);
} }
}, []); }, []);
@ -153,8 +152,7 @@ const useTransactions = () => {
const expandTransactions = async () => { const expandTransactions = async () => {
if (!nextTransaction || !transactions) { if (!nextTransaction || !transactions) {
toast.info('You reached the end of transactions'); return false;
return;
} }
try { try {
setIsLoading(true); setIsLoading(true);
@ -166,10 +164,12 @@ const useTransactions = () => {
const newTransactions = [...(transactions ?? []), ...normalizedData ]; const newTransactions = [...(transactions ?? []), ...normalizedData ];
setTransactions(newTransactions, prev, next); setTransactions(newTransactions, prev, next);
return true; // Return true to indicate successful expansion
} catch (err) { } catch (err) {
const messageError = err instanceof Error ? err.message : 'Error expanding transactions'; const messageError = err instanceof Error ? err.message : 'Error expanding transactions';
toast.error(messageError); toast.error(messageError);
setError(messageError); setError(messageError);
return false;
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }

Wyświetl plik

@ -1740,6 +1740,7 @@
"wallet.title": "Wallet", "wallet.title": "Wallet",
"wallet.transactions": "Transactions", "wallet.transactions": "Transactions",
"wallet.transactions.more": "More", "wallet.transactions.more": "More",
"wallet.transactions.no_more": "You reached the end of transactions",
"wallet.transactions.no_transactions": "You don't have transactions yet.", "wallet.transactions.no_transactions": "You don't have transactions yet.",
"wallet.transactions.show_more": "Show More", "wallet.transactions.show_more": "Show More",
"who_to_follow.title": "People To Follow", "who_to_follow.title": "People To Follow",