fix(v2): move Dashboard to tool links + fix Combat sidebar button

- Dashboard toggle moved from sidebar header to tool links area
  alongside Suitbuilder, Inv Search, Debug, Quests
- Combat sidebar button now opens a character picker window
  (combatpicker prefix) that lists all online characters — click
  one to open their full combat stats window

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-04-14 10:19:57 +02:00
parent 2095f54d79
commit 2cd68d0368
6 changed files with 46 additions and 14 deletions

View file

@ -59,7 +59,6 @@ export const Sidebar: React.FC<Props> = ({
{version && <div className="ml-version">v{version}</div>}
<div className="ml-sidebar-header">
<span className="ml-sidebar-title">Active Mosswart Enjoyers ({players.length})</span>
<button className="ml-view-toggle" onClick={onViewToggle}>Dashboard</button>
</div>
<div className="ml-server-status">
@ -80,6 +79,7 @@ export const Sidebar: React.FC<Props> = ({
{/* Tool links */}
<div className="ml-tool-links">
<span className="ml-tool-link" style={{ cursor: 'pointer' }} onClick={onViewToggle}>📊 Dashboard</span>
<a href="/inventory.html" className="ml-tool-link">🔍 Inv Search</a>
<a href="/suitbuilder.html" className="ml-tool-link">🛡 Suitbuilder</a>
<a href="/debug.html" className="ml-tool-link">🐛 Debug</a>

View file

@ -0,0 +1,29 @@
import React from 'react';
import { DraggableWindow } from './DraggableWindow';
import { useWindowManager } from '../../contexts/WindowManagerContext';
import type { CharacterState } from '../../types';
interface Props { id: string; zIndex: number; characters: Map<string, CharacterState>; }
export const CombatPickerWindow: React.FC<Props> = ({ id, zIndex, characters }) => {
const { openWindow } = useWindowManager();
const chars = Array.from(characters.keys()).sort();
return (
<DraggableWindow id={id} title="Combat Stats — Select Character" zIndex={zIndex} width={300} height={400}>
<div style={{ flex: 1, overflowY: 'auto', padding: 6 }}>
{chars.length === 0 ? (
<div style={{ padding: 12, color: '#666', textAlign: 'center', fontSize: '0.8rem' }}>No characters online</div>
) : chars.map(name => (
<div key={name}
style={{ padding: '5px 8px', cursor: 'pointer', borderBottom: '1px solid #222', color: '#ccc', fontSize: '0.82rem' }}
onMouseEnter={e => (e.currentTarget.style.background = '#2a2a2a')}
onMouseLeave={e => (e.currentTarget.style.background = '')}
onClick={() => openWindow(`combat-${name}`, `Combat: ${name}`, name)}>
{name}
</div>
))}
</div>
</DraggableWindow>
);
};

View file

@ -6,6 +6,7 @@ import { CharacterWindow } from './CharacterWindow';
import { InventoryWindow } from './InventoryWindow';
import { RadarWindow } from './RadarWindow';
import { CombatStatsWindow } from './CombatStatsWindow';
import { CombatPickerWindow } from './CombatPickerWindow';
import { IssuesWindow } from './IssuesWindow';
import { VitalSharingWindow } from './VitalSharingWindow';
import type { CharacterState } from '../../types';
@ -42,6 +43,8 @@ export const WindowRenderer: React.FC<Props> = ({ characters, chatMessages, near
socket={socket} radarData={nearbyObjects.get(charName) ?? null} />;
case 'combat':
return <CombatStatsWindow key={w.id} id={w.id} charName={charName} zIndex={w.zIndex} />;
case 'combatpicker':
return <CombatPickerWindow key={w.id} id={w.id} zIndex={w.zIndex} characters={characters} />;
case 'issues':
return <IssuesWindow key={w.id} id={w.id} zIndex={w.zIndex} />;
case 'vitalsharing':

File diff suppressed because one or more lines are too long

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mosswart Overlord v2</title>
<link rel="icon" type="image/png" href="/icons/7735.png" />
<script type="module" crossorigin src="/v2/assets/index-Bi20HmPd.js"></script>
<script type="module" crossorigin src="/v2/assets/index-CIKuZxvT.js"></script>
<link rel="stylesheet" crossorigin href="/v2/assets/index-CyLyPOVJ.css">
</head>
<body>