From 99a9295c97ef341513faaaa311c14125612c5023 Mon Sep 17 00:00:00 2001 From: Gio M Date: Tue, 10 Mar 2026 21:30:55 -0600 Subject: [PATCH] Improve UI usability for new users - Simplify navigation: reduce 10 tabs to 5 main + dropdown menu - Add 'Getting Started' banner on dashboard for empty state - Enhance empty states with clear CTAs and helpful tips - Improve visual hierarchy with better spacing and gradients - Add responsive navigation that hides labels on smaller screens --- css/components.css | 186 +++++++++++++++++++++++++++++++++++++ css/layout.css | 88 ++++++++++++++++++ index.html | 71 ++++++++------ js/app.js | 39 +++++++- js/components/dashboard.js | 57 ++++++++++-- js/components/rig-list.js | 20 +++- 6 files changed, 413 insertions(+), 48 deletions(-) diff --git a/css/components.css b/css/components.css index 1e5f0c7..84d612f 100644 --- a/css/components.css +++ b/css/components.css @@ -1188,6 +1188,67 @@ select { color: var(--text-muted); } +.empty-state.enhanced { + padding: var(--space-xxl) var(--space-xl); + background: var(--bg-secondary); + border: 1px solid var(--border-default); + border-radius: var(--radius-xl); + max-width: 500px; + margin: var(--space-xl) auto; +} + +.empty-state-icon-wrapper { + width: 80px; + height: 80px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, rgba(88, 166, 255, 0.1) 0%, rgba(163, 113, 247, 0.1) 100%); + border-radius: var(--radius-xl); + margin-bottom: var(--space-lg); +} + +.empty-state-icon-wrapper .material-icons { + font-size: 40px; + color: var(--accent-primary); +} + +.empty-state.enhanced h3 { + font-size: var(--text-xl); + font-weight: 600; + color: var(--text-primary); + margin: 0 0 var(--space-sm) 0; +} + +.empty-state.enhanced p { + font-size: var(--text-sm); + color: var(--text-secondary); + max-width: 400px; + margin: 0 0 var(--space-lg) 0; + line-height: 1.6; +} + +.empty-state-actions { + display: flex; + gap: var(--space-sm); + margin-bottom: var(--space-lg); +} + +.empty-state-hint { + display: flex; + align-items: center; + gap: var(--space-xs); + font-size: var(--text-xs); + color: var(--text-muted); + padding: var(--space-sm) var(--space-md); + background: var(--bg-tertiary); + border-radius: var(--radius-md); +} + +.empty-state-hint .material-icons { + font-size: 14px; +} + .empty-state-icon { font-size: 48px; margin-bottom: var(--space-md); @@ -5860,6 +5921,131 @@ select { --health-color: #6b7280; } +/* Getting Started Banner */ +.getting-started-banner { + background: linear-gradient(135deg, rgba(88, 166, 255, 0.1) 0%, rgba(163, 113, 247, 0.1) 100%); + border: 1px solid rgba(88, 166, 255, 0.3); + border-radius: var(--radius-xl); + padding: var(--space-xl); + margin-bottom: var(--space-lg); + animation: fadeIn 0.5s ease; +} + +.getting-started-content { + display: flex; + align-items: center; + gap: var(--space-lg); + margin-bottom: var(--space-lg); +} + +.getting-started-icon { + width: 64px; + height: 64px; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, var(--accent-primary) 0%, var(--accent-secondary) 100%); + border-radius: var(--radius-lg); + flex-shrink: 0; +} + +.getting-started-icon .material-icons { + font-size: 32px; + color: white; +} + +.getting-started-text { + flex: 1; +} + +.getting-started-text h2 { + font-size: var(--text-xl); + font-weight: 700; + margin: 0 0 var(--space-xs) 0; + color: var(--text-primary); +} + +.getting-started-text p { + font-size: var(--text-sm); + color: var(--text-secondary); + margin: 0; +} + +.getting-started-actions { + display: flex; + gap: var(--space-sm); + flex-shrink: 0; +} + +.btn-lg { + padding: var(--space-md) var(--space-xl); + font-size: var(--text-base); +} + +.getting-started-steps { + display: flex; + align-items: center; + justify-content: center; + gap: var(--space-md); + padding: var(--space-md); + background: var(--bg-secondary); + border-radius: var(--radius-lg); +} + +.getting-started-steps .step { + display: flex; + align-items: center; + gap: var(--space-sm); +} + +.getting-started-steps .step-number { + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + background: var(--accent-primary); + color: white; + border-radius: var(--radius-full); + font-weight: 600; + font-size: var(--text-sm); + flex-shrink: 0; +} + +.getting-started-steps .step-text { + font-size: var(--text-sm); + color: var(--text-secondary); + white-space: nowrap; +} + +.getting-started-steps .step-arrow { + color: var(--text-muted); +} + +.getting-started-steps .step-arrow .material-icons { + font-size: 20px; +} + +@media (max-width: 1024px) { + .getting-started-content { + flex-direction: column; + text-align: center; + } + + .getting-started-actions { + flex-direction: column; + width: 100%; + } + + .getting-started-steps { + flex-wrap: wrap; + } + + .getting-started-steps .step-arrow { + display: none; + } +} + /* Metrics Grid - 4-column balanced design */ .dashboard-metrics { display: grid; diff --git a/css/layout.css b/css/layout.css index ce951a4..22dc3f9 100644 --- a/css/layout.css +++ b/css/layout.css @@ -289,6 +289,94 @@ body { font-size: 20px; } +.nav-label { + display: inline; +} + +@media (max-width: 1200px) { + .nav-label { + display: none; + } + .nav-tab { + padding: var(--space-sm); + } +} + +.nav-dropdown { + position: relative; +} + +.nav-dropdown-toggle { + cursor: pointer; +} + +.nav-dropdown-arrow { + font-size: 16px !important; + transition: transform var(--transition-fast); +} + +.nav-dropdown:hover .nav-dropdown-arrow, +.nav-dropdown.open .nav-dropdown-arrow { + transform: rotate(180deg); +} + +.nav-dropdown-menu { + position: absolute; + top: 100%; + right: 0; + min-width: 200px; + background: var(--bg-secondary); + border: 1px solid var(--border-default); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-lg); + padding: var(--space-xs); + opacity: 0; + visibility: hidden; + transform: translateY(-8px); + transition: all var(--transition-fast); + z-index: var(--z-dropdown); +} + +.nav-dropdown:hover .nav-dropdown-menu, +.nav-dropdown.open .nav-dropdown-menu { + opacity: 1; + visibility: visible; + transform: translateY(0); +} + +.nav-dropdown-item { + display: flex; + align-items: center; + gap: var(--space-sm); + width: 100%; + padding: var(--space-sm) var(--space-md); + font-size: var(--text-sm); + color: var(--text-secondary); + border-radius: var(--radius-md); + transition: all var(--transition-fast); + text-align: left; +} + +.nav-dropdown-item:hover { + background: var(--bg-hover); + color: var(--text-primary); +} + +.nav-dropdown-item .material-icons { + font-size: 18px; +} + +.nav-dropdown-item.active { + color: var(--accent-primary); + background: var(--bg-tertiary); +} + +.nav-dropdown-divider { + height: 1px; + background: var(--border-default); + margin: var(--space-xs) 0; +} + .header-right { display: flex; align-items: center; diff --git a/index.html b/index.html index 4b512fc..cf8daeb 100644 --- a/index.html +++ b/index.html @@ -61,49 +61,60 @@
diff --git a/js/app.js b/js/app.js index 20d2a7c..00fcce4 100644 --- a/js/app.js +++ b/js/app.js @@ -214,28 +214,57 @@ async function init() { } -// Navigation setup function setupNavigation() { navTabs.forEach(tab => { tab.addEventListener('click', () => { const viewId = tab.dataset.view; - switchView(viewId); + if (viewId) { + switchView(viewId); + } + }); + }); + + document.querySelectorAll('.nav-dropdown-item').forEach(item => { + item.addEventListener('click', (e) => { + e.stopPropagation(); + const viewId = item.dataset.view; + if (viewId) { + switchView(viewId); + document.querySelectorAll('.nav-dropdown').forEach(d => d.classList.remove('open')); + } + }); + }); + + document.querySelectorAll('.nav-dropdown-toggle').forEach(toggle => { + toggle.addEventListener('click', (e) => { + e.stopPropagation(); + const dropdown = toggle.closest('.nav-dropdown'); + if (dropdown) { + dropdown.classList.toggle('open'); + } + }); + }); + + document.addEventListener('click', () => { + document.querySelectorAll('.nav-dropdown').forEach(d => { + d.classList.remove('open'); }); }); } function switchView(viewId) { - // Update tabs navTabs.forEach(tab => { tab.classList.toggle('active', tab.dataset.view === viewId); }); - // Update views + document.querySelectorAll('.nav-dropdown-item').forEach(item => { + item.classList.toggle('active', item.dataset.view === viewId); + }); + views.forEach(view => { view.classList.toggle('active', view.id === `view-${viewId}`); }); - // Load view-specific data if (viewId === 'dashboard') { loadDashboard(); } else if (viewId === 'mail') { diff --git a/js/components/dashboard.js b/js/components/dashboard.js index 1056821..695514a 100644 --- a/js/components/dashboard.js +++ b/js/components/dashboard.js @@ -182,15 +182,14 @@ function renderDashboard(status, health) { const agents = state.get('agents') || []; const mail = state.get('mail') || []; - // Calculate metrics const metrics = calculateMetrics(rigs, convoys, work, agents, mail); const healthStatus = calculateHealthStatus(health); + const isEmpty = rigs.length === 0 && convoys.length === 0 && work.length === 0; container.innerHTML = ` - + ${isEmpty ? renderGettingStarted() : ''} ${renderHealthBanner(healthStatus)} -
${renderMetricCard('local_shipping', 'Active Convoys', metrics.activeConvoys, metrics.totalConvoys, 'convoys', '#3b82f6')} ${renderMetricCard('task_alt', 'Open Work', metrics.openWork, metrics.totalWork, 'work', '#22c55e')} @@ -198,9 +197,7 @@ function renderDashboard(status, health) { ${renderMetricCard('mail', 'Unread Mail', metrics.unreadMail, metrics.totalMail, 'mail', '#f59e0b')}
-
-
bolt @@ -211,7 +208,6 @@ function renderDashboard(status, health) {
-
monitoring @@ -222,7 +218,6 @@ function renderDashboard(status, health) {
-
history @@ -233,7 +228,6 @@ function renderDashboard(status, health) {
-
folder_special @@ -246,10 +240,55 @@ function renderDashboard(status, health) {
`; - // Add event listeners for quick actions setupQuickActionHandlers(); } +function renderGettingStarted() { + return ` +
+
+
+ rocket_launch +
+
+

Welcome to Gas Town!

+

Get started by connecting your first project (rig) and creating work for your AI agents.

+
+
+ + +
+
+
+
+
1
+
Connect a GitHub repo
+
+
arrow_forward
+
+
2
+
Create a work item
+
+
arrow_forward
+
+
3
+
Assign to an agent
+
+
arrow_forward
+
+
4
+
Watch it work!
+
+
+
+ `; + /** * Calculate dashboard metrics */ diff --git a/js/components/rig-list.js b/js/components/rig-list.js index 419bc9d..d15a0d7 100644 --- a/js/components/rig-list.js +++ b/js/components/rig-list.js @@ -21,10 +21,22 @@ export function renderRigList(container, rigs) { if (!rigs || rigs.length === 0) { container.innerHTML = ` -
- folder_off -

No Rigs

-

Add a rig to get started with multi-agent development

+
+
+ folder_special +
+

No Rigs Yet

+

A rig connects your GitHub repository to Gas Town so AI agents can work on your code.

+
+ +
+
+ info + Tip: You can add multiple rigs for different projects +
`; return;