From 6fe3779fcb435da24a84671e9d45e1ede4ad8348 Mon Sep 17 00:00:00 2001 From: Dries Augustyns Date: Thu, 4 Dec 2025 11:23:55 +0100 Subject: [PATCH] Responsive design --- apps/web/src/components/DashboardLayout.tsx | 294 ++++++++++-------- .../components/EmailEditor/EmailEditor.tsx | 14 +- apps/web/src/pages/_document.tsx | 3 + apps/web/src/pages/activity/index.tsx | 4 +- apps/web/src/pages/analytics/index.tsx | 10 +- apps/web/src/pages/auth/login.tsx | 2 +- apps/web/src/pages/campaigns/[id].tsx | 62 ++-- apps/web/src/pages/campaigns/create.tsx | 20 +- apps/web/src/pages/campaigns/index.tsx | 15 +- apps/web/src/pages/contacts/[id].tsx | 21 +- apps/web/src/pages/contacts/index.tsx | 104 +++++-- apps/web/src/pages/index.tsx | 10 +- apps/web/src/pages/segments/index.tsx | 15 +- apps/web/src/pages/templates/[id].tsx | 37 ++- apps/web/src/pages/templates/create.tsx | 29 +- apps/web/src/pages/templates/index.tsx | 15 +- apps/web/src/pages/workflows/[id].tsx | 44 +-- apps/web/src/pages/workflows/index.tsx | 21 +- packages/ui/src/components/atoms/Dialog.tsx | 6 +- packages/ui/src/components/atoms/Select.tsx | 3 +- 20 files changed, 428 insertions(+), 301 deletions(-) diff --git a/apps/web/src/components/DashboardLayout.tsx b/apps/web/src/components/DashboardLayout.tsx index 3c002f9..94e3299 100644 --- a/apps/web/src/components/DashboardLayout.tsx +++ b/apps/web/src/components/DashboardLayout.tsx @@ -10,11 +10,13 @@ import { LayoutDashboard, LogOut, Megaphone, + Menu, Plus, Settings, User, Users, Workflow, + X, } from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; @@ -65,6 +67,7 @@ export function DashboardLayout({children}: DashboardLayoutProps) { const {activeProject, availableProjects, setActiveProject} = useActiveProject(); const [showProjectMenu, setShowProjectMenu] = useState(false); const [showUserMenu, setShowUserMenu] = useState(false); + const [showMobileMenu, setShowMobileMenu] = useState(false); const projectMenuRef = useRef(null); const userMenuRef = useRef(null); @@ -128,142 +131,185 @@ export function DashboardLayout({children}: DashboardLayoutProps) { void handleLogout(); }, [handleLogout]); + // Sidebar content (reusable for both desktop and mobile) + const SidebarContent = () => ( + <> + {/* Logo */} +
+ Plunk +

Plunk

+
+ + {/* Project Switcher */} +
+
+ + + {/* Project Dropdown */} + {showProjectMenu && ( +
+ {availableProjects.map(project => ( + + ))} +
+ + + Create project + +
+ )} +
+
+ + {/* Navigation */} + + + {/* Settings & User Menu */} +
+ setShowMobileMenu(false)} + className={`flex items-center gap-3 px-3 py-2 text-sm font-medium rounded-lg transition-colors text-neutral-700 ${ + router.pathname.startsWith('/settings') ? 'bg-neutral-100' : 'hover:bg-neutral-50 hover:text-neutral-900' + }`} + > + + Settings + + +
+ + + {/* User Dropdown */} + {showUserMenu && ( +
+ +
+ )} +
+
+ + ); + return (
- {/* Sidebar */} -
- {/* Logo */} -
- Plunk -

Plunk

+ {/* Desktop Sidebar - Hidden on mobile */} +
+ +
+ + {/* Mobile Sidebar Overlay */} + {showMobileMenu && ( +
setShowMobileMenu(false)} + > +
+ )} - {/* Project Switcher */} -
-
- - - {/* Project Dropdown */} - {showProjectMenu && ( -
- {availableProjects.map(project => ( - - ))} -
- - - Create project - -
- )} -
-
- - {/* Navigation */} - - - {/* Settings & User Menu */} -
- - - Settings - - -
- - - {/* User Dropdown */} - {showUserMenu && ( -
- -
- )} -
+ {/* Mobile Sidebar */} +
+
+
{/* Main Content */}
- {/* Header */} + {/* Mobile Header - Only visible on mobile */} +
+ +
+ Plunk +

Plunk

+
+
{/* Page Content */}
-
{children}
+
{children}
diff --git a/apps/web/src/components/EmailEditor/EmailEditor.tsx b/apps/web/src/components/EmailEditor/EmailEditor.tsx index 72396d1..1fc4d7a 100644 --- a/apps/web/src/components/EmailEditor/EmailEditor.tsx +++ b/apps/web/src/components/EmailEditor/EmailEditor.tsx @@ -396,7 +396,7 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT return (
{/* Mode toggle */} -
+
-
+
@@ -425,7 +425,7 @@ export function EmailEditor({value, onChange, placeholder, subject, from, replyT value={selectedContactId || 'none'} onValueChange={val => setSelectedContactId(val === 'none' ? '' : val)} > - + diff --git a/apps/web/src/pages/_document.tsx b/apps/web/src/pages/_document.tsx index be2ec70..c441687 100644 --- a/apps/web/src/pages/_document.tsx +++ b/apps/web/src/pages/_document.tsx @@ -4,6 +4,9 @@ function Document({locale}: {locale: string}) { return ( + {/* Viewport */} + + {/* Primary Meta Tags */} {/* Header */}
-

Activity

-

+

Activity

+

Real-time overview of events, emails, and workflow executions across your project.

diff --git a/apps/web/src/pages/analytics/index.tsx b/apps/web/src/pages/analytics/index.tsx index bb7f16b..39423a1 100644 --- a/apps/web/src/pages/analytics/index.tsx +++ b/apps/web/src/pages/analytics/index.tsx @@ -211,16 +211,16 @@ export default function AnalyticsPage() {
{/* Header */} -
-
-

Analytics

-

+

+
+

Analytics

+

Comprehensive insights into your email performance, engagement metrics, and delivery statistics.