Files
kycnotme/web/src/components/Header.astro
2025-05-26 16:04:25 +00:00

196 lines
6.6 KiB
Plaintext

---
import { Icon } from 'astro-icon/components'
import { sample } from 'lodash-es'
import { splashTexts } from '../constants/splashTexts'
import { cn } from '../lib/cn'
import { DEPLOYMENT_MODE } from '../lib/envVariables'
import { makeLoginUrl, makeUnimpersonateUrl } from '../lib/redirectUrls'
import AdminOnly from './AdminOnly.astro'
import HeaderNotificationIndicator from './HeaderNotificationIndicator.astro'
import HeaderSplashTextScript from './HeaderSplashTextScript.astro'
import Logo from './Logo.astro'
import Tooltip from './Tooltip.astro'
import UserBadge from './UserBadge.astro'
const user = Astro.locals.user
const actualUser = Astro.locals.actualUser
type Props = {
classNames?: {
nav?: string
}
showSplashText?: boolean
}
const { classNames, showSplashText = false } = Astro.props
const splashText = showSplashText ? sample(splashTexts) : null
---
<header
class={cn(
'bg-night-900/80 sticky inset-x-0 top-0 z-50 h-16 border-b border-zinc-800 backdrop-blur-sm [&_~_*_[id]]:scroll-mt-18',
{
'border-red-900 bg-red-500/60': !!actualUser,
}
)}
transition:name="header-container"
>
<nav class={cn('container mx-auto flex h-full w-full items-stretch justify-between px-4', classNames?.nav)}>
<div class="@container -ml-4 flex max-w-[192px] grow-99999 items-center">
<a href="/" class="relative inline-flex h-full items-center pr-4 pl-4 @[2rem]:pr-0">
<Logo
class={cn(
'h-6 text-green-500 transition-colors hover:text-green-400',
{
'hue-rotate-227 saturate-800': DEPLOYMENT_MODE === 'development',
'hue-rotate-60 saturate-800': DEPLOYMENT_MODE === 'staging',
},
'hidden @[192px]:block'
)}
transition:name="header-logo"
/>
<Logo
variant="small"
class={cn(
'font-title h-8 text-green-500 transition-colors hover:text-green-400',
{
'hue-rotate-227 saturate-800': DEPLOYMENT_MODE === 'development',
'hue-rotate-60 saturate-800': DEPLOYMENT_MODE === 'staging',
},
'hidden @[94px]:block @[192px]:hidden'
)}
transition:name="header-logo"
/>
<Logo
variant="mini"
class={cn(
'font-title h-8 text-green-500 transition-colors hover:text-green-400',
{
'hue-rotate-227 saturate-800': DEPLOYMENT_MODE === 'development',
'hue-rotate-60 saturate-800': DEPLOYMENT_MODE === 'staging',
},
'hidden @[63px]:block @[94px]:hidden'
)}
transition:name="header-logo"
/>
{
DEPLOYMENT_MODE !== 'production' && (
<span
class={cn(
'absolute bottom-1 left-9.5 -translate-x-1/2 @[192px]:left-12.5',
'text-2xs pointer-events-none hidden rounded-full bg-zinc-800 px-1.25 py-0.75 leading-none font-semibold tracking-wide text-white @[63px]:block',
{
'border border-red-800 bg-red-950 text-red-400': DEPLOYMENT_MODE === 'development',
'border border-cyan-800 bg-cyan-950 text-cyan-400': DEPLOYMENT_MODE === 'staging',
}
)}
transition:name="header-deployment-mode"
>
{DEPLOYMENT_MODE === 'development' ? 'DEV' : 'PRE'}
</span>
)
}
</a>
</div>
{
!!splashText && (
<div
class="js:cursor-pointer @container flex min-w-0 flex-1 items-center justify-center"
data-splash-text-container
aria-hidden="true"
>
<span
class="font-title line-clamp-2 hidden shrink text-center text-xs text-balance text-lime-500 @[6rem]:inline @4xl:ml-0"
data-splash-text
>
{splashText}
</span>
<HeaderSplashTextScript />
</div>
)
}
<div class="flex items-center">
<AdminOnly>
<Tooltip
as="a"
href="/admin"
class="flex h-full items-center text-red-500 transition-colors hover:text-red-400"
transition:name="header-admin-link"
text="Admin Dashboard"
position="left"
>
<Icon name="ri:home-gear-line" class="size-10" />
</Tooltip>
</AdminOnly>
{
user ? (
<>
{actualUser && (
<UserBadge
user={actualUser}
size="sm"
class="text-white/40 hover:text-white"
transition:name="header-actual-user-name"
/>
)}
<HeaderNotificationIndicator
class="xs:px-3 2xs:px-2 h-full px-1"
transition:name="header-notification-indicator"
/>
<UserBadge
href="/account"
user={user}
size="md"
class="xs:px-3 2xs:px-2 last:xs:-mr-3 last:2xs:-mr-2 h-full px-1 text-zinc-400 transition-colors last:-mr-1 hover:text-zinc-300"
classNames={{
image: 'max-2xs:hidden',
}}
transition:name="header-user-link"
/>
{actualUser ? (
<a
href={makeUnimpersonateUrl(Astro.url)}
data-astro-reload
data-astro-prefetch="tap"
class="xs:px-3 2xs:px-2 last:xs:-mr-3 last:2xs:-mr-2 flex h-full items-center px-1 text-sm text-stone-100 transition-colors last:-mr-1 hover:text-stone-200"
transition:name="header-unimpersonate-link"
aria-label="Unimpersonate"
>
<Icon name="ri:user-shared-2-line" class="size-4" />
</a>
) : (
<a
href="/account/logout"
data-astro-prefetch="tap"
class="xs:px-3 2xs:px-2 last:xs:-mr-3 last:2xs:-mr-2 flex h-full items-center px-1 text-sm text-stone-100 transition-colors last:-mr-1 hover:text-stone-200"
transition:name="header-logout-link"
aria-label="Logout"
>
<Icon name="ri:logout-box-r-line" class="size-4" />
</a>
)}
</>
) : (
<a
href={makeLoginUrl(Astro.url)}
data-astro-reload
class="xs:px-3 2xs:px-2 last:xs:-mr-3 last:2xs:-mr-2 flex h-full items-center px-1 text-sm text-green-500 transition-colors last:-mr-1 hover:text-green-400"
transition:name="header-login-link"
>
Login
</a>
)
}
</div>
</nav>
</header>