solana / src /components /dashboard /TargetWalletManager.tsx
dronesplace's picture
Initial upload
2acde71 verified
Raw
History Blame Contribute Delete
5.82 kB
import React, { useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Plus, Trash2, Target, Activity, DollarSign } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
interface TargetWalletManagerProps {
wallets: string[];
setWallets: (wallets: string[]) => void;
}
export const TargetWalletManager: React.FC<TargetWalletManagerProps> = ({
wallets,
setWallets
}) => {
const [newWallet, setNewWallet] = useState('');
const { toast } = useToast();
const addWallet = () => {
if (!newWallet.trim()) {
toast({
title: "Invalid Address",
description: "Please enter a valid Solana wallet address",
variant: "destructive"
});
return;
}
// Basic validation for Solana address (should be 32-44 characters)
if (newWallet.length < 32 || newWallet.length > 44) {
toast({
title: "Invalid Address Format",
description: "Solana addresses should be 32-44 characters long",
variant: "destructive"
});
return;
}
if (wallets.includes(newWallet)) {
toast({
title: "Wallet Already Added",
description: "This wallet address is already in your target list",
variant: "destructive"
});
return;
}
setWallets([...wallets, newWallet]);
setNewWallet('');
toast({
title: "Wallet Added",
description: "Target wallet successfully added to monitoring list",
});
};
const removeWallet = (wallet: string) => {
setWallets(wallets.filter(w => w !== wallet));
toast({
title: "Wallet Removed",
description: "Target wallet removed from monitoring list",
});
};
// Mock data for demonstration
const walletStats = {
[wallets[0]]: {
totalTrades: 156,
profitLoss: 2341.56,
successRate: 72.4,
lastActive: '2 minutes ago'
}
};
return (
<Card className="bg-gradient-card border-border/50">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Target className="h-5 w-5 text-primary" />
Target Wallets
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="wallet-address">Add Target Wallet</Label>
<div className="flex gap-2">
<Input
id="wallet-address"
placeholder="Enter Solana wallet address..."
value={newWallet}
onChange={(e) => setNewWallet(e.target.value)}
className="flex-1"
/>
<Button onClick={addWallet} className="gap-2">
<Plus className="h-4 w-4" />
Add
</Button>
</div>
</div>
<div className="space-y-3">
{wallets.length === 0 ? (
<div className="text-center py-8 text-muted-foreground">
<Target className="h-12 w-12 mx-auto mb-3 opacity-50" />
<p>No target wallets added yet</p>
<p className="text-sm">Add wallet addresses to start copying trades</p>
</div>
) : (
wallets.map((wallet, index) => (
<div
key={wallet}
className="p-4 rounded-lg border bg-secondary/50 animate-fade-in"
style={{ animationDelay: `${index * 0.1}s` }}
>
<div className="flex items-start justify-between mb-3">
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2 mb-1">
<Badge variant="outline" className="text-xs">
#{index + 1}
</Badge>
<Badge variant="secondary" className="text-xs">
Active
</Badge>
</div>
<p className="font-mono text-sm break-all">
{wallet.slice(0, 8)}...{wallet.slice(-8)}
</p>
</div>
<Button
variant="ghost"
size="sm"
onClick={() => removeWallet(wallet)}
className="text-destructive hover:text-destructive"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
{/* Mock stats for demonstration */}
{walletStats[wallet] && (
<div className="grid grid-cols-2 gap-4 text-xs">
<div className="flex items-center gap-1">
<Activity className="h-3 w-3 text-info" />
<span>{walletStats[wallet].totalTrades} trades</span>
</div>
<div className="flex items-center gap-1">
<DollarSign className="h-3 w-3 text-profit" />
<span className="text-profit">
${walletStats[wallet].profitLoss.toFixed(2)}
</span>
</div>
<div className="text-muted-foreground col-span-2">
Last active: {walletStats[wallet].lastActive}
</div>
</div>
)}
</div>
))
)}
</div>
</CardContent>
</Card>
);
};