From 41c57ee265d9c72bb51ff7c01824c938cc38e5ce Mon Sep 17 00:00:00 2001 From: 2Wits <2witstudios@gmail.com> Date: Wed, 24 Sep 2025 19:15:05 -0500 Subject: [PATCH 1/8] Improve responsive layout across web app --- apps/web/src/app/admin/AdminLayoutClient.tsx | 6 +- apps/web/src/app/admin/users/page.tsx | 4 +- apps/web/src/app/dashboard/storage/page.tsx | 63 ++--- apps/web/src/app/settings/ai/page.tsx | 2 +- apps/web/src/app/settings/page.tsx | 4 +- apps/web/src/components/admin/UsersTable.tsx | 58 +++-- .../src/components/billing/UsageCounter.tsx | 2 +- apps/web/src/components/layout/Layout.tsx | 131 +++++----- .../layout/left-sidebar/MemoizedSidebar.tsx | 8 +- .../left-sidebar/MessagesLeftSidebar.tsx | 13 +- .../components/layout/left-sidebar/index.tsx | 243 ++++++++++-------- .../components/layout/main-header/index.tsx | 97 ++++--- .../right-sidebar/MemoizedRightPanel.tsx | 6 +- .../components/layout/right-sidebar/index.tsx | 160 +++++++----- .../notifications/NotificationBell.tsx | 2 +- apps/web/src/hooks/use-breakpoint.ts | 39 +++ apps/web/src/hooks/use-mobile.ts | 25 +- apps/web/src/hooks/use-responsive-panels.ts | 29 +++ apps/web/src/stores/useLayoutStore.ts | 12 +- 19 files changed, 536 insertions(+), 368 deletions(-) create mode 100644 apps/web/src/hooks/use-breakpoint.ts create mode 100644 apps/web/src/hooks/use-responsive-panels.ts diff --git a/apps/web/src/app/admin/AdminLayoutClient.tsx b/apps/web/src/app/admin/AdminLayoutClient.tsx index 5590191551..f1ebd0cf96 100644 --- a/apps/web/src/app/admin/AdminLayoutClient.tsx +++ b/apps/web/src/app/admin/AdminLayoutClient.tsx @@ -16,8 +16,8 @@ export default function AdminLayoutClient({ pathname.includes('/support') ? 'support' : 'users'; return ( -
-
+
+
Admin Dashboard @@ -28,7 +28,7 @@ export default function AdminLayoutClient({ - + Monitoring diff --git a/apps/web/src/app/admin/users/page.tsx b/apps/web/src/app/admin/users/page.tsx index 6b6f7ad779..c58f5c56fb 100644 --- a/apps/web/src/app/admin/users/page.tsx +++ b/apps/web/src/app/admin/users/page.tsx @@ -82,7 +82,7 @@ export default function AdminUsersPage() { -
+
{[...Array(4)].map((_, i) => (
@@ -145,7 +145,7 @@ export default function AdminUsersPage() { -
+
{users.length}
diff --git a/apps/web/src/app/dashboard/storage/page.tsx b/apps/web/src/app/dashboard/storage/page.tsx index 6c6179f4a3..ed4452ac37 100644 --- a/apps/web/src/app/dashboard/storage/page.tsx +++ b/apps/web/src/app/dashboard/storage/page.tsx @@ -142,7 +142,7 @@ export default function StorageDashboard() { if (loading) { return ( -
+
@@ -157,7 +157,7 @@ export default function StorageDashboard() { if (!storageInfo) { return ( -
+
Error @@ -171,7 +171,7 @@ export default function StorageDashboard() { return (
-
+
-
+

Storage Dashboard

@@ -194,6 +194,7 @@ export default function StorageDashboard() { disabled={reconciling} variant="outline" size="sm" + className="w-full sm:w-auto" > Reconcile Storage @@ -233,7 +234,7 @@ export default function StorageDashboard() { value={quota.utilizationPercent} className="h-3" /> -

+
{quota.formattedAvailable} available @@ -247,7 +248,7 @@ export default function StorageDashboard() { {/* Tier Information Card */} - + Storage Plan {tierInfo.name} @@ -257,18 +258,18 @@ export default function StorageDashboard() {
-
+
Total Files: {totalFiles} {tierInfo.maxFileCount > 0 && ` / ${tierInfo.maxFileCount}`}
-
+
Max File Size: {formatBytes(tierInfo.maxFileSize)}
-
+
Concurrent Uploads: {tierInfo.maxConcurrentUploads}
@@ -318,28 +319,30 @@ export default function StorageDashboard() { Storage usage across your drives - - - - Drive Name - Files - Storage Used - Percentage - - - - {storageByDrive.map((drive) => ( - - {drive.driveName} - {drive.fileCount} - {drive.formattedSize} - - {Math.round((drive.totalSize / quota.usedBytes) * 100)}% - +
+
+ + + Drive Name + Files + Storage Used + Percentage - ))} - -
+ + + {storageByDrive.map((drive) => ( + + {drive.driveName} + {drive.fileCount} + {drive.formattedSize} + + {Math.round((drive.totalSize / quota.usedBytes) * 100)}% + + + ))} + + +
)} diff --git a/apps/web/src/app/settings/ai/page.tsx b/apps/web/src/app/settings/ai/page.tsx index 3fffcac46d..0ff58a7a2f 100644 --- a/apps/web/src/app/settings/ai/page.tsx +++ b/apps/web/src/app/settings/ai/page.tsx @@ -279,7 +279,7 @@ export default function AiSettingsPage() { -
+
OpenRouter {isProviderConfigured('openrouter') ? ( diff --git a/apps/web/src/app/settings/page.tsx b/apps/web/src/app/settings/page.tsx index 9dc34a32dc..77b79ad482 100644 --- a/apps/web/src/app/settings/page.tsx +++ b/apps/web/src/app/settings/page.tsx @@ -47,7 +47,7 @@ export default function SettingsPage() { ]; return ( -
+
-
+
{settingsCategories.map((category) => ( Content Statistics - - - - Drives - {user.stats.drives} - - - Pages - {user.stats.pages} - - - Page Messages - {user.stats.chatMessages} - - - Drive Messages - {user.stats.driveChatMessages} - - - Global Messages - {user.stats.globalMessages} - - - Active Sessions - {user.stats.refreshTokens} - - -
+
+ + + + Drives + {user.stats.drives} + + + Pages + {user.stats.pages} + + + Page Messages + {user.stats.chatMessages} + + + Drive Messages + {user.stats.driveChatMessages} + + + Global Messages + {user.stats.globalMessages} + + + Active Sessions + {user.stats.refreshTokens} + + +
+
{/* AI Settings and Account Info */} diff --git a/apps/web/src/components/billing/UsageCounter.tsx b/apps/web/src/components/billing/UsageCounter.tsx index a4745cc46d..3bc784c79e 100644 --- a/apps/web/src/components/billing/UsageCounter.tsx +++ b/apps/web/src/components/billing/UsageCounter.tsx @@ -108,7 +108,7 @@ export function UsageCounter() { } return ( -
+
{/* Usage Display */}
diff --git a/apps/web/src/components/layout/Layout.tsx b/apps/web/src/components/layout/Layout.tsx index da4cea22da..4cf574d114 100644 --- a/apps/web/src/components/layout/Layout.tsx +++ b/apps/web/src/components/layout/Layout.tsx @@ -7,6 +7,8 @@ import CenterPanel from "@/components/layout/middle-content/CenterPanel"; import MemoizedRightPanel from "@/components/layout/right-sidebar/MemoizedRightPanel"; import { NavigationProvider } from "@/components/layout/NavigationProvider"; import { useMobile } from "@/hooks/use-mobile"; +import { useBreakpoint } from "@/hooks/use-breakpoint"; +import { useResponsivePanels } from "@/hooks/use-responsive-panels"; import { motion, AnimatePresence } from "motion/react"; import { DebugPanel } from "./DebugPanel"; import { useLayoutStore } from "@/stores/useLayoutStore"; @@ -28,8 +30,13 @@ function Layout({ children }: LayoutProps) { rightSidebarOpen, toggleLeftSidebar, toggleRightSidebar, + setLeftSidebarOpen, + setRightSidebarOpen, } = useLayoutStore(); const hasHydrated = useHasHydrated(); + const shouldOverlaySidebars = useBreakpoint("(max-width: 1279px)"); + + useResponsivePanels(); // Monitor performance @@ -87,91 +94,87 @@ function Layout({ children }: LayoutProps) { return ( -
+
- -
- {/* Desktop Left Sidebar */} - {leftSidebarOpen && !isMobile && ( -
- + +
+ {!shouldOverlaySidebars && leftSidebarOpen && ( +
+
)} - {/* Mobile Left Sidebar */} - {isMobile && leftSidebarOpen && ( - <> - - - - - {/* Mobile Overlay */} - - + {shouldOverlaySidebars && leftSidebarOpen && ( + +
+ +
+
)}
- {/* Main Content Area */} -
- {/* Use our center panel instead of children */} +
{children || }
- {/* Desktop Right Sidebar */} - {rightSidebarOpen && !isMobile && ( -
- + {!shouldOverlaySidebars && rightSidebarOpen && ( +
+
)} - {/* Mobile Right Sidebar */} - {isMobile && rightSidebarOpen && ( - <> - - - - - {/* Mobile Overlay (if not already shown for left sidebar) */} - {!leftSidebarOpen && ( - - )} - + {shouldOverlaySidebars && rightSidebarOpen && ( + +
+ +
+
+ )} +
+ + + {shouldOverlaySidebars && (leftSidebarOpen || rightSidebarOpen) && ( + { + if (leftSidebarOpen) { + setLeftSidebarOpen(false); + } + if (rightSidebarOpen) { + setRightSidebarOpen(false); + } + }} + /> )}
- - {/* Debug Panel for Development */} +
diff --git a/apps/web/src/components/layout/left-sidebar/MemoizedSidebar.tsx b/apps/web/src/components/layout/left-sidebar/MemoizedSidebar.tsx index 4c412b72ea..18f23b6c13 100644 --- a/apps/web/src/components/layout/left-sidebar/MemoizedSidebar.tsx +++ b/apps/web/src/components/layout/left-sidebar/MemoizedSidebar.tsx @@ -2,7 +2,7 @@ import { memo } from 'react'; import { usePathname } from 'next/navigation'; -import Sidebar from './index'; +import Sidebar, { type SidebarProps } from './index'; import MessagesLeftSidebar from './MessagesLeftSidebar'; /** @@ -10,15 +10,15 @@ import MessagesLeftSidebar from './MessagesLeftSidebar'; * This helps avoid infinite loops in the layout system * Renders MessagesLeftSidebar when on messages route */ -const MemoizedSidebar = memo(() => { +const MemoizedSidebar = memo((props: SidebarProps) => { const pathname = usePathname(); const isMessagesRoute = pathname?.startsWith('/dashboard/messages'); if (isMessagesRoute) { - return ; + return ; } - return ; + return ; }); MemoizedSidebar.displayName = 'MemoizedSidebar'; diff --git a/apps/web/src/components/layout/left-sidebar/MessagesLeftSidebar.tsx b/apps/web/src/components/layout/left-sidebar/MessagesLeftSidebar.tsx index 7029562a95..7f2053a292 100644 --- a/apps/web/src/components/layout/left-sidebar/MessagesLeftSidebar.tsx +++ b/apps/web/src/components/layout/left-sidebar/MessagesLeftSidebar.tsx @@ -11,6 +11,7 @@ import { formatDistanceToNow } from 'date-fns'; import useSWR from 'swr'; import Link from 'next/link'; import { cn } from '@/lib/utils'; +import type { SidebarProps } from './index'; const fetcher = (url: string) => fetch(url).then((res) => res.json()); @@ -38,7 +39,7 @@ interface ConversationsResponse { }; } -export default function MessagesLeftSidebar() { +export default function MessagesLeftSidebar({ className, variant = 'desktop' }: SidebarProps) { const router = useRouter(); const params = useParams(); const [searchQuery, setSearchQuery] = useState(''); @@ -89,8 +90,14 @@ export default function MessagesLeftSidebar() { }; return ( -