1
0
forked from maik/IPFS-portal
Files
IPFS-portal-deploy/src/app/admin/payment/components/Overview.tsx
T

109 lines
4.4 KiB
TypeScript
Raw Normal View History

'use client';
import type { TokenInfo } from '@/lib/payment';
import { formatWeiToETH } from '@/lib/wallet';
/* ── Props ── */
interface OverviewProps {
totalUploads: bigint;
tokens: TokenInfo[];
revenues: Record<string, bigint>;
contractBalance: Record<string, string>;
contractAddress: string;
owner: string | null;
isOwner: boolean;
address: string | null;
deployed: boolean;
onNavigate: (view: string) => void;
}
/* ════════════════════════════ Component ════════════════════════════ */
export default function Overview({
totalUploads, tokens, revenues, contractBalance,
contractAddress, owner, isOwner, address, deployed, onNavigate,
}: OverviewProps) {
return (
<div className="space-y-6">
{/* Stats grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="glass rounded-xl p-4">
<div className="text-xs text-surface-400 mb-1">Total Uploads</div>
<div className="text-2xl font-bold text-white">{totalUploads.toString()}</div>
</div>
{tokens.filter(t => t.enabled).map(tk => {
const rev = revenues[tk.symbol] || BigInt(0);
const bal = contractBalance[tk.symbol];
return (
<div key={tk.symbol} className="glass rounded-xl p-4">
<div className="text-xs text-surface-400 mb-1">{tk.symbol} Revenue</div>
<div className="text-2xl font-bold text-white">
{tk.symbol === 'ETH' ? formatWeiToETH(rev, 6) : rev.toString()}
</div>
{bal && (
<div className="text-[10px] text-surface-500 mt-1">
Balance: {tk.symbol === 'ETH' ? formatWeiToETH(bal, 6) : bal} {tk.symbol}
</div>
)}
</div>
);
})}
</div>
{/* Contract info */}
<div className="glass rounded-xl p-5 space-y-3">
<h3 className="text-sm font-semibold text-white">Contract</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-xs">
<div className="flex justify-between py-1.5 px-3 rounded bg-surface-800/30">
<span className="text-surface-400">Address</span>
<span className="font-mono text-surface-200">
{contractAddress.slice(0, 10)}...
</span>
</div>
<div className="flex justify-between py-1.5 px-3 rounded bg-surface-800/30">
<span className="text-surface-400">Owner</span>
<span className="font-mono text-surface-200">
{owner ? `${owner.slice(0, 8)}...${owner.slice(-6)}` : '-'}
{isOwner && <span className="ml-1 text-accent-green"></span>}
</span>
</div>
<div className="flex justify-between py-1.5 px-3 rounded bg-surface-800/30">
<span className="text-surface-400">Deployed</span>
<span className={deployed ? 'text-accent-green' : 'text-accent-rose'}>
{deployed ? 'Yes' : 'No'}
</span>
</div>
<div className="flex justify-between py-1.5 px-3 rounded bg-surface-800/30">
<span className="text-surface-400">Connected</span>
<span className="text-surface-200 font-mono">
{address ? `${address.slice(0, 6)}...${address.slice(-4)}` : '-'}
</span>
</div>
</div>
</div>
{/* If owner — quick actions */}
{isOwner && (
<div className="glass rounded-xl p-5 space-y-3">
<h3 className="text-sm font-semibold text-white">Quick Actions</h3>
<div className="flex flex-wrap gap-2">
<button onClick={() => onNavigate('pricing')}
className="px-3 py-1.5 rounded-lg bg-surface-800 hover:bg-surface-700 text-surface-300 text-xs transition-colors">
Update Pricing
</button>
<button onClick={() => onNavigate('tokens')}
className="px-3 py-1.5 rounded-lg bg-surface-800 hover:bg-surface-700 text-surface-300 text-xs transition-colors">
Manage Tokens
</button>
<button onClick={() => onNavigate('tiers')}
className="px-3 py-1.5 rounded-lg bg-surface-800 hover:bg-surface-700 text-surface-300 text-xs transition-colors">
Discount Tiers
</button>
</div>
</div>
)}
</div>
);
}