pummmp.fun/components/header.tsx
2026-07-04 12:49:09 -07:00

200 lines
9.6 KiB
TypeScript

'use client'
import Link from 'next/link'
import { useSession, signIn, signOut } from 'next-auth/react'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import useSWR from 'swr'
import {
LgGeminiAi,
LgFolderInvoices,
LgComboChart,
LgPlus,
LgExit,
LgIdea // using LgIdea for rewards icon temporarily or can import another
} from '@/components/icons'
import { useRouter } from 'next/navigation'
import { UserBadges } from './ui/user-badges'
const fetcher = (url: string) => fetch(url).then((res) => res.json())
export function Header() {
const { data: session, status } = useSession()
const { data: userData } = useSWR(session ? '/api/user' : null, fetcher, {
refreshInterval: 10000,
})
const { data: solPrice } = useSWR('/api/sol-price', fetcher, {
refreshInterval: 60000,
})
// userouter -> login
const router = useRouter();
return (
<header className="sticky top-0 z-50 border-b border-border bg-background">
<div className="mx-auto flex h-16 max-w-7xl items-center justify-between px-4">
<div className="flex items-center gap-8">
<Link href="/" className="flex items-center gap-3">
<div className="relative">
<div className="relative flex h-10 w-10 items-center justify-center">
{/* <LgGeminiAi className="h-6 w-6" /> */}
<img src="/logo.svg" alt="Logo" className="h-10 w-10" />
</div>
</div>
<span className="text-xl font-semibold tracking-tight">
{/* pummmp - make this a gradient */}
{/* <span style={{ background: 'linear-gradient(90deg, #286eca, #ffffff)', WebkitBackgroundClip: 'text', WebkitTextFillColor: 'transparent' }}>pummmp</span> */}
pummmp<span className="text-[#286eca]">.fun</span>
</span>
</Link>
<nav className="hidden items-center gap-6 md:flex">
<Link
href="/"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Explore
</Link>
<Link
href="/create"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Create
</Link>
<Link
href="/swap"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Swap
</Link>
<Link
href="/rewards"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Daily Rewards
</Link>
{session && (
<Link
href="/dashboard"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Dashboard
</Link>
)}
</nav>
</div>
<div className="flex items-center gap-4">
{solPrice && (
<div className="hidden items-center gap-2 rounded-xl bg-card px-3 py-1.5 md:flex">
{/* <LgFolderInvoices className="h-4 w-4" /> */}
<img src="/solana.svg" alt="SOL" className="h-4 w-4" />
<span className="text-sm font-medium">${solPrice.price?.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} <span className='text-muted-foreground' style={{fontSize: '8px'}}>USD</span></span>
<span className={`text-xs ${solPrice.change24h >= 0 ? 'text-primary' : 'text-destructive'}`}>
{solPrice.change24h >= 0 ? '+' : ''}{solPrice.change24h?.toFixed(2)}%
</span>
</div>
)}
{status === 'loading' ? (
<div className="h-9 w-24 animate-pulse rounded-lg bg-muted" />
) : session ? (
<div className="flex items-center gap-3">
<div className="hidden flex-col items-end md:flex">
<span className="text-sm font-medium">
{userData?.balance?.toLocaleString('en-US', { minimumFractionDigits: 4, maximumFractionDigits: 4 }) ?? '...'} SOL
</span>
<span className="text-xs text-muted-foreground">
${((userData?.balance ?? 0) * (solPrice?.price ?? 0)).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} USD
</span>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-9 w-9 rounded-full">
<Avatar className="h-9 w-9 ring-2 ring-primary/20">
<AvatarImage src={session.user?.image ?? ''} alt={session.user?.name ?? ''} />
<AvatarFallback className="bg-primary/10 text-primary">
{session.user?.name?.[0]?.toUpperCase() ?? '?'}
</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<div className="flex items-center gap-2 p-2">
<Avatar className="h-8 w-8">
<AvatarImage src={session.user?.image ?? ''} />
<AvatarFallback>{session.user?.name?.[0]}</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<div className="flex items-center gap-1">
<span className="text-sm font-medium">{session.user?.name}</span>
<UserBadges
isAdmin={session.user?.isAdmin}
isVerified={session.user?.verified}
isBugHunter={session.user?.isBugHunter}
isBetaTester={session.user?.isBetaTester}
/>
</div>
<span className="text-xs text-muted-foreground">{session.user?.email}</span>
</div>
</div>
<DropdownMenuSeparator />
<DropdownMenuItem asChild className="cursor-pointer hover:bg-primary/10 focus:bg-primary/10">
<Link href="/dashboard" className="cursor-pointer">
<LgComboChart className="mr-2 h-4 w-4" />
Dashboard
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild className="cursor-pointer hover:bg-primary/10 focus:bg-primary/10">
<Link href="/create" className="cursor-pointer">
<LgPlus className="mr-2 h-4 w-4" />
Create Coin
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild className="cursor-pointer hover:bg-primary/10 focus:bg-primary/10">
<Link href={`/u/${encodeURIComponent(session.user?.name ?? '')}`} className="cursor-pointer">
<LgFolderInvoices className="mr-2 h-4 w-4" />
My Profile
</Link>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => signOut()}
className="cursor-pointer hover:bg-primary/10 focus:bg-primary/10"
>
<LgExit className="mr-2 h-4 w-4" />
Sign Out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
) : (
// <Button
// onClick={() => signIn('discord')}
// className="gap-2 bg-[#5865F2] text-foreground hover:bg-[#4752C4]"
// >
// <svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor">
// <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/>
// </svg>
// Sign in with Discord
// </Button>
<Button
onClick={() => router.push('/login')}
className="gap-2 bg-primary text-primary-foreground hover:bg-primary/90"
>
Sign In
</Button>
)}
</div>
</div>
</header>
)
}