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",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-image-gallery": "^1.3.0",
"react-router-dom": "^6.3.0",
"react-scroll-motion": "^0.3.0",
@ -1984,6 +1985,14 @@
"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": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/react-image-gallery/-/react-image-gallery-1.3.0.tgz",
@ -3713,6 +3722,12 @@
"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": {
"version": "1.3.0",
"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",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-image-gallery": "^1.3.0",
"react-router-dom": "^6.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 Header from "./components/Header";
import ExperianceDetail from "./pages/ExperienceDetail";
import FullPage from "./pages/FullPage";
import { RecoilRoot } from "recoil";
import ScrollToAnchor from "./components/ScrollToAnchor";
function App() {
return (
@ -14,10 +16,11 @@ function App() {
<RecoilRoot>
<main className=" min-h-screen">
<Header />
<ScrollToAnchor />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/experience" element={<Experience />} />
<Route path="/contact" element={<Contact />} />
<Route path="/" element={<FullPage />} />
{/* <Route path="/experience" element={<Experience />} />
<Route path="/contact" element={<Contact />} />*/}
<Route path="/experience/:id" element={<ExperianceDetail />} />
</Routes>
<Footer />

View File

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

View File

@ -4,5 +4,5 @@
@tailwind components;
@tailwind utilities;
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() {
return (
<div className="container content">
<h1>Welcome to Contact</h1>
<div className="relative">
<div id="contact" className=" absolute -top-16 "></div>
<h1>Welcome to C#ontact</h1>
</div>
);
}

View File

@ -49,8 +49,9 @@ function Experiance() {
});
return (
<div className="container mx-auto my-10 px-6">
<h1>Welcome to Experiance</h1>
<div className="relative">
<div id="experience" className=" absolute -top-16 "></div>
<h1>Welcome to Experience</h1>
<div className="py-4">{experianceListUI}</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 { projectsAtom } from "../store";
import ImageGallery from "react-image-gallery";
import Tags from "../components/Tags";
import { IoChevronBackOutline as BackButton } from "react-icons/io5";
function ExperianceDetail() {
const { id } = useParams();
const experianceList = useRecoilValue(projectsAtom);
const navigate = useNavigate();
//shorter variant of Find function with IF-sats
const myProject = experianceList.find((item) => item.id === id);
@ -35,6 +37,15 @@ function ExperianceDetail() {
return (
<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-1">
<h1>Project: {myProject.title}</h1>
@ -43,8 +54,8 @@ function ExperianceDetail() {
<Tags listOfTags={myProject.tags} />
</div>
{linkUI}
<div className="py-4 mb-8">{myProject.info}</div>
<div className="">
<div className="flex flex-col md:flex-row gap-4">
<div className="flex-1">
<ImageGallery
showThumbnails={false}
showBullets={true}
@ -54,8 +65,11 @@ function ExperianceDetail() {
items={projectImg}
/>
</div>
<div className="flex-1">{myProject.info}</div>
</div>
</div>
);
}
4;
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",
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/placeholder.png",
"/img/placeholder.png",
@ -17,7 +17,7 @@ const experianceList = [
{
id: "55515a25-deb1-451c-bc7d-006d293f54aa",
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/placeholder.png",
"/img/placeholder.png",

View File

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