pet-companion-front/src/components/modal/ResourceSelectionModal.tsx

137 lines
3.9 KiB
TypeScript
Executable File
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 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>
);
}