Start repository
This commit is contained in:
132
src/App.tsx
Normal file
132
src/App.tsx
Normal file
@@ -0,0 +1,132 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { usePartyKit } from './hooks/usePartyKit';
|
||||
import { ClickButton } from './components/ClickButton';
|
||||
import { Counter } from './components/Counter';
|
||||
import { UpgradeShop } from './components/UpgradeShop';
|
||||
import { Milestones } from './components/Milestones';
|
||||
import { Leaderboard } from './components/Leaderboard';
|
||||
import { Background } from './components/Background';
|
||||
import { MILESTONES } from './config/milestones';
|
||||
|
||||
function App() {
|
||||
const { gameState, sendClick, purchaseUpgrade, userId } = usePartyKit();
|
||||
const [celebrationMessage, setCelebrationMessage] = useState<string | null>(null);
|
||||
const [previousMilestones, setPreviousMilestones] = useState<Record<string, boolean>>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (gameState) {
|
||||
// Check for new milestones
|
||||
const newMilestones = Object.keys(gameState.milestones).filter(
|
||||
(milestoneId) =>
|
||||
gameState.milestones[milestoneId] &&
|
||||
!previousMilestones[milestoneId]
|
||||
);
|
||||
|
||||
if (newMilestones.length > 0) {
|
||||
const milestone = MILESTONES.find(m => m.id === newMilestones[0]);
|
||||
if (milestone) {
|
||||
setCelebrationMessage(milestone.reward);
|
||||
setTimeout(() => setCelebrationMessage(null), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
setPreviousMilestones(gameState.milestones);
|
||||
}
|
||||
}, [gameState, previousMilestones]);
|
||||
|
||||
if (!gameState) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-purple-900 to-pink-900">
|
||||
<div className="text-white text-2xl font-bold animate-pulse">
|
||||
Connecting to the Bozo Network...
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const userClicks = gameState.users[userId]?.clicks || 0;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen relative overflow-x-hidden">
|
||||
<Background background={gameState.currentBackground} />
|
||||
|
||||
{/* Celebration Message */}
|
||||
{celebrationMessage && (
|
||||
<div className="fixed top-0 left-0 right-0 z-50 flex justify-center pt-8">
|
||||
<div className="bg-gradient-to-r from-yellow-400 via-pink-500 to-purple-600 text-white px-8 py-4 rounded-full text-2xl font-bold shadow-2xl animate-bounce border-4 border-white">
|
||||
🎉 {celebrationMessage} 🎉
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="container mx-auto px-4 py-8 relative z-10">
|
||||
{/* Header */}
|
||||
<div className="mb-8">
|
||||
<Counter
|
||||
totalClicks={gameState.totalClicks}
|
||||
autoClickRate={gameState.autoClickRate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||||
{/* Left Column - Click Button */}
|
||||
<div className="lg:col-span-1 flex flex-col items-center justify-center">
|
||||
<ClickButton
|
||||
onClick={sendClick}
|
||||
imageUrl={gameState.currentClickImage}
|
||||
clickMultiplier={gameState.clickMultiplier}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Middle Column - Upgrades */}
|
||||
<div className="lg:col-span-1">
|
||||
<UpgradeShop
|
||||
gameState={gameState}
|
||||
userClicks={userClicks}
|
||||
onPurchase={purchaseUpgrade}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Right Column - Milestones and Leaderboard */}
|
||||
<div className="lg:col-span-1 space-y-6">
|
||||
<Milestones gameState={gameState} />
|
||||
<Leaderboard gameState={gameState} currentUserId={userId} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<div className="mt-12 text-center">
|
||||
<div className="bg-gradient-to-r from-pink-500 via-purple-500 to-cyan-500 p-4 rounded-xl border-4 border-yellow-300">
|
||||
<p className="text-white text-xl font-bold" style={{ fontFamily: 'Comic Sans MS, cursive' }}>
|
||||
✨ Keep clicking, fellow bozos! ✨
|
||||
</p>
|
||||
<p className="text-yellow-200 text-sm mt-2">
|
||||
This game is synchronized in real-time with all players!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sparkle Effects */}
|
||||
<div className="fixed inset-0 pointer-events-none z-20">
|
||||
{[...Array(10)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute text-2xl opacity-70 animate-pulse"
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
animationDelay: `${Math.random() * 3}s`,
|
||||
animationDuration: `${2 + Math.random() * 3}s`
|
||||
}}
|
||||
>
|
||||
✨
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user