|
1 | 1 | "use client" |
2 | | -import React, { useState } from 'react' |
3 | | -import Link from 'next/link' |
4 | | -import { Button } from "@/components/ui/button" |
5 | | -import { HoverBorderGradient } from "@/components/ui/hover-border-gradient" |
| 2 | + |
| 3 | +import { useState } from "react" |
| 4 | +import Link from "next/link" |
| 5 | +import { usePathname } from "next/navigation" |
6 | 6 | import { Menu, X } from "lucide-react" |
| 7 | +import { Button } from "@/components/ui/button" |
7 | 8 | import { RepoDocLogo } from "@/components/ui/repodoc-logo" |
8 | | -import { useUser } from "@clerk/nextjs" |
| 9 | +import { useUser, UserButton, SignInButton } from "@clerk/nextjs" |
| 10 | +import { HoverBorderGradient } from "@/components/ui/hover-border-gradient" |
| 11 | +import { cn } from "@/lib/utils" |
| 12 | + |
| 13 | +const navLinks = [ |
| 14 | + { href: "/", label: "Home" }, |
| 15 | + { href: "/about", label: "About" }, |
| 16 | + { href: "/pricing", label: "Pricing" }, |
| 17 | +] |
9 | 18 |
|
10 | 19 | export default function Navigation() { |
11 | 20 | const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false) |
12 | 21 | const { isSignedIn } = useUser() |
| 22 | + const pathname = usePathname() |
| 23 | + |
| 24 | + const handleToggle = () => setIsMobileMenuOpen((open) => !open) |
13 | 25 |
|
14 | 26 | return ( |
15 | | - <div className="sticky top-0 z-50 backdrop-blur-xl bg-black/20"> |
16 | | - <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> |
17 | | - <div className="flex justify-between items-center h-16"> |
18 | | - <div className="flex items-center space-x-3"> |
19 | | - <RepoDocLogo size="md" className="text-white" /> |
20 | | - <span className="text-xl font-semibold text-white tracking-tight">RepoDoc</span> |
21 | | - </div> |
22 | | - |
23 | | - {/* Desktop Navigation */} |
24 | | - <div className="hidden md:flex items-center space-x-3"> |
25 | | - <Link href="/pricing"> |
26 | | - <Button variant="ghost" size="sm" className="text-white/80 hover:text-white hover:bg-white/10 rounded-xl px-4 py-2 transition-all duration-200"> |
27 | | - Pricing |
28 | | - </Button> |
29 | | - </Link> |
30 | | - {isSignedIn ? ( |
31 | | - <Link href="/dashboard"> |
| 27 | + <nav className="sticky top-0 z-50 bg-transparent backdrop-blur-xl"> |
| 28 | + <div className="mx-auto flex max-w-7xl flex-wrap items-center justify-between gap-4 px-4 py-4 sm:px-6 lg:px-8"> |
| 29 | + <Link href="/" className="flex items-center gap-3"> |
| 30 | + <RepoDocLogo size="md" className="text-white" /> |
| 31 | + <span className="text-xl font-semibold text-white">RepoDoc</span> |
| 32 | + </Link> |
| 33 | + |
| 34 | + <div className="flex items-center gap-4 md:order-2"> |
| 35 | + {isSignedIn ? ( |
| 36 | + <UserButton |
| 37 | + appearance={{ |
| 38 | + elements: { |
| 39 | + userButtonAvatarBox: |
| 40 | + "h-9 w-9 border border-white/20 shadow-md shadow-blue-500/10", |
| 41 | + }, |
| 42 | + }} |
| 43 | + afterSignOutUrl="/" |
| 44 | + /> |
| 45 | + ) : ( |
| 46 | + <div className="hidden items-center gap-3 md:flex"> |
| 47 | + <SignInButton mode="modal"> |
| 48 | + <Button variant="ghost" className="rounded-lg px-4 text-white/80 hover:text-white"> |
| 49 | + Sign In |
| 50 | + </Button> |
| 51 | + </SignInButton> |
| 52 | + <Link href="/sign-up"> |
32 | 53 | <HoverBorderGradient |
33 | 54 | containerClassName="rounded-2xl" |
34 | 55 | as="button" |
35 | 56 | className="dark:bg-black bg-white text-black dark:text-white flex items-center space-x-2 px-4 py-1" |
36 | 57 | > |
37 | | - <span className="font-medium">Dashboard</span> |
| 58 | + <span className="font-medium">Sign Up</span> |
38 | 59 | </HoverBorderGradient> |
39 | 60 | </Link> |
40 | | - ) : ( |
41 | | - <> |
42 | | - <Link href="/sign-in"> |
43 | | - <Button variant="ghost" size="sm" className="text-white/80 hover:text-white hover:bg-white/10 rounded-xl px-4 py-2 transition-all duration-200"> |
44 | | - Sign In |
45 | | - </Button> |
46 | | - </Link> |
47 | | - <Link href="/sign-up"> |
48 | | - <HoverBorderGradient |
49 | | - containerClassName="rounded-2xl" |
50 | | - as="button" |
51 | | - className="dark:bg-black bg-white text-black dark:text-white flex items-center space-x-2 px-4 py-1" |
52 | | - > |
53 | | - <span className="font-medium">Sign Up</span> |
54 | | - </HoverBorderGradient> |
55 | | - </Link> |
56 | | - </> |
57 | | - )} |
58 | | - </div> |
| 61 | + </div> |
| 62 | + )} |
59 | 63 |
|
60 | | - {/* Mobile Menu Button */} |
61 | | - <div className="md:hidden"> |
62 | | - <Button |
63 | | - variant="ghost" |
64 | | - size="sm" |
65 | | - onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)} |
66 | | - aria-label="Toggle mobile menu" |
67 | | - className="text-white/80 hover:text-white hover:bg-white/10 rounded-xl p-2 transition-all duration-200" |
68 | | - > |
69 | | - {isMobileMenuOpen ? ( |
70 | | - <X className="w-5 h-5" /> |
71 | | - ) : ( |
72 | | - <Menu className="w-5 h-5" /> |
73 | | - )} |
74 | | - </Button> |
75 | | - </div> |
| 64 | + <button |
| 65 | + type="button" |
| 66 | + onClick={handleToggle} |
| 67 | + className="inline-flex h-10 w-10 items-center justify-center rounded-lg border border-white/10 text-white/70 transition hover:bg-white/10 focus:outline-none focus:ring-2 focus:ring-white/20 md:hidden" |
| 68 | + aria-controls="primary-navigation" |
| 69 | + aria-expanded={isMobileMenuOpen} |
| 70 | + > |
| 71 | + <span className="sr-only">Toggle menu</span> |
| 72 | + {isMobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />} |
| 73 | + </button> |
76 | 74 | </div> |
77 | 75 |
|
78 | | - {/* Mobile Navigation Menu */} |
79 | | - {isMobileMenuOpen && ( |
80 | | - <div className="md:hidden glass-card backdrop-blur-xl"> |
81 | | - <div className="px-4 pt-4 pb-4 space-y-3"> |
82 | | - <Link href="/pricing" className="w-full"> |
83 | | - <Button variant="ghost" size="sm" className="w-full justify-start text-white/80 hover:text-white hover:bg-white/10 rounded-xl py-3 transition-all duration-200"> |
84 | | - Pricing |
85 | | - </Button> |
86 | | - </Link> |
87 | | - {isSignedIn ? ( |
88 | | - <Link href="/dashboard" className="w-full"> |
89 | | - <HoverBorderGradient |
90 | | - containerClassName="rounded-2xl w-full" |
91 | | - as="button" |
92 | | - className="dark:bg-black bg-white text-black dark:text-white flex items-center justify-center space-x-2 w-full py-3" |
93 | | - > |
94 | | - <span className="font-medium">Dashboard</span> |
95 | | - </HoverBorderGradient> |
96 | | - </Link> |
97 | | - ) : ( |
98 | | - <> |
99 | | - <Link href="/sign-in" className="w-full"> |
100 | | - <Button variant="ghost" size="sm" className="w-full justify-start text-white/80 hover:text-white hover:bg-white/10 rounded-xl py-3 transition-all duration-200"> |
101 | | - Sign In |
102 | | - </Button> |
103 | | - </Link> |
104 | | - <Link href="/sign-up" className="w-full"> |
105 | | - <HoverBorderGradient |
106 | | - containerClassName="rounded-2xl w-full" |
107 | | - as="button" |
108 | | - className="dark:bg-black bg-white text-black dark:text-white flex items-center justify-center space-x-2 w-full py-3" |
109 | | - > |
110 | | - <span className="font-medium">Sign Up</span> |
111 | | - </HoverBorderGradient> |
| 76 | + <div |
| 77 | + id="primary-navigation" |
| 78 | + className={cn( |
| 79 | + "w-full md:w-auto md:flex md:items-center md:justify-center md:order-1", |
| 80 | + isMobileMenuOpen ? "block" : "hidden" |
| 81 | + )} |
| 82 | + > |
| 83 | + <ul className="flex flex-col gap-2 rounded-2xl border border-white/10 bg-white/[0.03] p-4 text-sm font-medium text-white md:flex-row md:items-center md:gap-8 md:border-transparent md:bg-transparent md:p-0 md:text-base"> |
| 84 | + {navLinks.map((link) => { |
| 85 | + const isActive = link.href !== "/" ? pathname.startsWith(link.href) : pathname === "/" |
| 86 | + const linkClasses = cn( |
| 87 | + "rounded-lg px-3 py-2 transition", |
| 88 | + isActive |
| 89 | + ? "bg-white/10 text-white shadow-md shadow-blue-500/20 md:bg-transparent md:text-white md:underline md:decoration-blue-400 md:decoration-2 md:underline-offset-8" |
| 90 | + : "text-white/70 hover:bg-white/10 hover:text-white" |
| 91 | + ) |
| 92 | + |
| 93 | + if (link.external) { |
| 94 | + return ( |
| 95 | + <li key={link.href}> |
| 96 | + <a href={link.href} className={linkClasses}> |
| 97 | + {link.label} |
| 98 | + </a> |
| 99 | + </li> |
| 100 | + ) |
| 101 | + } |
| 102 | + |
| 103 | + return ( |
| 104 | + <li key={link.href}> |
| 105 | + <Link href={link.href} className={linkClasses} onClick={() => setIsMobileMenuOpen(false)}> |
| 106 | + {link.label} |
112 | 107 | </Link> |
113 | | - </> |
114 | | - )} |
115 | | - </div> |
116 | | - </div> |
117 | | - )} |
| 108 | + </li> |
| 109 | + ) |
| 110 | + })} |
| 111 | + |
| 112 | + {!isSignedIn && ( |
| 113 | + <li className="md:hidden"> |
| 114 | + <SignInButton mode="modal"> |
| 115 | + <Button className="w-full rounded-lg bg-white text-black hover:bg-white/90">Sign In</Button> |
| 116 | + </SignInButton> |
| 117 | + </li> |
| 118 | + )} |
| 119 | + {!isSignedIn && ( |
| 120 | + <li className="md:hidden"> |
| 121 | + <Link href="/sign-up" onClick={() => setIsMobileMenuOpen(false)}> |
| 122 | + <Button variant="outline" className="w-full rounded-lg border-white/30 text-white hover:bg-white/10"> |
| 123 | + Sign Up |
| 124 | + </Button> |
| 125 | + </Link> |
| 126 | + </li> |
| 127 | + )} |
| 128 | + </ul> |
| 129 | + </div> |
118 | 130 | </div> |
119 | | - </div> |
| 131 | + </nav> |
120 | 132 | ) |
121 | 133 | } |
0 commit comments