Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

119
src/components/Header.astro Normal file
View File

@@ -0,0 +1,119 @@
---
import { NAVIGATION } from '../site.config';
import ThemeToggle from './ThemeToggle.astro';
import LanguageSwitcher from './LanguageSwitcher.astro';
import { t } from '../utils/i18n';
---
<header class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
<nav class="container-custom">
<div class="flex h-16 items-center justify-between">
<!-- Logo -->
<div class="flex items-center">
<a href="/" class="flex items-center space-x-2">
<div class="h-8 w-8 flex items-center justify-center">
<img
src="/images/TIBER365.png"
alt="Tiber365 Logo"
class="h-6 w-6 object-contain"
/>
</div>
<span class="font-display font-bold text-xl text-foreground">Tiber365</span>
</a>
</div>
<!-- Desktop Navigation -->
<div class="hidden md:flex items-center space-x-6">
{NAVIGATION.map((item) => (
<a
href={item.href}
target={item.type === 'external' ? '_blank' : undefined}
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
class="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors relative group"
>
{t(item.label)}
{item.type === 'external' && (
<svg class="inline h-3 w-3 ml-1 opacity-70" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
)}
<span class="absolute inset-x-0 -bottom-1 h-0.5 bg-primary scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
</a>
))}
</div>
<!-- Theme Toggle & Language Switcher -->
<div class="flex items-center space-x-4">
<LanguageSwitcher />
<ThemeToggle />
<!-- Mobile Menu Button -->
<button
id="mobile-menu-button"
class="md:hidden inline-flex items-center justify-center p-2 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent focus:outline-none focus:ring-2 focus:ring-primary"
aria-expanded="false"
aria-label="Toggle mobile menu"
>
<svg id="mobile-menu-icon" class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
<svg id="mobile-close-icon" class="h-6 w-6 hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</div>
<!-- Mobile Navigation -->
<div id="mobile-menu" class="md:hidden hidden border-t border-border">
<div class="px-2 pt-2 pb-3 space-y-1">
{NAVIGATION.map((item) => (
<a
href={item.href}
target={item.type === 'external' ? '_blank' : undefined}
rel={item.type === 'external' ? 'noopener noreferrer' : undefined}
class="block px-3 py-2 text-base font-medium text-muted-foreground hover:text-foreground hover:bg-accent rounded-md transition-colors"
>
{t(item.label)}
{item.type === 'external' && (
<svg class="inline h-4 w-4 ml-1 opacity-70" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
)}
</a>
))}
</div>
</div>
</nav>
</header>
<script>
// Mobile menu functionality
document.addEventListener('DOMContentLoaded', () => {
const mobileMenuButton = document.getElementById('mobile-menu-button');
const mobileMenu = document.getElementById('mobile-menu');
const menuIcon = document.getElementById('mobile-menu-icon');
const closeIcon = document.getElementById('mobile-close-icon');
if (mobileMenuButton && mobileMenu && menuIcon && closeIcon) {
mobileMenuButton.addEventListener('click', () => {
const isExpanded = mobileMenuButton.getAttribute('aria-expanded') === 'true';
mobileMenuButton.setAttribute('aria-expanded', (!isExpanded).toString());
mobileMenu.classList.toggle('hidden');
menuIcon.classList.toggle('hidden');
closeIcon.classList.toggle('hidden');
});
// Close mobile menu when clicking outside
document.addEventListener('click', (event) => {
if (!mobileMenuButton.contains(event.target as Node) && !mobileMenu.contains(event.target as Node)) {
mobileMenuButton.setAttribute('aria-expanded', 'false');
mobileMenu.classList.add('hidden');
menuIcon.classList.remove('hidden');
closeIcon.classList.add('hidden');
}
});
}
});
</script>