Files
democratic-money/src/app/casino/[game]/page.tsx
2026-05-16 00:47:44 +00:00

96 lines
4.8 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.
import { redirect, notFound } from "next/navigation";
import Link from "next/link";
import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";
import { creditTicker } from "@/lib/credits-brand";
import { SiteFooter } from "@/components/SiteFooter";
import { ExchangePanel } from "@/components/casino/ExchangePanel";
import { CrashGame } from "@/components/casino/CrashGame";
import { DiceGame } from "@/components/casino/DiceGame";
import { MinesGame } from "@/components/casino/MinesGame";
import { TowerGame } from "@/components/casino/TowerGame";
import { SlotsGame } from "@/components/casino/SlotsGame";
import { BlackjackGame } from "@/components/casino/BlackjackGame";
import { RouletteGame } from "@/components/casino/RouletteGame";
import { CoinFlipRoom } from "@/components/casino/CoinFlipRoom";
import { PongGame } from "@/components/casino/PongGame";
import { PredictionMarket } from "@/components/casino/PredictionMarket";
const T = creditTicker();
const GAME_META: Record<string, { name: string; icon: string; desc: string }> = {
crash: { name: `${T} Crash`, icon: "📈", desc: "Multiplier rises from 1x — cash out before it crashes. Provably fair." },
dice: { name: "Dice Roll", icon: "🎲", desc: "Pick over or under a threshold. Adjust your risk and win chance live." },
mines: { name: "Mines", icon: "💣", desc: "5×5 grid — reveal tiles to grow your multiplier and cash out before hitting a mine." },
tower: { name: "Tower Climb", icon: "🏰", desc: "Pick a safe tile on each floor to climb higher and earn bigger multipliers." },
slots: { name: "Slots", icon: "🎰", desc: "3-reel classic slot machine with configurable seeds and a full paytable." },
blackjack: { name: "Blackjack", icon: "🃏", desc: "Classic single-deck blackjack. Hit, stand, or double down against the house." },
roulette: { name: "Roulette", icon: "🎡", desc: "European roulette (single zero). Bet on numbers, colors, dozens, and more." },
coinflip: { name: "Coin Flip Duel", icon: "🪙", desc: "Create or join a room. Both players wager the same amount — the flip decides." },
pong: { name: "PvP Pong", icon: "🏓", desc: `Real-time pong against another player. Bet ${T} — first to 5 wins the pot.` },
prediction: { name: "Prediction Market", icon: "📊", desc: `Post a yes/no question. Users pool ${T} — correct side splits the pot.` },
};
export default async function GamePage({ params }: { params: Promise<{ game: string }> }) {
const { game } = await params;
const meta = GAME_META[game];
if (!meta) notFound();
const session = await auth();
if (!session?.user?.id) redirect(`/login?callbackUrl=${encodeURIComponent(`/casino/${game}`)}`);
const wallet = await prisma.wallet.findUnique({ where: { userId: session.user.id } });
const balance = wallet?.balanceCredits ?? 0;
const userId = session.user.id;
function GameComponent() {
switch (game) {
case "crash": return <CrashGame balance={balance} />;
case "dice": return <DiceGame balance={balance} />;
case "mines": return <MinesGame balance={balance} />;
case "tower": return <TowerGame balance={balance} />;
case "slots": return <SlotsGame balance={balance} />;
case "blackjack": return <BlackjackGame balance={balance} />;
case "roulette": return <RouletteGame balance={balance} />;
case "coinflip": return <CoinFlipRoom userId={userId} balance={balance} />;
case "pong": return <PongGame userId={userId} balance={balance} />;
case "prediction": return <PredictionMarket userId={userId} balance={balance} />;
default: return null;
}
}
return (
<>
<main className="min-h-screen bg-[#030712] px-4 py-8 sm:px-6">
<div className="mx-auto max-w-6xl">
<div className="flex items-center gap-3 mb-6">
<Link href="/casino" className="text-slate-400 hover:text-white transition-colors text-sm">
Casino
</Link>
<span className="text-slate-600">/</span>
<span className="text-white font-medium">{meta.name}</span>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div className="space-y-4">
<ExchangePanel initialBalance={balance} />
<div className="rounded-2xl border border-white/10 bg-white/5 p-5">
<div className="flex items-center gap-3 mb-2">
<span className="text-3xl">{meta.icon}</span>
<h1 className="text-xl font-bold text-white">{meta.name}</h1>
</div>
<p className="text-slate-400 text-sm">{meta.desc}</p>
</div>
</div>
<div className="lg:col-span-2 rounded-2xl border border-white/10 bg-white/5 p-5">
<GameComponent />
</div>
</div>
</div>
</main>
<SiteFooter />
</>
);
}