import { useState, useEffect, useRef, useCallback } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { Wallet, Users, History, Landmark, Plus, Minus, Send, ArrowRightLeft, TrendingUp, Zap, ChevronRight, X, Check, CreditCard, DollarSign, Activity, Shield } from "lucide-react"; const STARTING_BALANCE = 1500; const NEON_GREEN = "#00ff9d"; const NEON_CYAN = "#00e5ff"; const GOLD = "#ffd700"; const formatMoney = (amount) => new Intl.NumberFormat("de-DE", { style: "currency", currency: "USD", maximumFractionDigits: 0 }).format(amount); const GlowCard = ({ children, className = "", accent = "green", onClick, hover = true }) => { const accents = { green: "border-emerald-500/30 hover:border-emerald-400/60 hover:shadow-emerald-500/20", cyan: "border-cyan-500/30 hover:border-cyan-400/60 hover:shadow-cyan-500/20", gold: "border-yellow-500/30 hover:border-yellow-400/60 hover:shadow-yellow-500/20", red: "border-red-500/30 hover:border-red-400/60 hover:shadow-red-500/20", }; return (
{children}
); }; const NeonButton = ({ children, onClick, variant = "green", size = "md", disabled = false, className = "" }) => { const variants = { green: "bg-emerald-500/20 border-emerald-400/50 text-emerald-300 hover:bg-emerald-500/40 hover:border-emerald-300 hover:shadow-emerald-500/40", cyan: "bg-cyan-500/20 border-cyan-400/50 text-cyan-300 hover:bg-cyan-500/40 hover:border-cyan-300 hover:shadow-cyan-500/40", gold: "bg-yellow-500/20 border-yellow-400/50 text-yellow-300 hover:bg-yellow-500/40 hover:border-yellow-300 hover:shadow-yellow-500/40", red: "bg-red-500/20 border-red-400/50 text-red-300 hover:bg-red-500/40 hover:border-red-300 hover:shadow-red-500/40", ghost: "bg-white/5 border-white/10 text-white/70 hover:bg-white/10 hover:border-white/20", }; const sizes = { sm: "px-3 py-1.5 text-xs", md: "px-4 py-2 text-sm", lg: "px-6 py-3 text-base", }; return ( {children} ); }; const NeonInput = ({ value, onChange, placeholder, type = "text", className = "" }) => ( ); const NeonSelect = ({ value, onChange, children, className = "" }) => ( ); const StatCard = ({ icon: Icon, label, value, accent = "green", delay = 0 }) => { const colors = { green: { text: "text-emerald-400", bg: "bg-emerald-500/10", glow: "shadow-emerald-500/20" }, cyan: { text: "text-cyan-400", bg: "bg-cyan-500/10", glow: "shadow-cyan-500/20" }, gold: { text: "text-yellow-400", bg: "bg-yellow-500/10", glow: "shadow-yellow-500/20" }, purple: { text: "text-purple-400", bg: "bg-purple-500/10", glow: "shadow-purple-500/20" }, }; const c = colors[accent]; return (

{label}

{value}

); }; const PlayerCard = ({ player, onAdjust, onRemove, index }) => { const isRich = player.balance >= 2000; const isPoor = player.balance < 500; const balanceColor = isRich ? "text-emerald-400" : isPoor ? "text-red-400" : "text-cyan-300"; return (
{player.name.charAt(0).toUpperCase()}

{player.name}

ID: #{String(player.id).padStart(4, "0")}

Kontostand

{formatMoney(player.balance)}

onAdjust(player.id, 100)} className="flex-1 flex items-center justify-center gap-1" > $100 onAdjust(player.id, 50)} className="flex-1 flex items-center justify-center gap-1" > $50 onAdjust(player.id, -100)} className="flex-1 flex items-center justify-center gap-1" > $100
); }; const TransactionItem = ({ tx, index }) => { const isBank = tx.from === "Bank" || tx.to === "Bank"; return (
{isBank ? : }
{tx.from} → {tx.to} {formatMoney(tx.amount)}

{tx.time}

); }; export default function MonopolyBank() { const [players, setPlayers] = useState([ { id: 1, name: "Alice", balance: 1500 }, { id: 2, name: "Bob", balance: 1500 }, ]); const [transactions, setTransactions] = useState([ { id: 1, from: "Bank", to: "Alice", amount: 1500, time: "Spielstart" }, { id: 2, from: "Bank", to: "Bob", amount: 1500, time: "Spielstart" }, ]); const [newPlayerName, setNewPlayerName] = useState(""); const [transferFrom, setTransferFrom] = useState(""); const [transferTo, setTransferTo] = useState(""); const [transferAmount, setTransferAmount] = useState(""); const [toast, setToast] = useState(null); const [activeTab, setActiveTab] = useState("players"); const nextId = useRef(3); const totalMoney = players.reduce((s, p) => s + p.balance, 0); const showToast = (msg, type = "success") => { setToast({ msg, type }); setTimeout(() => setToast(null), 2800); }; const addPlayer = () => { const name = newPlayerName.trim(); if (!name) return showToast("Bitte Namen eingeben", "error"); if (players.find(p => p.name.toLowerCase() === name.toLowerCase())) return showToast("Spieler bereits vorhanden", "error"); const player = { id: nextId.current++, name, balance: STARTING_BALANCE }; setPlayers(prev => [...prev, player]); setTransactions(prev => [ { id: Date.now(), from: "Bank", to: name, amount: STARTING_BALANCE, time: new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) }, ...prev, ]); setNewPlayerName(""); showToast(`${name} hat ${formatMoney(STARTING_BALANCE)} erhalten`); }; const removePlayer = (id) => { const player = players.find(p => p.id === id); if (!player) return; setPlayers(prev => prev.filter(p => p.id !== id)); showToast(`${player.name} wurde entfernt`, "error"); }; const adjustBalance = useCallback((id, delta) => { const player = players.find(p => p.id === id); if (!player) return; if (player.balance + delta < 0) return showToast("Nicht genug Geld!", "error"); setPlayers(prev => prev.map(p => p.id === id ? { ...p, balance: p.balance + delta } : p)); const desc = delta > 0 ? "Bank" : player.name; const dest = delta > 0 ? player.name : "Bank"; setTransactions(prev => [ { id: Date.now(), from: desc, to: dest, amount: Math.abs(delta), time: new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) }, ...prev, ]); }, [players]); const transfer = useCallback(() => { const amount = parseInt(transferAmount); if (!transferFrom || !transferTo) { return showToast("Bitte Sender und Empfänger auswählen", "error"); } if (transferFrom === transferTo) { return showToast("Sender und Empfänger müssen unterschiedlich sein", "error"); } if (!amount || amount <= 0 || isNaN(amount)) { return showToast("Bitte einen gültigen Betrag eingeben", "error"); } const sender = players.find(p => String(p.id) === String(transferFrom)); const receiver = players.find(p => String(p.id) === String(transferTo)); if (!sender || !receiver) { return showToast("Spieler nicht gefunden", "error"); } if (sender.balance < amount) { return showToast(`${sender.name} hat nicht genug Guthaben!`, "error"); } setPlayers(prev => prev.map(p => { if (String(p.id) === String(transferFrom)) { return { ...p, balance: p.balance - amount }; } if (String(p.id) === String(transferTo)) { return { ...p, balance: p.balance + amount }; } return p; })); setTransactions(prev => [ { id: Date.now(), from: sender.name, to: receiver.name, amount: amount, time: new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit", second: "2-digit" }) }, ...prev, ]); setTransferAmount(""); showToast(`${formatMoney(amount)} von ${sender.name} an ${receiver.name} transferiert`); }, [transferFrom, transferTo, transferAmount, players]); const tabs = [ { id: "players", label: "Spieler", icon: Users }, { id: "transfer", label: "Transfer", icon: Send }, { id: "history", label: "Verlauf", icon: History }, ]; return (
{/* Animated background grid */}
{/* Toast */} {toast && (
{toast.type === "error" ? : } {toast.msg}
)}
{/* Header */}

MONO BANK

Digital Banking System

AKTIV
{/* Stats */}
{/* Main Panel */}
{/* Add Player */}

Spieler hinzufügen

setNewPlayerName(e.target.value)} placeholder="Spielername eingeben…" className="flex-1" onKeyPress={e => e.key === 'Enter' && addPlayer()} /> Hinzufügen +

Startguthaben: {formatMoney(STARTING_BALANCE)} automatisch

{/* Mobile tabs */}
{tabs.map(t => ( ))}
{/* Transfer Panel */}

Geld transferieren

setTransferFrom(e.target.value)}> {players.map(p => ( ))}
setTransferTo(e.target.value)}> {players.map(p => ( ))}
setTransferAmount(e.target.value)} placeholder="z.B. 200" onKeyPress={e => e.key === 'Enter' && transfer()} />
Transfer senden
{/* Players Grid */}

Kontoübersicht

{players.length} Spieler
{players.length === 0 ? (

Keine Spieler vorhanden

Füge oben einen Spieler hinzu

) : (
{players.map((player, i) => ( ))}
)}
{/* Sidebar – Transactions */}

Transaktionsverlauf

Live
{transactions.length === 0 ? (

Keine Transaktionen

) : ( transactions.slice(0, 30).map((tx, i) => ( )) )}
{/* Footer */}
); }