This commit is contained in:
Mariia Shabelnik 2023-10-12 09:56:13 +02:00
parent 90da024c00
commit 90398455f1
16 changed files with 2169 additions and 350 deletions

2121
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,18 @@
"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-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",
"recoil": "^0.7.7"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^18.0.15", "@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^2.0.0", "@vitejs/plugin-react": "^2.0.0",
"autoprefixer": "^10.4.15",
"postcss": "^8.4.29",
"tailwindcss": "^3.3.3",
"vite": "^3.0.0" "vite": "^3.0.0"
} }
} }

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

BIN
public/img/placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -1,3 +1,10 @@
body {
margin: 0;
font-family: "Roboto Mono", monospace;
background-color: #302f39;
color: white;
}
.container { .container {
max-width: 1000px; max-width: 1000px;
margin: 0 auto; margin: 0 auto;

View File

@ -1,21 +1,28 @@
import "./App.css"; //import "./App.css";
import { Routes, Route } from "react-router-dom"; import { Routes, Route } from "react-router-dom";
import Home from "./pages/Home"; import Home from "./pages/Home";
import Experience from "./pages/Experience"; import Experience from "./pages/Experience";
import Contact from "./pages/Contact"; 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 { RecoilRoot } from "recoil";
function App() { function App() {
return ( return (
<div> <div className="text-white">
<RecoilRoot>
<main className=" min-h-screen">
<Header /> <Header />
<Routes> <Routes>
<Route path="/" element={<Home />} /> <Route path="/" element={<Home />} />
<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 />} />
</Routes> </Routes>
<Footer /> <Footer />
</main>
</RecoilRoot>
</div> </div>
); );
} }

View File

@ -1,11 +1,11 @@
function Footer() { function Footer() {
const fullYear = new Date().getFullYear(); const fullYear = new Date().getFullYear();
return ( return (
<div className="container"> <footer className="container mx-auto my-10 px-6 sticky top-[95vh]">
<div className="copyright"> <div className=" text-center text-sm text-white/50 ">
© {fullYear} Mariia Shabelnik, all rights reserved © {fullYear} Mariia Shabelnik, all rights reserved
</div> </div>
</div> </footer>
); );
} }

View File

@ -1,79 +1,58 @@
import { Link } from "react-router-dom"; import { Link, useLocation } from "react-router-dom";
import { Turn as Hamburger } from "hamburger-react"; import { Turn as Hamburger } from "hamburger-react";
import { useState } from "react"; import { useState } from "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 hamburgerMenu = ( const menu = [
<div className="hamburger-menu"> { link: "/", title: ".me()" },
<div> { link: "/experience", title: ".experience()" },
<Link { link: "/contact", title: ".contact()" },
onClick={() => { ];
setTimeout(() => {
setOpen(false); const menuUI = menu.map((item) => {
}, menuTimeout); let className = "drop-shadow-light hover:drop-shadow-doublelight";
}} if (location.pathname === item.link) {
to="/" className += " text-white";
> } else {
.me() className += " text-white/40";
}
return (
<li key={item.link}>
<Link className={className} to={item.link}>
{item.title}
</Link> </Link>
</div> </li>
<div>
<Link
onClick={() => {
setTimeout(() => {
setOpen(false);
}, menuTimeout);
}}
to="/experience"
>
.experience()
</Link>
</div>
<div>
<Link
onClick={() => {
setTimeout(() => {
setOpen(false);
}, menuTimeout);
}}
to="/contact"
>
.contact()
</Link>
</div>
</div>
); );
});
return ( return (
<div className="nav"> <header className="sticky top-0 z-50 backdrop-blur-sm bg-bgColor/90 ">
<div className="container"> <div className="container mx-auto">
<div className=" nav-items"> <nav className="flex items-center mx-4 py-4">
<div className="logo"> <div className="flex-none text-4xl font-black">
<Link to="/">MS.</Link> <Link
className=" drop-shadow-doublelight hover:drop-shadow-light"
to="/"
>
MS.
</Link>
</div> </div>
<div className="hamburger"> {/* <div className="hamburger">
<Hamburger color="#e5e5ff" toggled={isOpen} toggle={setOpen} /> <Hamburger color="#e5e5ff" toggled={isOpen} toggle={setOpen} />
</div> */}
<div className="grow"></div>
<div className="flex-none ">
<ul className="flex flex-row gap-4 text-lg">{menuUI}</ul>
</div> </div>
</nav>
<div className="menu-items ">
<div>
<Link to="/">.me()</Link>
</div>
<div>
<Link to="/experience">.experience()</Link>
</div>
<div>
<Link to="/contact">.contact()</Link>
</div>
</div>
</div>
{isOpen && hamburgerMenu} {isOpen && hamburgerMenu}
</div> </div>
</div> </header>
); );
} }

