This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import React, { useState } from 'react';
|
||||
import logo from '../assets/logo.jpg';
|
||||
import { FaFacebookF, FaInstagram, FaLinkedinIn } from 'react-icons/fa';
|
||||
import { SiTypescript, SiReact, SiJavascript } from 'react-icons/si';
|
||||
|
||||
type Language = 'en' | 'cs';
|
||||
|
||||
const translations = {
|
||||
en: {
|
||||
home: 'Home',
|
||||
about: 'About',
|
||||
contact: 'Contact',
|
||||
welcome: 'WELCOME TO MY WORLD',
|
||||
hello: "Hello, I'm",
|
||||
job: 'a Developer.',
|
||||
desc: "I use animation as a third dimension by which to simplify experiences and guiding through each and every interaction. I'm not adding motion just to spruce things up, but doing it in ways that matter.",
|
||||
findMe: 'FIND WITH ME',
|
||||
bestSkill: 'BEST SKILL ON',
|
||||
aboutMe: 'About Me',
|
||||
aboutDesc: 'I build accessible, pixel-perfect, and performant web experiences. Passionate about technology and design.',
|
||||
getInTouch: 'Get In Touch',
|
||||
contactDesc: 'Interested in working together?',
|
||||
emailMe: 'Email me',
|
||||
},
|
||||
cs: {
|
||||
home: 'Domů',
|
||||
about: 'O mně',
|
||||
contact: 'Kontakt',
|
||||
welcome: 'VÍTEJTE V MÉM SVĚTĚ',
|
||||
hello: "Ahoj, jsem",
|
||||
job: 'Vývojář.',
|
||||
desc: "Používám animaci jako třetí rozměr, kterým zjednodušuji zážitky a provázím každou interakcí. Nepřidávám pohyb jen pro efekt, ale dělám to způsoby, které mají smysl.",
|
||||
findMe: 'NAJDETE MĚ NA',
|
||||
bestSkill: 'DOVEDNOSTI',
|
||||
aboutMe: 'O mně',
|
||||
aboutDesc: 'Tvořím přístupné, pixel-perfect a výkonné webové zážitky. Vášnivý pro technologie a design.',
|
||||
getInTouch: 'Napište mi',
|
||||
contactDesc: 'Máte zájem o spolupráci?',
|
||||
emailMe: 'Napište mi',
|
||||
}
|
||||
};
|
||||
|
||||
const Home: React.FC = () => {
|
||||
const [language, setLanguage] = useState<Language>('en');
|
||||
const t = translations[language];
|
||||
|
||||
const handleNavClick = (id: string, e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
const element = document.getElementById(id);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="home-container fade-in">
|
||||
<nav className="navbar">
|
||||
<div className="nav-content">
|
||||
<div
|
||||
className="logo-container"
|
||||
onClick={(e) => handleNavClick('home', e)}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<img src={logo} alt="David Fencl Logo" className="nav-logo" />
|
||||
</div>
|
||||
<div className="nav-right">
|
||||
<div className="language-switcher">
|
||||
<button
|
||||
className={`lang-btn ${language === 'en' ? 'active' : ''}`}
|
||||
onClick={() => setLanguage('en')}
|
||||
>
|
||||
EN
|
||||
</button>
|
||||
<span className="lang-separator">/</span>
|
||||
<button
|
||||
className={`lang-btn ${language === 'cs' ? 'active' : ''}`}
|
||||
onClick={() => setLanguage('cs')}
|
||||
>
|
||||
CZ
|
||||
</button>
|
||||
</div>
|
||||
<div className="links">
|
||||
<a href="#about" onClick={(e) => handleNavClick('about', e)}>{t.about}</a>
|
||||
<a href="#contact" onClick={(e) => handleNavClick('contact', e)}>{t.contact}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section id="home" className="hero fade-in">
|
||||
<div className="hero-content">
|
||||
<div className="hero-text">
|
||||
<span className="welcome-text">{t.welcome}</span>
|
||||
<h1>{t.hello} <span className="highlight">Davis</span></h1>
|
||||
<h2 className="job-title">{t.job}</h2>
|
||||
<p className="description">
|
||||
{t.desc}
|
||||
</p>
|
||||
|
||||
<div className="hero-footer">
|
||||
<div className="socials">
|
||||
<span className="footer-label">{t.findMe}</span>
|
||||
<div className="icon-group">
|
||||
<button className="icon-btn"><FaFacebookF /></button>
|
||||
<button className="icon-btn"><FaInstagram /></button>
|
||||
<button className="icon-btn"><FaLinkedinIn /></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="skills">
|
||||
<span className="footer-label">{t.bestSkill}</span>
|
||||
<div className="icon-group">
|
||||
<button className="icon-btn"><SiTypescript /></button>
|
||||
<button className="icon-btn"><SiReact /></button>
|
||||
<button className="icon-btn"><SiJavascript /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hero-image-container">
|
||||
<div className="hero-image-placeholder">
|
||||
<span>Photo</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="about" className="section about fade-in">
|
||||
<h2>{t.aboutMe}</h2>
|
||||
<p>
|
||||
{t.aboutDesc}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="contact" className="section contact fade-in">
|
||||
<h2>{t.getInTouch}</h2>
|
||||
<p>
|
||||
{t.contactDesc} <a href="mailto:hello@example.com">{t.emailMe}</a>.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import '../index.css';
|
||||
|
||||
interface LoadingScreenProps {
|
||||
onLoaded: () => void;
|
||||
}
|
||||
|
||||
const LoadingScreen: React.FC<LoadingScreenProps> = ({ onLoaded }) => {
|
||||
const [fading, setFading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setFading(true);
|
||||
setTimeout(onLoaded, 500); // Wait for fade out animation
|
||||
}, 2500); // Show loading screen for 2.5 seconds
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [onLoaded]);
|
||||
|
||||
return (
|
||||
<div className={`loading-screen ${fading ? 'fade-out' : ''}`}>
|
||||
<div className="loader-content">
|
||||
<div className="spinner"></div>
|
||||
<h1 className="loading-text">Welcome</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingScreen;
|
||||
Reference in New Issue
Block a user