kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Implement pagination in transactions
rodzic
8b097aeef2
commit
0877e388d2
|
@ -89,7 +89,7 @@ interface ITransactions {
|
||||||
limit?: number;
|
limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transactions = ({ limit = 4 }: ITransactions) => {
|
const Transactions = ({ limit }: ITransactions) => {
|
||||||
const { account } = useOwnAccount();
|
const { account } = useOwnAccount();
|
||||||
const { transactions } = useTransactions();
|
const { transactions } = useTransactions();
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,24 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||||
import Button from 'soapbox/components/ui/button.tsx';
|
import Button from 'soapbox/components/ui/button.tsx';
|
||||||
import { Column } from 'soapbox/components/ui/column.tsx';
|
import { Column } from 'soapbox/components/ui/column.tsx';
|
||||||
import Transactions from 'soapbox/features/wallet/components/transactions.tsx';
|
import Transactions from 'soapbox/features/wallet/components/transactions.tsx';
|
||||||
|
import { useTransactions } from 'soapbox/features/zap/hooks/useHooks.ts';
|
||||||
|
|
||||||
const messages = defineMessages({
|
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…' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const WalletTransactions = () => {
|
const WalletTransactions = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const { isLoading, expandTransactions } = useTransactions();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column label={intl.formatMessage(messages.title)} >
|
<Column label={intl.formatMessage(messages.title)} >
|
||||||
<Transactions limit={20} />
|
<Transactions />
|
||||||
<div className='flex w-full justify-center'>
|
<div className='flex w-full justify-center'>
|
||||||
<Button icon={moreIcon} theme='primary' to='/wallet/transactions'>
|
<Button icon={isLoading ? undefined : moreIcon} theme='primary' onClick={expandTransactions}>
|
||||||
{intl.formatMessage(messages.more)}
|
{isLoading ? intl.formatMessage(messages.loading) : intl.formatMessage(messages.more)}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Column>
|
</Column>
|
||||||
|
|
|
@ -11,9 +11,11 @@ interface WalletState {
|
||||||
wallet: WalletData | null;
|
wallet: WalletData | null;
|
||||||
transactions: Transactions | null;
|
transactions: Transactions | null;
|
||||||
nutzapsList: Record<string, { status: StatusEntity; amount: number; comment: string }>; // TODO: remove
|
nutzapsList: Record<string, { status: StatusEntity; amount: number; comment: string }>; // TODO: remove
|
||||||
|
prevTransaction?: string | null;
|
||||||
|
nextTransaction?: string | null;
|
||||||
|
|
||||||
setWallet: (wallet: WalletData | null) => void;
|
setWallet: (wallet: WalletData | null) => void;
|
||||||
setTransactions: (transactions: Transactions | null) => void;
|
setTransactions: (transactions: Transactions | null, prevTransaction?: string | null, nextTransaction?: string | null) => void;
|
||||||
addNutzap: (statusId: string, data: { status: StatusEntity; amount: number; comment: string }) => void;
|
addNutzap: (statusId: string, data: { status: StatusEntity; amount: number; comment: string }) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,10 +27,12 @@ interface IWalletInfo {
|
||||||
const useWalletStore = create<WalletState>((set) => ({
|
const useWalletStore = create<WalletState>((set) => ({
|
||||||
wallet: null,
|
wallet: null,
|
||||||
transactions: null,
|
transactions: null,
|
||||||
|
prevTransaction: null,
|
||||||
|
nextTransaction: null,
|
||||||
nutzapsList: {},
|
nutzapsList: {},
|
||||||
|
|
||||||
setWallet: (wallet) => set({ wallet }),
|
setWallet: (wallet) => set({ wallet }),
|
||||||
setTransactions: (transactions) => set({ transactions }),
|
setTransactions: (transactions, prevTransaction, nextTransaction) => set({ transactions, prevTransaction, nextTransaction }),
|
||||||
addNutzap: (statusId, data) =>
|
addNutzap: (statusId, data) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
nutzapsList: {
|
nutzapsList: {
|
||||||
|
@ -92,7 +96,7 @@ const useWallet = () => {
|
||||||
|
|
||||||
const useTransactions = () => {
|
const useTransactions = () => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
const { transactions, setTransactions } = useWalletStore();
|
const { transactions, nextTransaction, setTransactions } = useWalletStore();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
@ -100,10 +104,11 @@ const useTransactions = () => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await api.get('/api/v1/ditto/cashu/transactions');
|
const response = await api.get('/api/v1/ditto/cashu/transactions');
|
||||||
|
const { prev, next } = response.pagination();
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data) {
|
if (data) {
|
||||||
const normalizedData = transactionsSchema.parse(data);
|
const normalizedData = transactionsSchema.parse(data);
|
||||||
setTransactions(normalizedData);
|
setTransactions(normalizedData, prev, next);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const messageError = err instanceof Error ? err.message : 'Transactions not found';
|
const messageError = err instanceof Error ? err.message : 'Transactions not found';
|
||||||
|
@ -114,13 +119,37 @@ const useTransactions = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const expandTransactions = async () => {
|
||||||
|
if (!nextTransaction || !transactions) {
|
||||||
|
toast.info('You reached the end of transactions');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
setIsLoading(true);
|
||||||
|
const response = await api.get(nextTransaction);
|
||||||
|
const { prev, next } = response.pagination();
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const normalizedData = transactionsSchema.parse(data);
|
||||||
|
const newTransactions = [...(transactions ?? []), ...normalizedData ];
|
||||||
|
|
||||||
|
setTransactions(newTransactions, prev, next);
|
||||||
|
} catch (err) {
|
||||||
|
const messageError = err instanceof Error ? err.message : 'Error expanding transactions';
|
||||||
|
toast.error(messageError);
|
||||||
|
setError(messageError);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!transactions) {
|
if (!transactions) {
|
||||||
getTransactions();
|
getTransactions();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return { transactions, isLoading, error, getTransactions };
|
return { transactions, isLoading, error, getTransactions, expandTransactions };
|
||||||
};
|
};
|
||||||
|
|
||||||
const useNutzapRequest = () => {
|
const useNutzapRequest = () => {
|
||||||
|
@ -128,6 +157,8 @@ const useNutzapRequest = () => {
|
||||||
const { nutzapsList, addNutzap } = useWalletStore();
|
const { nutzapsList, addNutzap } = useWalletStore();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const { getWallet } = useWallet();
|
||||||
|
const { getTransactions } = useTransactions();
|
||||||
|
|
||||||
const nutzapRequest = async (account: AccountEntity, amount: number, comment: string, status?: StatusEntity) => {
|
const nutzapRequest = async (account: AccountEntity, amount: number, comment: string, status?: StatusEntity) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
@ -147,6 +178,8 @@ const useNutzapRequest = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.success(data.message || 'Nutzap sent successfully!');
|
toast.success(data.message || 'Nutzap sent successfully!');
|
||||||
|
getWallet();
|
||||||
|
getTransactions();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const messageError = err instanceof Error ? err.message : 'An unexpected error occurred';
|
const messageError = err instanceof Error ? err.message : 'An unexpected error occurred';
|
||||||
setError(messageError);
|
setError(messageError);
|
||||||
|
|
|
@ -1724,6 +1724,7 @@
|
||||||
"wallet.create_wallet.question": "Do you want create one?",
|
"wallet.create_wallet.question": "Do you want create one?",
|
||||||
"wallet.create_wallet.title": "You don't have a wallet",
|
"wallet.create_wallet.title": "You don't have a wallet",
|
||||||
"wallet.invalid_url": "All strings must be valid URLs.",
|
"wallet.invalid_url": "All strings must be valid URLs.",
|
||||||
|
"wallet.loading": "Loading…",
|
||||||
"wallet.loading_error": "An unexpected error occurred while loading your wallet data.",
|
"wallet.loading_error": "An unexpected error occurred while loading your wallet data.",
|
||||||
"wallet.management": "Wallet Management",
|
"wallet.management": "Wallet Management",
|
||||||
"wallet.mints": "Mints",
|
"wallet.mints": "Mints",
|
||||||
|
|
Ładowanie…
Reference in New Issue