Compare commits

...

7 Commits

Author SHA1 Message Date
Mariia Shabelnik
7a9f716f62 Merge branch 'release/v1'
Some checks failed
ci/cd / Build (push) Failing after 1s
2024-01-08 12:11:44 +01:00
Mariia Shabelnik
4912c527f1 Added readme 2024-01-08 12:11:35 +01:00
Mariia Shabelnik
fd86e00417 Added tag
All checks were successful
ci/cd / Build (push) Successful in 9s
2024-01-08 12:09:03 +01:00
Mariia Shabelnik
c0bccc8458 added text
All checks were successful
ci/cd / Build (push) Successful in 8s
2024-01-08 12:00:31 +01:00
Mariia Shabelnik
0cbe047fc5 UI update and added text_imgs
All checks were successful
ci/cd / Build (push) Successful in 9s
2024-01-05 21:57:43 +01:00
Mariia Shabelnik
9ddf5233ad added text and UI
All checks were successful
ci/cd / Build (push) Successful in 14s
2024-01-05 12:52:34 +01:00
Mariia Shabelnik
03711da9ef added update
All checks were successful
ci/cd / Build (push) Successful in 18s
2024-01-02 23:04:17 +01:00
24 changed files with 342 additions and 228 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# Portfolio

View File

@ -17,6 +17,15 @@
href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Ubuntu+Mono:wght@400;700&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Tektur:wght@400;500;600;700;800;900&display=swap"
rel="stylesheet"
/>
<title>Mariia Shabelnik</title>
</head>
<body>

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",

BIN
public/img/letsfly_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
public/img/letsfly_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

BIN
public/img/letsfly_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 KiB

BIN
public/img/net0_0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

BIN
public/img/net0_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

