137 lines
3.9 KiB
TypeScript
Executable File
137 lines
3.9 KiB
TypeScript
Executable File
import React from 'react';
|
||
import { Brain, Coins, Pizza, X, StopCircle } from 'lucide-react';
|
||
import { Pet } from '../../types/Pet';
|
||
import { formatResourceName, getResourceFromAction } from '../../utils/petUtils';
|
||
|
||
interface ResourceSelectionModalProps {
|
||
isOpen: boolean;
|
||
onClose: () => void;
|
||
onGather: (resourceType: string) => void;
|
||
pet: Pet;
|
||
isGathering: boolean;
|
||
}
|
||
|
||
interface ResourceOption {
|
||
type: string;
|
||
name: string;
|
||
icon: React.ElementType;
|
||
formula: string;
|
||
stat: keyof typeof statMultipliers;
|
||
color: string;
|
||
}
|
||
|
||
const statMultipliers = {
|
||
intelligence: 2,
|
||
strength: 3,
|
||
charisma: 1.5,
|
||
};
|
||
|
||
const resourceOptions: ResourceOption[] = [
|
||
{
|
||
type: 'wisdom',
|
||
name: 'Wisdom',
|
||
icon: Brain,
|
||
formula: 'Intelligence × 2',
|
||
stat: 'intelligence',
|
||
color: 'purple',
|
||
},
|
||
{
|
||
type: 'gold',
|
||
name: 'Gold',
|
||
icon: Coins,
|
||
formula: 'Strength × 3',
|
||
stat: 'strength',
|
||
color: 'yellow',
|
||
},
|
||
{
|
||
type: 'food',
|
||
name: 'Food',
|
||
icon: Pizza,
|
||
formula: 'Charisma × 1.5',
|
||
stat: 'charisma',
|
||
color: 'green',
|
||
},
|
||
];
|
||
|
||
export default function ResourceSelectionModal({
|
||
isOpen,
|
||
onClose,
|
||
onGather,
|
||
pet,
|
||
isGathering,
|
||
}: ResourceSelectionModalProps) {
|
||
if (!isOpen) return null;
|
||
|
||
const calculateEstimatedYield = (option: ResourceOption) => {
|
||
const baseStat = pet.stats[option.stat];
|
||
const multiplier = statMultipliers[option.stat];
|
||
return Math.floor(baseStat * multiplier);
|
||
};
|
||
|
||
const currentResource = getResourceFromAction(pet.petGatherAction);
|
||
|
||
return (
|
||
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center p-4 z-50">
|
||
<div className="bg-gray-800 rounded-xl max-w-2xl w-full p-6 relative">
|
||
<button
|
||
onClick={onClose}
|
||
className="absolute top-4 right-4 text-gray-400 hover:text-white"
|
||
>
|
||
<X className="w-6 h-6" />
|
||
</button>
|
||
|
||
<h2 className="text-2xl font-bold mb-6 text-white">Gather Resources</h2>
|
||
|
||
{isGathering && currentResource && (
|
||
<div className="mb-4 p-4 bg-blue-900/30 border-2 border-blue-500/30 rounded-lg">
|
||
<p className="text-blue-300">
|
||
Currently gathering {formatResourceName(currentResource)}
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||
{resourceOptions.map((option) => (
|
||
<button
|
||
key={option.type}
|
||
onClick={() => onGather(option.type)}
|
||
disabled={isGathering}
|
||
className={`bg-gray-700/50 hover:bg-gray-700
|
||
border-2 border-${option.color}-500/30
|
||
rounded-lg p-4 transition-all duration-300
|
||
transform hover:scale-105 text-left
|
||
${isGathering ? 'opacity-50 cursor-not-allowed' : ''}`}
|
||
>
|
||
<div className="flex items-center space-x-2 mb-2">
|
||
<option.icon className={`w-6 h-6 text-${option.color}-400`} />
|
||
<span className="font-semibold text-white">{option.name}</span>
|
||
</div>
|
||
<div className="text-sm text-gray-400 mb-2">
|
||
Formula: {option.formula}
|
||
</div>
|
||
<div className="text-sm">
|
||
Estimated yield per hour:
|
||
<span className={`ml-2 font-bold text-${option.color}-400`}>
|
||
{calculateEstimatedYield(option)}
|
||
</span>
|
||
</div>
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{isGathering && (
|
||
<button
|
||
onClick={() => onGather('stop')}
|
||
className="mt-4 w-full flex items-center justify-center space-x-2
|
||
bg-red-900/30 hover:bg-red-800/50
|
||
border-2 border-red-500/30 rounded-lg p-4
|
||
transition-all duration-300"
|
||
>
|
||
<StopCircle className="w-6 h-6 text-red-400" />
|
||
<span>Stop Gathering</span>
|
||
</button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
);
|
||
} |