refactor(dashboard): extract modular Preact component structure
Replace the monolithic single-file dashboards (dashboard.html,
dashboard-preact.html) with a proper modular directory structure:
dashboard/
index.html - Entry point, loads main.js
main.js - App bootstrap, mounts <App> to #root
styles.css - Global styles (dark theme, typography)
components/
App.js - Root component, state management, polling
Header.js - Top bar with refresh/timing info
Sidebar.js - Project tree navigation
SessionCard.js - Individual session card with status/actions
SessionGroup.js - Group sessions by project path
Modal.js - Full conversation viewer overlay
ChatMessages.js - Message list with role styling
MessageBubble.js - Individual message with markdown
QuestionBlock.js - User question input with quick options
EmptyState.js - "No sessions" placeholder
OptionButton.js - Quick response button component
SimpleInput.js - Text input with send button
lib/
preact.js - Preact + htm ESM bundle (CDN shim)
markdown.js - Lightweight markdown-to-HTML renderer
utils/
api.js - fetch wrappers for /api/* endpoints
formatting.js - Time formatting, truncation helpers
status.js - Session status logic, action availability
This structure enables:
- Browser-native ES modules (no build step required)
- Component reuse and isolation
- Easier styling and theming
- IDE support for component navigation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
107
dashboard/index.html
Normal file
107
dashboard/index.html
Normal file
@@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Agent Mission Control</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Tailwind CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
bg: '#01040b',
|
||||
surface: '#070d18',
|
||||
surface2: '#0d1830',
|
||||
selection: '#223454',
|
||||
fg: '#e0ebff',
|
||||
bright: '#fbfdff',
|
||||
dim: '#8ba3cc',
|
||||
active: '#5fd0a4',
|
||||
attention: '#e0b45e',
|
||||
starting: '#7cb2ff',
|
||||
done: '#e39a8c',
|
||||
},
|
||||
fontFamily: {
|
||||
display: ['Space Grotesk', 'IBM Plex Sans', 'sans-serif'],
|
||||
sans: ['IBM Plex Sans', 'system-ui', 'sans-serif'],
|
||||
mono: ['IBM Plex Mono', 'SFMono-Regular', 'Menlo', 'monospace'],
|
||||
chat: ['JetBrains Mono', 'IBM Plex Mono', 'monospace'],
|
||||
},
|
||||
fontSize: {
|
||||
micro: ['clamp(0.68rem, 0.05vw + 0.66rem, 0.78rem)', { lineHeight: '1.35' }],
|
||||
label: ['clamp(0.76rem, 0.07vw + 0.74rem, 0.86rem)', { lineHeight: '1.4' }],
|
||||
ui: ['clamp(0.84rem, 0.09vw + 0.81rem, 0.94rem)', { lineHeight: '1.45' }],
|
||||
body: ['clamp(0.88rem, 0.1vw + 0.85rem, 0.98rem)', { lineHeight: '1.55' }],
|
||||
chat: ['clamp(0.92rem, 0.12vw + 0.89rem, 1.02rem)', { lineHeight: '1.6' }],
|
||||
},
|
||||
boxShadow: {
|
||||
panel: '0 8px 18px rgba(10, 14, 20, 0.28)',
|
||||
halo: '0 0 0 1px rgba(117, 138, 166, 0.12), 0 6px 14px rgba(10, 14, 20, 0.24)',
|
||||
},
|
||||
keyframes: {
|
||||
float: {
|
||||
'0%, 100%': { transform: 'translateY(0)' },
|
||||
'50%': { transform: 'translateY(-4px)' },
|
||||
},
|
||||
fadeInUp: {
|
||||
'0%': { opacity: '0', transform: 'translateY(10px)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
float: 'float 6s ease-in-out infinite',
|
||||
'fade-in-up': 'fadeInUp 0.35s ease-out',
|
||||
},
|
||||
}
|
||||
},
|
||||
safelist: [
|
||||
'bg-attention/30',
|
||||
'bg-active/30',
|
||||
'bg-starting/30',
|
||||
'bg-done/30',
|
||||
'bg-attention/18',
|
||||
'bg-active/18',
|
||||
'bg-starting/18',
|
||||
'bg-done/18',
|
||||
'bg-selection/80',
|
||||
'border-attention/40',
|
||||
'border-active/40',
|
||||
'border-starting/40',
|
||||
'border-done/40',
|
||||
'border-l-attention',
|
||||
'border-l-active',
|
||||
'border-l-starting',
|
||||
'border-l-done',
|
||||
'text-attention',
|
||||
'text-active',
|
||||
'text-starting',
|
||||
'text-done',
|
||||
'border-emerald-500/30',
|
||||
'bg-emerald-500/10',
|
||||
'text-emerald-400',
|
||||
'border-emerald-400/45',
|
||||
'bg-emerald-500/14',
|
||||
'text-emerald-300',
|
||||
'border-violet-500/30',
|
||||
'bg-violet-500/10',
|
||||
'text-violet-400',
|
||||
'border-violet-400/45',
|
||||
'bg-violet-500/14',
|
||||
'text-violet-300',
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body class="min-h-screen text-fg antialiased">
|
||||
<div id="app"></div>
|
||||
<script type="module" src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user