feat: update personal information and localization in various components
Deploy Portfolio Selfmade / deploy (push) Failing after 15s

This commit is contained in:
2026-05-10 14:52:21 +02:00
parent 4ff07915b8
commit 430e02c8ce
14 changed files with 337 additions and 186 deletions
@@ -1,49 +1,54 @@
import React from 'react';
import { motion } from 'framer-motion';
import React, { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Menu, X } from 'lucide-react';
import { useNavigation } from '../hooks/useNavigation';
import { useScrollToSection } from '../../../shared/hooks/useScrollToSection';
import Button from '../../../shared/components/Button';
const navItems = [
{ id: 'home', label: 'About' },
{ id: 'skills', label: 'Skills' },
{ id: 'projects', label: 'Projects' },
{ id: 'experience', label: 'Experience' },
{ id: 'contact', label: 'Contact' },
{ id: 'home', label: 'Über mich' },
{ id: 'skills', label: 'Fähigkeiten' },
{ id: 'projects', label: 'Projekte' },
{ id: 'experience', label: 'Erfahrung' },
{ id: 'contact', label: 'Kontakt' },
];
export const Navigation: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const { activeSection, isScrolled } = useNavigation();
const { scrollToSection } = useScrollToSection();
const handleNavClick = (id: string) => {
setIsOpen(false);
scrollToSection(id);
};
return (
<motion.nav
initial={{ y: -100 }}
initial={{ y: -120 }}
animate={{ y: 0 }}
transition={{ duration: 0.5 }}
transition={{ duration: 0.45, ease: 'easeOut' }}
className={`fixed top-0 w-full z-50 transition-all duration-300 ${
isScrolled
? 'bg-black/80 backdrop-blur-md border-b border-green-500/20'
? 'bg-black/90 backdrop-blur-xl border-b border-green-500/20 shadow-lg shadow-emerald-500/5'
: 'bg-transparent'
}`}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
{/* Logo */}
<motion.div
whileHover={{ scale: 1.05 }}
className="text-2xl font-bold text-green-500 cursor-pointer"
onClick={() => scrollToSection('home')}
onClick={() => handleNavClick('home')}
>
&lt;/&gt; Alex
&lt;/&gt; Robert Bretz
</motion.div>
{/* Nav Items */}
<div className="hidden md:flex gap-8">
{navItems.map((item) => (
<motion.button
key={item.id}
onClick={() => scrollToSection(item.id)}
onClick={() => handleNavClick(item.id)}
className={`text-sm font-medium transition-colors duration-300 pb-2 border-b-2 ${
activeSection === item.id
? 'text-green-500 border-green-500'
@@ -57,12 +62,51 @@ export const Navigation: React.FC = () => {
))}
</div>
{/* CTA Button */}
<Button variant="primary" size="sm">
Hire Me
</Button>
<div className="flex items-center gap-3">
<div className="hidden md:block">
<Button variant="primary" size="sm">
Anfrage
</Button>
</div>
<button
type="button"
aria-label="Open mobile menu"
className="md:hidden p-2 rounded-full border border-green-500/20 bg-green-500/10 text-green-400 hover:text-white hover:border-green-500 transition-all"
onClick={() => setIsOpen((prev) => !prev)}
>
{isOpen ? <X size={22} /> : <Menu size={22} />}
</button>
</div>
</div>
</div>
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="md:hidden bg-black/95 border-t border-green-500/20"
>
<div className="px-6 py-6 space-y-4">
{navItems.map((item) => (
<button
key={item.id}
onClick={() => handleNavClick(item.id)}
className={`w-full text-left text-lg font-medium px-4 py-3 rounded-xl transition-colors duration-300 ${
activeSection === item.id
? 'bg-green-500/15 text-green-400'
: 'text-gray-300 hover:bg-white/5 hover:text-white'
}`}
>
{item.label}
</button>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</motion.nav>
);
};