783 lines
28 KiB
HTML
783 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Dashboard Layout Tool - Claude Code DevTools</title>
|
|
<style>
|
|
/* CSS Reset & Base */
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
:root {
|
|
--bg-primary: #0d1117;
|
|
--bg-secondary: #161b22;
|
|
--bg-tertiary: #21262d;
|
|
--border-color: #30363d;
|
|
--text-primary: #c9d1d9;
|
|
--text-secondary: #8b949e;
|
|
--accent-blue: #58a6ff;
|
|
--accent-green: #3fb950;
|
|
--accent-yellow: #d29922;
|
|
--accent-purple: #bc8cff;
|
|
--accent-red: #f85149;
|
|
--shadow: rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
|
|
background: var(--bg-primary);
|
|
color: var(--text-primary);
|
|
line-height: 1.6;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* Header */
|
|
header {
|
|
background: var(--bg-secondary);
|
|
border-bottom: 1px solid var(--border-color);
|
|
padding: 1.5rem 2rem;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
box-shadow: 0 2px 8px var(--shadow);
|
|
}
|
|
|
|
header h1 {
|
|
font-size: 1.5rem;
|
|
font-weight: 600;
|
|
color: var(--accent-blue);
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
header .tagline {
|
|
color: var(--text-secondary);
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
/* Main Grid Dashboard Layout */
|
|
/* Technique 1: grid-template-areas for named layout regions */
|
|
main {
|
|
display: grid;
|
|
grid-template-areas:
|
|
"stats stats timeline timeline"
|
|
"usage usage activity activity"
|
|
"performance performance activity activity"
|
|
"docs docs docs docs";
|
|
grid-template-columns: repeat(4, 1fr);
|
|
grid-template-rows: auto auto auto auto;
|
|
gap: 1.5rem;
|
|
padding: 2rem;
|
|
max-width: 1600px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* Grid Area Assignments */
|
|
.stats-panel {
|
|
grid-area: stats;
|
|
}
|
|
|
|
.timeline-panel {
|
|
grid-area: timeline;
|
|
}
|
|
|
|
.usage-panel {
|
|
grid-area: usage;
|
|
}
|
|
|
|
.activity-panel {
|
|
grid-area: activity;
|
|
}
|
|
|
|
.performance-panel {
|
|
grid-area: performance;
|
|
}
|
|
|
|
.docs {
|
|
grid-area: docs;
|
|
}
|
|
|
|
/* Panel Styling */
|
|
.panel {
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 6px;
|
|
padding: 1.5rem;
|
|
box-shadow: 0 1px 3px var(--shadow);
|
|
transition: transform 0.2s, box-shadow 0.2s;
|
|
}
|
|
|
|
.panel:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 12px var(--shadow);
|
|
}
|
|
|
|
.panel h2 {
|
|
font-size: 1.125rem;
|
|
font-weight: 600;
|
|
margin-bottom: 1rem;
|
|
color: var(--accent-blue);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.panel-icon {
|
|
font-size: 1.25rem;
|
|
}
|
|
|
|
/* Stats Grid - Technique 2: auto-fit with minmax for responsive cards */
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.stat-card {
|
|
background: var(--bg-tertiary);
|
|
padding: 1rem;
|
|
border-radius: 4px;
|
|
border: 1px solid var(--border-color);
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 1.75rem;
|
|
font-weight: 700;
|
|
display: block;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 0.75rem;
|
|
color: var(--text-secondary);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.stat-card.blue .stat-value { color: var(--accent-blue); }
|
|
.stat-card.green .stat-value { color: var(--accent-green); }
|
|
.stat-card.yellow .stat-value { color: var(--accent-yellow); }
|
|
.stat-card.purple .stat-value { color: var(--accent-purple); }
|
|
|
|
/* Timeline */
|
|
.timeline {
|
|
position: relative;
|
|
}
|
|
|
|
.timeline-item {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1rem;
|
|
padding-bottom: 1rem;
|
|
border-bottom: 1px solid var(--border-color);
|
|
}
|
|
|
|
.timeline-item:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.timeline-time {
|
|
font-size: 0.75rem;
|
|
color: var(--text-secondary);
|
|
min-width: 60px;
|
|
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
}
|
|
|
|
.timeline-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.timeline-title {
|
|
font-weight: 500;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.timeline-desc {
|
|
font-size: 0.875rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.timeline-badge {
|
|
display: inline-block;
|
|
padding: 0.125rem 0.5rem;
|
|
border-radius: 3px;
|
|
font-size: 0.7rem;
|
|
font-weight: 500;
|
|
margin-left: 0.5rem;
|
|
}
|
|
|
|
.timeline-badge.edit { background: var(--accent-blue); color: #000; }
|
|
.timeline-badge.read { background: var(--accent-green); color: #000; }
|
|
.timeline-badge.bash { background: var(--accent-yellow); color: #000; }
|
|
.timeline-badge.search { background: var(--accent-purple); color: #000; }
|
|
|
|
/* Tool Usage Chart */
|
|
.usage-bars {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
}
|
|
|
|
.usage-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.usage-label {
|
|
min-width: 80px;
|
|
font-size: 0.875rem;
|
|
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
}
|
|
|
|
.usage-bar-bg {
|
|
flex: 1;
|
|
height: 24px;
|
|
background: var(--bg-tertiary);
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.usage-bar-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, var(--accent-blue), var(--accent-purple));
|
|
transition: width 1s ease;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
padding-right: 0.5rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* Activity Feed */
|
|
.activity-feed {
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
padding-right: 0.5rem;
|
|
}
|
|
|
|
.activity-feed::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
.activity-feed::-webkit-scrollbar-track {
|
|
background: var(--bg-tertiary);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.activity-feed::-webkit-scrollbar-thumb {
|
|
background: var(--border-color);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.activity-item {
|
|
display: flex;
|
|
gap: 0.75rem;
|
|
margin-bottom: 1rem;
|
|
padding: 0.75rem;
|
|
background: var(--bg-tertiary);
|
|
border-radius: 4px;
|
|
border-left: 3px solid var(--accent-blue);
|
|
}
|
|
|
|
.activity-item.success { border-left-color: var(--accent-green); }
|
|
.activity-item.warning { border-left-color: var(--accent-yellow); }
|
|
.activity-item.error { border-left-color: var(--accent-red); }
|
|
|
|
.activity-icon {
|
|
font-size: 1.25rem;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.activity-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.activity-title {
|
|
font-weight: 500;
|
|
margin-bottom: 0.25rem;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.activity-meta {
|
|
font-size: 0.75rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* Performance Metrics Grid */
|
|
.performance-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.metric-card {
|
|
background: var(--bg-tertiary);
|
|
padding: 1rem;
|
|
border-radius: 4px;
|
|
border: 1px solid var(--border-color);
|
|
}
|
|
|
|
.metric-title {
|
|
font-size: 0.75rem;
|
|
color: var(--text-secondary);
|
|
text-transform: uppercase;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.metric-value {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
color: var(--accent-green);
|
|
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
}
|
|
|
|
.metric-bar {
|
|
height: 4px;
|
|
background: var(--bg-primary);
|
|
border-radius: 2px;
|
|
margin-top: 0.5rem;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.metric-bar-fill {
|
|
height: 100%;
|
|
background: var(--accent-green);
|
|
transition: width 1s ease;
|
|
}
|
|
|
|
/* Documentation Section */
|
|
.docs {
|
|
background: var(--bg-secondary);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 6px;
|
|
padding: 2rem;
|
|
}
|
|
|
|
.docs h2 {
|
|
font-size: 1.25rem;
|
|
margin-bottom: 1.5rem;
|
|
color: var(--accent-blue);
|
|
}
|
|
|
|
.doc-content h3 {
|
|
font-size: 1rem;
|
|
margin-top: 1.5rem;
|
|
margin-bottom: 0.75rem;
|
|
color: var(--accent-green);
|
|
}
|
|
|
|
.doc-content h3:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.doc-content p {
|
|
margin-bottom: 1rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.doc-content ul, .doc-content ol {
|
|
margin-bottom: 1rem;
|
|
padding-left: 1.5rem;
|
|
}
|
|
|
|
.doc-content li {
|
|
margin-bottom: 0.5rem;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.doc-content strong {
|
|
color: var(--text-primary);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.doc-content code {
|
|
background: var(--bg-tertiary);
|
|
padding: 0.125rem 0.375rem;
|
|
border-radius: 3px;
|
|
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
font-size: 0.875rem;
|
|
color: var(--accent-yellow);
|
|
}
|
|
|
|
/* Footer */
|
|
footer {
|
|
background: var(--bg-secondary);
|
|
border-top: 1px solid var(--border-color);
|
|
padding: 1.5rem 2rem;
|
|
text-align: center;
|
|
margin-top: 2rem;
|
|
}
|
|
|
|
footer p {
|
|
color: var(--text-secondary);
|
|
font-size: 0.875rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
footer a {
|
|
color: var(--accent-blue);
|
|
text-decoration: none;
|
|
}
|
|
|
|
footer a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Responsive Layout - Technique 3: Media queries with grid-template-areas */
|
|
@media (max-width: 1200px) {
|
|
main {
|
|
grid-template-areas:
|
|
"stats stats timeline timeline"
|
|
"usage usage usage usage"
|
|
"activity activity activity activity"
|
|
"performance performance performance performance"
|
|
"docs docs docs docs";
|
|
grid-template-columns: repeat(4, 1fr);
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
main {
|
|
grid-template-areas:
|
|
"stats"
|
|
"timeline"
|
|
"usage"
|
|
"activity"
|
|
"performance"
|
|
"docs";
|
|
grid-template-columns: 1fr;
|
|
padding: 1rem;
|
|
gap: 1rem;
|
|
}
|
|
|
|
header {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.panel {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.stats-grid {
|
|
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
|
}
|
|
}
|
|
|
|
/* Animation */
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(10px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.panel {
|
|
animation: fadeIn 0.5s ease forwards;
|
|
}
|
|
|
|
.stats-panel { animation-delay: 0.1s; }
|
|
.timeline-panel { animation-delay: 0.2s; }
|
|
.usage-panel { animation-delay: 0.3s; }
|
|
.activity-panel { animation-delay: 0.4s; }
|
|
.performance-panel { animation-delay: 0.5s; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<h1>📊 Dashboard Layout Tool</h1>
|
|
<p class="tagline">Responsive developer analytics dashboard powered by CSS Grid</p>
|
|
</header>
|
|
|
|
<main>
|
|
<!-- Stats Panel -->
|
|
<section class="panel stats-panel">
|
|
<h2><span class="panel-icon">📈</span>Session Overview</h2>
|
|
<div class="stats-grid">
|
|
<div class="stat-card blue">
|
|
<span class="stat-value" id="stat-sessions">24</span>
|
|
<span class="stat-label">Sessions</span>
|
|
</div>
|
|
<div class="stat-card green">
|
|
<span class="stat-value" id="stat-messages">1,847</span>
|
|
<span class="stat-label">Messages</span>
|
|
</div>
|
|
<div class="stat-card yellow">
|
|
<span class="stat-value" id="stat-tools">432</span>
|
|
<span class="stat-label">Tool Calls</span>
|
|
</div>
|
|
<div class="stat-card purple">
|
|
<span class="stat-value" id="stat-hours">18.5h</span>
|
|
<span class="stat-label">Active Time</span>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Timeline Panel -->
|
|
<section class="panel timeline-panel">
|
|
<h2><span class="panel-icon">🕐</span>Recent Activity</h2>
|
|
<div class="timeline">
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">14:32</div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-title">
|
|
Created dashboard component
|
|
<span class="timeline-badge edit">Edit</span>
|
|
</div>
|
|
<div class="timeline-desc">Modified 3 files in /src/components</div>
|
|
</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">14:28</div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-title">
|
|
Read configuration files
|
|
<span class="timeline-badge read">Read</span>
|
|
</div>
|
|
<div class="timeline-desc">Analyzed package.json and tsconfig.json</div>
|
|
</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">14:15</div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-title">
|
|
Ran test suite
|
|
<span class="timeline-badge bash">Bash</span>
|
|
</div>
|
|
<div class="timeline-desc">npm test -- 23 tests passed</div>
|
|
</div>
|
|
</div>
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">14:02</div>
|
|
<div class="timeline-content">
|
|
<div class="timeline-title">
|
|
Searched codebase
|
|
<span class="timeline-badge search">Search</span>
|
|
</div>
|
|
<div class="timeline-desc">Found 12 matches for "useEffect"</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Tool Usage Panel -->
|
|
<section class="panel usage-panel">
|
|
<h2><span class="panel-icon">🔧</span>Tool Usage Distribution</h2>
|
|
<div class="usage-bars" id="usage-chart"></div>
|
|
</section>
|
|
|
|
<!-- Activity Feed Panel -->
|
|
<section class="panel activity-panel">
|
|
<h2><span class="panel-icon">📋</span>Activity Feed</h2>
|
|
<div class="activity-feed" id="activity-feed"></div>
|
|
</section>
|
|
|
|
<!-- Performance Metrics Panel -->
|
|
<section class="panel performance-panel">
|
|
<h2><span class="panel-icon">⚡</span>Performance Metrics</h2>
|
|
<div class="performance-grid">
|
|
<div class="metric-card">
|
|
<div class="metric-title">Avg Response</div>
|
|
<div class="metric-value">2.3s</div>
|
|
<div class="metric-bar">
|
|
<div class="metric-bar-fill" style="width: 77%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-title">Success Rate</div>
|
|
<div class="metric-value">94.2%</div>
|
|
<div class="metric-bar">
|
|
<div class="metric-bar-fill" style="width: 94.2%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-title">Token Usage</div>
|
|
<div class="metric-value">847K</div>
|
|
<div class="metric-bar">
|
|
<div class="metric-bar-fill" style="width: 65%;"></div>
|
|
</div>
|
|
</div>
|
|
<div class="metric-card">
|
|
<div class="metric-title">Files Modified</div>
|
|
<div class="metric-value">142</div>
|
|
<div class="metric-bar">
|
|
<div class="metric-bar-fill" style="width: 82%;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Documentation -->
|
|
<section class="docs">
|
|
<h2>About This Tool</h2>
|
|
<div class="doc-content">
|
|
<h3>Purpose</h3>
|
|
<p>A demonstration of CSS Grid Layout techniques applied to create a flexible, responsive developer dashboard for Claude Code analytics. This tool showcases how to build modular dashboard layouts that adapt seamlessly to different screen sizes while maintaining visual hierarchy and usability.</p>
|
|
|
|
<h3>Features</h3>
|
|
<ul>
|
|
<li><strong>Named Grid Areas</strong> - Semantic layout regions using <code>grid-template-areas</code></li>
|
|
<li><strong>Responsive Auto-Fit</strong> - Stats cards that automatically adjust columns with <code>auto-fit</code> and <code>minmax()</code></li>
|
|
<li><strong>Consistent Spacing</strong> - Clean gaps between panels using CSS Grid <code>gap</code> property</li>
|
|
<li><strong>Multi-Panel Layout</strong> - 6 distinct dashboard sections arranged in an intelligent grid</li>
|
|
<li><strong>Adaptive Breakpoints</strong> - Layout reconfigures at 1200px and 768px for optimal viewing</li>
|
|
<li><strong>Dark Developer Theme</strong> - Eye-friendly color scheme for extended coding sessions</li>
|
|
<li><strong>Interactive Metrics</strong> - Live data visualization with tool usage, timeline, and performance stats</li>
|
|
</ul>
|
|
|
|
<h3>Web Research Integration</h3>
|
|
<p><strong>Source:</strong> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" target="_blank">MDN - CSS Grid Layout</a></p>
|
|
<p><strong>Techniques Applied:</strong></p>
|
|
<ul>
|
|
<li><strong>grid-template-areas</strong> - Created named layout regions ("stats", "timeline", "usage", "activity", "performance", "docs") for semantic, maintainable dashboard structure. This allows easy reconfiguration at different breakpoints by simply redefining the areas.</li>
|
|
<li><strong>auto-fit with minmax()</strong> - Implemented responsive card grids (stats-grid, performance-grid) that automatically adjust column count based on available space using <code>repeat(auto-fit, minmax(120px, 1fr))</code>. Cards flow and resize without media queries.</li>
|
|
<li><strong>gap property</strong> - Applied consistent spacing between all grid items using the <code>gap: 1.5rem</code> property, eliminating the need for margin calculations and ensuring uniform visual rhythm across the entire dashboard.</li>
|
|
</ul>
|
|
|
|
<h3>Grid Layout Structure</h3>
|
|
<p>The main dashboard uses a 4-column grid with named areas:</p>
|
|
<ul>
|
|
<li><strong>Desktop (>1200px):</strong> 4x4 grid with stats/timeline sharing top row, usage/activity in middle rows</li>
|
|
<li><strong>Tablet (768-1200px):</strong> 4-column grid with full-width sections stacked vertically</li>
|
|
<li><strong>Mobile (<768px):</strong> Single column stack for optimal mobile viewing</li>
|
|
</ul>
|
|
|
|
<h3>Usage</h3>
|
|
<ol>
|
|
<li>Open the tool to see a complete analytics dashboard layout</li>
|
|
<li>Resize the browser window to observe responsive grid reconfiguration</li>
|
|
<li>Notice how named grid areas reorganize at different breakpoints</li>
|
|
<li>Observe auto-fit behavior in stats cards and performance metrics</li>
|
|
<li>Use this pattern for building your own modular dashboards</li>
|
|
<li>Inspect the CSS to understand grid-template-areas syntax</li>
|
|
</ol>
|
|
|
|
<h3>Developer Notes</h3>
|
|
<p>This dashboard demonstrates key advantages of CSS Grid for developer tools:</p>
|
|
<ul>
|
|
<li><strong>Maintainability:</strong> Named grid areas make layout intent clear and changes simple</li>
|
|
<li><strong>Flexibility:</strong> Easy to add, remove, or reorder dashboard panels</li>
|
|
<li><strong>Responsiveness:</strong> Auto-fit and minmax() eliminate brittle breakpoint logic</li>
|
|
<li><strong>Performance:</strong> Pure CSS solution with no JavaScript layout calculations</li>
|
|
<li><strong>Accessibility:</strong> Grid maintains semantic HTML structure regardless of visual layout</li>
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<footer>
|
|
<p>Claude Code DevTools | Generated via web-enhanced infinite loop</p>
|
|
<p>Web Source: <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout" target="_blank">MDN - CSS Grid Layout</a></p>
|
|
</footer>
|
|
|
|
<script>
|
|
// Generate tool usage bars
|
|
const toolUsageData = [
|
|
{ tool: 'Edit', count: 156, max: 200 },
|
|
{ tool: 'Read', count: 142, max: 200 },
|
|
{ tool: 'Bash', count: 89, max: 200 },
|
|
{ tool: 'Grep', count: 67, max: 200 },
|
|
{ tool: 'Write', count: 45, max: 200 },
|
|
{ tool: 'Glob', count: 33, max: 200 }
|
|
];
|
|
|
|
const usageChart = document.getElementById('usage-chart');
|
|
toolUsageData.forEach(item => {
|
|
const percentage = (item.count / item.max * 100).toFixed(1);
|
|
const bar = document.createElement('div');
|
|
bar.className = 'usage-bar';
|
|
bar.innerHTML = `
|
|
<div class="usage-label">${item.tool}</div>
|
|
<div class="usage-bar-bg">
|
|
<div class="usage-bar-fill" style="width: ${percentage}%">
|
|
${item.count}
|
|
</div>
|
|
</div>
|
|
`;
|
|
usageChart.appendChild(bar);
|
|
});
|
|
|
|
// Generate activity feed
|
|
const activities = [
|
|
{ type: 'success', icon: '✅', title: 'Successfully deployed to production', meta: '2 minutes ago', class: 'success' },
|
|
{ type: 'info', icon: '📝', title: 'Updated README documentation', meta: '15 minutes ago', class: '' },
|
|
{ type: 'warning', icon: '⚠️', title: 'Deprecated API usage detected', meta: '32 minutes ago', class: 'warning' },
|
|
{ type: 'success', icon: '🧪', title: 'All tests passed (23/23)', meta: '1 hour ago', class: 'success' },
|
|
{ type: 'info', icon: '🔍', title: 'Code review requested', meta: '2 hours ago', class: '' },
|
|
{ type: 'error', icon: '❌', title: 'Build failed on branch feature-123', meta: '3 hours ago', class: 'error' },
|
|
{ type: 'success', icon: '🚀', title: 'Feature flag enabled: dark-mode', meta: '4 hours ago', class: 'success' },
|
|
{ type: 'info', icon: '💾', title: 'Database backup completed', meta: '5 hours ago', class: '' }
|
|
];
|
|
|
|
const activityFeed = document.getElementById('activity-feed');
|
|
activities.forEach(activity => {
|
|
const item = document.createElement('div');
|
|
item.className = `activity-item ${activity.class}`;
|
|
item.innerHTML = `
|
|
<div class="activity-icon">${activity.icon}</div>
|
|
<div class="activity-content">
|
|
<div class="activity-title">${activity.title}</div>
|
|
<div class="activity-meta">${activity.meta}</div>
|
|
</div>
|
|
`;
|
|
activityFeed.appendChild(item);
|
|
});
|
|
|
|
// Animate stats on load
|
|
function animateValue(id, start, end, duration) {
|
|
const element = document.getElementById(id);
|
|
const startTime = performance.now();
|
|
|
|
function update(currentTime) {
|
|
const elapsed = currentTime - startTime;
|
|
const progress = Math.min(elapsed / duration, 1);
|
|
|
|
const current = Math.floor(start + (end - start) * progress);
|
|
|
|
if (id === 'stat-hours') {
|
|
element.textContent = (start + (end - start) * progress).toFixed(1) + 'h';
|
|
} else if (id === 'stat-messages') {
|
|
element.textContent = current.toLocaleString();
|
|
} else {
|
|
element.textContent = current;
|
|
}
|
|
|
|
if (progress < 1) {
|
|
requestAnimationFrame(update);
|
|
}
|
|
}
|
|
|
|
requestAnimationFrame(update);
|
|
}
|
|
|
|
// Trigger animations after page load
|
|
window.addEventListener('load', () => {
|
|
animateValue('stat-sessions', 0, 24, 1000);
|
|
animateValue('stat-messages', 0, 1847, 1200);
|
|
animateValue('stat-tools', 0, 432, 1100);
|
|
animateValue('stat-hours', 0, 18.5, 1300);
|
|
});
|
|
|
|
// Add keyboard shortcut hint
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.ctrlKey && e.key === 'k') {
|
|
e.preventDefault();
|
|
alert('Keyboard shortcuts:\n\nCtrl+K: This help menu\nCtrl+R: Refresh dashboard\nCtrl+E: Export data');
|
|
}
|
|
if (e.ctrlKey && e.key === 'r') {
|
|
e.preventDefault();
|
|
location.reload();
|
|
}
|
|
if (e.ctrlKey && e.key === 'e') {
|
|
e.preventDefault();
|
|
alert('Export functionality would trigger here (not implemented in this demo)');
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|