File size: 6,780 Bytes
bcce530
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"use client"

import Link from "next/link"
import { usePathname } from "next/navigation"
import { Suspense } from "react"
import { Sparkles, Menu, X, Plus, Loader2 } from "lucide-react"
import { Button } from "@/components/ui/button"
import { ThemeToggle } from "@/components/ui/theme-toggle"
import { UserButton } from "@/components/auth/user-button"
import { NotificationBell } from "@/components/notifications/notification-center"
import { OllamaSettingsModal } from "@/components/ollama/ollama-settings"
import { useState } from "react"
import { cn } from "@/lib/utils"

const navLinks = [
    { href: "/explore", label: "Explore" },
    { href: "/tools", label: "Tools" },
    { href: "/thunderdome", label: "Thunderdome" },
    { href: "/workflows", label: "Workflows" },
    { href: "/frameworks", label: "Frameworks" },
    { href: "/performance", label: "Performance" },
    { href: "/dashboard", label: "Dashboard" },
]

// Loading fallback for UserButton
function UserButtonFallback() {
    return (
        <div className="h-9 w-24 rounded-lg bg-muted animate-pulse flex items-center justify-center">
            <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
        </div>
    )
}

export function Header() {
    const pathname = usePathname()
    const [mobileMenuOpen, setMobileMenuOpen] = useState(false)

    return (
        <header className="sticky top-0 z-50 w-full border-b border-border glass-strong">
            <div className="container mx-auto px-4">
                <nav className="flex h-16 items-center justify-between">
                    {/* Logo */}
                    <Link href="/" className="flex items-center gap-2 group">
                        <div className="relative h-9 w-9 overflow-hidden rounded-lg shadow-lg group-hover:shadow-primary/25 transition-shadow">
                            <img
                                src="/logos/logo.svg"
                                alt="OpenPrompt Logo"
                                className="h-full w-full object-cover"
                            />
                        </div>
                        <span className="font-semibold text-lg tracking-tight hidden sm:block">
                            Open<span className="text-primary">Prompt</span>
                        </span>
                    </Link>

                    {/* Desktop Navigation */}
                    <div className="hidden md:flex items-center gap-1">
                        {navLinks.map((link) => {
                            const isActive = pathname === link.href || pathname?.startsWith(`${link.href}/`)
                            return (
                                <Link
                                    key={link.href}
                                    href={link.href}
                                    className={cn(
                                        "px-4 py-2 text-sm font-medium transition-colors rounded-lg",
                                        isActive
                                            ? "text-foreground bg-muted font-semibold"
                                            : "text-muted-foreground hover:text-foreground hover:bg-muted"
                                    )}
                                >
                                    {link.label}
                                </Link>
                            )
                        })}
                    </div>

                    {/* Right Side Actions */}
                    <div className="flex items-center gap-2">
                        <OllamaSettingsModal />
                        <NotificationBell />
                        <ThemeToggle />

                        <Link href="/create" className="hidden sm:flex">
                            <Button size="sm" className="gap-2">
                                <Plus className="h-4 w-4" />
                                Create
                            </Button>
                        </Link>

                        {/* User Button with Suspense boundary */}
                        <div className="hidden md:flex">
                            <Suspense fallback={<UserButtonFallback />}>
                                <UserButton />
                            </Suspense>
                        </div>

                        {/* Mobile Menu Button */}
                        <button
                            onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
                            className="md:hidden h-9 w-9 rounded-lg border border-border bg-background flex items-center justify-center hover:bg-muted transition-colors"
                            aria-label="Toggle menu"
                        >
                            {mobileMenuOpen ? (
                                <X className="h-4 w-4" />
                            ) : (
                                <Menu className="h-4 w-4" />
                            )}
                        </button>
                    </div>
                </nav>

                {/* Mobile Menu */}
                <div
                    className={cn(
                        "md:hidden overflow-hidden transition-all duration-300",
                        mobileMenuOpen ? "max-h-96 pb-4" : "max-h-0"
                    )}
                >
                    <div className="flex flex-col gap-2 pt-2">
                        {navLinks.map((link) => (
                            <Link
                                key={link.href}
                                href={link.href}
                                className="px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors rounded-lg hover:bg-muted"
                                onClick={() => setMobileMenuOpen(false)}
                            >
                                {link.label}
                            </Link>
                        ))}
                        <div className="flex gap-2 pt-2 border-t border-border mt-2">
                            <Link href="/create" className="flex-1">
                                <Button size="sm" className="w-full gap-2">
                                    <Plus className="h-4 w-4" />
                                    Create
                                </Button>
                            </Link>
                        </div>
                        {/* Mobile User Button with Suspense */}
                        <div className="pt-2">
                            <Suspense fallback={<UserButtonFallback />}>
                                <UserButton />
                            </Suspense>
                        </div>
                    </div>
                </div>
            </div>
        </header>
    )
}