Files
Mana-Loop/src/components/game/StatsTab/ElementStatsSection.tsx
T
Refactoring Agent 221d3e4b41
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s
fix: complete store migration — fix all tab crashes and ghost field reads
2026-05-05 12:45:07 +02:00

83 lines
3.6 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.
'use client';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { FlaskConical } from 'lucide-react';
import { ELEMENTS } from '@/lib/game/constants';
import { getTierMultiplier } from '@/lib/game/skill-evolution';
import { fmt, fmtDec } from '@/lib/game/stores';
import { useSkillStore, usePrestigeStore, useManaStore } from '@/lib/game/stores';
interface ElementStatsSectionProps {
elemMax: number;
}
export function ElementStatsSection({ elemMax }: ElementStatsSectionProps) {
const skills = useSkillStore((s) => s.skills);
const skillTiers = useSkillStore((s) => s.skillTiers);
const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades);
const elements = useManaStore((s) => s.elements);
const getElemAttunementBonus = () => {
const ea = skillTiers?.elemAttune || 1;
const tieredSkillId = ea > 1 ? `elemAttune_t${ea}` : 'elemAttune';
const level = skills[tieredSkillId] || skills.elemAttune || 0;
const tierMult = getTierMultiplier(tieredSkillId);
return level * 50 * tierMult;
};
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-green-400 game-panel-title text-xs flex items-center gap-2">
<FlaskConical className="w-4 h-4" />
Element Stats
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span className="text-gray-400">Element Capacity:</span>
<span className="text-green-300">{elemMax}</span>
</div>
<div className="flex justify-between text-sm">
<span className="text-gray-400">Elem. Attunement Bonus:</span>
<span className="text-green-300">+{getElemAttunementBonus()}</span>
</div>
<div className="flex justify-between text-sm">
<span className="text-gray-400">Prestige Attunement:</span>
<span className="text-green-300">+{(prestigeUpgrades.elementalAttune || 0) * 25}</span>
</div>
</div>
<div className="space-y-2">
<div className="flex justify-between text-sm">
<span className="text-gray-400">Unlocked Elements:</span>
<span className="text-green-300">{Object.values(elements || {}).filter((e: any) => e.unlocked).length} / {Object.keys(ELEMENTS).length}</span>
</div>
<div className="flex justify-between text-sm">
<span className="text-gray-400">Elem. Crafting Bonus:</span>
<span className="text-green-300">×{fmtDec(1 + (skills.elemCrafting || 0) * 0.25, 2)}</span>
</div>
</div>
</div>
<Separator className="bg-gray-700 my-3" />
<div className="text-xs text-gray-400 mb-2">Elemental Mana Pools:</div>
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2">
{Object.entries(elements)
.filter(([, state]: [string, any]) => state.unlocked)
.map(([id, state]: [string, any]) => {
const def = ELEMENTS[id];
return (
<div key={id} className="p-2 rounded border border-gray-700 bg-gray-800/50 text-center">
<div className="text-lg">{def?.sym}</div>
<div className="text-xs text-gray-400">{state.current}/{state.max}</div>
</div>
);
})}
</div>
</CardContent>
</Card>
);
}