tars / client /src /components /Header.tsx
surekim's picture
Upload 109 files
390536f verified
Raw History Blame Contribute Delete
3.83 kB
import { useAuth } from "@/hooks/use-auth";
import { useQuery } from "@tanstack/react-query";
import { Link, useLocation } from "wouter";
import { LogIn, LogOut, Telescope, CreditCard, HelpCircle } from "lucide-react";
export function Header() {
const { user, isLoading, isAuthenticated } = useAuth();
const [location] = useLocation();
const { data: creditsData } = useQuery<{
credits: number;
freeUsesRemaining: number;
totalAnalyses: number;
}>({
queryKey: ["/api/credits"],
enabled: isAuthenticated,
});
const navItems = [
{ path: "/pricing", label: "Pricing", icon: CreditCard },
{ path: "/help", label: "Help", icon: HelpCircle },
];
return (
<div className="flex items-center justify-between gap-4 px-4 sm:px-6 lg:px-8 py-3 sm:py-4 border-b border-white/[0.06]">
<div className="flex items-center gap-4">
<Link href="/">
<span className="flex items-center gap-3 cursor-pointer" data-testid="link-home">
<div className="w-[7px] h-[7px] rounded-full bg-emerald-400 shadow-[0_0_8px_rgba(52,211,153,0.4)]" />
<span className="font-mono text-[11px] text-white/35 tracking-[0.08em] uppercase">v1.1</span>
</span>
</Link>
<div className="flex items-center gap-1">
{navItems.map((item) => (
<Link key={item.path} href={item.path}>
<span
data-testid={`link-${item.label.toLowerCase()}`}
className={`flex items-center gap-1.5 px-2.5 py-1.5 rounded-md font-sans text-[12px] transition-all cursor-pointer ${
location === item.path
? "text-white/70 bg-white/[0.06]"
: "text-white/30 hover:text-white/50 hover:bg-white/[0.03]"
}`}
>
<item.icon className="w-3 h-3" />
<span className="hidden sm:inline">{item.label}</span>
</span>
</Link>
))}
</div>
</div>
<div className="flex items-center gap-3 flex-wrap">
{isAuthenticated && creditsData && (
<div className="flex items-center gap-1.5 px-2.5 py-1 rounded-md bg-white/[0.04] border border-white/[0.06]" data-testid="display-credits">
<Telescope className="w-3 h-3 text-emerald-400" />
<span className="font-mono text-[11px] text-white/50">
{creditsData.totalAnalyses} scans
</span>
</div>
)}
{isLoading ? null : isAuthenticated ? (
<div className="flex items-center gap-2">
{user?.profileImageUrl && (
<img
src={user.profileImageUrl}
alt=""
className="w-6 h-6 rounded-full border border-white/10"
data-testid="img-user-avatar"
/>
)}
<span className="font-sans text-[12px] text-white/50 hidden sm:inline" data-testid="text-username">
{user?.firstName || user?.email || "User"}
</span>
<a
href="/api/logout"
className="flex items-center gap-1 px-2 py-1 rounded-md text-[11px] font-mono text-white/30 hover:text-white/50 hover:bg-white/[0.04] transition-all"
data-testid="button-logout"
>
<LogOut className="w-3 h-3" />
</a>
</div>
) : (
<a
href="/api/login"
className="flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-emerald-500/20 border border-emerald-500/30 text-[12px] font-sans text-emerald-400 hover:bg-emerald-500/30 transition-all"
data-testid="button-login"
>
<LogIn className="w-3 h-3" />
Sign in
</a>
)}
</div>
</div>
);
}