Files
Pay2Gateway/components/admin/PlatformTreasuryWidget.tsx

132 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client';
import React, { useState, useEffect } from 'react';
import { Wallet, RefreshCw, Zap, TrendingUp, AlertCircle } from 'lucide-react';
export default function PlatformTreasuryWidget() {
const [treasuryData, setTreasuryData] = useState<any>(null);
const [isLoading, setIsLoading] = useState(true);
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const fetchTreasury = async () => {
setIsLoading(true);
try {
const res = await fetch('/api/admin/treasury/balances');
const data = await res.json();
if (res.ok) {
setTreasuryData(data.balances);
setLastUpdated(new Date());
}
} catch (e) {
console.error('[Treasury Widget] Error:', e);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchTreasury();
}, []);
const networks = [
{ id: 'SOLANA', color: 'text-emerald-500', bg: 'bg-emerald-50', icon: '🟢' },
{ id: 'POLYGON', color: 'text-purple-500', bg: 'bg-purple-50', icon: '🟣' },
{ id: 'TRON', color: 'text-red-500', bg: 'bg-red-50', icon: '🔴' },
{ id: 'BSC', color: 'text-yellow-500', bg: 'bg-yellow-50', icon: '🟡' },
{ id: 'ETH', color: 'text-blue-500', bg: 'bg-blue-50', icon: '🔵' },
{ id: 'BITCOIN', color: 'text-orange-500', bg: 'bg-orange-50', icon: '🟠' }
];
return (
<div className="bg-white rounded-[40px] border border-gray-100 shadow-sm overflow-hidden">
<div className="p-8 border-b border-gray-50 flex justify-between items-center">
<div className="flex items-center gap-4">
<div className="w-12 h-12 bg-gray-900 rounded-2xl flex items-center justify-center text-white shadow-xl">
<Wallet size={24} />
</div>
<div>
<h2 className="text-xl font-black text-gray-900 leading-none">Platform Hazinesi</h2>
<p className="text-[10px] text-gray-400 font-bold uppercase tracking-widest mt-2 flex items-center gap-1.5">
<Zap size={10} className="text-emerald-500 fill-emerald-500" />
Sistem Genelindeki On-Chain Likidite
</p>
</div>
</div>
<div className="flex items-center gap-4">
{lastUpdated && (
<span className="text-[9px] font-black text-gray-300 uppercase tracking-tighter">
Son Güncelleme: {lastUpdated.toLocaleTimeString('tr-TR')}
</span>
)}
<button
onClick={fetchTreasury}
disabled={isLoading}
className={`p-3 rounded-2xl border border-gray-100 text-gray-400 hover:text-gray-900 hover:border-gray-300 transition-all ${isLoading ? 'animate-spin border-transparent text-blue-600' : ''}`}
>
<RefreshCw size={20} />
</button>
</div>
</div>
<div className="p-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-6 gap-6">
{networks.map((net) => {
const data = treasuryData?.[net.id];
const nativeSymbol = data?.nativeSymbol || net.id;
const balance = data?.native || '0.00';
const tokenList = data?.tokens ? Object.entries(data.tokens) : [];
return (
<div key={net.id} className="group relative">
<div className={`p-6 rounded-[32px] border border-gray-100 shadow-sm transition-all duration-300 hover:shadow-xl hover:-translate-y-1 ${net.bg}/20`}>
<div className="flex items-center justify-between mb-4">
<span className="text-2xl drop-shadow-sm">{net.icon}</span>
<span className={`text-[10px] font-black uppercase tracking-widest px-2 py-0.5 rounded-lg bg-white/80 border ${net.color}`}>
{net.id}
</span>
</div>
<div className="space-y-1">
<p className="text-xs font-bold text-gray-400 uppercase tracking-tighter leading-none">Ana Varlık</p>
<div className="flex items-baseline gap-1.5 overflow-hidden">
<h3 className={`text-xl font-black tabular-nums transition-all ${isLoading ? 'blur-sm' : ''} ${net.color}`}>
{balance}
</h3>
<span className="text-[10px] font-black text-gray-400 uppercase">{nativeSymbol}</span>
</div>
</div>
{tokenList.length > 0 && (
<div className="mt-4 pt-4 border-t border-gray-50 space-y-2">
{tokenList.map(([symbol, bal]) => (
<div key={symbol as string} className="flex justify-between items-center text-[10px] font-bold">
<span className="text-gray-400 uppercase">{symbol as string}</span>
<span className="text-gray-900 tabular-nums">{bal as string}</span>
</div>
))}
</div>
)}
{balance === "Error" && (
<div className="mt-2 text-[8px] font-black text-red-500 uppercase flex items-center gap-1">
<AlertCircle size={10} /> Bağlantı Hatası
</div>
)}
</div>
</div>
);
})}
</div>
<div className="mt-8 p-4 bg-blue-50/50 rounded-2xl border border-blue-100/50 flex items-center gap-3">
<TrendingUp className="text-blue-600" size={18} />
<p className="text-[10px] font-bold text-blue-800 leading-relaxed uppercase tracking-tight">
Yukarıdaki bakiyeler platformun operasyonel cüzdanlarından (Platform Treasury) anlık olarak çekilir. Ödemeler bu likidite üzerinden karşılanmaktadır.
</p>
</div>
</div>
</div>
);
}