📝 update breadcrumbs , nav for mobile and homepage translations
All checks were successful
PR Checks / lint-and-build (pull_request) Successful in 21s
Build and Deploy Next.js Blog to Production / 🔍 Code Quality Checks (push) Successful in 16s
Build and Deploy Next.js Blog to Production / 🏗️ Build and Push Docker Image (push) Successful in 1m4s
Build and Deploy Next.js Blog to Production / 🚀 Deploy to Production (push) Successful in 55s

This commit was merged in pull request #17.
This commit is contained in:
RJ
2025-12-05 16:25:56 +02:00
parent bba507a7e8
commit 6adb3a6979
14 changed files with 411 additions and 57 deletions

View File

@@ -5,11 +5,13 @@ import { useTranslations } from 'next-intl'
import { Link } from '@/i18n/navigation'
import { ThemeToggle } from '@/components/theme-toggle'
import LanguageSwitcher from '@/components/layout/LanguageSwitcher'
import { GlitchButton } from '@/components/effects/glitch-button'
export function Navbar() {
const t = useTranslations('Navigation')
const [isVisible, setIsVisible] = useState(true)
const [lastScrollY, setLastScrollY] = useState(0)
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
useEffect(() => {
const handleScroll = () => {
@@ -19,6 +21,7 @@ export function Navbar() {
setIsVisible(true)
} else if (currentScrollY > lastScrollY) {
setIsVisible(false)
setIsMobileMenuOpen(false)
} else {
setIsVisible(true)
}
@@ -44,11 +47,12 @@ export function Navbar() {
>
< {t('home')}
</Link>
<span className="font-mono text-sm text-zinc-100 dark:text-zinc-300 uppercase tracking-wider">
<span className="font-mono text-sm text-zinc-100 dark:text-zinc-300 uppercase tracking-wider hidden md:block">
// <span style={{ color: 'var(--neon-pink)' }}>{t('blog')}</span> ARCHIVE
</span>
</div>
<div className="flex items-center gap-6">
<div className="hidden md:flex items-center gap-6">
<Link
href="/about"
className="font-mono text-sm text-zinc-400 dark:text-zinc-500 uppercase tracking-wider hover:text-cyan-400 dark:hover:text-cyan-300 transition-colors cursor-pointer"
@@ -64,7 +68,45 @@ export function Navbar() {
<ThemeToggle />
<LanguageSwitcher />
</div>
<div className="md:hidden flex items-center gap-4">
<GlitchButton
variant="subtle"
glitchColor="cyan"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="font-mono text-sm uppercase tracking-wider px-4 py-2 border-4 border-slate-700 bg-slate-800 dark:bg-zinc-900 text-zinc-100 dark:text-zinc-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500"
aria-label="Toggle mobile menu"
aria-expanded={isMobileMenuOpen}
>
// {isMobileMenuOpen ? 'CLOSE' : 'MENU'}
</GlitchButton>
</div>
</div>
{isMobileMenuOpen && (
<div className="md:hidden mt-4 pt-4 border-t-4 border-slate-700">
<div className="flex flex-col gap-4">
<Link
href="/about"
className="font-mono text-sm text-zinc-400 dark:text-zinc-500 uppercase tracking-wider hover:text-cyan-400 dark:hover:text-cyan-300 transition-colors cursor-pointer px-4 py-2 border-2 border-slate-700"
onClick={() => setIsMobileMenuOpen(false)}
>
[{t('about')}]
</Link>
<Link
href="/blog"
className="font-mono text-sm text-zinc-400 dark:text-zinc-500 uppercase tracking-wider hover:text-cyan-400 dark:hover:text-cyan-300 transition-colors cursor-pointer px-4 py-2 border-2 border-slate-700"
onClick={() => setIsMobileMenuOpen(false)}
>
[{t('blog')}]
</Link>
<div className="flex items-center gap-4 px-4 py-2">
<ThemeToggle />
<LanguageSwitcher />
</div>
</div>
</div>
)}
</div>
</nav>
)

View File

@@ -0,0 +1,43 @@
'use client'
import React from 'react'
import { cn } from '@/lib/utils'
interface GlitchButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode
variant?: 'default' | 'subtle'
glitchColor?: 'cyan' | 'pink' | 'purple' | 'magenta'
disabled?: boolean
}
export function GlitchButton({
children,
variant = 'default',
glitchColor = 'cyan',
disabled = false,
className,
...props
}: GlitchButtonProps) {
const glitchClasses = !disabled
? cn('glitch-btn-cyber', variant === 'subtle' && 'glitch-btn-subtle', 'relative')
: ''
const overlayColorClass = {
cyan: '',
pink: 'glitch-overlay-pink',
purple: 'glitch-overlay-purple',
magenta: 'glitch-overlay-magenta',
}[glitchColor]
return (
<button className={cn(glitchClasses, className)} disabled={disabled} {...props}>
{children}
{!disabled && (
<div className={cn('glitch-overlay', overlayColorClass)} aria-hidden="true">
{children}
</div>
)}
</button>
)
}

View File

@@ -0,0 +1,99 @@
'use client'
import { useState, useEffect } from 'react'
import { Link } from '@/i18n/navigation'
import Image from 'next/image'
import { ThemeToggle } from '@/components/theme-toggle'
import { GlitchButton } from '@/components/effects/glitch-button'
import LanguageSwitcher from './LanguageSwitcher'
import { useLocale, useTranslations } from 'next-intl'
export function HeroHeader() {
const locale = useLocale()
const t = useTranslations('Home')
const tNav = useTranslations('Navigation')
const terminalVersion = t('terminalVersion')
const blogLabel = tNav('blog')
const aboutLabel = tNav('about')
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
const [isMobile, setIsMobile] = useState(false)
useEffect(() => {
const checkMobile = () => setIsMobile(window.innerWidth < 768)
checkMobile()
window.addEventListener('resize', checkMobile)
return () => window.removeEventListener('resize', checkMobile)
}, [])
return (
<div className="mb-8 border-b-2 border-slate-300 dark:border-slate-800 pb-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Image src="/logo.png" alt="Logo" width={32} height={32} className="opacity-80" />
<span className="font-mono text-xs text-slate-500 uppercase tracking-widest">
{terminalVersion}
</span>
</div>
{!isMobile && (
<div className="flex gap-4 items-center">
<Link
href="/blog"
className="font-mono text-xs text-slate-600 dark:text-slate-400 uppercase tracking-wider hover:text-cyan-600 dark:hover:text-cyan-400"
>
[{blogLabel}]
</Link>
<Link
href="/about"
className="font-mono text-xs text-slate-600 dark:text-slate-400 uppercase tracking-wider hover:text-cyan-600 dark:hover:text-cyan-400"
>
[{aboutLabel}]
</Link>
<ThemeToggle />
</div>
)}
{isMobile && (
<div>
<GlitchButton
variant="subtle"
glitchColor="cyan"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="font-mono text-xs uppercase tracking-wider px-3 py-2 border-2 border-slate-400 dark:border-slate-700 bg-white dark:bg-slate-800 text-slate-600 dark:text-slate-300"
aria-label="Toggle menu"
aria-expanded={isMobileMenuOpen}
>
// {isMobileMenuOpen ? 'X' : 'MENU'}
</GlitchButton>
</div>
)}
</div>
{isMobileMenuOpen && isMobile && (
<div className="mt-4 pt-4 border-t-2 border-slate-300 dark:border-slate-800">
<div className="flex flex-col gap-3">
<Link
href="/blog"
className="font-mono text-xs text-slate-600 dark:text-slate-400 uppercase tracking-wider hover:text-cyan-600 dark:hover:text-cyan-400 px-3 py-2 border-2 border-slate-300 dark:border-slate-700"
onClick={() => setIsMobileMenuOpen(false)}
>
[{blogLabel}]
</Link>
<Link
href="/about"
className="font-mono text-xs text-slate-600 dark:text-slate-400 uppercase tracking-wider hover:text-cyan-600 dark:hover:text-cyan-400 px-3 py-2 border-2 border-slate-300 dark:border-slate-700"
onClick={() => setIsMobileMenuOpen(false)}
>
[{aboutLabel}]
</Link>
<div className="flex items-center gap-4 px-4 py-2">
<ThemeToggle />
<LanguageSwitcher />
</div>
</div>
</div>
)}
</div>
)
}