From 6e257453bfb579b89275acdd75f415eda7aa899f Mon Sep 17 00:00:00 2001 From: yousifpa98 Date: Sat, 21 Dec 2024 04:05:54 +0100 Subject: [PATCH] About view done. all styled and animated. some minor animation fixes overall and codecleaning --- src/components/Home.jsx | 38 +++++- src/components/LangSelect.jsx | 8 +- src/components/Mail.jsx | 14 ++- src/components/Switch.jsx | 15 ++- src/components/TechStack.jsx | 96 +++++++++++++-- src/components/mainViews/About.jsx | 75 +++++++++++- .../subComponents/About/Specialties.jsx | 24 ++++ .../subComponents/About/TallContentAbout.jsx | 71 +++++++++++ src/css/GridContainer.css | 47 ++++++++ src/css/Home.css | 54 --------- src/css/Navigation.css | 2 + src/css/Specialties.css | 9 ++ src/css/TallContentAbout.css | 33 +++++ src/css/TechStack.css | 113 ++++++++++-------- 14 files changed, 467 insertions(+), 132 deletions(-) create mode 100644 src/components/subComponents/About/Specialties.jsx create mode 100644 src/components/subComponents/About/TallContentAbout.jsx create mode 100644 src/css/GridContainer.css create mode 100644 src/css/Specialties.css create mode 100644 src/css/TallContentAbout.css diff --git a/src/components/Home.jsx b/src/components/Home.jsx index 7a428c7..7829696 100644 --- a/src/components/Home.jsx +++ b/src/components/Home.jsx @@ -12,8 +12,11 @@ import Location from "./Location"; import "animate.css"; import { useState } from "react"; import TallContent from "./TallContent"; +import "../css/GridContainer.css"; const Home = () => { + const [isExpanded, setIsExpanded] = useState(false); + const social = (url) => () => { window.open(url, "_blank", "noopener,noreferrer"); }; @@ -35,12 +38,39 @@ const Home = () => { /> setIsExpanded(!isExpanded)} /> - - - + + {isExpanded ? ( + "" + ) : ( + + )} + {isExpanded ? ( + "" + ) : ( + + )} + {isExpanded ? ( + "" + ) : ( + + )} { - return
LangSelect
; +const LangSelect = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { + const [animation, setAnimation] = useState(initialAnimation); + return
onMouseEnter(setAnimation)} + onAnimationEnd={() => onAnimationEnd(setAnimation)}>LangSelect
; }; export default LangSelect; diff --git a/src/components/Mail.jsx b/src/components/Mail.jsx index 90e4dd9..cedddad 100644 --- a/src/components/Mail.jsx +++ b/src/components/Mail.jsx @@ -1,8 +1,18 @@ import React from "react"; import "../css/Mail.css"; +import { useState } from "react"; -const Mail = () => { - return
Mail
; +const Mail = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { + const [animation, setAnimation] = useState(initialAnimation); + return ( +
onMouseEnter(setAnimation)} + onAnimationEnd={() => onAnimationEnd(setAnimation)} + > + Mail +
+ ); }; export default Mail; diff --git a/src/components/Switch.jsx b/src/components/Switch.jsx index 64dde80..3cb78f4 100644 --- a/src/components/Switch.jsx +++ b/src/components/Switch.jsx @@ -1,8 +1,19 @@ import React from "react"; import "../css/Switch.css"; +import { useState } from "react"; +import "animate.css"; -const Switch = () => { - return
Switch
; +const Switch = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { + const [animation, setAnimation] = useState(initialAnimation); + return ( +
onMouseEnter(setAnimation)} + onAnimationEnd={() => onAnimationEnd(setAnimation)} + > + Switch +
+ ); }; export default Switch; diff --git a/src/components/TechStack.jsx b/src/components/TechStack.jsx index d073969..2cee298 100644 --- a/src/components/TechStack.jsx +++ b/src/components/TechStack.jsx @@ -1,4 +1,5 @@ import React, { useState } from "react"; +import clsx from "clsx"; import ReactIcon from "../assets/icons/skill-icons/icons/React-Dark.svg?react"; import NodeIcon from "../assets/icons/skill-icons/icons/NodeJS-Dark.svg?react"; import MongoIcon from "../assets/icons/skill-icons/icons/MongoDB.svg?react"; @@ -7,11 +8,24 @@ import NextJsIcon from "../assets/icons/skill-icons/icons/NextJS-Dark.svg?react" import DockerIcon from "../assets/icons/skill-icons/icons/Docker.svg?react"; import TypeScriptIcon from "../assets/icons/skill-icons/icons/TypeScript.svg?react"; import ExpressIcon from "../assets/icons/skill-icons/icons/ExpressJS-Dark.svg?react"; +import KubernetesIcon from "../assets/icons/skill-icons/icons/Kubernetes.svg?react"; +import GitIcon from "../assets/icons/skill-icons/icons/Git.svg?react"; +import TailwindIcon from "../assets/icons/skill-icons/icons/TailwindCSS-Dark.svg?react"; +import PostgreSQL from "../assets/icons/skill-icons/icons/PostgreSQL-Dark.svg?react"; +import NestjsIcon from "../assets/icons/skill-icons/icons/NestJS-Dark.svg?react"; +import Linux from "../assets/icons/skill-icons/icons/Linux-Dark.svg?react"; + import "../css/TechStack.css"; import { Link } from "react-router-dom"; import "animate.css"; -const TechStack = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { +const TechStack = ({ + initialAnimation, + onMouseEnter, + onAnimationEnd, + isExpanded, + onExpandToggle, // Receive the handler as a prop +}) => { const techStack = [ { name: "React", component: ReactIcon, className: "reactIcon", id: 1 }, { name: "Node.js", component: NodeIcon, className: "nodeIcon", id: 2 }, @@ -36,30 +50,86 @@ const TechStack = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { className: "expressIcon", id: 8, }, + { + name: "Kubernetes", + component: KubernetesIcon, + className: "kubernetesIcon", + id: 9, + needExpand: true, + }, + { + name: "Git", + component: GitIcon, + className: "gitIcon", + id: 10, + needExpand: true, + }, + { + name: "Tailwind CSS", + component: TailwindIcon, + className: "tailwindIcon", + id: 11, + needExpand: true, + }, + { + name: "PostgreSQL", + component: PostgreSQL, + className: "postgresqlIcon", + id: 12, + needExpand: true, + }, + { + name: "NestJS", + component: NestjsIcon, + className: "nestjsIcon", + id: 13, + needExpand: true, + }, + { + name: "Linux", + component: Linux, + className: "linuxIcon", + id: 14, + needExpand: true, + }, ]; - /* Animations */ const [animation, setAnimation] = useState(initialAnimation); return (
onMouseEnter(setAnimation)} onAnimationEnd={() => onAnimationEnd(setAnimation)} >

Tech Stack

- {techStack.map((tech) => { - const IconComponent = tech.component; - return ( -
- -
- ); - })} + {techStack + .filter((tech) => isExpanded || !tech.needExpand) // Filter based on isExpanded + .map((tech) => { + const IconComponent = tech.component; + return ( +
+ +
+ ); + })}
- - Show More + { + e.preventDefault(); // Prevent default link behavior + onExpandToggle(); // Toggle the expanded state + }} + > + {isExpanded ? "Show Less" : "Show More"} {/* Toggle link text */}
); diff --git a/src/components/mainViews/About.jsx b/src/components/mainViews/About.jsx index bea4d72..cd09512 100644 --- a/src/components/mainViews/About.jsx +++ b/src/components/mainViews/About.jsx @@ -1,9 +1,72 @@ -import React from 'react' +import React from "react"; +import Hero from "../Hero"; +import "../../css/Home.css"; +import LangSelect from "../LangSelect"; +import Mail from "../Mail"; +import Switch from "../Switch"; +import Navigation from "../Navigation"; +import LinkedInIcon from "../../assets/icons/socials/linkedin.svg?react"; +import GitHubIcon from "../../assets/icons/socials/square-github.svg?react"; +import Location from "../Location"; +import "animate.css"; +import { useState } from "react"; +import TallContentAbout from "../subComponents/About/TallContentAbout"; +import "../../css/GridContainer.css"; +import Specialties from "../subComponents/About/Specialties"; const About = () => { - return ( -
About
- ) -} + const social = (url) => () => { + window.open(url, "_blank", "noopener,noreferrer"); + }; + const [hoverAnimation, setHoverAnimation] = useState("animate__headShake"); -export default About \ No newline at end of file + const handleMouseEnter = (setAnimation) => { + setAnimation(hoverAnimation); // Trigger hover animation + }; + + const handleAnimationEnd = (setAnimation) => { + setAnimation(""); // Clear animation to prevent re-triggering + }; + return ( +
+ + + + + +
+ +
+
+ +
+ + + +
+ ); +}; + +export default About; diff --git a/src/components/subComponents/About/Specialties.jsx b/src/components/subComponents/About/Specialties.jsx new file mode 100644 index 0000000..a26971a --- /dev/null +++ b/src/components/subComponents/About/Specialties.jsx @@ -0,0 +1,24 @@ +import React from "react"; +import "../../../css/Specialties.css"; +import { useState } from "react"; + +const Specialties = ({ initialAnimation, onMouseEnter, onAnimationEnd }) => { + const [animation, setAnimation] = useState(initialAnimation); + return ( +
onMouseEnter(setAnimation)} + onAnimationEnd={() => onAnimationEnd(setAnimation)} + > +

+ I’m a fullstack developer who loves creating web applications that are + functional and easy to use. My go-to tools are React, Node.js, and + TypeScript, and I enjoy working on both the front-end and back-end. I + focus on clean, practical solutions that work in the real world and + approach every project with curiosity and attention to detail. +

+
+ ); +}; + +export default Specialties; diff --git a/src/components/subComponents/About/TallContentAbout.jsx b/src/components/subComponents/About/TallContentAbout.jsx new file mode 100644 index 0000000..8acd668 --- /dev/null +++ b/src/components/subComponents/About/TallContentAbout.jsx @@ -0,0 +1,71 @@ +import React from "react"; +import { useState } from "react"; +import "../../../css/TallContentAbout.css"; + +const TallContentAbout = ({ + initialAnimation, + onMouseEnter, + onAnimationEnd, +}) => { + const [animation, setAnimation] = useState(initialAnimation); + + return ( +
onMouseEnter(setAnimation)} + onAnimationEnd={() => onAnimationEnd(setAnimation)} + > +
+

Some Fun-Facts about me:

+
    +
  • +

    + 2300+ Chess.com blitz rating and a lifelong love for strategy. +

    +
  • +
  • +

    + Big fan of tycoon simulation games—I could spend hours building + and managing virtual worlds. +

    +
  • +
  • +

    + I love Asian food, especially Japanese cuisine, and enjoy trying + new recipes. +

    +
  • +
  • +

    Football is my passion (and no, I won’t call it soccer).

    +
  • +
  • +

    + I have a guilty pleasure for sitcoms like The Big Bang Theory and + can’t resist a good Taylor Swift track. +

    +
  • + {/*
  • +

    Hiking is one of my favorite ways to relax and recharge.

    +
  • */} +
  • +

    I enjoy baking, especially experimenting with new desserts.

    +
  • +
  • +

    + I’ve been drawing and painting since I was young, and it’s still + one of my favorite creative outlets. +

    +
  • +
+
+ {/*

+ Outside of tech, I enjoy spending time outdoors, baking, and diving into + new hobbies. I like to keep things balanced—challenging my mind with + strategy games or chess and unwinding with great food, music, and some + classic sitcoms. +

*/} +
+ ); +}; + +export default TallContentAbout; diff --git a/src/css/GridContainer.css b/src/css/GridContainer.css new file mode 100644 index 0000000..be2b9e8 --- /dev/null +++ b/src/css/GridContainer.css @@ -0,0 +1,47 @@ +.gridContainer { + display: grid; + grid-template-columns: repeat(11, 1fr); + grid-template-rows: repeat(9, 1fr); + gap: 10px; + width: 50%; + height: 80%; +} + +.container { + background-color: #28272a; + padding: 2rem; + border-radius: 0.5rem; + border: 0.5px solid rgb(73, 73, 73); + box-shadow: 0 0 10px -5px rgba(184, 184, 184, 0.2); +} + +.container:hover { + cursor: pointer; + animation-duration: 0.5s; +} + +.linkedIn { + grid-area: 8 / 5 / 10 / 7; + background-color: #2b6498; + border: 1px solid #0072b1; +} + +.linkedInIcon { + fill: white; +} + +.githubIcon { + fill: white; +} + +.github { + grid-area: 8 / 7 / 10 / 9; + background-color: #373e4c; +} + +.linkedIn, +.github { + display: flex; + justify-content: center; + align-items: center; +} diff --git a/src/css/Home.css b/src/css/Home.css index 34a10a5..89c1b36 100644 --- a/src/css/Home.css +++ b/src/css/Home.css @@ -1,59 +1,5 @@ -.gridContainer { - display: grid; - grid-template-columns: repeat(11, 1fr); - grid-template-rows: repeat(9, 1fr); - gap: 10px; - width: 50%; - height: 80%; -} - -.container { - background-color: #28272a; - padding: 2rem; - border-radius: 0.5rem; - border: 0.5px solid rgb(73, 73, 73); - box-shadow: 0 0 10px -5px rgba(184, 184, 184, 0.2); -} - -.container:hover { - cursor: pointer; - animation-duration: 0.5s; -} - h2 { color: white; } -.linkedIn { - grid-area: 8 / 5 / 10 / 7; - background-color: #001d2c; - border: 1px solid #0072b1; -} - -.linkedInIcon { - fill: #0072b1; -} - -.githubIcon { - fill: black; -} - -.github { - grid-area: 8 / 7 / 10 / 9; - background-color: #333; -} - -.linkedIn, -.github { - display: flex; - justify-content: center; - align-items: center; -} - -.langSelect, -.eMail, -.switch { - animation: zoomIn; - animation-duration: 1s; -} diff --git a/src/css/Navigation.css b/src/css/Navigation.css index 6d95040..5ed5fcf 100644 --- a/src/css/Navigation.css +++ b/src/css/Navigation.css @@ -37,4 +37,6 @@ .navLink.active span { border-bottom: 1px solid white; + font-weight: bold; + transition: font-weight 0.3s ease, border-bottom 0.3s ease; } diff --git a/src/css/Specialties.css b/src/css/Specialties.css new file mode 100644 index 0000000..0477612 --- /dev/null +++ b/src/css/Specialties.css @@ -0,0 +1,9 @@ +.specialties { + grid-area: 4 / 1 / 8 / 5; +} + +.specialtyText { + color: rgb(151, 151, 151); + font-size: 1.2rem; + text-align: justify; +} diff --git a/src/css/TallContentAbout.css b/src/css/TallContentAbout.css new file mode 100644 index 0000000..3e431eb --- /dev/null +++ b/src/css/TallContentAbout.css @@ -0,0 +1,33 @@ +.tallContentAbout { + grid-area: 1 / 5 / 8 / 9; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; +} + +.funFacts { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; + height: 100%; +} + +.funFactList { + /* list-style: none; */ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0.5rem; +} + +.funFactList li p { + color: rgb(151, 151, 151); +} + +.persText { + color: white; + font-size: 1.1rem; +} diff --git a/src/css/TechStack.css b/src/css/TechStack.css index 8a5d306..4a811ef 100644 --- a/src/css/TechStack.css +++ b/src/css/TechStack.css @@ -1,51 +1,66 @@ .techStackContainer { - grid-area: 4 / 1 / 8 / 5; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - animation-duration: 1s; -} - - - -.techStackContainer h2 { - margin-bottom: 10px; - align-self: flex-start; -} - -.techIcon { - width: 4rem; - height: 4rem; - filter: grayscale(0.7); - transition: transform 0.3s ease, filter 0.3s ease; -} - -.techIcon:hover { - filter: none; - animation: tada 1s; - cursor: pointer; -} - -.techStack { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 10px; - margin-bottom: 1rem; -} - -.techStackShowMore { - font-size: 1.2rem; - color: rgb(151, 151, 151); - text-decoration: none; - border-bottom: 1px solid rgb(151, 151, 151); - /* align-self: flex-start; */ -} - -@keyframes techIconHover { - 10% { - transform: scale(); + grid-area: 4 / 1 / 8 / 5; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + animation-duration: 1s; } -} + + .techStackContainer.expanded { + grid-area: 4 / 1 / 10 / 5; + min-width: 356.43px; + } + + .techStackContainer h2 { + margin-bottom: 10px; + align-self: flex-start; + } + + .techIcon { + width: 4rem; + height: 4rem; + filter: grayscale(0.7); + transition: transform 0.3s ease, filter 0.3s ease; + } + + .techIcon:hover { + filter: none; + animation: tada 1s; + cursor: pointer; + } + + .techStack { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: 10px; + margin-bottom: 1rem; + } + + .techStackShowMore { + font-size: 1.2rem; + color: rgb(151, 151, 151); + text-decoration: none; + border-bottom: 1px solid rgb(151, 151, 151); + /* align-self: flex-start; */ + } + + @keyframes techIconHover { + 10% { + transform: scale(); + } + } + + /* Smooth expand/collapse animations */ + .techStackContainer { + max-height: 320px; /* Initial max-height */ + overflow: hidden; + transition: max-height 1s ease-in-out; + } + + .techStackContainer.expanded { + max-height: 600px; /* Expanded max-height */ + } + \ No newline at end of file