fix: resolve Docker build errors - JSX ternary, missing barrel export, missing ActivityLog component
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m22s

This commit is contained in:
2026-05-18 15:07:34 +02:00
parent 14ba02d987
commit afbdb71548
6 changed files with 71 additions and 17 deletions
+3 -6
View File
@@ -1,11 +1,8 @@
# Circular Dependencies # Circular Dependencies
Generated: 2026-05-18T12:47:02.133Z Generated: 2026-05-18T12:51:42.611Z
Found: 4 circular chain(s) — these MUST be fixed before modifying involved files. Found: 1 circular chain(s) — these MUST be fixed before modifying involved files.
1. Processed 122 files (1.3s) (30 warnings) 1. Processed 122 files (1.2s) (30 warnings)
2. 1) stores/combatStore.ts > stores/gameStore.ts
3. 2) stores/combatStore.ts > stores/gameStore.ts > stores/gameActions.ts
4. 3) stores/combatStore.ts > stores/gameStore.ts > stores/gameLoopActions.ts
## How to fix ## How to fix
1. Identify which import in the chain can be extracted to a shared types/utils file. 1. Identify which import in the chain can be extracted to a shared types/utils file.
+1 -2
View File
@@ -1,6 +1,6 @@
{ {
"_meta": { "_meta": {
"generated": "2026-05-18T12:47:00.491Z", "generated": "2026-05-18T12:51:41.151Z",
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.", "description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry." "usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
}, },
@@ -416,7 +416,6 @@
"stores/combatStore.ts": [ "stores/combatStore.ts": [
"stores/combat-actions.ts", "stores/combat-actions.ts",
"stores/combat-state.types.ts", "stores/combat-state.types.ts",
"stores/gameStore.ts",
"stores/prestigeStore.ts", "stores/prestigeStore.ts",
"types.ts", "types.ts",
"utils/activity-log.ts", "utils/activity-log.ts",
+2
View File
@@ -108,6 +108,7 @@ Mana-Loop/
│ │ │ ├── shared/ │ │ │ ├── shared/
│ │ │ │ └── MemorySlotPicker.tsx │ │ │ │ └── MemorySlotPicker.tsx
│ │ │ ├── tabs/ │ │ │ ├── tabs/
│ │ │ │ ├── ActivityLog.tsx
│ │ │ │ ├── DisciplinesTab.tsx │ │ │ │ ├── DisciplinesTab.tsx
│ │ │ │ └── index.ts │ │ │ │ └── index.ts
│ │ │ ├── AchievementsDisplay.tsx │ │ │ ├── AchievementsDisplay.tsx
@@ -203,6 +204,7 @@ Mana-Loop/
│ │ │ │ ├── enchanter.ts │ │ │ │ ├── enchanter.ts
│ │ │ │ ├── fabricator-disciplines.ts │ │ │ │ ├── fabricator-disciplines.ts
│ │ │ │ ├── fabricator.ts │ │ │ │ ├── fabricator.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── invoker-disciplines.ts │ │ │ │ ├── invoker-disciplines.ts
│ │ │ │ └── invoker.ts │ │ │ │ └── invoker.ts
│ │ │ ├── enchantments/ │ │ │ ├── enchantments/
+34
View File
@@ -0,0 +1,34 @@
import type { ActivityLogEntry } from '@/lib/game/types';
interface ActivityLogProps {
activityLog: ActivityLogEntry[];
maxEntries?: number;
}
export function ActivityLog({ activityLog, maxEntries = 20 }: ActivityLogProps) {
const entries = activityLog.slice(0, maxEntries);
if (entries.length === 0) {
return (
<div className="text-sm text-gray-500 italic p-2">
No activity yet.
</div>
);
}
return (
<div className="space-y-1 max-h-64 overflow-y-auto">
{entries.map((entry) => (
<div
key={entry.id}
className="text-xs text-gray-300 border-b border-gray-700 pb-1 last:border-0"
>
<span className="text-gray-500 mr-1">
[{entry.eventType}]
</span>
{entry.message}
</div>
))}
</div>
);
}
+11 -9
View File
@@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useDisciplineStore } from '@/lib/game/stores/discipline-slice'; import { useDisciplineStore } from '@/lib/game/stores/discipline-slice';
import type { DisciplineDefinition } from '@/types/disciplines'; import type { DisciplineDefinition } from '@/types/disciplines';
import baseDisciplines from '../data/disciplines/base'; import { baseDisciplines } from '@/lib/game/data/disciplines/base';
import enchanterDisciplines from '../data/disciplines/enchanter'; import { enchanterDisciplines } from '@/lib/game/data/disciplines/enchanter';
import fabricatorDisciplines from '../data/disciplines/fabricator'; import { fabricatorDisciplines } from '@/lib/game/data/disciplines/fabricator';
import invokerDisciplines from '../data/disciplines/invoker'; import { invokerDisciplines } from '@/lib/game/data/disciplines/invoker';
import { calculateStatBonus, calculateManaDrain } from '@/lib/game/utils/discipline-math'; import { calculateStatBonus, calculateManaDrain } from '@/lib/game/utils/discipline-math';
import { useRef } from 'react'; import { useRef } from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -148,9 +148,11 @@ export const DisciplinesTab: React.FC = () => {
<div className="mt-2"> <div className="mt-2">
<strong>Perks:</strong> <strong>Perks:</strong>
<ul className="mt-1 list-disc list-inside space-y-1 text-xs"> <ul className="mt-1 list-disc list-inside space-y-1 text-xs">
{unlockedPerks?.map((p) => ( {unlockedPerks && unlockedPerks.length > 0 ? (
<li key={p} className="text-green-500">{p.replace(/-([0-9]+)$/, ' $1')}</li> unlockedPerks.map((p) => (
)) : ( <li key={p} className="text-green-500">{p.replace(/-([0-9]+)$/, ' $1')}</li>
))
) : (
<li className="text-gray-400">locked</li> <li className="text-gray-400">locked</li>
)} )}
</ul> </ul>
@@ -193,11 +195,11 @@ export const DisciplinesTab: React.FC = () => {
return ( return (
<button <button
key={tab.label} key={tab.label}
onClick={() => onClick={() => {
// Here you could dispatch an action to switch tabs if needed // Here you could dispatch an action to switch tabs if needed
// For simplicity, we just render the tabs // For simplicity, we just render the tabs
console.log(`Switch to ${tab.label}`); console.log(`Switch to ${tab.label}`);
} }}
className={clsx('rounded px-3 py-1', { className={clsx('rounded px-3 py-1', {
'bg-blue-600 text-white': tab.label === 'Base', // highlight first for demo 'bg-blue-600 text-white': tab.label === 'Base', // highlight first for demo
'text-gray-600': tab.label !== 'Base', 'text-gray-600': tab.label !== 'Base',
+20
View File
@@ -0,0 +1,20 @@
// ─── Disciplines Barrel ───────────────────────────────────────────────────────
// Aggregates all discipline definitions into a single ALL_DISCIPLINES array
import { baseDisciplines } from './base';
import { enchanterDisciplines } from './enchanter';
import { fabricatorDisciplines } from './fabricator';
import { invokerDisciplines } from './invoker';
import type { DisciplineDefinition } from '../../types/disciplines';
export const ALL_DISCIPLINES: DisciplineDefinition[] = [
...baseDisciplines,
...enchanterDisciplines,
...fabricatorDisciplines,
...invokerDisciplines,
];
export { baseDisciplines } from './base';
export { enchanterDisciplines } from './enchanter';
export { fabricatorDisciplines } from './fabricator';
export { invokerDisciplines } from './invoker';