Add mobile-first responsive design with bottom tab navigation

Converts desktop sidebar to hidden on mobile, adds bottom tab bar with
5 primary items and a "More" overflow menu. All pages get responsive
spacing, smaller touch targets, and tighter grids on small screens.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-16 12:58:48 -06:00
parent faa7dbf4d3
commit 4903b84aef
14 changed files with 263 additions and 137 deletions

View File

@@ -108,8 +108,8 @@ export default function Downloads() {
return (
<div>
<div className="mb-6">
<h1 className="text-2xl font-bold text-white mb-1">Downloads</h1>
<div className="mb-4 md:mb-6">
<h1 className="text-xl md:text-2xl font-bold text-white mb-1">Downloads</h1>
<p className="text-gray-500 text-sm">
Manage and monitor media downloads
</p>
@@ -239,8 +239,8 @@ export default function Downloads() {
</div>
) : history.length === 0 ? null : (
<div className="bg-[#161616] border border-[#222] rounded-lg overflow-hidden">
{/* Table Header */}
<div className="grid grid-cols-[1fr_auto_auto_auto] gap-4 px-4 py-3 border-b border-[#222] text-xs font-semibold text-gray-500 uppercase tracking-wider">
{/* Table Header - hidden on mobile */}
<div className="hidden md:grid grid-cols-[1fr_auto_auto_auto] gap-4 px-4 py-3 border-b border-[#222] text-xs font-semibold text-gray-500 uppercase tracking-wider">
<span>User</span>
<span className="text-right">Files</span>
<span className="text-right">Status</span>
@@ -253,33 +253,43 @@ export default function Downloads() {
return (
<div
key={uid || index}
className={`grid grid-cols-[1fr_auto_auto_auto] gap-4 px-4 py-3 items-center ${
className={`px-4 py-3 ${
index < history.length - 1 ? 'border-b border-[#1a1a1a]' : ''
}`}
>
<div className="flex items-center gap-3 min-w-0">
<div className="w-8 h-8 rounded-full bg-[#333] flex-shrink-0" />
<span className="text-sm text-white truncate">
{usernames[uid] ? `@${usernames[uid]}` : `User ${uid}`}
{/* Desktop row */}
<div className="hidden md:grid grid-cols-[1fr_auto_auto_auto] gap-4 items-center">
<div className="flex items-center gap-3 min-w-0">
<div className="w-8 h-8 rounded-full bg-[#333] flex-shrink-0" />
<span className="text-sm text-white truncate">
{usernames[uid] ? `@${usernames[uid]}` : `User ${uid}`}
</span>
</div>
<span className="text-sm text-gray-400 text-right tabular-nums">
{item.fileCount || item.file_count || 0}
</span>
<span className="text-right">
<StatusBadge status="complete" />
</span>
<span className="text-xs text-gray-500 text-right whitespace-nowrap">
{formatDate(item.lastDownload || item.last_download || item.completedAt || item.created_at)}
</span>
</div>
<span className="text-sm text-gray-400 text-right tabular-nums">
{item.fileCount || item.file_count || 0}
</span>
<span className="text-right">
{/* Mobile row */}
<div className="md:hidden flex items-center justify-between">
<div className="flex items-center gap-3 min-w-0 flex-1">
<div className="w-8 h-8 rounded-full bg-[#333] flex-shrink-0" />
<div className="min-w-0">
<span className="text-sm text-white truncate block">
{usernames[uid] ? `@${usernames[uid]}` : `User ${uid}`}
</span>
<span className="text-xs text-gray-500">
{item.fileCount || item.file_count || 0} files
</span>
</div>
</div>
<StatusBadge status="complete" />
</span>
<span className="text-xs text-gray-500 text-right whitespace-nowrap">
{formatDate(
item.lastDownload ||
item.last_download ||
item.completedAt ||
item.created_at
)}
</span>
</div>
</div>
)
})}