added update
All checks were successful
ci/cd / Build (push) Successful in 18s

This commit is contained in:
Mariia Shabelnik 2024-01-02 23:04:17 +01:00
parent f45ca70b21
commit 03711da9ef
15 changed files with 199 additions and 53 deletions

15
package-lock.json generated
View File

@ -11,6 +11,7 @@
"hamburger-react": "^2.5.0", "hamburger-react": "^2.5.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-image-gallery": "^1.3.0", "react-image-gallery": "^1.3.0",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scroll-motion": "^0.3.0", "react-scroll-motion": "^0.3.0",
@ -1984,6 +1985,14 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-icons": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
"integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/react-image-gallery": { "node_modules/react-image-gallery": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz", "resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz",
@ -3713,6 +3722,12 @@
"scheduler": "^0.23.0" "scheduler": "^0.23.0"
} }
}, },
"react-icons": {
"version": "4.12.0",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
"integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==",
"requires": {}
},
"react-image-gallery": { "react-image-gallery": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz", "resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz",

View File

@ -12,6 +12,7 @@
"hamburger-react": "^2.5.0", "hamburger-react": "^2.5.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-image-gallery": "^1.3.0", "react-image-gallery": "^1.3.0",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scroll-motion": "^0.3.0", "react-scroll-motion": "^0.3.0",

View File

@ -6,7 +6,9 @@ import Contact from "./pages/Contact";
import Footer from "./components/Footer"; import Footer from "./components/Footer";
import Header from "./components/Header"; import Header from "./components/Header";
import ExperianceDetail from "./pages/ExperienceDetail"; import ExperianceDetail from "./pages/ExperienceDetail";
import FullPage from "./pages/FullPage";
import { RecoilRoot } from "recoil"; import { RecoilRoot } from "recoil";
import ScrollToAnchor from "./components/ScrollToAnchor";
function App() { function App() {
return ( return (
@ -14,10 +16,11 @@ function App() {
<RecoilRoot> <RecoilRoot>
<main className=" min-h-screen"> <main className=" min-h-screen">
<Header /> <Header />
<ScrollToAnchor />
<Routes> <Routes>
<Route path="/" element={<Home />} /> <Route path="/" element={<FullPage />} />
<Route path="/experience" element={<Experience />} /> {/* <Route path="/experience" element={<Experience />} />
<Route path="/contact" element={<Contact />} /> <Route path="/contact" element={<Contact />} />*/}
<Route path="/experience/:id" element={<ExperianceDetail />} /> <Route path="/experience/:id" element={<ExperianceDetail />} />
</Routes> </Routes>
<Footer /> <Footer />

View File

@ -1,16 +1,21 @@
import { Link, useLocation } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import { Turn as Hamburger } from "hamburger-react"; import { useState, useEffect } from "react";
import { useState } from "react"; import { Divide as Hamburger } from "hamburger-react";
function Header() { function Header() {
const [isOpen, setOpen] = useState(false); const [isOpen, setOpen] = useState(false);
const menuTimeout = 400; const menuTimeout = 400;
const location = useLocation(); const location = useLocation();
useEffect(() => {
document.body.style.overflow = isOpen ? "hidden" : "unset";
}, [isOpen]);
const menu = [ const menu = [
{ link: "/", title: ".me()" }, { link: "/#about", title: ".me()" },
{ link: "/experience", title: ".experience()" }, { link: "/#experience", title: ".experience()" },
{ link: "/contact", title: ".contact()" }, { link: "/#contact", title: ".contact()" },
]; ];
const menuUI = menu.map((item) => { const menuUI = menu.map((item) => {
@ -21,38 +26,70 @@ function Header() {
className += " text-white/40"; className += " text-white/40";
} }
return ( return (
<li key={item.link}> <li className="my-10 text-xl md:my-0 md:text-base" key={item.link}>
<Link className={className} to={item.link}> <Link
className={className}
onClick={() => {
setOpen(false);
}}
to={item.link}
>
{item.title} {item.title}
</Link> </Link>
</li> </li>
); );
}); });
const headerClasses = ["sticky", "top-0", "z-40", "backdrop-blur-sm", "h-16"];
const logoClasses = ["hover:drop-shadow-light"];
const overlayMenu = [
"bg-black/90",
"z-50",
"fixed",
"left-0",
"right-0",
"top-16",
"h-screen",
"backdrop-blur-sm",
"p-2",
];
if (isOpen) {
headerClasses.push("bg-black/90");
logoClasses.push("drop-shadow-yellow");
} else {
headerClasses.push("bg-bgColor/90");
logoClasses.push("drop-shadow-doublelight");
}
return ( return (
<header className="sticky top-0 z-50 backdrop-blur-sm bg-bgColor/90 "> <>
<div className="container mx-auto"> {isOpen && (
<nav className="flex items-center mx-4 py-4"> <div className={overlayMenu.join(" ")}>
<div className="flex-none text-4xl font-black"> <div className=" h-[calc(100vh-20rem)] flex flex-col justify-center">
<Link <ul>{menuUI}</ul>
className=" drop-shadow-doublelight hover:drop-shadow-light" </div>
to="/" </div>
> )}
<header className={headerClasses.join(" ")}>
<div className="container mx-auto h-full">
<nav className="flex items-center h-full px-2">
<div className="flex-none text-4xl font-black ">
<Link className={logoClasses.join(" ")} to="/#start">
MS. MS.
</Link> </Link>
</div> </div>
{/* <div className="hamburger">
<Hamburger color="#e5e5ff" toggled={isOpen} toggle={setOpen} />
</div> */}
<div className="grow"></div> <div className="grow"></div>
<div className="flex-none "> <div className="flex-none hidden md:block ">
<ul className="flex flex-row gap-4 text-lg">{menuUI}</ul> <ul className="flex flex-row gap-4 text-lg">{menuUI}</ul>
</div> </div>
<div className="flex-none block md:hidden">
<Hamburger toggled={isOpen} toggle={setOpen} duration={0.9} />
</div>
</nav> </nav>
{isOpen && hamburgerMenu}
</div> </div>
</header> </header>
</>
); );
} }

View File

@ -0,0 +1,28 @@
import { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";
function ScrollToAnchor() {
const location = useLocation();
const lastHash = useRef("");
// listen to location change using useEffect with location as dependency
// https://jasonwatmore.com/react-router-v6-listen-to-location-route-change-without-history-listen
useEffect(() => {
if (location.hash) {
lastHash.current = location.hash.slice(1); // safe hash for further use after navigation
}
if (lastHash.current && document.getElementById(lastHash.current)) {
setTimeout(() => {
document
.getElementById(lastHash.current)
?.scrollIntoView({ behavior: "smooth", block: "start" });
lastHash.current = "";
}, 100);
}
}, [location]);
return null;
}
export default ScrollToAnchor;

View File

@ -1,12 +1,12 @@
function Tags({ listOfTags }) { function Tags({ listOfTags }) {
const tagList = listOfTags.map((itemTag, keyTag) => { const tagList = listOfTags.map((itemTag, keyTag) => {
return ( return (
<div className={`bg-indigo-500/40 py-2 px-4 rounded-full `} key={keyTag}> <div className={`bg-gray-600 py-1 px-1 rounded-xl `} key={keyTag}>
{itemTag} {itemTag}
</div> </div>
); );
}); });
return <div className="text-xs flex gap-4 mt-6 ">{tagList}</div>; return <div className="text-xs flex gap-2 mt-6 ">{tagList}</div>;
} }
export default Tags; export default Tags;

View File

@ -4,5 +4,5 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
body { body {
background-color: #302f39; background-color: #031417;
} }

10
src/pages/About.jsx Normal file
View File

@ -0,0 +1,10 @@
function About() {
return (
<div className="relative">
<div id="about" className=" absolute -top-16 "></div>
<h1> About</h1>
</div>
);
}
export default About;

View File

@ -1,7 +1,8 @@
function Contact() { function Contact() {
return ( return (
<div className="container content"> <div className="relative">
<h1>Welcome to Contact</h1> <div id="contact" className=" absolute -top-16 "></div>
<h1>Welcome to C#ontact</h1>
</div> </div>
); );
} }

View File

@ -49,8 +49,9 @@ function Experiance() {
}); });
return ( return (
<div className="container mx-auto my-10 px-6"> <div className="relative">
<h1>Welcome to Experiance</h1> <div id="experience" className=" absolute -top-16 "></div>
<h1>Welcome to Experience</h1>
<div className="py-4">{experianceListUI}</div> <div className="py-4">{experianceListUI}</div>
</div> </div>
); );

View File

@ -1,12 +1,14 @@
import { useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { useRecoilValue } from "recoil"; import { useRecoilValue } from "recoil";
import { projectsAtom } from "../store"; import { projectsAtom } from "../store";
import ImageGallery from "react-image-gallery"; import ImageGallery from "react-image-gallery";
import Tags from "../components/Tags"; import Tags from "../components/Tags";
import { IoChevronBackOutline as BackButton } from "react-icons/io5";
function ExperianceDetail() { function ExperianceDetail() {
const { id } = useParams(); const { id } = useParams();
const experianceList = useRecoilValue(projectsAtom); const experianceList = useRecoilValue(projectsAtom);
const navigate = useNavigate();
//shorter variant of Find function with IF-sats //shorter variant of Find function with IF-sats
const myProject = experianceList.find((item) => item.id === id); const myProject = experianceList.find((item) => item.id === id);
@ -35,6 +37,15 @@ function ExperianceDetail() {
return ( return (
<div className="container mx-auto my-10 px-6"> <div className="container mx-auto my-10 px-6">
<button
className="text-4xl"
aria-label="Back"
onClick={() => {
navigate(-1);
}}
>
<BackButton />
</button>
<div className="flex"> <div className="flex">
<div className="flex-1"> <div className="flex-1">
<h1>Project: {myProject.title}</h1> <h1>Project: {myProject.title}</h1>
@ -43,8 +54,8 @@ function ExperianceDetail() {
<Tags listOfTags={myProject.tags} /> <Tags listOfTags={myProject.tags} />
</div> </div>
{linkUI} {linkUI}
<div className="py-4 mb-8">{myProject.info}</div> <div className="flex flex-col md:flex-row gap-4">
<div className=""> <div className="flex-1">
<ImageGallery <ImageGallery
showThumbnails={false} showThumbnails={false}
showBullets={true} showBullets={true}
@ -54,8 +65,11 @@ function ExperianceDetail() {
items={projectImg} items={projectImg}
/> />
</div> </div>
<div className="flex-1">{myProject.info}</div>
</div>
</div> </div>
); );
} }
4;
export default ExperianceDetail; export default ExperianceDetail;

17
src/pages/FullPage.jsx Normal file
View File

@ -0,0 +1,17 @@
import About from "./About";
import Contact from "./Contact";
import Experiance from "./Experience";
import Start from "./Start";
function FullPage() {
return (
<div className="container mx-auto px-2">
<Start />
<About />
<Experiance />
<Contact />
</div>
);
}
export default FullPage;

18
src/pages/Start.jsx Normal file
View File

@ -0,0 +1,18 @@
function Start() {
return (
<div className="relative">
<div id="start" className="absolute -top-16 "></div>
<div>
<h1> Start</h1>
</div>
<div>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eos nostrum
repudiandae, excepturi, eaque autem tenetur commodi qui praesentium
nesciunt atque ullam consectetur cum aliquam corporis quae maxime libero
impedit exercitationem?
</div>
</div>
);
}
export default Start;

View File

@ -4,7 +4,7 @@ const experianceList = [
{ {
id: "46bf76ae-8915-4e5d-ae92-4151be80e75a", id: "46bf76ae-8915-4e5d-ae92-4151be80e75a",
title: "Netzero web", title: "Netzero web",
info: "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Beatae cumque laborum, placeat nobis fugit nemo ipsa voluptates error quo possimus ea velit quos voluptatum magnam id eius quam accusamus. Eum blanditiis aperiam minus inventore laboriosam, et vel ipsam perspiciatis a facilis cum, iure alias recusandae dolorem adipisci illum. Quo maxime nisi minus mollitia praesentium cumque, temporibus incidunt nulla culpa eligendi consequatur doloremque repudiandae aspernatur quas necessitatibus tenetur. Similique fuga rerum provident distinctio doloremque qui accusamus, sequi voluptate eveniet voluptatum autem odio placeat quasi temporibus quas nulla laborum sunt tenetur dolorum, incidunt error porro amet modi? Temporibus amet optio mollitia omnis?", info: "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Beatae cumque laborum, placeat nobis fugit nemo ipsa voluptates error quo possimus ea velit quos voluptatum magnam id eius quam accusamus. Eum blanditiis aperiam minus inventore laboriosam, et vel ipsam perspiciatis a facilis cum, iure alias recusandae dolorem adipisci illum. Quo maxime nisi minus mollitia praesentium cumque, temporibus incidunt nulla culpa eligendi consequatur doloremque repudiandae aspernatur quas necessitatibus tenetur. ",
img: [ img: [
"/img/placeholder.png", "/img/placeholder.png",
"/img/placeholder.png", "/img/placeholder.png",
@ -17,7 +17,7 @@ const experianceList = [
{ {
id: "55515a25-deb1-451c-bc7d-006d293f54aa", id: "55515a25-deb1-451c-bc7d-006d293f54aa",
title: "Lets fly", title: "Lets fly",
info: "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Beatae cumque laborum, placeat nobis fugit nemo ipsa voluptates error quo possimus ea velit quos voluptatum magnam id eius quam accusamus. Eum blanditiis aperiam minus inventore laboriosam, et vel ipsam perspiciatis a facilis cum, iure alias recusandae dolorem adipisci illum. Quo maxime nisi minus mollitia praesentium cumque, temporibus incidunt nulla culpa eligendi consequatur doloremque repudiandae aspernatur quas necessitatibus tenetur. Similique fuga rerum provident distinctio doloremque qui accusamus, sequi voluptate eveniet voluptatum autem odio placeat quasi temporibus quas nulla laborum sunt tenetur dolorum, incidunt error porro amet modi? Temporibus amet optio mollitia omnis?", info: "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Beatae cumque laborum, placeat nobis fugit nemo ipsa voluptates error quo possimus ea velit quos voluptatum magnam id eius quam accusamus. Eum blanditiis aperiam minus inventore laboriosam, et vel ipsam perspiciatis a facilis cum, iure alias recusandae dolorem adipisci illum. Quo maxime nisi minus mollitia praesentium cumque, temporibus incidunt nulla culpa eligendi consequatur doloremque repudiandae aspernatur quas necessitatibus tenetur. ",
img: [ img: [
"/img/placeholder.png", "/img/placeholder.png",
"/img/placeholder.png", "/img/placeholder.png",

View File

@ -13,6 +13,7 @@ export default {
}, },
dropShadow: { dropShadow: {
light: "0 0 5px theme('colors.indigo.800')", light: "0 0 5px theme('colors.indigo.800')",
yellow: "0 0 9px theme('colors.lime.400')",
doublelight: [ doublelight: [
"0 0 5px theme('colors.lime.400')", "0 0 5px theme('colors.lime.400')",
"0 0 15px theme('colors.yellow.400')", "0 0 15px theme('colors.yellow.400')",