Add files via upload

This commit is contained in:
Hazem Krimi
2020-06-29 00:46:17 +01:00
committed by GitHub
parent 32b078b98d
commit 58db162ac8
26 changed files with 15689 additions and 0 deletions
+14683
View File
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
{
"name": "hamdi-halleb",
"version": "0.1.0",
"private": true,
"dependencies": {
"node-sass": "^4.13.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-scripts": "3.3.0",
"react-spring": "^8.0.27"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
+18
View File
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Personal Portfolio of Hamdi Halleb"
/>
<title>Hamdi Halleb</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+30
View File
@@ -0,0 +1,30 @@
import React, { lazy, Suspense } from 'react';
import Loading from './components/loading/Loading';
import './App.scss';
const Nav = lazy(() => import("./components/nav/Nav"));
const Welcome = lazy(() => import("./components/welcome/Welcome"));
const Background = lazy(() => import("./components/background/Background"));
const About = lazy(() => import("./components/about/About"));
const AboutText = lazy(() => import("./components/about/AboutText"));
const Portrait = lazy(() => import("./components/portrait/Portrait"));
const SkillsText = lazy(() => import("./components/skills/SkillsText"));
const Skills = lazy(() => import("./components/skills/Skills"));
const App = () => {
return (
<Suspense fallback={<Loading />}>
<Nav />
<Background>
<Portrait />
<AboutText />
<Skills />
</Background>
<Welcome />
<About />
<SkillsText />
</Suspense>
);
}
export default App;
+13
View File
@@ -0,0 +1,13 @@
@import url('https://fonts.googleapis.com/css?family=Montserrat|Work+Sans&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
font-family: Montserrat;
overflow: hidden;
}
+35
View File
@@ -0,0 +1,35 @@
import React, { useContext } from 'react';
import './About.scss';
import { useTransition, animated } from 'react-spring';
import { MainContext } from '../../contexts/MainContext';
const About = () => {
const { current, previous } = useContext(MainContext);
const about = current === "about";
const transition = useTransition(about, null, {
from: { transform: previous === "welcome" ? "translateX(-300%) translateY(0%)" : "translateX(0%) translateY(-300%)", opacity: 0 },
enter: { transform: "translateX(0%) translateY(0%)", opacity: 1 },
leave: { transform: current === "welcome" ? "translateX(-300%) translateY(0%)" : "translateX(0%) translateY(-300%)", opacity: 0 }
});
return (
<>
{
transition.map(({ item, key, props }) =>
item &&
<animated.div key={key} id="about" style={props}>
<div className="container">
<h1>
ABOUT MYSELF
<span></span>
</h1>
</div>
</animated.div>
)
}
</>
);
}
export default About;
+28
View File
@@ -0,0 +1,28 @@
@import '../../App.scss';
#about {
height: 100vh;
width: 90vw;
position: absolute;
top: 35%;
left: 12.5%;
.container {
margin-top: 5%;
h1 {
display: inline-block;
font-weight: 600;
font-size: 3rem;
span {
position: relative;
left: -50%;
border: 3px solid #D8B269;
box-sizing: content-box;
padding: 3px 100px 3px 135px;
margin-left: 3%;
}
}
}
}
+37
View File
@@ -0,0 +1,37 @@
import React, { useContext } from 'react';
import { MainContext } from '../../contexts/MainContext';
import { useTransition, animated } from 'react-spring';
import './AboutText.scss';
const AboutText = () => {
const { current, previous } = useContext(MainContext);
const aboutText = current === "about";
const transition = useTransition(aboutText, null, {
from: { transform: previous === "welcome" ? "translateX(300%) translateY(0%)" : "translateX(0%) translateY(-200%)", opacity: 0 },
enter: { transform: "translateX(0%) translateY(0%)", opacity: 1 },
leave: { transform: current === "welcome" ? "translateX(300%) translateY(0%)" : "translateX(0%) translateY(-200%)", opacity: 0 }
});
return (
<>
{
transition.map(({ item, key, props }) => (
item &&
<animated.p id="about-text" key={key} style={props}>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et.
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
At vero eos et accusam et.
</animated.p>
))
}
</>
);
}
export default AboutText;
+10
View File
@@ -0,0 +1,10 @@
@import '../../App.scss';
#about-text {
position: absolute;
top: 0%;
left: 0%;
color: #D8B269;
margin: 10% 20%;
line-height: 1.5;
}
+27
View File
@@ -0,0 +1,27 @@
import React from 'react';
import { useSpring, animated } from 'react-spring';
import './Background.scss';
const Background = ({ children }) => {
const blackSpring = useSpring({
from: {
transform: "translateX(200%)",
opacity: 0
},
to: {
transform: "translateX(0%)",
opacity: 1
},
config: {
velocity: 10
}
});
return (
<animated.div id="background" style={blackSpring}>
{children}
</animated.div>
);
}
export default Background;
+10
View File
@@ -0,0 +1,10 @@
@import '../../App.scss';
#background {
height: 100vh;
width: 50%;
position: absolute;
top: 0%;
left: 50%;
background: #050A0D;
}
+34
View File
@@ -0,0 +1,34 @@
import React from 'react';
import { useSpring, animated, config } from 'react-spring';
const Loading = () => {
const spring = useSpring({
from: {
x: 0
},
to: async next => {
while (1) {
await next({ x: 900 });
await next({ x: 0 });
}
},
config: config.slow,
duration: 1000
});
return (
<div style={{ height: "100vh" }}>
<animated.svg width="3rem" height="3rem" viewBox="0 0 110.692 98.157" strokeDashoffset={spring.x} style={{ position: "relative", top: "40%", left: "50%" }}>
<path
d="M80.402 75.676l.116-29L80.705 0l27.1 46.693-27.1 46.7H26.512L26.904 0 0 46.668l79.873.025"
fill="none"
stroke="#050b0d"
strokeMiterlimit={10}
strokeWidth={2}
strokeDasharray={900}
/>
</animated.svg>
</div>
);
}
export default Loading;
+60
View File
@@ -0,0 +1,60 @@
import React, { useContext } from 'react';
import { useTransition, animated } from 'react-spring';
import { MainContext } from '../../contexts/MainContext';
const Logo = () => {
const { current } = useContext(MainContext);
const welcome = current === "welcome";
const transition = useTransition(welcome, null, {
initial: {
top: "40%",
left: "50%",
width: "3rem",
height: "3rem"
},
from: {
top: "-100%",
left: "11.5%",
width: "3rem",
height: "3rem",
opacity: 0
},
enter: {
top: "15%",
left: "11.5%",
width: "2.5rem",
height: "2.5rem",
opacity: 1
},
leave: {
top: "-40%",
left: "12%",
width: "2.5rem",
height: "2.5rem",
opacity: 0
}
});
return (
<>
{
transition.map(({ item, key, props }) => (
item &&
<animated.svg key={key} width={props.width} height={props.height} viewBox="0 0 110.692 98.157" style={{ position: "absolute", ...props }}>
<path
d="M80.402 75.676l.116-29L80.705 0l27.1 46.693-27.1 46.7H26.512L26.904 0 0 46.668l79.873.025"
fill="none"
stroke="#050b0d"
strokeMiterlimit={10}
strokeWidth={2}
strokeDasharray={900}
/>
</animated.svg>
))
}
</>
);
}
export default Logo;
+128
View File
@@ -0,0 +1,128 @@
import React, { useContext } from 'react';
import { useSpring, animated } from 'react-spring';
import './Nav.scss';
import { MainContext } from '../../contexts/MainContext';
const Polygon = ({ location, current }) => (
<svg id="nav-polygon" width="3rem" height="3rem" viewBox="0 0 90 78">
<g fill="none">
<path d="M67.5 0L90 39 67.5 78h-45L0 39 22.5 0z" />
<text
transform="translate(36 50)"
fill="#d8b269"
fontSize={35}
fontFamily="Montserrat"
fontWeight={300}
>
<tspan x={0} y={0} style={{ userSelect: "none" }}>
{location.findIndex(route => route === current) + 1}
</tspan>
</text>
<path
d="M23.655 2L2.31 39l21.346 37h42.69L87.69 39 66.345 2h-42.69M22.5 0h45L90 39 67.5 78h-45L0 39 22.5 0z"
fill="#d8b269"
/>
</g>
</svg>
)
const Menu = ({ location, current }) => (
<div id="nav-menu">
{
location.map(route => (
<svg key={route} width="1rem" height="1rem" viewBox="0 0 18.975 1.617">
<path fill={route === current ? "#d8b269" : "#b8bcbe"} d="M0 0h18.975v1.617H0z" />
</svg>
))
}
</div>
)
const UpArrow = ({ location, current, previousLocation }) => (
<svg width="1.5rem" height="1.5rem" viewBox="0 0 47.414 25.414" onClick={() => previousLocation()}>
<defs>
<clipPath id="clip-path">
<path fill="none" d="M0 0h25.414v47.414H0z" />
</clipPath>
<style>
{`.nav-arrow-up{fill:none;stroke:${location.findIndex(route => route === current) > 0 ? "#d8b269" : "#b8bcbe"};stroke-width:4px}`}
</style>
</defs>
<g
transform="rotate(-90 12.707 12.707)"
clipPath="url(#clip-path)"
>
<path
className="nav-arrow-up"
transform="translate(.707 .707)"
d="M0 0l23 25"
/>
<path
className="nav-arrow-up"
transform="translate(1.707 23.707)"
d="M0 23L21 0"
/>
</g>
</svg>
)
const DownArrow = ({ location, current, nextLocation }) => (
<svg width="1.5rem" height="1.5rem" viewBox="0 0 47.414 25.414" onClick={() => nextLocation()}>
<defs>
<clipPath id="clip-path">
<path fill="none" d="M0 0h25.414v47.414H0z" />
</clipPath>
<style>
{`.nav-arrow-down{fill:none;stroke:${location.findIndex(route => route === current) < location.length - 1 ? "#d8b269" : "#b8bcbe"};stroke-width:4px}`}
</style>
</defs>
<g
transform="rotate(90 23.707 23.707)"
clipPath="url(#clip-path)"
>
<path
id="nav-arrow-down_svg__Line_2"
className="nav-arrow-down"
transform="translate(.707 .707)"
d="M0 0l23 25"
/>
<path
id="nav-arrow-down_svg__Line_3"
className="nav-arrow-down"
transform="translate(1.707 23.707)"
d="M0 23L21 0"
/>
</g>
</svg>
)
const Nav = () => {
const { location, current, nextLocation, previousLocation } = useContext(MainContext);
const spring = useSpring({
from: {
transform: "translateY(100%)"
},
to: {
transform: "translateY(0%)"
},
duration: 5000,
delay: 250
});
return (
<animated.nav style={{ transform: spring.transform }}>
<div id="nav-label">
<Polygon current={current} location={location}/>
<Menu current={current} location={location}/>
<h2>{current}</h2>
</div>
<div id="nav-arrows">
<UpArrow current={current} location={location} previousLocation={previousLocation}/>
<DownArrow current={current} location={location} nextLocation={nextLocation}/>
</div>
</animated.nav>
);
}
export default Nav;
+58
View File
@@ -0,0 +1,58 @@
@import '../../App.scss';
nav {
height: 100vh;
width: 10vw;
padding: 1rem 0rem;
position: fixed;
z-index: 3;
top: 0%;
left: 0%;
display: grid;
grid-template-rows: 1fr auto;
grid-row-gap: .5rem;
justify-items: center;
align-items: center;
#nav-label {
margin-top: 6rem;
align-self: center;
display: grid;
grid-template-columns: 1fr;
grid-row-gap: .5rem;
justify-items: center;
align-items: center;
#nav-menu {
display: grid;
grid-template-columns: 1fr;
justify-items: center;
align-items: center;
}
#nav-polygon {
align-self: flex-end;
}
h2 {
margin-top: 3rem;
font-weight: 200;
color: #B8BCBE;
transform: rotate(270deg);
text-transform: capitalize;
}
}
#nav-arrows {
align-self: flex-end;
display: grid;
grid-template-columns: 1fr;
justify-items: center;
align-items: center;
grid-row-gap: .5rem;
* {
cursor: pointer;
}
}
}
+133
View File
@@ -0,0 +1,133 @@
import React, { useContext } from 'react';
import { useTransition, animated } from 'react-spring';
import { MainContext } from '../../contexts/MainContext';
import './Portrait.scss'
const Portrait = () => {
const { current } = useContext(MainContext);
const welcome = current === "welcome";
const transition = useTransition(welcome, null, {
initial: null,
from: { transform: "translateY(-200%)", opacity: 0 },
enter: { transform: "translateY(0%)", opacity: 1 },
leave: { transform: "translateY(-200%)", opacity: 0 }
});
return (
<>
{
transition.map(({ item, key, props }) => (
item &&
<animated.svg id="portrait" key={key} width="30rem" height="30rem" viewBox="0 0 660 720.128" style={props}>
<defs>
<style>
{
".cls-1{fill:#d8b269}.cls-2{fill:#bf9563}.cls-3,.cls-4,.cls-6,.cls-8{fill:none}.cls-3,.cls-4{stroke:#bf9563;stroke-width:4px;stroke-miterlimit:10}.cls-4{stroke:#050a0d;stroke-width:9px}.cls-5{fill:#050a0d}.cls-6{stroke:#d8b269;stroke-width:5px}.cls-7{stroke:none}"
}
</style>
</defs>
<g
transform="translate(-1110 -210)"
>
<g transform="translate(1148.151 220.998)">
<g>
<g>
<path
className="cls-1"
d="M248.5 383.209l-102.545-26.342-46.1-140.178 1.581-8.919-55.449-25.89L14 190.347v70.559l49.862 34.809 19.757 3.763 23.52 87.493-12.23 62.092 207.915 99.724 31.986-21.637 13.171-83.73 4.5-51.329-14.6 7.112z"
transform="translate(12.342 160.342)"
/>
<path
className="cls-1"
d="M96.758 336.558l58.329 21.642-23.52 11.289 64.915 15.993 47.04-48.921 65.385-25.4 12.7 17.4 12.23-16.464 43.032 51.838 2.822-83.824-14.112-33.868 7.526-57.369-40.454-52.684-17.874-51.745-96.431-31.065L57 126.78 91.809 171 57 239.657l7.15 77.843L57 239.657z"
transform="translate(50.25 47.059)"
/>
<path
className="cls-1"
d="M166.14 234.511l50.8-24.461 14.112 5.645 12.23-5.645 27.283 24.461-39.513 7.526z"
transform="translate(146.466 185.176)"
/>
<path
className="cls-2"
d="M166.14 234.591l50.539-13.171 14.827 4.553 11.76-6.19 27.3 14.808-27.3-24.461-12.23 5.889-13.7-5.889z" transform="translate(146.466 185.247)"
/>
<path
className="cls-3"
d="M197.4 245.165l23.427-38.886-42.711-68.847L198.889 115l42.986 11.722"
transform="translate(172.405 96.382)"
/>
<path
className="cls-4"
d="M206.418 241.288l21.638-35.75-43.276-69.618 21.638-23.52 58.329 16.934"
transform="translate(157.899 97.09)"
/>
<path
className="cls-5"
d="M20.7 353.737L0 220.145 47.04 86.553l86.553-72.441L249.309 0l148.645 69.618-14.582 95.961-12.7-38.572-106.31-35.75-174.046 85.612 40.454 47.98-31.987 64.444 6.586 64.444-48.922-15.993z"
/>
<path
className="cls-4"
d="M134.928 135.364l56.9-18.974 58.329 23.5"
transform="translate(82.951 86.331)"
/>
<path
className="cls-3"
d="M129.531 129.089L184.2 110.7l56.568 22.851"
transform="translate(90.144 98.35)"
/>
<path
className="cls-5"
d="M56.142 194.062L60 200.279l83.976-61.625 26.26 61.625 91.735-14.5 8.4-48.674 14.706-4.714-3.935-7.012h28.943l-3.062 7.012 34.9 53.388 66.166 22.972v-81.36l-56.447-8-41.558 5.984h-28.94l-14.272 4.025-16.106-10.01-104.69 4.056-4.228 8.941z"
transform="translate(52.895 105.252)"
/>
<path
className="cls-2"
d="M76.113 250.562l29.616 90 205.581 45.963-1.994 22.711-36.992-2.822L99.218 371.3 59.63 200.38z"
transform="translate(52.569 176.651)"
/>
<path
className="cls-2"
d="M76.738 209.637L42.249 189.88l-22.579 9.878v44.067l11.91 8.618-3.763-42.806 15.053-7.207 38.892 21.318z"
transform="translate(17.341 167.395)"
/>
</g>
</g>
</g>
<g
className="cls-6"
>
<path
className="cls-7"
d="M0 0h600v600H0z"
transform="translate(1110 210)"
/>
<path
className="cls-8"
d="M2.5 2.5h595v595H2.5z"
transform="translate(1110 210)"
/>
</g>
<g
className="cls-6"
>
<path
className="cls-7"
d="M0 0h600v600H0z"
transform="translate(1170 276)"
/>
<path
className="cls-8"
d="M2.5 2.5h595v595H2.5z"
transform="translate(1170 276)"
/>
</g>
</g>
</animated.svg>
))
}
</>
);
}
export default Portrait;
+7
View File
@@ -0,0 +1,7 @@
@import '../../App.scss';
#portrait {
position: absolute;
top: 15%;
left: 15%;
}
+120
View File
@@ -0,0 +1,120 @@
import React, { useState, useContext } from 'react';
import { useSpring, useTransition, animated } from 'react-spring';
import { MainContext } from '../../contexts/MainContext';
import './Skills.scss';
const Stat = () => {
const spring = useSpring({
from: { left: "5%", width: "100%" },
to: { left: "100%", width: "0%" },
delay: 700
});
return (
<div id="stat">
<svg width="400px" height="40px" viewBox="0 0 657 30" style={{ position: "relative", zIndex: 2 }}>
<g clipPath="url(#clip)">
<path
d="M630.75 30l-5.25-9h-98l-5.25 9h-17.5l-5.25-9h-96l-5.25 9h-17.5l-5.25-9h-96l-5.25 9h-17.5l-5.25-9h-96l-5.25 9h-17.5l-5.25-9h-96l-5.25 9H8.75L0 15 8.75 0h17.5l4.667 8h97.167l4.667-8h17.5l4.667 8h97.167l4.667-8h17.5l4.667 8h97.167l4.667-8h17.5l4.667 8h97.167l4.667-8h17.5l4.667 8h99.167l4.667-8h17.5l8.75 15-8.75 15z"
fill="#d8b269"
/>
</g>
</svg>
<animated.div
style={{
position: "relative",
transform: "translateY(-108%)",
left: spring.left,
width: spring.width,
height: "40px",
backgroundColor: "#050a0d",
zIndex: 3
}}
></animated.div>
</div>
);
}
const Skills = () => {
const { current, previous } = useContext(MainContext);
const skill = current === "skills";
const mainTransition = useTransition(skill, null, {
from: { transform: previous === "about" ? "translateX(300%) translateY(0%)" : "translateX(0%) translateY(-200%)", opacity: 0 },
enter: { transform: "translateX(0%) translateY(0%)", opacity: 1 },
leave: { transform: current === "about" ? "translateX(300%) translateY(0%)" : "translateX(0%) translateY(-200%)", opacity: 0 }
});
const [skills] = useState([
{
id: 1,
name: "Graphic Design",
tools: [
{ name: "Adobe Xd", id: 1 },
{ name: "Adobe Xd", id: 2 },
{ name: "Adobe Xd", id: 3 }
],
show: true
},
{
id: 2,
name: "Photography",
tools: [
{ name: "Adobe Xd", id: 1 },
{ name: "Adobe Xd", id: 2 },
{ name: "Adobe Xd", id: 3 }
],
show: false
},
{
id: 3,
name: "Web and Mobile Development",
tools: [
{ name: "Adobe Xd", id: 1 },
{ name: "Adobe Xd", id: 2 },
{ name: "Adobe Xd", id: 3 }
],
show: false
},
]);
const skillTransition = useTransition(skills, skill => skill.id, {
from: { opacity: 0 },
enter: { opacity: 1 },
leave: { opacity: 0 }
});
return (
<>
{
mainTransition.map(({ item, key, props }) =>
item &&
<animated.div id="skills" key={key} style={props}>
{skillTransition.map(({ item: { show, name, tools }, key, props }) => (
item && show &&
<animated.div style={props} key={key}>
<h2 style={{ display: "inline", color: "#f2f2f2", marginBottom: "20px" }}>
{name}
</h2>
<div id="skill-stats">
{
tools.map(({ name, id }) =>
<div key={id}>
<h4 style={{ color: "#f2f2f2", margin: "10px 0px" }}>
{name}
</h4>
<Stat />
</div>
)
}
</div>
</animated.div>
))}
</animated.div>
)
}
</>
);
}
export default Skills;
+22
View File
@@ -0,0 +1,22 @@
@import '../../App.scss';
#skills {
position: absolute;
top: 0%;
left: 0%;
margin: 10% 20%;
h2 {
font-size: 40px;
font-weight: normal;
}
#skill-stats {
margin-top: 70px;
h4 {
font-size: 20px;
font-weight: normal;
}
}
}
+35
View File
@@ -0,0 +1,35 @@
import React, { useContext } from 'react';
import { useTransition, animated } from 'react-spring';
import './SkillsText.scss';
import { MainContext } from '../../contexts/MainContext';
const SkillsText = () => {
const { current, previous } = useContext(MainContext);
const skillsText = current === "skills";
const transition = useTransition(skillsText, null, {
from: { transform: previous === "about" ? "translateX(-300%) translateY(0%)" : "translateX(0%) translateY(-300%)", opacity: 0 },
enter: { transform: "translateX(0%) translateY(0%)", opacity: 1 },
leave: { transform: current === "about" ? "translateX(-300%) translateY(0%)" : "translateX(0%) translateY(-300%)", opacity: 0 }
});
return (
<>
{
transition.map(({ item, key, props }) =>
item &&
<animated.div key={key} id="skills-text" style={props}>
<div className="container">
<h1>
WHAT
<span>CAN I DO</span>
</h1>
</div>
</animated.div>
)
}
</>
);
}
export default SkillsText;
+26
View File
@@ -0,0 +1,26 @@
@import '../../App.scss';
#skills-text {
height: 100vh;
width: 90vw;
position: absolute;
top: 35%;
left: 12.5%;
.container {
margin-top: 5%;
h1 {
display: inline-block;
font-weight: 600;
font-size: 3rem;
span {
border: 3px solid #D8B269;
box-sizing: content-box;
padding: 2px;
margin-left: 5px;
}
}
}
}
+43
View File
@@ -0,0 +1,43 @@
import React, { useContext } from 'react';
import Logo from '../logo/Logo';
import { useTransition, animated } from 'react-spring';
import './Welcome.scss';
import { MainContext } from '../../contexts/MainContext';
const Welcome = () => {
const { current } = useContext(MainContext);
const welcome = current === 'welcome';
const transition = useTransition(welcome, null, {
initial: {
transform: "translateX(-300%) translateY(0%)",
opacity: 1
},
from: { transform: "translateX(0%) translateY(-300%)", opacity: 0 },
enter: { transform: "translateX(0%) translateY(0%)", opacity: 1 },
leave: { transform: "translateX(0%) translateY(-300%)", opacity: 1 }
});
return (
<>
<Logo />
{
transition.map(({ item, key, props }) =>
item &&
<animated.div key={key} id="welcome" style={props}>
<div className="container">
<h3>Welcome</h3>
<div id="description">
<h4>My name is</h4>
<h1>HAMDI <span>HALLEB</span></h1>
<h3>Graphic Designer-Photographer-Developer</h3>
</div>
</div>
</animated.div>
)
}
</>
);
}
export default Welcome;
+47
View File
@@ -0,0 +1,47 @@
@import '../../App.scss';
#welcome {
height: 100vh;
width: 90vw;
.container {
position: absolute;
top: 35%;
left: 12.5%;
display: grid;
grid-template-columns: 1fr;
grid-row-gap: 3rem;
h3 {
font-weight: 200;
color: #D8B269;
}
#description {
display: grid;
grid-row-gap: .5rem;
align-items: center;
justify-items: flex-start;
h4 {
font-weight: 200;
color: #B8BCBE;
}
h1 {
font-weight: 600;
font-size: 3rem;
span {
border: 3px solid #D8B269;
box-sizing: content-box;
padding: 3px 30px 0px 1px;
}
}
h3 {
font-family: "Work Sans", Montserrat;
}
}
}
}
+42
View File
@@ -0,0 +1,42 @@
import React, { createContext, useState } from 'react';
export const MainContext = createContext();
const MainContextProvider = ({ children }) => {
const location = [
'welcome',
'about',
'skills',
'wins',
'work',
'portfolio',
'blog',
'contact'
];
const [previous, setPrevious] = useState('');
const [current, setCurrent] = useState('welcome');
const nextLocation = () => {
let index = location.findIndex(route => route === current);
if (index < location.length - 1) {
setPrevious(current);
setCurrent(location[index + 1]);
}
};
const previousLocation = () => {
let index = location.findIndex(route => route === current);
if (index > 0) {
setPrevious(current);
setCurrent(location[index - 1]);
}
};
return (
<MainContext.Provider value={{ location, current, previous, nextLocation, previousLocation }}>
{children}
</MainContext.Provider>
);
}
export default MainContextProvider;
+10
View File
@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import MainContextProvider from './contexts/MainContext';
import App from './App';
ReactDOM.render(
<MainContextProvider>
<App />
</MainContextProvider>,
document.getElementById('root'));