12
src/components/Tags.jsx Normal file
View File

@ -0,0 +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}>
{itemTag}
</div>
);
});
return <div className="text-xs flex gap-4 mt-6 ">{tagList}</div>;
}
export default Tags;

View File

@ -1,6 +1,8 @@
@import "react-image-gallery/styles/css/image-gallery.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
body { body {
margin: 0;
font-family: "Roboto Mono", monospace;
background-color: #302f39; background-color: #302f39;
color: white;
} }

View File

@ -1,7 +1,57 @@
import { Link } from "react-router-dom";
import { useRecoilValue } from "recoil";
import { projectsAtom } from "../store";
import Tags from "../components/Tags";
function Experiance() { function Experiance() {
const experianceList = useRecoilValue(projectsAtom);
const experianceListUI = experianceList.map((item, key) => {
const position = key % 2;
const imgClasses = ["flex-1", "hidden", "md:block"];
if (position === 1) {
imgClasses.push("md:order-last");
}
return ( return (
<div className="container content"> <section className="flex flex-col md:flex-row gap-4 mb-12" key={item.id}>
<div className={imgClasses.join(" ")}>
<img className="rounded-md" src={item.img[0]} />
</div>
<div className="flex-1 flex flex-col">
<div>
<h2 className="text-2xl mb-4"> {item.title}</h2>
</div>
<div>
<img
className="block md:hidden mb-4 rounded-md"
src={item.img[0]}
/>
</div>
<div className="text-sm">
<p>{item.info}</p>
</div>
<Tags listOfTags={item.tags} />
<div className="grow"></div>
<div className=" text-right">
<Link
className=" drop-shadow-doublelight hover:drop-shadow-light "
to={`/experience/${item.id}`}
>
read more
</Link>
</div>
</div>
</section>
);
});
return (
<div className="container mx-auto my-10 px-6">
<h1>Welcome to Experiance</h1> <h1>Welcome to Experiance</h1>
<div className="py-4">{experianceListUI}</div>
</div> </div>
); );
} }

View File

@ -0,0 +1,61 @@
import { useParams } from "react-router-dom";
import { useRecoilValue } from "recoil";
import { projectsAtom } from "../store";
import ImageGallery from "react-image-gallery";
import Tags from "../components/Tags";
function ExperianceDetail() {
const { id } = useParams();
const experianceList = useRecoilValue(projectsAtom);
//shorter variant of Find function with IF-sats
const myProject = experianceList.find((item) => item.id === id);
if (myProject === undefined) {
return (
<div className="container mx-auto my-10 px-6">
404 the project does not exists
</div>
);
}
const projectImg = myProject.img.map((item) => {
return { original: item, thumbnail: item };
});
let linkUI = <></>;
if (myProject.link !== undefined) {
linkUI = (
<a href={myProject.link} target="_blank">
Visit page
</a>
);
}
return (
<div className="container mx-auto my-10 px-6">
<div className="flex">
<div className="flex-1">
<h1>Project: {myProject.title}</h1>
</div>
<Tags listOfTags={myProject.tags} />
</div>
{linkUI}
<div className="py-4 mb-8">{myProject.info}</div>
<div className="">
<ImageGallery
showThumbnails={false}
showBullets={true}
autoPlay={true}
slideDuration={1000}
slideInterval={4000}
items={projectImg}
/>
</div>
</div>
);
}
export default ExperianceDetail;

