Files
Mana-Loop/src/app/components/LeftPanel.tsx
T
n8n-gitea 1a0886f702
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s
chore: golemancy redesign cleanup — remove orphaned legacy code and update docs
2026-06-07 12:54:12 +02:00

132 lines
5.8 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Mountain } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { ManaDisplay } from '@/components/game';
import { ActionButtons } from '@/components/game';
import { AttunementStatus } from '@/components/game/AttunementStatus';
import { ActivityLogPanel } from '@/components/game/ActivityLogPanel';
import { DebugName } from '@/components/game/debug/debug-context';
import { useGameStore, useManaStore, useCombatStore, useCraftingStore, usePrestigeStore } from '@/lib/game/stores';
import { getUnifiedEffects } from '@/lib/game/effects';
import { getMeditationBonus, getIncursionStrength } from '@/lib/game/stores';
import { computeTotalMaxMana, computeTotalRegen, computeTotalClickMana } from '@/lib/game/effects';
import { computeDisciplineEffects } from '@/lib/game/effects/discipline-effects';
export function LeftPanel() {
const [isGathering, setIsGathering] = useState(false);
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const meditateTicks = useManaStore((s) => s.meditateTicks);
const elementRegen = useManaStore((s) => s.elementRegen);
const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const gatherMana = useGameStore((s) => s.gatherMana);
const spireMode = useCombatStore((s) => s.spireMode);
const enterSpireMode = useCombatStore((s) => s.enterSpireMode);
const currentAction = useCombatStore((s) => s.currentAction);
const designProgress = useCraftingStore((s) => s.designProgress);
const designProgress2 = useCraftingStore((s) => s.designProgress2);
const cancelDesign = useCraftingStore((s) => s.cancelDesign);
const preparationProgress = useCraftingStore((s) => s.preparationProgress);
const applicationProgress = useCraftingStore((s) => s.applicationProgress);
const equipmentCraftingProgress = useCraftingStore((s) => s.equipmentCraftingProgress);
const handleGatherStart = () => { setIsGathering(true); gatherMana(); };
const handleGatherEnd = () => { setIsGathering(false); };
useEffect(() => {
if (!isGathering) return;
let lastGatherTime = 0;
const minGatherInterval = 100;
let animationFrameId: number;
const gatherLoop = (timestamp: number) => {
if (timestamp - lastGatherTime >= minGatherInterval) {
gatherMana();
lastGatherTime = timestamp;
}
animationFrameId = requestAnimationFrame(gatherLoop);
};
animationFrameId = requestAnimationFrame(gatherLoop);
return () => cancelAnimationFrame(animationFrameId);
}, [isGathering, gatherMana]);
const upgradeEffects = getUnifiedEffects({ skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances });
const disciplineEffects = computeDisciplineEffects();
const maxMana = computeTotalMaxMana({ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const baseRegen = computeTotalRegen({ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const clickMana = computeTotalClickMana({ skills: {}, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const meditationMultiplier = getMeditationBonus(meditateTicks, upgradeEffects.meditationEfficiency, disciplineEffects.meditationCapBonus);
const incursionStrength = getIncursionStrength(useGameStore((s) => s.day), useGameStore((s) => s.hour));
const effectiveRegen = baseRegen * (1 - incursionStrength) * meditationMultiplier;
return (
<div className="md:w-80 space-y-3 flex-shrink-0 p-1">
{/* 1. Mana Display */}
<DebugName name="ManaDisplay">
<ManaDisplay
rawMana={rawMana}
maxMana={maxMana}
effectiveRegen={effectiveRegen}
meditationMultiplier={meditationMultiplier}
clickMana={clickMana}
isGathering={isGathering}
onGatherStart={handleGatherStart}
onGatherEnd={handleGatherEnd}
elements={elements}
elementRegen={elementRegen}
/>
</DebugName>
{/* 2. Spire Entry */}
{!spireMode && (
<DebugName name="ClimbSpireButton">
<Button className="w-full bg-gradient-to-r from-amber-600 to-orange-600 hover:from-amber-700 hover:to-orange-600 text-white" size="lg" onClick={enterSpireMode}>
<Mountain className="w-5 h-5 mr-2" />
Climb the Spire
</Button>
</DebugName>
)}
{/* 3. Current Action */}
{!spireMode && (
<DebugName name="ActionButtons">
<Card className="bg-[var(--bg-surface)] border-[var(--border-subtle)]">
<CardContent className="pt-3">
<ActionButtons
currentAction={currentAction}
designProgress={designProgress}
designProgress2={designProgress2}
preparationProgress={preparationProgress}
applicationProgress={applicationProgress}
equipmentCraftingProgress={equipmentCraftingProgress}
cancelDesign={cancelDesign}
/>
</CardContent>
</Card>
</DebugName>
)}
{/* 4. Attunement Status */}
{!spireMode && (
<DebugName name="AttunementStatus">
<Card className="bg-[var(--bg-surface)] border-[var(--border-subtle)]">
<CardContent className="pt-3">
<AttunementStatus />
</CardContent>
</Card>
</DebugName>
)}
{/* 5. Activity Log */}
<DebugName name="ActivityLogPanel">
<ActivityLogPanel />
</DebugName>
</div>
);
}