adding a stake form and approvals in both stake and swap form

This commit is contained in:
2025-10-28 11:27:26 -04:00
parent dbfdfbd4ab
commit 66e28ed08d
6 changed files with 752 additions and 33 deletions

View File

@@ -5,18 +5,18 @@ import { useTranslation } from 'react-i18next';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { ArrowDownUp, ChevronDown, Settings } from 'lucide-react';
import { ArrowDownUp, ChevronDown, Settings, CheckCircle, XCircle, Loader2 } from 'lucide-react';
import { useAccount } from 'wagmi';
import { useTokenDetails, useGetPoolsByToken, type TokenDetails } from '@/hooks/usePartyPlanner';
import { useSwapAmounts, useSwap, selectBestSwapRoute } from '@/hooks/usePartyPool';
import { formatUnits, parseUnits } from 'viem';
import { SwapReviewModal } from './swap-review-modal';
import { useToast } from '@/components/ui/toast';
type TransactionStatus = 'idle' | 'pending' | 'success' | 'error';
export function SwapForm() {
const { t } = useTranslation();
const { isConnected, address } = useAccount();
const { addToast, updateToast } = useToast();
const [fromAmount, setFromAmount] = useState('');
const [toAmount, setToAmount] = useState('');
const [selectedFromToken, setSelectedFromToken] = useState<TokenDetails | null>(null);
@@ -26,6 +26,8 @@ export function SwapForm() {
const [maxSlippage, setMaxSlippage] = useState<string>('5.5'); // Default 5.5%
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
const [isReviewModalOpen, setIsReviewModalOpen] = useState(false);
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('idle');
const [transactionError, setTransactionError] = useState<string | null>(null);
const fromDropdownRef = useRef<HTMLDivElement>(null);
const toDropdownRef = useRef<HTMLDivElement>(null);
@@ -95,12 +97,8 @@ export function SwapForm() {
return;
}
// Show swapping toast
const toastId = addToast({
title: 'Swapping',
description: `${fromAmount} ${selectedFromToken.symbol}${toAmount} ${selectedToToken.symbol}`,
type: 'loading',
});
setTransactionStatus('pending');
setTransactionError(null);
try {
// Use the shared helper to select the best swap route
@@ -108,11 +106,8 @@ export function SwapForm() {
if (!bestRoute) {
console.error('No valid swap route found');
updateToast(toastId, {
title: 'Swap Failed',
description: 'No valid swap route found',
type: 'error',
});
setTransactionError('No valid swap route found');
setTransactionStatus('error');
return;
}
@@ -129,26 +124,24 @@ export function SwapForm() {
currentSlippage
);
// Update toast to success
updateToast(toastId, {
title: 'Swap Confirmed',
description: `Successfully swapped ${fromAmount} ${selectedFromToken.symbol} to ${toAmount} ${selectedToToken.symbol}`,
type: 'success',
});
setTransactionStatus('success');
} catch (err) {
console.error('Swap failed:', err);
setTransactionError(err instanceof Error ? err.message : 'Transaction failed');
setTransactionStatus('error');
}
};
const handleCloseModal = () => {
if (transactionStatus === 'success') {
// Clear the form after successful swap
setFromAmount('');
setToAmount('');
setSelectedFromToken(null);
setSelectedToToken(null);
} catch (err) {
console.error('Swap failed:', err);
updateToast(toastId, {
title: 'Swap Failed',
description: err instanceof Error ? err.message : 'Transaction failed',
type: 'error',
});
}
setTransactionStatus('idle');
setTransactionError(null);
};
const switchTokens = () => {
@@ -177,7 +170,7 @@ export function SwapForm() {
}, [swapAmounts, selectedFromToken, selectedToToken, fromAmount, currentSlippage, isConnected]);
return (
<Card className="w-full max-w-md mx-auto">
<Card className="w-full max-w-md mx-auto relative">
<CardHeader>
<div className="flex justify-between items-center">
<CardTitle>Swap</CardTitle>
@@ -428,6 +421,59 @@ export function SwapForm() {
}}
isSwapping={isSwapping}
/>
{/* Transaction Modal Overlay */}
{transactionStatus !== 'idle' && (
<div className="absolute inset-0 bg-background/80 backdrop-blur-sm flex items-center justify-center z-50 rounded-lg">
<div className="bg-card border rounded-lg p-8 max-w-sm w-full mx-4 shadow-lg">
{transactionStatus === 'pending' && (
<div className="flex flex-col items-center space-y-4">
<Loader2 className="h-16 w-16 animate-spin text-primary" />
<h3 className="text-xl font-semibold text-center">Approving Swap</h3>
<p className="text-sm text-muted-foreground text-center">
Swapping {fromAmount} {selectedFromToken?.symbol} {toAmount} {selectedToToken?.symbol}
</p>
<p className="text-xs text-muted-foreground text-center">
Please confirm the transactions in your wallet
</p>
</div>
)}
{transactionStatus === 'success' && (
<div className="flex flex-col items-center space-y-4">
<CheckCircle className="h-16 w-16 text-green-500" />
<h3 className="text-xl font-semibold text-center">Swap Confirmed!</h3>
<p className="text-sm text-muted-foreground text-center">
Successfully swapped {fromAmount} {selectedFromToken?.symbol} to {toAmount} {selectedToToken?.symbol}
</p>
<Button
onClick={handleCloseModal}
className="w-full mt-4"
>
Close
</Button>
</div>
)}
{transactionStatus === 'error' && (
<div className="flex flex-col items-center space-y-4">
<XCircle className="h-16 w-16 text-destructive" />
<h3 className="text-xl font-semibold text-center">Swap Failed</h3>
<p className="text-sm text-muted-foreground text-center break-words">
{transactionError || 'Transaction failed'}
</p>
<Button
onClick={handleCloseModal}
variant="outline"
className="w-full mt-4"
>
Close
</Button>
</div>
)}
</div>
</div>
)}
</Card>
);
}