From 178c691e088bab0e483371319f39ea0e5cb4ceea Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Sun, 30 Nov 2025 06:26:29 +0000 Subject: [PATCH 1/2] feat(web): add mobile drawer layout for about and brand pages Co-Authored-By: john@hyprnote.com --- apps/web/src/routes/_view/about.tsx | 137 ++++++++++++++++++++++++++- apps/web/src/routes/_view/brand.tsx | 141 +++++++++++++++++++++++++++- 2 files changed, 274 insertions(+), 4 deletions(-) diff --git a/apps/web/src/routes/_view/about.tsx b/apps/web/src/routes/_view/about.tsx index d284a0318f..8358114cb8 100644 --- a/apps/web/src/routes/_view/about.tsx +++ b/apps/web/src/routes/_view/about.tsx @@ -1,6 +1,7 @@ import { Icon } from "@iconify-icon/react"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { Mail, XIcon } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; import { useEffect, useState } from "react"; import { @@ -8,6 +9,7 @@ import { ResizablePanel, ResizablePanelGroup, } from "@hypr/ui/components/ui/resizable"; +import { useIsMobile } from "@hypr/ui/hooks/use-mobile"; import { cn } from "@hypr/utils"; import { Image } from "@/components/image"; @@ -224,13 +226,44 @@ function AboutContentSection({ selectedItem: SelectedItem | null; setSelectedItem: (item: SelectedItem | null) => void; }) { + const isMobile = useIsMobile(); + const [drawerOpen, setDrawerOpen] = useState(false); + return (
- -
+ setDrawerOpen(true)} + className="p-1 hover:bg-neutral-200 rounded transition-colors" + aria-label="Open navigation" + > + + + ) + } + > +
{!selectedItem ? ( + ) : isMobile ? ( + <> + setDrawerOpen(false)} + selectedItem={selectedItem} + setSelectedItem={setSelectedItem} + /> + + ) : ( void; + selectedItem: SelectedItem; + setSelectedItem: (item: SelectedItem) => void; +}) { + return ( + + {open && ( + <> + + +
+ + Navigation + + +
+
+ { + setSelectedItem(item); + onClose(); + }} + /> + { + setSelectedItem(item); + onClose(); + }} + /> + { + setSelectedItem(item); + onClose(); + }} + /> +
+
+ + )} +
+ ); +} + +function AboutDetailContent({ + selectedItem, + setSelectedItem, +}: { + selectedItem: SelectedItem; + setSelectedItem: (item: SelectedItem | null) => void; +}) { + return ( +
+ {selectedItem?.type === "story" && ( + setSelectedItem(null)} /> + )} + {selectedItem?.type === "founder" && ( + setSelectedItem(null)} + /> + )} + {selectedItem?.type === "photo" && ( + setSelectedItem(null)} + /> + )} +
+ ); +} + function AboutSidebar({ selectedItem, setSelectedItem, diff --git a/apps/web/src/routes/_view/brand.tsx b/apps/web/src/routes/_view/brand.tsx index d1abe21212..62ea6107a0 100644 --- a/apps/web/src/routes/_view/brand.tsx +++ b/apps/web/src/routes/_view/brand.tsx @@ -1,5 +1,7 @@ +import { Icon } from "@iconify-icon/react"; import { createFileRoute } from "@tanstack/react-router"; import { XIcon } from "lucide-react"; +import { AnimatePresence, motion } from "motion/react"; import { useState } from "react"; import { @@ -7,6 +9,7 @@ import { ResizablePanel, ResizablePanelGroup, } from "@hypr/ui/components/ui/resizable"; +import { useIsMobile } from "@hypr/ui/hooks/use-mobile"; import { cn } from "@hypr/utils"; import { MockWindow } from "@/components/mock-window"; @@ -159,13 +162,44 @@ function BrandContentSection({ selectedItem: SelectedItem | null; setSelectedItem: (item: SelectedItem | null) => void; }) { + const isMobile = useIsMobile(); + const [drawerOpen, setDrawerOpen] = useState(false); + return (
- -
+ setDrawerOpen(true)} + className="p-1 hover:bg-neutral-200 rounded transition-colors" + aria-label="Open navigation" + > + + + ) + } + > +
{!selectedItem ? ( + ) : isMobile ? ( + <> + setDrawerOpen(false)} + selectedItem={selectedItem} + setSelectedItem={setSelectedItem} + /> + + ) : ( void; + selectedItem: SelectedItem; + setSelectedItem: (item: SelectedItem) => void; +}) { + return ( + + {open && ( + <> + + +
+ + Navigation + + +
+
+ { + setSelectedItem(item); + onClose(); + }} + /> + { + setSelectedItem(item); + onClose(); + }} + /> + { + setSelectedItem(item); + onClose(); + }} + /> +
+
+ + )} +
+ ); +} + +function BrandDetailContent({ + selectedItem, + setSelectedItem, +}: { + selectedItem: SelectedItem; + setSelectedItem: (item: SelectedItem | null) => void; +}) { + return ( +
+ {selectedItem.type === "visual" && ( + setSelectedItem(null)} + /> + )} + {selectedItem.type === "typography" && ( + setSelectedItem(null)} + /> + )} + {selectedItem.type === "color" && ( + setSelectedItem(null)} + /> + )} +
+ ); +} + function BrandSidebar({ selectedItem, setSelectedItem, From abbec2626cb197c4e6f5ed00e3c2f7f5a6f80160 Mon Sep 17 00:00:00 2001 From: ComputelessComputer Date: Mon, 1 Dec 2025 10:11:19 +0900 Subject: [PATCH 2/2] Use lucide-react Menu/X icons for drawer buttons Replace Iconify icons with lucide-react Menu and X icons in about and brand views to unify the drawer icon implementation and remove the @iconify-icon/react dependency. This updates imports and swaps Icon components for when opening the drawer and when closing it, adjusting classes to match sizing and styling. --- apps/web/src/routes/_view/about.tsx | 7 +++---- apps/web/src/routes/_view/brand.tsx | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/web/src/routes/_view/about.tsx b/apps/web/src/routes/_view/about.tsx index 8358114cb8..71e869f229 100644 --- a/apps/web/src/routes/_view/about.tsx +++ b/apps/web/src/routes/_view/about.tsx @@ -1,6 +1,5 @@ -import { Icon } from "@iconify-icon/react"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; -import { Mail, XIcon } from "lucide-react"; +import { Mail, Menu, X, XIcon } from "lucide-react"; import { AnimatePresence, motion } from "motion/react"; import { useEffect, useState } from "react"; @@ -243,7 +242,7 @@ function AboutContentSection({ className="p-1 hover:bg-neutral-200 rounded transition-colors" aria-label="Open navigation" > - + ) } @@ -460,7 +459,7 @@ function MobileSidebarDrawer({ className="p-1 hover:bg-neutral-200 rounded transition-colors" aria-label="Close drawer" > - +
diff --git a/apps/web/src/routes/_view/brand.tsx b/apps/web/src/routes/_view/brand.tsx index 62ea6107a0..a22a638a4a 100644 --- a/apps/web/src/routes/_view/brand.tsx +++ b/apps/web/src/routes/_view/brand.tsx @@ -1,6 +1,5 @@ -import { Icon } from "@iconify-icon/react"; import { createFileRoute } from "@tanstack/react-router"; -import { XIcon } from "lucide-react"; +import { Menu, X, XIcon } from "lucide-react"; import { AnimatePresence, motion } from "motion/react"; import { useState } from "react"; @@ -179,7 +178,7 @@ function BrandContentSection({ className="p-1 hover:bg-neutral-200 rounded transition-colors" aria-label="Open navigation" > - + ) } @@ -384,7 +383,7 @@ function MobileSidebarDrawer({ className="p-1 hover:bg-neutral-200 rounded transition-colors" aria-label="Close drawer" > - +