mirror of
https://gitbruv.vercel.app/api/git/bruv/gitbruv.git
synced 2025-12-20 23:24:09 +01:00
mvp
This commit is contained in:
parent
8f672d012c
commit
46cab693db
49 changed files with 4725 additions and 118 deletions
103
components/header.tsx
Normal file
103
components/header.tsx
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { GitBranch, Plus, LogOut, User, ChevronDown } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { signOut, useSession } from "@/lib/auth-client";
|
||||
|
||||
export function Header() {
|
||||
const router = useRouter();
|
||||
const { data: session } = useSession();
|
||||
|
||||
async function handleSignOut() {
|
||||
await signOut();
|
||||
router.push("/");
|
||||
router.refresh();
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 w-full border-b border-border bg-[#010409]">
|
||||
<div className="container flex h-16 items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="/" className="flex items-center gap-2.5 group">
|
||||
<span className="font-bold text-xl tracking-tight hidden sm:inline">gitbruv</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{session?.user ? (
|
||||
<>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="sm" className="h-8 gap-1 px-2 text-muted-foreground hover:text-foreground">
|
||||
<Plus className="h-4 w-4" />
|
||||
<ChevronDown className="h-3 w-3" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuItem asChild>
|
||||
<Link href="/new" className="cursor-pointer gap-2">
|
||||
<BookIcon className="h-4 w-4" />
|
||||
New repository
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 rounded-full p-0 overflow-hidden ring-2 ring-transparent hover:ring-accent/50 transition-all">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src={session.user.image || undefined} />
|
||||
<AvatarFallback className="bg-gradient-to-br from-accent/40 to-primary/40 text-foreground text-xs font-semibold">
|
||||
{session.user.name?.charAt(0).toUpperCase() || "U"}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
<div className="px-3 py-2">
|
||||
<p className="text-sm font-medium">{session.user.name}</p>
|
||||
<p className="text-xs text-muted-foreground">@{(session.user as { username?: string }).username}</p>
|
||||
</div>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem asChild>
|
||||
<Link href={`/${(session.user as { username?: string }).username}`} className="cursor-pointer gap-2">
|
||||
<User className="h-4 w-4" />
|
||||
Your profile
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem onClick={handleSignOut} className="cursor-pointer gap-2 text-destructive focus:text-destructive focus:bg-destructive/10">
|
||||
<LogOut className="h-4 w-4" />
|
||||
Sign out
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="ghost" size="sm" asChild className="text-muted-foreground hover:text-foreground">
|
||||
<Link href="/login">Sign in</Link>
|
||||
</Button>
|
||||
<Button size="sm" asChild>
|
||||
<Link href="/register">Sign up</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
function BookIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 16 16" fill="currentColor">
|
||||
<path d="M0 1.75A.75.75 0 0 1 .75 1h4.253c1.227 0 2.317.59 3 1.501A3.743 3.743 0 0 1 11.006 1h4.245a.75.75 0 0 1 .75.75v10.5a.75.75 0 0 1-.75.75h-4.507a2.25 2.25 0 0 0-1.591.659l-.622.621a.75.75 0 0 1-1.06 0l-.622-.621A2.25 2.25 0 0 0 5.258 13H.75a.75.75 0 0 1-.75-.75Zm7.251 10.324.004-5.073-.002-2.253A2.25 2.25 0 0 0 5.003 2.5H1.5v9h3.757a3.75 3.75 0 0 1 1.994.574ZM8.755 4.75l-.004 7.322a3.752 3.752 0 0 1 1.992-.572H14.5v-9h-3.495a2.25 2.25 0 0 0-2.25 2.25Z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue