2026-01-15 11:31:09 +01:00

124 lines
3.7 KiB
TypeScript

import Link from 'next/link'
import { ConditionalPublishButton } from './ConditionalPublishButton'
import { LanguageSelector } from './LanguageSelector'
import { t } from '@/lib/i18n'
import { KeyIndicator } from './KeyIndicator'
function GitIcon(): React.ReactElement {
return (
<svg
className="w-5 h-5"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M23.546 10.93L13.067.452c-.604-.603-1.582-.603-2.188 0L8.708 2.627l2.76 2.76c.645-.215 1.379-.07 1.889.441.516.515.658 1.258.438 1.9l2.658 2.66c.645-.223 1.387-.078 1.9.435.721.72.721 1.884 0 2.604-.719.719-1.881.719-2.6 0-.539-.541-.674-1.337-.404-1.996L12.86 8.955v6.525c.176.086.342.203.488.348.713.721.713 1.883 0 2.6-.719.721-1.884.721-2.599 0-.719-.719-.719-1.879 0-2.598.182-.18.387-.316.605-.406V8.835c-.217-.091-.424-.222-.6-.401-.545-.545-.676-1.342-.396-2.009L7.496 3.866.45 10.913c-.6.605-.6 1.584 0 2.189l10.484 10.481c.604.604 1.582.604 2.186 0l10.43-10.43c.605-.603.605-1.584 0-2.189z" />
</svg>
)
}
function DocsIcon(): React.ReactElement {
return (
<svg
className="w-5 h-5"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<polyline points="14 2 14 8 20 8" />
<line x1="16" y1="13" x2="8" y2="13" />
<line x1="16" y1="17" x2="8" y2="17" />
<polyline points="10 9 9 9 8 9" />
</svg>
)
}
function FundingIcon(): React.ReactElement {
return (
<svg
className="w-5 h-5"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
<line x1="12" y1="1" x2="12" y2="23" />
<path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
</svg>
)
}
export function PageHeader(): React.ReactElement {
return (
<header role="navigation" className="bg-cyber-dark border-b border-neon-cyan/30 shadow-glow-cyan">
<div className="max-w-4xl mx-auto px-4 py-4 flex justify-between items-center">
<HeaderLeft />
<HeaderRight />
</div>
</header>
)
}
function HeaderLeft(): React.ReactElement {
return (
<div className="flex items-center gap-2">
<Link href="/" className="text-2xl font-bold text-neon-cyan text-glow-cyan font-mono hover:text-neon-green transition-colors">
{t('home.title')}
</Link>
<HeaderLinks />
<KeyIndicator />
</div>
)
}
function HeaderLinks(): React.ReactElement {
return (
<>
<Link
href="/docs"
className="text-cyber-accent hover:text-neon-cyan transition-colors"
title={t('nav.documentation')}
aria-label={t('nav.documentation')}
>
<DocsIcon />
</Link>
<Link
href="/funding"
className="text-cyber-accent hover:text-neon-cyan transition-colors"
title={t('funding.title')}
aria-label={t('funding.title')}
>
<FundingIcon />
</Link>
<a
href="https://git.4nkweb.com/4nk/story-research-zapwall"
target="_blank"
rel="noopener noreferrer"
className="text-cyber-accent hover:text-neon-cyan transition-colors"
title={t('common.repositoryGit')}
aria-label={t('common.repositoryGit')}
onClick={(e) => e.stopPropagation()}
>
<GitIcon />
</a>
</>
)
}
function HeaderRight(): React.ReactElement {
return (
<div className="flex items-center gap-4">
<LanguageSelector />
<ConditionalPublishButton />
</div>
)
}