feat: redesign mobile app with tactile UI
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState, type ReactNode } from 'react';
|
||||
import { useEffect, useMemo, useState, type ReactNode } from 'react';
|
||||
import { Flame, Gem, Heart, Wifi, WifiOff } from 'lucide-react';
|
||||
import { useCompanion } from '../../api/CompanionContext.js';
|
||||
import type { ScreenId } from '../../app/navigation.js';
|
||||
import { BottomNav } from '../bottom-nav/BottomNav.js';
|
||||
@@ -9,6 +10,14 @@ type AppShellProps = {
|
||||
onNavigate: (screen: ScreenId) => void;
|
||||
};
|
||||
|
||||
const screenTitles: Record<ScreenId, { title: string; kicker: string }> = {
|
||||
chat: { title: 'Quest', kicker: 'Hermes training path' },
|
||||
files: { title: 'Backpack', kicker: 'Workspace loot' },
|
||||
terminal: { title: 'Power move', kicker: 'Run a command' },
|
||||
activity: { title: 'League', kicker: 'Companion stats' },
|
||||
settings: { title: 'Nest', kicker: 'Connection setup' },
|
||||
};
|
||||
|
||||
export function AppShell({ activeScreen, children, onNavigate }: AppShellProps) {
|
||||
const { client } = useCompanion();
|
||||
const [online, setOnline] = useState(false);
|
||||
@@ -30,20 +39,32 @@ export function AppShell({ activeScreen, children, onNavigate }: AppShellProps)
|
||||
};
|
||||
}, [client]);
|
||||
|
||||
const title = useMemo(() => screenTitles[activeScreen], [activeScreen]);
|
||||
|
||||
return (
|
||||
<div className="app-shell">
|
||||
<header className="app-header">
|
||||
<div>
|
||||
<p className="eyebrow">Hermes Mobile</p>
|
||||
<h1>Agent command center</h1>
|
||||
<div className="phone-app">
|
||||
<div className="app-shell">
|
||||
<header className="app-header">
|
||||
<div className="avatar-badge" aria-hidden="true">⚡</div>
|
||||
<div className="app-header__copy">
|
||||
<p className="eyebrow">{title.kicker}</p>
|
||||
<h1>{title.title}</h1>
|
||||
</div>
|
||||
<div className="top-stats" aria-label="Hermes status summary">
|
||||
<span className="stat-chip stat-chip--fire"><Flame size={16} fill="currentColor" />7</span>
|
||||
<span className="stat-chip stat-chip--gem"><Gem size={16} fill="currentColor" />550</span>
|
||||
<span className="stat-chip stat-chip--heart"><Heart size={16} fill="currentColor" />3</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className={`connection-banner ${online ? 'connection-banner--online' : ''}`}>
|
||||
{online ? <Wifi size={18} /> : <WifiOff size={18} />}
|
||||
<span>{online ? 'Companion online — ready for quests' : 'Companion offline — check Settings'}</span>
|
||||
</div>
|
||||
<div className={`status-pill ${online ? 'status-pill--online' : ''}`}>
|
||||
<span className="status-pill__dot" />
|
||||
{online ? 'Online' : 'Offline'}
|
||||
</div>
|
||||
</header>
|
||||
<main className="app-main">{children}</main>
|
||||
<BottomNav activeScreen={activeScreen} onNavigate={onNavigate} />
|
||||
|
||||
<main className="app-main">{children}</main>
|
||||
<BottomNav activeScreen={activeScreen} onNavigate={onNavigate} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user