Crypto Arbitrage - Copy this React, Tailwind Component to your project
import-React,-{-useState,-useCallback,-useEffect-}-from-'react';-import-{-Card,-CardHeader,-CardTitle,-CardContent-}-from-'@/components/ui/card';-import-{-Tabs,-TabsList,-TabsTrigger,-TabsContent-}-from-'@/components/ui/tabs';-import-{-Switch-}-from-'@/components/ui/switch';-import-{-Slider-}-from-'@/components/ui/slider';-import-{-Alert,-AlertDescription-}-from-'@/components/ui/alert';-import-{-Button-}-from-'@/components/ui/button';-import-{-Badge-}-from-'@/components/ui/badge';-import-{-Bell,-ArrowUpDown,-LineChart,-Wallet,-Shield,-History,-Settings,-Play,-TrendingUp,-Lock,-AlertTriangle-}-from-'lucide-react';-import-{-AreaChart,-Area,-XAxis,-YAxis,-CartesianGrid,-Tooltip,-ResponsiveContainer-}-from-'recharts';-const-CryptoArbitrageApp-=-()-=>-{-//-Core-state-management-const-[activeTab,-setActiveTab]-=-useState('opportunities');-const-[demoMode,-setDemoMode]-=-useState(false);-const-[selectedPair,-setSelectedPair]-=-useState('BTC/USDT');-const-[autoTrading,-setAutoTrading]-=-useState(false);-const-[profitThreshold,-setProfitThreshold]-=-useState(1.0);-const-[notifications,-setNotifications]-=-useState([]);-const-[balance,-setBalance]-=-useState(demoMode-?-10000-:-0);-const-[activeOpportunities,-setActiveOpportunities]-=-useState([]);-const-[transactions,-setTransactions]-=-useState([]);-//-Market-data-state-const-[tradingPairs]-=-useState([-{-pair:-'BTC/USDT',-volume:-'$2.5B',-change:-'+2.3%',-price:-45000-},-{-pair:-'ETH/USDT',-volume:-'$1.8B',-change:-'+1.5%',-price:-3200-},-{-pair:-'SOL/USDT',-volume:-'$850M',-change:-'+4.2%',-price:-98-},-{-pair:-'BNB/USDT',-volume:-'$720M',-change:-'-0.8%',-price:-320-},-]);-//-Generate-simulated-opportunities-const-generateOpportunities-=-useCallback(()-=>-{-const-baseOpportunities-=-tradingPairs.map((pair,-index)-=>-{-const-priceDiff-=-(Math.random()-*-2-+-0.5).toFixed(2);-const-volume-=-Math.floor(Math.random()-*-50000-+-10000);-const-profit-=-(volume-*-(parseFloat(priceDiff)-/-100)).toFixed(2);-return-{-id:-index-+-1,-pair:-pair.pair,-buyExchange:-'Binance',-sellExchange:-'Coinbase',-priceDiff:-`${priceDiff}%`,-profit:-`$${profit}`,-volume:-`$${volume}`,-risk:-parseFloat(priceDiff)-<-1-?-'Low'-:-parseFloat(priceDiff)-<-1.5-?-'Medium'-:-'High',-timeWindow:-`${Math.floor(Math.random()-*-30-+-15)}s`-};-});-setActiveOpportunities(baseOpportunities);-},-[tradingPairs]);-//-Auto-update-opportunities-useEffect(()-=>-{-const-interval-=-setInterval(()-=>-{-if-(demoMode)-{-generateOpportunities();-}-},-5000);-return-()-=>-clearInterval(interval);-},-[demoMode,-generateOpportunities]);-//-Initialize-demo-data-useEffect(()-=>-{-if-(demoMode)-{-generateOpportunities();-}-},-[demoMode,-generateOpportunities]);-//-Handle-trade-execution-const-executeTrade-=-useCallback((opportunity)-=>-{-if-(!demoMode)-{-setNotifications(prev-=>-[...prev,-{-id:-Date.now(),-message:-'Please-enable-demo-mode-to-test-trading-functionality',-type:-'warning'-}]);-return;-}-const-profit-=-parseFloat(opportunity.profit.replace('$',-''));-const-newBalance-=-balance-+-profit;-setBalance(newBalance);-setTransactions(prev-=>-[{-id:-Date.now(),-pair:-opportunity.pair,-type:-'Arbitrage',-profit:-opportunity.profit,-time:-'Just-now',-status:-'Completed',-fees:-`$${(profit-*-0.001).toFixed(2)}`,-},-...prev]);-setNotifications(prev-=>-[...prev,-{-id:-Date.now(),-message:-`Successfully-executed-${opportunity.pair}-arbitrage-trade`,-type:-'success'-}]);-},-[demoMode,-balance]);-//-Generate-profit-chart-data-const-profitChartData-=-transactions.slice(0,-7).map((tx,-index)-=>-({-name:-`Trade-${index-+-1}`,-profit:-parseFloat(tx.profit.replace('$',-'')),-})).reverse();-return-(-<div-className="max-w-md-mx-auto-bg-gray-50-min-h-screen">-{/*-Demo-Mode-Banner-*/}-{demoMode-&&-(-<div-className="bg-yellow-500-text-white-px-4-py-2-text-center-text-sm">-Demo-Mode-Active---Using-Simulated-Data-</div>-)}-{/*-Notifications-*/}-<div-className="fixed-top-4-right-4-z-50-space-y-2">-{notifications.map(notification-=>-(-<Alert-key={notification.id}-className={`w-64-${-notification.type-===-'success'-?-'bg-green-500'-:-'bg-yellow-500'-}-text-white`}>-<AlertDescription>{notification.message}</AlertDescription>-</Alert>-))}-</div>-{/*-Header-*/}-<div-className="bg-blue-600-text-white-p-4">-<div-className="flex-justify-between-items-center">-<h1-className="text-xl-font-bold">CryptoArb-Pro</h1>-<div-className="flex-gap-2-items-center">-<span-className="text-sm">Demo</span>-<Switch-checked={demoMode}-onCheckedChange={setDemoMode}-className="data-[state=checked]:bg-yellow-500"-/>-</div>-</div>-{/*-Balance-Display-*/}-<div-className="mt-4-bg-blue-500-rounded-lg-p-4">-<div-className="flex-justify-between-items-center">-<div>-<p-className="text-sm-opacity-80">Available-Balance</p>-<p-className="text-2xl-font-bold">${balance.toFixed(2)}</p>-</div>-<div-className="h-16-w-32">-{profitChartData.length->-0-&&-(-<ResponsiveContainer-width="100%"-height="100%">-<AreaChart-data={profitChartData}>-<Area-type="monotone"-dataKey="profit"-stroke="#ffffff"-fill="rgba(255,255,255,0.2)"-/>-</AreaChart>-</ResponsiveContainer>-)}-</div>-</div>-</div>-</div>-{/*-Trading-Pairs-*/}-<div-className="bg-white-border-b-overflow-x-auto">-<div-className="flex-p-2-space-x-2">-{tradingPairs.map((pair)-=>-(-<div-key={pair.pair}-onClick={()-=>-setSelectedPair(pair.pair)}-className={`flex-shrink-0-p-2-rounded-lg-border-cursor-pointer-${selectedPair-===-pair.pair-?-'border-blue-500-bg-blue-50'-:-'border-gray-200'}`}->-<div-className="text-sm-font-bold">{pair.pair}</div>-<div-className="text-xs-text-gray-500">{pair.volume}</div>-<div-className={`text-xs-${pair.change.startsWith('+')-?-'text-green-600'-:-'text-red-600'}`}>-{pair.change}-</div>-</div>-))}-</div>-</div>-{/*-Main-Content-*/}-<Tabs-value={activeTab}-onValueChange={setActiveTab}-className="w-full">-<TabsList-className="grid-w-full-grid-cols-4-bg-white-border-b">-<TabsTrigger-value="opportunities">-<ArrowUpDown-className="w-5-h-5"-/>-</TabsTrigger>-<TabsTrigger-value="trades">-<History-className="w-5-h-5"-/>-</TabsTrigger>-<TabsTrigger-value="analysis">-<TrendingUp-className="w-5-h-5"-/>-</TabsTrigger>-<TabsTrigger-value="settings">-<Settings-className="w-5-h-5"-/>-</TabsTrigger>-</TabsList>-<TabsContent-value="opportunities">-<Card>-<CardHeader-className="flex-flex-row-items-center-justify-between">-<CardTitle>Live-Opportunities</CardTitle>-<Badge-variant="outline">{activeOpportunities.length}-Active</Badge>-</CardHeader>-<CardContent>-<div-className="space-y-4">-{activeOpportunities.map(opp-=>-(-<div-key={opp.id}-className="bg-white-p-4-rounded-lg-border-hover:border-blue-500-transition-all">-<div-className="flex-justify-between-items-center">-<div>-<h3-className="font-bold">{opp.pair}</h3>-<p-className="text-sm-text-gray-500">-{opp.buyExchange}-→-{opp.sellExchange}-</p>-</div>-<div-className="text-right">-<p-className="text-green-600-font-bold">{opp.priceDiff}</p>-<p-className="text-sm-text-gray-500">Est.-Profit:-{opp.profit}</p>-</div>-</div>-<div-className="mt-2-flex-justify-between-items-center">-<div-className="flex-items-center-space-x-2">-<span-className="text-sm-text-gray-500">Vol:-{opp.volume}</span>-<span-className="text-sm-text-gray-500">Window:-{opp.timeWindow}</span>-</div>-<span-className={`text-sm-px-2-py-1-rounded-${-opp.risk-===-'Low'-?-'bg-green-100-text-green-800'-:-opp.risk-===-'Medium'-?-'bg-yellow-100-text-yellow-800'-:-'bg-red-100-text-red-800'-}`}>{opp.risk}-Risk</span>-</div>-<Button-className="w-full-mt-2"-onClick={()-=>-executeTrade(opp)}-disabled={!demoMode}->-Execute-Trade-{demoMode-?-'(Demo)'-:-''}-</Button>-</div>-))}-</div>-</CardContent>-</Card>-</TabsContent>-<TabsContent-value="trades">-<Card>-<CardHeader>-<CardTitle>Recent-Trades</CardTitle>-</CardHeader>-<CardContent>-{transactions.length-===-0-?-(-<div-className="text-center-text-gray-500-py-8">-No-trades-executed-yet-</div>-)-:-(-<div-className="space-y-4">-{transactions.map(tx-=>-(-<div-key={tx.id}-className="bg-white-p-4-rounded-lg-border">-<div-className="flex-justify-between-items-center">-<div>-<h3-className="font-bold">{tx.pair}</h3>-<p-className="text-sm-text-gray-500">{tx.time}</p>-</div>-<div-className="text-right">-<p-className="text-green-600-font-bold">{tx.profit}</p>-<p-className="text-sm-text-gray-500">{tx.status}</p>-</div>-</div>-<div-className="mt-2-text-sm-text-gray-600">-<p>Fees:-{tx.fees}</p>-</div>-</div>-))}-</div>-)}-</CardContent>-</Card>-</TabsContent>-</Tabs>-</div>-);-};-export-default-CryptoArbitrageApp;