View File

@ -27,17 +27,20 @@ function Home() {
<Animator animation={batch(Fade(), Sticky(), MoveOut(0, 200))}> <Animator animation={batch(Fade(), Sticky(), MoveOut(0, 200))}>
<span>Hello, my name is Mariia 😀</span> <span>Hello, my name is Mariia 😀</span>
</Animator> </Animator>
<span style={{ fontSize: "40px" }}>
<Animator animation={MoveIn(-1000, 0)}>Hello Guys 👋🏻</Animator>
</span>
</ScrollPage> </ScrollPage>
<ScrollPage> <ScrollPage>
<Animator animation={ZoomInScrollOut}> <Animator animation={ZoomInScrollOut}>
<span style={{ fontSize: "40px" }}>I'm FadeUpScrollOut </span> <span style={{ fontSize: "40px" }}>I'm Frontend developer </span>
</Animator> </Animator>
</ScrollPage> </ScrollPage>
<ScrollPage> <ScrollPage>
<Animator animation={FadeUp}> <Animator animation={FadeUp}>
<span style={{ fontSize: "40px" }}>I'm FadeUp </span> <span style={{ fontSize: "40px" }}>I'm Webbdesigner </span>
</Animator> </Animator>
</ScrollPage> </ScrollPage>
@ -51,7 +54,6 @@ function Home() {
}} }}
> >
<span style={{ fontSize: "40px" }}> <span style={{ fontSize: "40px" }}>
<Animator animation={MoveIn(-1000, 0)}>Hello Guys 👋🏻</Animator>
<Animator animation={MoveIn(1000, 0)}>Nice to meet you 🙋🏻</Animator> <Animator animation={MoveIn(1000, 0)}>Nice to meet you 🙋🏻</Animator>
- I'm Dante Chun - - I'm Dante Chun -
<Animator animation={MoveOut(1000, 0)}>Good bye 🏻</Animator> <Animator animation={MoveOut(1000, 0)}>Good bye 🏻</Animator>

71
src/store.js Normal file
View File

@ -0,0 +1,71 @@
import { atom } from "recoil";
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?",
img: [
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
],
tags: ["react", "vite", "wordpress"],
link: "https://www.net0.se",
},
{
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?",
img: [
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
],
tags: ["react", "vite", "shopify"],
link: undefined,
},
{
id: "e93a5d54-3442-4b19-b568-8ae550aa09fe",
title: "Project 3",
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?",
img: [
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
],
tags: ["react", "vite", "wordpress"],
link: undefined,
},
{
id: "cedeb531-0409-4e1f-b7e9-9668dcaa5e71",
title: "Project 4",
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?",
img: [
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
],
tags: ["react", "vite", "wordpress"],
link: undefined,
},
{
id: "5e2ea8b8-bb1e-4c9d-a723-42406bf7be72",
title: "Project 5",
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?",
img: [
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
"/img/placeholder.png",
],
tags: ["react", "vite", "wordpress"],
link: undefined,
},
];
export const projectsAtom = atom({ key: "projects", default: experianceList });

28
tailwind.config.js Normal file
View File

@ -0,0 +1,28 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
fontFamily: {
sans: ["Roboto Mono", "system-ui"],
headline: ["Roboto Mono", "system-ui"],
},
extend: {
colors: {
neon: "#ccff00",
bgColor: "#302f39",
},
dropShadow: {
light: "0 0 5px theme('colors.indigo.800')",
doublelight: [
"0 0 5px theme('colors.lime.400')",
"0 0 15px theme('colors.yellow.400')",
],
active: [
"0 0 5px theme('colors.lime.400')",
"0 0 15px theme('colors.indigo.950')",
],
},
},
},
plugins: [],
};

View File

@ -1,7 +1,7 @@
import { defineConfig } from 'vite' import { defineConfig } from "vite";
import react from '@vitejs/plugin-react' import react from "@vitejs/plugin-react";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react()] plugins: [react()],
}) });