ce084a61a3
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m21s
- GuardianPactsTab: extracted GuardianCard, PactHeaderSummary, TierFilter + 5 helper components into guardian-pacts-components.tsx - SpireSummaryTab: extracted TopStatsRow, NextGuardianCard, GuardianRoster, GuardianRosterItem, FloorLegend - PrestigeTab: extracted InsightSummary, MemoriesCard, PactsCard, ResetLoopSection - GameStateDebug: extracted WarningBanner, DisplayOptions, GameResetSection, ManaDebugSection, TimeControlSection, QuickActionsSection - EquipmentCrafter: extracted CraftingProgress, BlueprintCard, BlueprintList, MaterialCard, MaterialsInventory - PactDebug: extracted GuardianPactRow, GuardianPactList - GameStateDebugSection: extracted DisplayOptions, GameResetSection, ManaDebugSection, TimeControlSection, QuickActionsSection - PactDebugSection: extracted GuardianPactRow - SpireCombatPage: extracted useSpireStats hook - page.tsx: extracted GrimoireTab to separate file, useGameDerivedStats hook, TabTriggers, LazyTab wrapper All files now under 400 lines. Build passes. All 639 tests pass.
169 lines
5.6 KiB
TypeScript
169 lines
5.6 KiB
TypeScript
'use client';
|
|
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Bug } from 'lucide-react';
|
|
import { usePrestigeStore, useManaStore, useUIStore, useGameStore } from '@/lib/game/stores';
|
|
import { GUARDIANS, ELEMENTS } from '@/lib/game/constants';
|
|
|
|
// ─── Guardian Pact Row ───────────────────────────────────────────────────────
|
|
|
|
function GuardianPactRow({ floor, isSigned, onForceSign, onRemove }: {
|
|
floor: number;
|
|
isSigned: boolean;
|
|
onForceSign: () => void;
|
|
onRemove: () => void;
|
|
}) {
|
|
const guardian = GUARDIANS[floor];
|
|
|
|
return (
|
|
<div
|
|
className={`p-2 rounded border flex items-center justify-between ${
|
|
isSigned ? 'border-green-600/50 bg-green-900/20' : 'border-gray-700'
|
|
}`}
|
|
style={{ borderColor: isSigned ? undefined : guardian.color, borderWidth: '1px' }}
|
|
>
|
|
<div>
|
|
<div className="text-sm font-semibold" style={{ color: guardian.color }}>
|
|
{guardian.name}
|
|
</div>
|
|
<div className="text-xs text-gray-400">
|
|
Floor {floor} | {guardian.pact}x multiplier
|
|
</div>
|
|
<div className="text-xs text-gray-500">
|
|
Element: {ELEMENTS[guardian.element]?.name || guardian.element}
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-1">
|
|
{isSigned ? (
|
|
<Button size="sm" variant="destructive" onClick={onRemove} className="text-xs">
|
|
Remove
|
|
</Button>
|
|
) : (
|
|
<Button size="sm" variant="default" onClick={onForceSign} className="text-xs bg-amber-600 hover:bg-amber-700">
|
|
Force Sign
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// ─── Main Component ───────────────────────────────────────────────────────────
|
|
|
|
export function PactDebugSection() {
|
|
const signedPacts = usePrestigeStore((s) => s.signedPacts);
|
|
const signedPactDetails = usePrestigeStore((s) => s.signedPactDetails);
|
|
const elements = useManaStore((s) => s.elements);
|
|
const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades);
|
|
|
|
const addSignedPact = usePrestigeStore((s) => s.addSignedPact);
|
|
const removePact = usePrestigeStore((s) => s.removePact);
|
|
const debugSetSignedPacts = usePrestigeStore((s) => s.debugSetSignedPacts);
|
|
const debugSetPactDetails = usePrestigeStore((s) => s.debugSetPactDetails);
|
|
const unlockElement = useManaStore((s) => s.unlockElement);
|
|
|
|
const addLog = useUIStore((s) => s.addLog);
|
|
|
|
const guardianFloors = Object.keys(GUARDIANS || {}).map(Number).sort((a, b) => a - b);
|
|
|
|
const forcePact = (floor: number) => {
|
|
const guardian = GUARDIANS[floor];
|
|
if (!guardian) return;
|
|
|
|
if (signedPacts.includes(floor)) {
|
|
addLog(`⚠️ Already signed pact with ${guardian.name}!`);
|
|
return;
|
|
}
|
|
|
|
const maxPacts = 1 + (prestigeUpgrades?.pactCapacity || 0);
|
|
if (signedPacts.length >= maxPacts) {
|
|
addLog(`⚠️ Cannot sign more pacts! Maximum: ${maxPacts}.`);
|
|
return;
|
|
}
|
|
|
|
addSignedPact(floor);
|
|
|
|
const newSignedPactDetails = {
|
|
...signedPactDetails,
|
|
[floor]: {
|
|
floor,
|
|
guardianId: guardian.element,
|
|
signedAt: { day: useGameStore.getState().day, hour: useGameStore.getState().hour },
|
|
skillLevels: {} as Record<string, number>,
|
|
},
|
|
};
|
|
debugSetPactDetails(newSignedPactDetails);
|
|
|
|
addLog(`📜 DEBUG: Pact with ${guardian.name} force-signed!`);
|
|
};
|
|
|
|
const removePactHandler = (floor: number) => {
|
|
const guardian = GUARDIANS[floor];
|
|
|
|
removePact(floor);
|
|
|
|
const newSignedPactDetails = { ...signedPactDetails };
|
|
delete newSignedPactDetails[floor];
|
|
debugSetPactDetails(newSignedPactDetails);
|
|
|
|
addLog(`📜 DEBUG: Removed pact with ${guardian?.name || 'Unknown'}!`);
|
|
};
|
|
|
|
const signAllPacts = () => {
|
|
guardianFloors.forEach((floor) => {
|
|
if (!signedPacts.includes(floor)) {
|
|
forcePact(floor);
|
|
}
|
|
});
|
|
};
|
|
|
|
const clearAllPacts = () => {
|
|
addLog(`📜 DEBUG: Cleared all pacts!`);
|
|
debugSetSignedPacts([]);
|
|
debugSetPactDetails({});
|
|
};
|
|
|
|
return (
|
|
<Card className="bg-gray-900/80 border-gray-700">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-orange-400 text-sm flex items-center gap-2">
|
|
<Bug className="w-4 h-4" />
|
|
Pact Debug
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button size="sm" variant="outline" onClick={signAllPacts}>
|
|
Sign All Pacts
|
|
</Button>
|
|
<Button size="sm" variant="destructive" onClick={clearAllPacts}>
|
|
Clear All Pacts ({signedPacts.length})
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
|
|
{guardianFloors.map((floor) => (
|
|
<GuardianPactRow
|
|
key={floor}
|
|
floor={floor}
|
|
isSigned={signedPacts.includes(floor)}
|
|
onForceSign={() => forcePact(floor)}
|
|
onRemove={() => removePactHandler(floor)}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
<div className="text-xs text-gray-400 pt-2 border-t border-gray-700">
|
|
Signed Pacts: {signedPacts.length} |
|
|
Max Pacts: {1 + (prestigeUpgrades?.pactCapacity || 0)}
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|
|
|
|
PactDebugSection.displayName = 'PactDebugSection';
|