108 lines
4.0 KiB
TypeScript
108 lines
4.0 KiB
TypeScript
import React from 'react';
|
|
import { UPGRADES } from '../config/upgrades';
|
|
import { GameState, MascotTier, UserState } from '../types'; // Import MascotTier
|
|
|
|
interface UpgradeShopProps {
|
|
gameState: GameState;
|
|
userState: UserState | null;
|
|
onPurchase: (upgradeId: string) => void;
|
|
}
|
|
|
|
// Helper function to get mascot name from image source
|
|
const getMascotName = (imageSrc: string): string => {
|
|
const fileName = imageSrc.split('/').pop() || '';
|
|
const nameWithoutExtension = fileName.split('.')[0];
|
|
// remove the word neurosama if it exists in the name
|
|
if (nameWithoutExtension.includes('neurosama')) {
|
|
return nameWithoutExtension.replace('neurosama', '').trim();
|
|
}
|
|
return nameWithoutExtension
|
|
.split('-')
|
|
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
.join(' ');
|
|
};
|
|
|
|
export function UpgradeShop({ userState, onPurchase }: UpgradeShopProps) { // Changed from userClicks
|
|
if (!userState) {
|
|
return null; // Or a loading/signed-out state
|
|
}
|
|
|
|
const { clicks: userClicks, upgrades: userUpgrades } = userState;
|
|
|
|
return (
|
|
<div className="bg-gradient-to-b from-purple-800 to-pink-600 p-6 rounded-xl border-4 border-cyan-400 shadow-2xl">
|
|
<h2 className="text-3xl font-bold text-yellow-300 mb-6 text-center" style={{ fontFamily: 'Comic Sans MS, cursive' }}>
|
|
✨ BOZO SHOP ✨
|
|
</h2>
|
|
|
|
<div className="space-y-4">
|
|
{UPGRADES.map((upgrade) => {
|
|
const owned = userUpgrades[upgrade.id]?.owned || 0;
|
|
const cost = userUpgrades[upgrade.id]?.cost || upgrade.baseCost;
|
|
const canAfford = userClicks >= cost;
|
|
|
|
// If it's a one-time upgrade and already owned, don't display it
|
|
if (upgrade.oneTime && owned > 0) {
|
|
return null;
|
|
}
|
|
|
|
let description = upgrade.description;
|
|
|
|
// Custom description for Friend Boost upgrade
|
|
if (upgrade.id === 'friendBoost' && upgrade.mascotTiers) {
|
|
const nextMascotTier = upgrade.mascotTiers.find(
|
|
(tier: MascotTier) => owned < tier.level
|
|
);
|
|
|
|
if (nextMascotTier) {
|
|
description = `Spawns various clickable friends. Next: ${getMascotName(nextMascotTier.imageSrc)} at level ${nextMascotTier.level}`;
|
|
} else {
|
|
description = 'All mascots unlocked! Spawns various clickable friends.';
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div
|
|
key={upgrade.id}
|
|
className={`bg-gradient-to-r from-pink-500 to-purple-600 p-4 rounded-lg border-2 transition-all duration-300 ${
|
|
canAfford
|
|
? 'border-green-400 hover:scale-105 cursor-pointer hover:shadow-lg'
|
|
: 'border-gray-500 opacity-60'
|
|
}`}
|
|
onClick={() => canAfford && onPurchase(upgrade.id)}
|
|
>
|
|
<div className="flex justify-between items-center">
|
|
<div className="flex-1">
|
|
<div className="flex items-center space-x-2">
|
|
<span className="text-2xl">{upgrade.icon}</span>
|
|
<h3 className="text-lg font-bold text-white">{upgrade.name}</h3>
|
|
{owned > 0 && (
|
|
<span className="bg-yellow-400 text-black px-2 py-1 rounded-full text-sm font-bold">
|
|
{owned}
|
|
</span>
|
|
)}
|
|
</div>
|
|
<p className="text-cyan-200 text-sm mt-1">{description}</p>
|
|
</div>
|
|
|
|
<div className="text-right">
|
|
<div className={`text-xl font-bold ${canAfford ? 'text-green-300' : 'text-red-300'}`}>
|
|
{cost.toLocaleString()}
|
|
</div>
|
|
<div className="text-xs text-gray-300">clicks</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
<div className="mt-6 text-center">
|
|
<div className="text-2xl font-bold text-yellow-300">
|
|
Your Clicks: {userClicks.toLocaleString()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|