Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/tasks/backlog/P10-T110.md → docs/tasks/done/P10-T110.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# P10-T110: Add responsive design using Tailwind CSS (via CDN or standalone CLI)

**Phase:** P10 - Dashboard & Monitoring UI
**Status:** Not Started
**Status:** Completed
**Priority:** Low
**Dependencies:** [P10-T040]
**Estimated Effort:** Small
Expand All @@ -14,11 +14,11 @@ Ensure the dashboard is fully responsive and visually polished across mobile, ta

## Acceptance Criteria

- [ ] Implement a mobile-first sidebar/menu that collapses into a "hamburger" menu.
- [ ] Set responsive column widths for lists and tables (`hidden md:table-cell`).
- [ ] Verify chart scaling on small devices.
- [ ] Optimize the login screen for mobile use.
- [ ] Use Tailwind colors consistently across all components.
- [x] Implement a mobile-first sidebar/menu that collapses into a "hamburger" menu.
- [x] Set responsive column widths for lists and tables (`hidden md:table-cell`).
- [x] Verify chart scaling on small devices.
- [x] Optimize the login screen for mobile use.
- [x] Use Tailwind colors consistently across all components.

## Implementation Notes

Expand Down
4 changes: 2 additions & 2 deletions go/internal/server/e2e_worker_crash_recovery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestWorkerCrashRecovery(t *testing.T) {
var lastCheckpoint int64

checkSuccess := false
for range 50 {
for range 100 {
time.Sleep(200 * time.Millisecond)
q := database.NewQueries(db)
jobs, err := q.GetJobsByWorker(context.Background(), sql.NullString{String: workerID, Valid: true})
Expand Down Expand Up @@ -150,7 +150,7 @@ func TestWorkerCrashRecovery(t *testing.T) {
// checking the DB for the final result is better.

completed := false
for range 50 {
for range 100 {
time.Sleep(200 * time.Millisecond)
q := database.NewQueries(db)
j, err := q.GetJobByID(context.Background(), jobID)
Expand Down
14 changes: 7 additions & 7 deletions go/internal/server/ui/templates/active_workers.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ <h3 class="text-base font-semibold leading-6 text-gray-900">Active Fleet Status<
class="px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
Status</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
class="hidden md:table-cell px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
Workload</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
Throughput</th>
<th scope="col"
class="px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
class="hidden lg:table-cell px-6 py-3 text-left text-xs font-bold text-gray-500 uppercase tracking-wider">
Last Activity</th>
</tr>
</thead>
Expand All @@ -42,7 +42,7 @@ <h3 class="text-base font-semibold leading-6 text-gray-900">Active Fleet Status<
<tr class="hover:bg-gray-50 transition-colors">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="{{workerIconClass .WorkerType}}">
<div class="{{workerIconClass .WorkerType}} flex-shrink-0">
{{if eq .WorkerType "pc"}}
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
Expand All @@ -55,8 +55,8 @@ <h3 class="text-base font-semibold leading-6 text-gray-900">Active Fleet Status<
</svg>
{{end}}
</div>
<div class="ml-4">
<div class="text-sm font-bold text-gray-900 leading-none mb-1">
<div class="ml-4 truncate">
<div class="text-sm font-bold text-gray-900 leading-none mb-1 truncate">
<a {{workerLinkAttr .ID}}
class="hover:text-blue-600 hover:underline underline-offset-4 transition">
{{.ID}}
Expand All @@ -73,7 +73,7 @@ <h3 class="text-base font-semibold leading-6 text-gray-900">Active Fleet Status<
ACTIVE
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<td class="hidden md:table-cell px-6 py-4 whitespace-nowrap">
{{if .CurrentNonce.Valid}}
<div class="flex flex-col">
<span class="text-xs font-mono text-gray-500 mb-1">Prefix: 0x{{printf "%x"
Expand All @@ -98,7 +98,7 @@ <h3 class="text-base font-semibold leading-6 text-gray-900">Active Fleet Status<
<div class="text-sm text-gray-300 font-mono">---</div>
{{end}}
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<td class="hidden lg:table-cell px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div class="text-xs text-gray-500 font-mono">{{.LastSeen.UTC.Format "15:04:05"}} UTC
</div>
</td>
Expand Down
63 changes: 48 additions & 15 deletions go/internal/server/ui/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
<!-- Mobile Menu Button -->
<div class="md:hidden flex items-center">
<button type="button" onclick="document.getElementById('mobile-menu').classList.toggle('hidden')"
class="bg-gray-800 p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 transition">
class="bg-gray-800 p-2 rounded-md text-gray-300 hover:text-white hover:bg-gray-700 transition focus:outline-none focus:ring-2 focus:ring-blue-500">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 6h16M4 12h16M4 18h16" />
Expand All @@ -82,27 +82,60 @@
</div>
</div>

<!-- Mobile Menu (Hidden by default) -->
<!-- Mobile Menu (Overlay) -->
{{if not .HideNav}}
<div id="mobile-menu" class="hidden md:hidden border-t border-gray-800 bg-gray-900 absolute w-full shadow-lg">
<div class="px-4 py-3 space-y-2">
<a href="/dashboard" {{navAttr .CurrentPath "/dashboard" "block w-full" }}>Overview</a>
<a href="/dashboard/daily" {{navAttr .CurrentPath "/dashboard/daily" "block w-full" }}>Daily</a>
<a href="/dashboard/monthly" {{navAttr .CurrentPath "/dashboard/monthly" "block w-full" }}>Monthly</a>
<a href="/dashboard/leaderboard" {{navAttr .CurrentPath "/dashboard/leaderboard" "block w-full" }}>Hall
of Fame</a>
<a href="/dashboard/workers" {{navAttr .CurrentPath "/dashboard/workers" "block w-full" }}>Workers</a>
<a href="/dashboard/settings" {{navAttr .CurrentPath "/dashboard/settings" "block w-full"
}}>Settings</a>
<div class="border-t border-gray-700 pt-2 mt-2">
<div id="mobile-menu" class="hidden md:hidden fixed inset-0 z-50">
<!-- Backdrop -->
<div class="fixed inset-0 bg-gray-900/60 backdrop-blur-sm"
onclick="document.getElementById('mobile-menu').classList.add('hidden')"></div>

<!-- Sidebar Panel -->
<nav
class="fixed inset-y-0 right-0 w-64 max-w-xs bg-gray-900 shadow-xl overflow-y-auto border-l border-gray-800 flex flex-col transition-all duration-300">
<div class="px-6 py-5 flex items-center justify-between border-b border-gray-800">
<div class="flex items-center">
<img class="h-8 w-8 rounded-md" src="/static/img/apple-touch-icon.png" alt="EthScanner Logo">
<span class="ml-3 text-sm font-bold uppercase tracking-widest">Navigation</span>
</div>
<button type="button" onclick="document.getElementById('mobile-menu').classList.add('hidden')"
class="p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-800 transition">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>

<div class="px-4 py-6 space-y-2 flex-grow">
<a href="/dashboard" {{navAttr
.CurrentPath "/dashboard" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Overview</a>
<a href="/dashboard/daily" {{navAttr
.CurrentPath "/dashboard/daily" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Daily Stats</a>
<a href="/dashboard/monthly" {{navAttr
.CurrentPath "/dashboard/monthly" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Monthly Stats</a>
<a href="/dashboard/leaderboard" {{navAttr
.CurrentPath "/dashboard/leaderboard" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Leaderboard</a>
<a href="/dashboard/workers" {{navAttr
.CurrentPath "/dashboard/workers" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Workers</a>
<a href="/dashboard/settings" {{navAttr
.CurrentPath "/dashboard/settings" "block w-full py-3 px-4 rounded-lg text-sm font-bold" }}
onclick="document.getElementById('mobile-menu').classList.add('hidden')">Settings</a>
</div>

<div class="p-4 border-t border-gray-800">
<form action="/logout" method="POST" class="w-full">
<button type="submit"
class="w-full text-left px-3 py-2 text-red-400 hover:bg-gray-800 rounded-md text-sm font-medium transition">
class="w-full text-center px-4 py-3 bg-red-600/10 text-red-400 hover:bg-red-600/20 rounded-lg text-xs font-bold transition uppercase tracking-widest border border-red-900/50">
Logout
</button>
</form>
</div>
</div>
</nav>
</div>
{{end}}
</header>
Expand Down
11 changes: 7 additions & 4 deletions go/internal/server/ui/templates/daily.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,23 @@ <h3 class="text-xs font-bold text-gray-500 uppercase tracking-widest">Daily Log
class="px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">Date
</th>
<th scope="col"
class="px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">Status
class="hidden sm:table-cell px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">
Status
</th>
<th scope="col"
class="px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">Volume
(Keys)</th>
<th scope="col"
class="px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">Errors
class="hidden md:table-cell px-6 py-3 text-left text-[10px] font-bold text-gray-400 uppercase tracking-widest">
Errors
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-100">
{{range .DailyStats}}
<tr class="hover:bg-gray-50/50 transition leading-none">
<td class="px-6 py-4 text-sm font-bold text-gray-600 font-mono">{{.StatsDate}}</td>
<td class="px-6 py-4 text-sm text-gray-500">
<td class="hidden sm:table-cell px-6 py-4 text-sm text-gray-500">
{{if .TotalKeysScanned}}
<div class="flex items-center">
<span class="h-1.5 w-1.5 rounded-full bg-green-400 mr-2"></span>
Expand All @@ -143,7 +145,8 @@ <h3 class="text-xs font-bold text-gray-500 uppercase tracking-widest">Daily Log
</td>
<td class="px-6 py-4 text-sm font-black text-gray-800 tracking-tight">
{{printf "%.0f" (float64 .TotalKeysScanned)}}</td>
<td {{errorStatusAttr .TotalErrors}} class="px-6 py-4 text-sm uppercase tracking-tighter">
<td {{errorStatusAttr .TotalErrors}}
class="hidden md:table-cell px-6 py-4 text-sm uppercase tracking-tighter">
{{printf "%.0f" (float64 .TotalErrors)}}</td>
</tr>
{{else}}
Expand Down
Loading