first commit
This commit is contained in:
181
components/header.tsx
Normal file
181
components/header.tsx
Normal file
@@ -0,0 +1,181 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { useSession, signOut } from "next-auth/react";
|
||||
import clsx from "clsx";
|
||||
import { Search, ShoppingCart, ChevronDown, LogOut, User } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ThemeToggle } from "@/components/theme-toggle";
|
||||
import {
|
||||
getCookieSession,
|
||||
logoutViaCookie,
|
||||
clearTokens,
|
||||
AUTH_CHANGE_EVENT,
|
||||
notifyAuthChange,
|
||||
} from "@/lib/auth-api";
|
||||
|
||||
const navItems = [
|
||||
{ label: "Home", href: "/", hasDropdown: true },
|
||||
{ label: "About Us", href: "/about", hasDropdown: false },
|
||||
{ label: "Pages", href: "/pages", hasDropdown: true },
|
||||
{ label: "Blog", href: "/blog", hasDropdown: true, active: true },
|
||||
{ label: "Contact", href: "/contact", hasDropdown: false },
|
||||
];
|
||||
|
||||
function TechwixLogo() {
|
||||
return (
|
||||
<Link href="/" className="flex items-center gap-2">
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="shrink-0"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="logoGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stopColor="#3b82f6" />
|
||||
<stop offset="100%" stopColor="#8b5cf6" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
{/* Single gradient shape - diamond/arrowhead */}
|
||||
<path
|
||||
d="M16 5L27 16L16 27L5 16L16 5Z"
|
||||
fill="url(#logoGrad)"
|
||||
/>
|
||||
<path
|
||||
d="M16 9L23 16L16 23L9 16L16 9Z"
|
||||
fill="white"
|
||||
fillOpacity="0.2"
|
||||
/>
|
||||
</svg>
|
||||
<span className="text-xl font-semibold text-neutral-800 dark:text-neutral-100">
|
||||
Techwix
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Header() {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const { data: session, status } = useSession();
|
||||
const [cookieLoggedIn, setCookieLoggedIn] = useState(false);
|
||||
|
||||
const isLoggedIn = Boolean(session?.user) || cookieLoggedIn;
|
||||
|
||||
useEffect(() => {
|
||||
const onScroll = () => setScrolled(window.scrollY > 8);
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
onScroll();
|
||||
return () => window.removeEventListener("scroll", onScroll);
|
||||
}, []);
|
||||
|
||||
const refreshCookieSession = () => {
|
||||
getCookieSession().then((s) => setCookieLoggedIn(s.loggedIn));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshCookieSession();
|
||||
const handler = () => refreshCookieSession();
|
||||
window.addEventListener(AUTH_CHANGE_EVENT, handler);
|
||||
return () => window.removeEventListener(AUTH_CHANGE_EVENT, handler);
|
||||
}, []);
|
||||
|
||||
const handleLogout = async () => {
|
||||
clearTokens(); // eski localStorage token varsa temizle
|
||||
await logoutViaCookie();
|
||||
signOut({ callbackUrl: "/" });
|
||||
setCookieLoggedIn(false);
|
||||
notifyAuthChange();
|
||||
};
|
||||
|
||||
return (
|
||||
<header
|
||||
className={clsx(
|
||||
"sticky top-0 z-40 w-full border-b border-neutral-200/80 transition-colors duration-200 backdrop-blur dark:border-neutral-800",
|
||||
scrolled
|
||||
? "bg-white/95 shadow-sm dark:bg-neutral-950/95"
|
||||
: "bg-white dark:bg-neutral-950/90"
|
||||
)}
|
||||
>
|
||||
<div className="container mx-auto flex h-16 items-center justify-between gap-6 px-4 lg:px-6">
|
||||
<TechwixLogo />
|
||||
|
||||
<nav className="hidden items-center gap-1 md:flex">
|
||||
{navItems.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className={clsx(
|
||||
"flex items-center gap-0.5 rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
||||
item.active
|
||||
? "text-blue-500 dark:text-blue-400"
|
||||
: "text-neutral-700 hover:text-neutral-900 dark:text-neutral-300 dark:hover:text-white"
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
{item.hasDropdown && (
|
||||
<ChevronDown className="size-3.5 text-current opacity-70" />
|
||||
)}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<ThemeToggle />
|
||||
<button
|
||||
type="button"
|
||||
className="relative rounded-md p-2 text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-white"
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingCart className="size-5" />
|
||||
<span className="absolute -right-0.5 -top-0.5 flex size-4 items-center justify-center rounded-full bg-blue-500 text-[10px] font-medium text-white">
|
||||
0
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-md p-2 text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-white"
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="size-5" />
|
||||
</button>
|
||||
{status === "loading" ? null : isLoggedIn ? (
|
||||
<>
|
||||
<Link
|
||||
href="/profile"
|
||||
className="flex items-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800 dark:hover:text-white"
|
||||
>
|
||||
<User className="size-4" />
|
||||
<span className="hidden sm:inline">Profil</span>
|
||||
</Link>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleLogout}
|
||||
className="flex items-center gap-1.5 rounded-md px-3 py-2 text-sm font-medium text-neutral-700 hover:bg-neutral-100 hover:text-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800 dark:hover:text-white"
|
||||
>
|
||||
<LogOut className="size-4" />
|
||||
<span className="hidden sm:inline">Çıkış</span>
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Button variant="ghost" size="sm" asChild>
|
||||
<Link href="/auth/login">Giriş</Link>
|
||||
</Button>
|
||||
<Button
|
||||
asChild
|
||||
size="sm"
|
||||
className="rounded-md bg-gradient-to-r from-blue-500 to-blue-400 text-white shadow-sm hover:from-blue-600 hover:to-blue-500 dark:from-blue-600 dark:to-blue-500 dark:hover:from-blue-700 dark:hover:to-blue-600"
|
||||
>
|
||||
<Link href="/auth/register">Kayıt</Link>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user