eny.space Landingpage
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(site-header): implement mobile menu

+112 -23
+109 -20
app/actions/components/site-header.tsx
··· 1 + "use client"; 2 + 3 + import { useState } from "react"; 1 4 import Link from "next/link"; 2 5 import Image from "next/image"; 3 6 import { signOut } from "@/actions/auth"; 4 7 import { Button } from "@/actions/components/ui/button"; 5 - import { ArrowUpRightIcon } from "lucide-react"; 8 + import { ArrowUpRightIcon, MenuIcon, XIcon } from "lucide-react"; 6 9 import type { User } from "@supabase/supabase-js"; 7 10 8 11 const navLinkClass = ··· 13 16 } 14 17 15 18 export function SiteHeader({ user }: SiteHeaderProps) { 19 + const [mobileOpen, setMobileOpen] = useState(false); 20 + 21 + const closeMobile = () => setMobileOpen(false); 22 + 16 23 return ( 17 24 <header className="sticky top-0 z-50 w-full border-b border-white/10 bg-neutral-950"> 18 - <div className="mx-auto flex h-14 max-w-7xl items-center justify-between gap-6 px-4 sm:px-6"> 25 + <div className="mx-auto flex h-14 max-w-7xl items-center justify-between gap-4 px-4 sm:px-6"> 19 26 {/* Logo */} 20 27 <Link 21 28 href="/" 22 29 className="flex items-center gap-2 font-semibold text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/30 focus-visible:ring-offset-2 focus-visible:ring-offset-neutral-950" 30 + onClick={closeMobile} 23 31 > 24 32 <Image 25 33 src="/logo.svg" 26 34 alt="" 27 - width={48} 28 - height={48} 35 + width={40} 36 + height={40} 29 37 className="shrink-0" 30 38 /> 31 39 <span className="text-lg">eny.space</span> 32 40 </Link> 33 41 34 - {/* Center nav */} 35 - <nav className="flex flex-1 justify-center gap-1"> 42 + {/* Desktop nav */} 43 + <nav className="hidden flex-1 justify-center gap-1 md:flex"> 36 44 <Link href="/" className={navLinkClass}> 37 45 Home 38 46 </Link> ··· 46 54 </Link> 47 55 </nav> 48 56 49 - {/* Right – action buttons */} 50 - <div className="flex items-center gap-2"> 57 + {/* Desktop actions */} 58 + <div className="hidden items-center gap-2 md:flex"> 51 59 {user ? ( 52 - <> 53 - <form action={signOut}> 54 - <Button 55 - type="submit" 56 - size="default" 57 - className="inline-flex items-center rounded-full bg-white px-4 text-xs font-medium uppercase tracking-wide text-neutral-950 hover:bg-white/90" 58 - > 59 - <span>Sign out</span> 60 - <ArrowUpRightIcon className="ml-1 size-3.5" aria-hidden /> 61 - </Button> 62 - </form> 63 - </> 60 + <form action={signOut}> 61 + <Button 62 + type="submit" 63 + size="default" 64 + className="inline-flex items-center rounded-full bg-white px-4 text-xs font-medium uppercase tracking-wide text-neutral-950 hover:bg-white/90" 65 + > 66 + <span>Sign out</span> 67 + <ArrowUpRightIcon className="ml-1 size-3.5" aria-hidden /> 68 + </Button> 69 + </form> 64 70 ) : ( 65 71 <> 66 72 <Button ··· 84 90 </> 85 91 )} 86 92 </div> 93 + 94 + {/* Mobile menu toggle */} 95 + <button 96 + type="button" 97 + aria-label="Toggle navigation" 98 + className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-white/20 text-white md:hidden" 99 + onClick={() => setMobileOpen((open) => !open)} 100 + > 101 + {mobileOpen ? ( 102 + <XIcon className="size-4" aria-hidden /> 103 + ) : ( 104 + <MenuIcon className="size-4" aria-hidden /> 105 + )} 106 + </button> 87 107 </div> 108 + 109 + {/* Mobile menu panel */} 110 + {mobileOpen && ( 111 + <div className="border-t border-white/10 bg-neutral-950 px-4 pb-4 pt-3 md:hidden"> 112 + <nav className="flex flex-col gap-2"> 113 + <Link 114 + href="/" 115 + className="text-sm font-medium text-white/90" 116 + onClick={closeMobile} 117 + > 118 + Home 119 + </Link> 120 + {user && ( 121 + <Link 122 + href="/dashboard" 123 + className="text-sm font-medium text-white/90" 124 + onClick={closeMobile} 125 + > 126 + Dashboard 127 + </Link> 128 + )} 129 + <Link 130 + href="/#about" 131 + className="text-sm font-medium text-white/90" 132 + onClick={closeMobile} 133 + > 134 + About 135 + </Link> 136 + </nav> 137 + 138 + <div className="mt-3 flex flex-col gap-2"> 139 + {user ? ( 140 + <form action={signOut}> 141 + <Button 142 + type="submit" 143 + size="default" 144 + className="inline-flex h-9 items-center justify-center rounded-full bg-white px-4 text-xs font-medium uppercase tracking-wide text-neutral-950 hover:bg-white/90" 145 + > 146 + <span>Sign out</span> 147 + <ArrowUpRightIcon className="ml-1 size-3.5" aria-hidden /> 148 + </Button> 149 + </form> 150 + ) : ( 151 + <> 152 + <Button 153 + variant="outline" 154 + size="default" 155 + className="inline-flex h-9 w-full items-center justify-center rounded-full border-white/20 bg-transparent px-4 text-xs font-medium uppercase tracking-wide text-white/90 hover:bg-white/10 hover:text-white" 156 + asChild 157 + > 158 + <Link href="/login" onClick={closeMobile}> 159 + Login 160 + </Link> 161 + </Button> 162 + <Button 163 + size="default" 164 + className="inline-flex h-9 w-full items-center justify-center rounded-full bg-white px-4 text-xs font-medium uppercase tracking-wide text-neutral-950 hover:bg-white/90" 165 + asChild 166 + > 167 + <Link href="/signup" onClick={closeMobile}> 168 + Get started 169 + <ArrowUpRightIcon className="ml-1 size-3.5" aria-hidden /> 170 + </Link> 171 + </Button> 172 + </> 173 + )} 174 + </div> 175 + </div> 176 + )} 88 177 </header> 89 178 ); 90 179 }
+3 -3
app/components/logo-bar/logo-bar.tsx
··· 13 13 const PLACEHOLDER_LINKS = [ 14 14 { label: "Short", href: "#", icon: BoxIcon }, 15 15 { label: "Medium Label", href: "#", icon: SparklesIcon }, 16 - { label: "DescriptiveTxt", href: "#", icon: CircleIcon }, 16 + { label: "Descriptive Text", href: "#", icon: CircleIcon }, 17 17 { label: "Another Link", href: "#", icon: LayersIcon }, 18 - { label: "QuickLabel", href: "#", icon: CircleDotIcon }, 19 - { label: "LabelName123", href: "#", icon: SquareIcon }, 18 + { label: "Quick Label", href: "#", icon: CircleDotIcon }, 19 + { label: "Label Name Text", href: "#", icon: SquareIcon }, 20 20 { label: "Final Example", href: "#", icon: HexagonIcon }, 21 21 ]; 22 22