From 3896eb671cbccf6cbab78c5511693fd7aab5f47d Mon Sep 17 00:00:00 2001 From: Mark Henderson Date: Mon, 2 Mar 2026 20:56:20 -0800 Subject: [PATCH] feat: PWA support + mobile-responsive layout + QR code to open Atlas on phone Made-with: Cursor --- .../project/[projectId]/overview/page.tsx | 61 +++++++++++++++++++ app/layout.tsx | 27 +++++++- components/AtlasChat.tsx | 2 +- components/layout/project-shell.tsx | 27 ++++++-- public/manifest.json | 26 ++++++++ public/sw.js | 47 ++++++++++++++ 6 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 public/manifest.json create mode 100644 public/sw.js diff --git a/app/[workspace]/project/[projectId]/overview/page.tsx b/app/[workspace]/project/[projectId]/overview/page.tsx index 27dfb59..b90d1a3 100644 --- a/app/[workspace]/project/[projectId]/overview/page.tsx +++ b/app/[workspace]/project/[projectId]/overview/page.tsx @@ -7,6 +7,57 @@ import { AtlasChat } from "@/components/AtlasChat"; import { OrchestratorChat } from "@/components/OrchestratorChat"; import { Loader2 } from "lucide-react"; +function MobileQRButton({ projectId, workspace }: { projectId: string; workspace: string }) { + const [show, setShow] = useState(false); + const url = typeof window !== "undefined" + ? `${window.location.origin}/${workspace}/project/${projectId}/overview` + : ""; + const qrSrc = `https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=${encodeURIComponent(url)}&bgcolor=f6f4f0&color=1a1a1a&margin=2`; + + return ( +
+ + {show && ( +
+ QR code +

+ Scan to open Atlas on your phone +

+

+ {url} +

+ +
+ )} +
+ ); +} + interface Project { id: string; productName: string; @@ -16,6 +67,7 @@ interface Project { export default function ProjectOverviewPage() { const params = useParams(); const projectId = params.projectId as string; + const workspace = params.workspace as string; const { status: authStatus } = useSession(); const [project, setProject] = useState(null); const [loading, setLoading] = useState(true); @@ -50,6 +102,15 @@ export default function ProjectOverviewPage() { return (
+ {/* Desktop-only: Open on phone button */} + +
+ +
+ {(!project.stage || project.stage === "discovery") ? ( ) { return ( + + + + + + @@ -42,6 +58,13 @@ export default function RootLayout({ {children} +