BIN
public/img/net0_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -1,109 +0,0 @@
body {
margin: 0;
font-family: "Roboto Mono", monospace;
background-color: #302f39;
color: white;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 1em;
}
.nav .container {
height: 4em;
}
.content {
margin-top: 5em;
}
.nav {
background-color: #302f38;
height: 4em;
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 100000;
}
/*box-shadow: inset 0px 3px 20px 10px rgba(0, 0, 0, 0.3);*/
.nav a {
text-decoration: none;
color: #e5e5ff;
transition: 0.3s;
}
.nav a:hover {
color: #fff;
text-shadow: 0 0 5px #f2ef00;
}
.nav-items {
display: flex;
justify-content: space-between;
height: 100%;
align-items: center;
}
.menu-items {
display: flex;
}
.menu-items div {
margin-left: 1em;
}
.logo {
font-size: 2em;
font-weight: bold;
}
.logo a {
text-shadow: 0 0 5px #ccff00, 0 0 15px #ccff00;
z-index: 10000;
}
.hamburger {
display: none;
}
.copyright {
font-size: 0.7em;
text-align: center;
}
.hamburger-menu {
background-color: #302f38;
z-index: 100;
position: fixed;
right: 0;
backdrop-filter: blur(3px) contrast(60%);
-webkit-backdrop-filter: blur(3px) contrast(60%);
top: 4em;
bottom: 0;
left: 0px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-end;
}
.hamburger-menu a {
font-size: 2em;
text-decoration: none;
margin-right: 1em;
}
@media screen and (max-width: 768px) {
.hamburger {
display: inline;
}
.menu-items {
display: none;
}
}

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-md", "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">
<div className="flex-none text-4xl font-black">
<Link
className=" drop-shadow-doublelight hover:drop-shadow-light"
to="/"
>
<>
{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-3xl md:text-4xl font-black font-headline ">
<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,16 @@
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-800 py-1 px-2 rounded-xl `} key={keyTag}>
{itemTag}
</div>
);
});
return <div className="text-xs flex gap-4 mt-6 ">{tagList}</div>;
return (
<div className="text-tags flex flex-wrap gap-2 font-tags text-highlight ">
{tagList}
</div>
);
}
export default Tags;

View File

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

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

@ -0,0 +1,41 @@
import { useRecoilValue } from "recoil";
import Tags from "../components/Tags";
import { skillsAtom } from "../store";
function About() {
const skills = useRecoilValue(skillsAtom);
console.log(skills);
return (
<div className="relative">
<div id="about" className=" absolute -top-16 "></div>
<h2 className="mb-2 text-subTPhone md:text-subT font-headline">
About<span className=" text-highlight">.</span>
</h2>
<div className="flex flex-col md:flex-row">
<div className="basis-2/3 text-base">
<p>
As a prospective Frontend Developer, I seek a challenging career
opportunity in the IT industry, where I can collaborate with a
dynamic team, continually learn, and foster innovation. My
dedication lies in transforming design concepts into user-friendly
experiences and achieving organizational goals through creativity
and teamwork. I aspire to engage in work that allows the utilization
of technical and creative skills to contribute effectively to the
growth of an organization. If you think you've got an opening that I
might like, let's connect 🔗
</p>
</div>
<div className=" basis-1/3">
<h4 className="mb-2 text-subTMini">Languages:</h4>
<Tags listOfTags={skills.languages} />
<h4 className="my-2 text-subTMini">Frameworks:</h4>{" "}
<Tags listOfTags={skills.frameworks} />
<h4 className="my-2 text-subTMini">Tools I use:</h4>{" "}
<Tags listOfTags={skills.tools} />
</div>
</div>
</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

@ -9,7 +9,7 @@ function Experiance() {
const experianceListUI = experianceList.map((item, key) => {
const position = key % 2;
const imgClasses = ["flex-1", "hidden", "md:block"];
const imgClasses = ["basis-1/3", "hidden", "md:block"];
if (position === 1) {
imgClasses.push("md:order-last");
@ -20,9 +20,11 @@ function Experiance() {
<div className={imgClasses.join(" ")}>
<img className="rounded-md" src={item.img[0]} />
</div>
<div className="flex-1 flex flex-col">
<div className="basis-2/3 flex flex-col">
<div>
<h2 className="text-2xl mb-4"> {item.title}</h2>
<h2 className="text-subTMiniPhone md:text-subTMini mb-4 ">
{item.title}
</h2>
</div>
<div>
<img
@ -30,7 +32,7 @@ function Experiance() {
src={item.img[0]}
/>
</div>
<div className="text-sm">
<div className="text-base mb-6 line-clamp-3 md:line-clamp-6">
<p>{item.info}</p>
</div>
<Tags listOfTags={item.tags} />
@ -49,8 +51,11 @@ 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>
<h2 className=" text-subTPhone md:text-subT font-headline">
Experience<span className=" text-highlight">.</span>
</h2>
<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,16 +37,27 @@ function ExperianceDetail() {
return (
<div className="container mx-auto my-10 px-6">
<div className="flex">
<button
className="text-4xl "
aria-label="Back"
onClick={() => {
navigate(-1);
}}
>
<BackButton />
</button>
<div className="flex flex-col">
<div className="flex-1">
<h1>Project: {myProject.title}</h1>
<h1 className=" text-subTPhone md:text-subT">
Project: {myProject.title}
</h1>
</div>
<div className="flex-1 mt-2 mb-6">
<Tags listOfTags={myProject.tags} />
</div>{" "}
</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 +67,16 @@ function ExperianceDetail() {
items={projectImg}
/>
</div>
<div className="flex-1 text-base">
{myProject.info}
<div className=" drop-shadow-doublelight hover:drop-shadow-light my-2 text-end">
{linkUI}
</div>
</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;

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

@ -0,0 +1,26 @@
function Start() {
return (
<div className="relative">
<div id="start" className="absolute -top-16 "></div>
<div>
<h1 className="text-titlePhone md:text-title md:leading-tight mb-2 font-headline">
Hello, my name is Maria<span className=" text-highlight">.</span>
</h1>
<h2 className="text-subTPhone md:text-subT font-headline">
I'm a<span className=" text-highlight"> Frontend Engineer</span>
</h2>
<p className="text-base">
In my recent journey as a junior frontend engineer, I've gained
valuable experience through involvement in various projects within
startup environments. Passionate about art and design, I've developed
my skills beyond coding. Let's connect and explore opportunities
together! By the way, you might catch a glimpse of my black mini
poodle, Oreo, who's an integral part of my creative space.
</p>
</div>
</div>
);
}
export default Start;

View File

@ -4,68 +4,60 @@ 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",
info: "Discover the intersection of sustainability and technology in my collaboration with Net0. As the creative force behind the UI/UX design, I meticulously crafted a seamless and visually appealing user experience. Bringing this vision to life, I also spearheaded the frontend development, using React to construct an intuitive and efficient system for Net0. Immerse yourself in the synergy of eco-conscious practices and cutting-edge technology as we navigate towards a greener future, one React component at a time.",
img: ["/img/net0_0.png", "/img/net0_1.png", "/img/net0_2.png"],
tags: [
"React",
"Vite",
"Figma",
"Tailwind",
"TypeScript",
"Rest API",
"Node.js",
"Postgres",
"Prisma",
"Javascript",
],
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,
info: "Letsfly is a website aimed at providing a platform for aviation-related services and information. Built on Next.js, a popular React framework, the website leverages its server-side rendering (SSR) capability to enhance performance and user experience. Tailwind was used as the CSS framework to quickly and efficiently create an attractive and responsive design. WordPress, a well-known Content Management System (CMS), was employed as the content management system to administer and publish content on the website. The reason for choosing WordPress was a client request; he was familiar with this system and wanted to be able to modify the content himself. GraphQL was selected as the API layer to enable efficient data management and flexible data queries between the frontend and backend.",
img: ["/img/letsfly_1.png", "/img/letsfly_2.png", "/img/letsfly_3.png"],
tags: ["React", "NextJS", "Wordpress", "GraphQL", "MySQL", "Tailwind"],
link: "https://preview.letsfly.app/",
},
];
export const projectsAtom = atom({ key: "projects", default: experianceList });
export const skillsAtom = atom({
key: "skills",
default: {
languages: ["JavaScript", "TypeScript", "SQL", "HTML", "CSS"],
frameworks: [
"React",
"Node.js",
"Next.js",
"Vite.js",
"Apollo GraphQL",
"Tailwind",
"Material UI",
"Chakra UI",
"Axios & Fetch",
"Framer Motion",
"WordPress",
"Shopify",
],
tools: [
"GIT",
"MySQL",
"Docker",
"Visual Studio Code",
"Postman API",
"TablePlus",
"Trello",
"Figma",
],
},
});

View File

@ -3,16 +3,35 @@ export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
fontFamily: {
sans: ["Roboto Mono", "system-ui"],
headline: ["Roboto Mono", "system-ui"],
sans: ["Ubuntu Mono", "system-ui"],
headline: ["Tektur", "system-ui"],
tags: ["Ubuntu Mono", "system-ui"],
},
fontSize: {
title: ["5rem", { lineHeight: "5rem", fontWeight: "900" }],
titlePhone: ["3rem", { lineHeight: "3rem", fontWeight: "900" }],
subT: ["3.5rem", { lineHeight: "3.5rem", fontWeight: "800" }],
subTPhone: ["2.5rem", { lineHeight: "2.5rem", fontWeight: "800" }],
subTMini: ["1.4rem", { lineHeight: "1.4rem", fontWeight: "900" }],
subTMiniPhone: ["1.2rem", { lineHeight: "1.2rem", fontWeight: "800" }],
tags: ["0.8rem", { fontWeight: "400" }],
sm: "0.8rem",
base: "1rem",
xl: "1.25rem",
"2xl": "1.563rem",
"3xl": "1.953rem",
"4xl": "2.441rem",
"5xl": "3.052rem",
},
extend: {
colors: {
neon: "#ccff00",
bgColor: "#302f39",
bgColor: "#031417",
highlight: "#ccff00",
},
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')",