From fc0c323278a56bf9f02f5ec24060b2fe8b1bf546 Mon Sep 17 00:00:00 2001 From: Modupe Akanni Date: Sat, 7 Jan 2023 15:05:55 +0100 Subject: [PATCH] next-app --- components/Acomplishments/Acomplishments.js | 27 + .../Acomplishments/AcomplishmentsStyles.js | 134 +++ .../BackgroundAnimation.js | 365 ++++++++ components/Footer/Footer.js | 40 + components/Footer/FooterStyles.js | 159 ++++ components/Header/Header.js | 48 + components/Header/HeaderStyles.js | 129 +++ components/Hero/Hero.js | 22 + components/Hero/HeroStyles.js | 19 + components/NavDropDown/NavDropDown.js | 76 ++ components/NavDropDown/index.js | 13 + components/Projects/Projects.js | 38 + components/Projects/ProjectsStyles.js | 112 +++ components/Technologies/Technologies.js | 50 ++ components/Technologies/TechnologiesStyles.js | 133 +++ components/TimeLine/TimeLine.js | 117 +++ components/TimeLine/TimeLineStyles.js | 154 ++++ constants/constants.js | 46 + layout/Layout.js | 15 + layout/LayoutStyles.js | 7 + package-lock.json | 825 +++++++++++++++++- package.json | 5 +- pages/_app.js | 11 +- pages/_document.js | 54 +- pages/api/hello.js | 4 +- pages/index.js | 143 +-- public/favicon.ico | Bin 25931 -> 15086 bytes public/images/1.png | Bin 0 -> 168810 bytes public/images/2.png | Bin 0 -> 145557 bytes public/images/3.jpg | Bin 0 -> 61243 bytes public/images/4.jpg | Bin 0 -> 61166 bytes public/images/Screenshot (88).png | Bin 0 -> 681952 bytes public/images/Screenshot (89).png | Bin 0 -> 1054855 bytes public/images/Screenshot (90).png | Bin 0 -> 1125983 bytes public/images/Screenshot (91).png | Bin 0 -> 2210313 bytes public/images/profile.jpeg | Bin 0 -> 70198 bytes public/images/projects.jpeg | Bin 0 -> 584127 bytes public/next.svg | 1 - public/thirteen.svg | 1 - public/vercel.svg | 5 +- styles/GlobalComponents/Button.js | 11 + styles/GlobalComponents/index.js | 281 ++++++ styles/Home.module.css | 278 ------ styles/globals.css | 107 --- styles/globals.js | 37 + styles/theme.js | 13 + themes/default.js | 22 + 47 files changed, 2977 insertions(+), 525 deletions(-) create mode 100644 components/Acomplishments/Acomplishments.js create mode 100644 components/Acomplishments/AcomplishmentsStyles.js create mode 100644 components/BackgrooundAnimation/BackgroundAnimation.js create mode 100644 components/Footer/Footer.js create mode 100644 components/Footer/FooterStyles.js create mode 100644 components/Header/Header.js create mode 100644 components/Header/HeaderStyles.js create mode 100644 components/Hero/Hero.js create mode 100644 components/Hero/HeroStyles.js create mode 100644 components/NavDropDown/NavDropDown.js create mode 100644 components/NavDropDown/index.js create mode 100644 components/Projects/Projects.js create mode 100644 components/Projects/ProjectsStyles.js create mode 100644 components/Technologies/Technologies.js create mode 100644 components/Technologies/TechnologiesStyles.js create mode 100644 components/TimeLine/TimeLine.js create mode 100644 components/TimeLine/TimeLineStyles.js create mode 100644 constants/constants.js create mode 100644 layout/Layout.js create mode 100644 layout/LayoutStyles.js create mode 100644 public/images/1.png create mode 100644 public/images/2.png create mode 100644 public/images/3.jpg create mode 100644 public/images/4.jpg create mode 100644 public/images/Screenshot (88).png create mode 100644 public/images/Screenshot (89).png create mode 100644 public/images/Screenshot (90).png create mode 100644 public/images/Screenshot (91).png create mode 100644 public/images/profile.jpeg create mode 100644 public/images/projects.jpeg delete mode 100644 public/next.svg delete mode 100644 public/thirteen.svg create mode 100644 styles/GlobalComponents/Button.js create mode 100644 styles/GlobalComponents/index.js delete mode 100644 styles/Home.module.css delete mode 100644 styles/globals.css create mode 100644 styles/globals.js create mode 100644 styles/theme.js create mode 100644 themes/default.js diff --git a/components/Acomplishments/Acomplishments.js b/components/Acomplishments/Acomplishments.js new file mode 100644 index 0000000..1d8f437 --- /dev/null +++ b/components/Acomplishments/Acomplishments.js @@ -0,0 +1,27 @@ +import React from 'react'; + +import { Section, SectionDivider, SectionTitle } from '../../styles/GlobalComponents'; +import { Box, Boxes, BoxNum, BoxText } from './AcomplishmentsStyles'; + +const data = [ + { number: 20, text: 'Open Source Projects'}, + { number: 1000, text: 'Students', }, + { number: 1900, text: 'Github Followers', }, + { number: 5000, text: 'Github Stars', } +]; + +const Acomplishments = () => ( +
+ Personal Accomplishments + + {data.map((card, index) => ( + + {card.number}+ + {card.text} + + ))} + +
+); + +export default Acomplishments; diff --git a/components/Acomplishments/AcomplishmentsStyles.js b/components/Acomplishments/AcomplishmentsStyles.js new file mode 100644 index 0000000..95daa29 --- /dev/null +++ b/components/Acomplishments/AcomplishmentsStyles.js @@ -0,0 +1,134 @@ +import styled from "styled-components" + +export const Boxes = styled.div` + width: 100%; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 24px; + margin: 24px 0 40px; + + @media ${props => props.theme.breakpoints.md}{ + gap: 16px; + margin: 20px 0 32px; + grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); + } + + @media ${props => props.theme.breakpoints.sm}{ + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px; + max-width: 500px; + margin: 24px auto; + } +` + +export const Box = styled.div` + background: #212D45; + border-radius: 12px; + height: 144px; + padding: 24px; + @media ${props => props.theme.breakpoints.lg} { + height: 210px; + + } + + @media ${props => props.theme.breakpoints.md} { + height: 135px; + padding: 16px; + } + + @media ${props => props.theme.breakpoints.sm} { + height: 110px; + padding: 12px; + + &:nth-child(2n){ + grid-row:2; + } + } +` +export const BoxNum = styled.h5` + font-style: normal; + font-weight: 600; + font-size: 36px; + line-height: 40px; + letter-spacing: 0.01em; + color: #FFFFFF; + margin-bottom: 8px; + + @media ${props => props.theme.breakpoints.md} { + font-size: 28px; + line-height: 32px; + } + @media ${props => props.theme.breakpoints.sm} { + font-size: 24px; + line-height: 26px; +} +` + +export const BoxText = styled.p` + font-style: normal; + font-weight: normal; + font-size: 18px; + line-height: 24px; + letter-spacing: 0.02em; + color: rgba(255, 255, 255, 0.75); + + @media ${props => props.theme.breakpoints.md}{ + font-size: 16px; + line-height: 20px; + }; + + @media ${props => props.theme.breakpoints.sm} { + font-size: 10px; + line-height: 14px; + } +` + +export const Join = styled.div` + display: flex; + max-width: 1040px; + justify-content: center; + align-items: center; + padding-bottom: 80px; + + @media ${props => props.theme.breakpoints.md}{ + display: flex; + justify-content: center; + padding-bottom: 64px; + } + + @media ${props => props.theme.breakpoints.sm}{ + display: flex; + flex-direction: column; + align-items: center; + padding-bottom: 32px; + } +` + +export const JoinText = styled.h5` + display: flex; + font-size: 24px; + line-height: 40px; + letter-spacing: 0.02em; + color: rgba(255, 255, 255, 0.5); + +@media ${props => props.theme.breakpoints.md}{ + line-height: 32px; + font-size: 20px; +}; + +@media ${props => props.theme.breakpoints.sm}{ + font-size: 16px; + line-height: 24px; + margin: 0 0 16px; +} +` + +export const IconContainer = styled.div` + display: flex; + + @media ${props => props.theme.breakpoints.sm}{ + width: 160px; + justify-content: space-between; + } +` diff --git a/components/BackgrooundAnimation/BackgroundAnimation.js b/components/BackgrooundAnimation/BackgroundAnimation.js new file mode 100644 index 0000000..1dd2e12 --- /dev/null +++ b/components/BackgrooundAnimation/BackgroundAnimation.js @@ -0,0 +1,365 @@ +import React from 'react'; + +const BackgroundAnimation = () => ( +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+); + +export default BackgroundAnimation; \ No newline at end of file diff --git a/components/Footer/Footer.js b/components/Footer/Footer.js new file mode 100644 index 0000000..05d4f63 --- /dev/null +++ b/components/Footer/Footer.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { AiFillGithub, AiFillInstagram, AiFillLinkedin } from 'react-icons/ai'; + +import { SocialIcons } from '../Header/HeaderStyles'; +import { CompanyContainer, FooterWrapper, LinkColumn, LinkItem, LinkList, LinkTitle, Slogan, SocialContainer, SocialIconsContainer } from './FooterStyles'; + +const Footer = () => { + return ( + + + + Call + +234-8117266403 + + + Mail + modupe775@gmail.com + + + + + Solving Problems one code at a time + + + + + + + + + + + + + + + ); +}; + +export default Footer; diff --git a/components/Footer/FooterStyles.js b/components/Footer/FooterStyles.js new file mode 100644 index 0000000..63b4f5d --- /dev/null +++ b/components/Footer/FooterStyles.js @@ -0,0 +1,159 @@ +import styled from "styled-components" + +export const FooterWrapper = styled.section` + width: calc(100vw - 96px); + max-width: 1040px; + padding: 2rem 48px 40px; + margin: 1rem auto; + box-sizing: content-box; + + + @media ${props => props.theme.breakpoints.sm} { + padding: 0 16px 48px; + width: calc(100vw - 32px); + } +` + +export const LinkItem = styled.a` + font-size: 18px; + line-height: 30px; + color: rgba(255, 255, 255, 0.75); + margin-bottom: 16px; + transition: .3s ease; + position: relative; + left: 0; + + &:hover { + color: #fff; + left: 6px; + } + + @media ${props => props.theme.breakpoints.md} { + font-size: 16px; + line-height: 28px; + display: flex; + } + + @media ${props => props.theme.breakpoints.sm} { + font-size: 8px; + line-height: 14px; + margin-bottom: 8px; + display: flex; + align-items: center; + } +` + +export const SocialIconsContainer = styled.div` +max-width: 1040px; +display: flex; +justify-content: space-between; + +@media ${props => props.theme.breakpoints.md}{ + display: flex; + justify-content: space-between; +} + +@media ${props => props.theme.breakpoints.sm}{ + display: flex; + width: 100%; + flex-direction: column; +} +` + +export const CompanyContainer = styled.div` + display: flex; + align-items:baseline; + flex-wrap: wrap; + margin-right: auto; + + + @media ${props => props.theme.breakpoints.md}{ + flex-direction: column; + align-items: baseline; + } + + @media ${props => props.theme.breakpoints.sm}{ + display: flex; + flex-direction: column; + margin: 0 0 32px; + align-items: center; + } +` + + +export const Slogan = styled.p` + color: rgba(255, 255, 255, 0.5); + min-width: 280px; + letter-spacing: 0.02em; + font-size: 18px; + line-height: 30px; + padding: 1rem; + + @media ${props => props.theme.breakpoints.md}{ + font-size: 16px; + line-height: 28px; + } + + @media ${props => props.theme.breakpoints.sm}{ + line-height: 22px; + font-size: 14px; + min-width: 100px; + } +` + +export const SocialContainer = styled.div` + display: flex; + align-items: center; + + @media ${props => props.theme.breakpoints.md}{ + justify-content: center; + padding-right: 16px; + flex-wrap: wrap; + } +` + + +export const LinkList = styled.ul` + border-top: 1px solid rgba(255, 255, 255, 0.1); + display: grid; + grid-template-columns: repeat(3, minmax(85px, 220px)); + gap: 40px; + padding: 40px 0 28px; + + @media ${props => props.theme.breakpoints.lg} { + padding: 32px 0 16px; + } + + @media ${props => props.theme.breakpoints.md} { + width: 100%; + padding: 32px 0 16px; + gap: 16px; + } + @media ${props => props.theme.breakpoints.sm} { + width: 100%; + padding: 32px 4px 16px; + gap: 5px; + } +` + +export const LinkColumn = styled.div` + display: flex; + flex-direction: column; + max-width: 220px; + width: 100%; +` +export const LinkTitle = styled.h4` + font-style: normal; + font-weight: 600; + font-size: 12px; + line-height: 24px; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.4); + margin-bottom: 16px; + + @media ${props => props.theme.breakpoints.sm} { + font-size: 10px; + line-height: 12px; + margin-bottom: 8px; + } +` diff --git a/components/Header/Header.js b/components/Header/Header.js new file mode 100644 index 0000000..f4bee09 --- /dev/null +++ b/components/Header/Header.js @@ -0,0 +1,48 @@ +import Link from 'next/link'; +import React from 'react'; +import { AiFillGithub, AiFillInstagram, AiFillLinkedin } from 'react-icons/ai'; +import { DiCssdeck } from 'react-icons/di'; + +import { Container, Div1, Div2, Div3, NavLink, SocialIcons, Span } from './HeaderStyles'; + +const Header = () => ( + + + + + Portfolio + + + + +
  • + + Projects + +
  • +
  • + + Technologies + +
  • +
  • + + About + +
  • +
    + + + + + + + + + + + +
    +); + +export default Header; diff --git a/components/Header/HeaderStyles.js b/components/Header/HeaderStyles.js new file mode 100644 index 0000000..e8bb1b8 --- /dev/null +++ b/components/Header/HeaderStyles.js @@ -0,0 +1,129 @@ +import { IoIosArrowDropdown } from 'react-icons/io'; +import styled from 'styled-components'; + +export const Container = styled.div` + display: grid; + grid-template-columns: repeat(5, 1fr); + grid-template-rows: 1fr; + grid-column-gap: 2rem; + padding: 1rem; + padding-top: 2rem; + + @media ${(props) => props.theme.breakpoints.sm} { + display: grid; + grid-template-columns: repeat(5, 1fr); + grid-template-rows: repeat(2, 60px); + grid-column-gap: 0.5rem; + grid-row-gap: 0.5rem; + } +`; + +export const Span = styled.span` + font-size: 2rem; +`; + +export const Div1 = styled.div` + grid-area: 1 / 1 / 2 / 2; + display: flex; + flex-direction: row; + align-content: center; + @media ${(props) => props.theme.breakpoints.sm} { + grid-area: 1 / 1 / 2 / 3; + } +`; +export const Div2 = styled.div` + grid-area: 1 / 2 / 2 / 4; + display: flex; + justify-content: space-around; + @media ${(props) => props.theme.breakpoints.sm} { + grid-area: 2 / 2 / 3 / 5; + } +`; +export const Div3 = styled.div` + grid-area: 1 / 5 / 2 / 6; + display: flex; + justify-content: space-around; + align-items: center; + @media ${(props) => props.theme.breakpoints.sm} { + align-items: center; + grid-area: 1 / 4 / 2 / 6; + } +`; + +// Navigation Links +export const NavLink = styled.a` + font-size: 2rem; + line-height: 32px; + color: rgba(255, 255, 255, 0.75); + transition: 0.4s ease; + &:hover { + color: #fff; + opacity: 1; + cursor: pointer; + } + @media ${(props) => props.theme.breakpoints.sm} { + padding: 0.5rem; + } +`; + +/// DropDown Contact +export const ContactDropDown = styled.button` + border: none; + display: flex; + position: relative; + background: none; + font-size: 1.7rem; + + line-height: 32px; + color: rgba(255, 255, 255, 0.75); + cursor: pointer; + transition: 0.3s ease; + + &:focus { + outline: none; + } + &:hover { + color: #fff; + } + + @media ${(props) => props.theme.breakpoints.sm} { + padding: 0.4rem 0; + } + @media ${(props) => props.theme.breakpoints.md} { + padding: 0; + } +`; + +export const NavProductsIcon = styled(IoIosArrowDropdown)` + margin-left: 8px; + display: flex; + align-self: center; + transition: 0.3s ease; + opacity: ${({ isOpen }) => (isOpen ? '1' : '.75')}; + transform: ${({ isOpen }) => (isOpen ? 'scaleY(-1)' : 'scaleY(1)')}; + + &:hover { + opacity: 1; + } + + @media ${(props) => props.theme.breakpoints.sm} { + margin: 2px 0 0 2px; + width: 15px; + } +`; + + +// Social Icons + +export const SocialIcons = styled.a` +transition: 0.3s ease; +color: white; +border-radius: 50px; + padding: 8px; +&:hover { + background-color: #212d45; + transform: scale(1.2); + cursor: pointer; + + } +` \ No newline at end of file diff --git a/components/Hero/Hero.js b/components/Hero/Hero.js new file mode 100644 index 0000000..70e5bf2 --- /dev/null +++ b/components/Hero/Hero.js @@ -0,0 +1,22 @@ +import React from 'react'; + +import { Section, SectionText, SectionTitle } from '../../styles/GlobalComponents'; +import Button from '../../styles/GlobalComponents/Button'; +import { LeftSection } from './HeroStyles'; + +const Hero = () => ( +
    + + + Welcome To
    + My Personal Portfolio +
    + + An Experienced Front-end Developer passionate about making Impact and building beautiful modern websites. + + +
    +
    +); + +export default Hero; \ No newline at end of file diff --git a/components/Hero/HeroStyles.js b/components/Hero/HeroStyles.js new file mode 100644 index 0000000..6a0c7fc --- /dev/null +++ b/components/Hero/HeroStyles.js @@ -0,0 +1,19 @@ +import styled from 'styled-components'; + +export const LeftSection = styled.div` + width: 100%; + @media ${(props) => props.theme.breakpoints.sm} { + width: 80%; + display: flex; + flex-direction: column; + + margin: 0 auto; + } + @media ${(props) => props.theme.breakpoints.md} { + width: 100%; + display: flex; + flex-direction: column; + + margin: 0 auto; + } +`; diff --git a/components/NavDropDown/NavDropDown.js b/components/NavDropDown/NavDropDown.js new file mode 100644 index 0000000..93bbc3d --- /dev/null +++ b/components/NavDropDown/NavDropDown.js @@ -0,0 +1,76 @@ +import styled from 'styled-components' + +export const DropDownContainer = styled.div` + position: absolute; + display: flex; + flex-direction: column; + right: -25%; + top: 40px; + width: 280px; + background-color: #fff; + border-radius: 8px; + z-index: 100; + padding: 4px 0; + cursor: default; + overflow: hidden; + transition: 0.3s ease; + visibility: ${({ active }) => active ? 'visible' : 'hidden'}; + opacity: ${({ active }) => active ? '1' : '0'}; + transform-origin: top; + transform: ${({ active }) => active ? 'scaleY(1)' : 'scaleY(.3)'}; + + @media ${(props) => props.theme.breakpoints.md} { + top: 32px; + } + @media ${(props) => props.theme.breakpoints.sm} { + top: 24px; + } +` +export const DropDownItem = styled.a` + width: 100%; + display: flex; + align-items: flex-start; + cursor: pointer; + transition: .3s ease; + padding: 12px 16px; + + &:hover { + transform: scale(1.05); + background-color: #eee; + box-shadow: 0 3px 6px 3px rgba(0,0,0,.3); + } + + &:nth-of-type(2n):hover { + box-shadow: 0 0 8px 4px rgba(0,0,0,.3); + } + + &:nth-of-type(3n):hover { + box-shadow: 0 -3px 6px 3px rgba(0,0,0,.3); + } +` + +export const DropDownIcon = styled.div` + width: 32px; + height: 32px; + margin-right: 16px; +` + +export const DropDownTextContainer = styled.div` + display: flex; + flex-direction: column; +` + +export const DropDownItemTitle = styled.h2` + color: #0f1624; + font-size: 18px; + line-height: 26px; + text-align: start; +` + +export const DropDownItemDesc = styled.p` + color: #0f1624; + opacity: 0.5; + font-size: 14px; + line-height: 22px; + text-align: start; +` \ No newline at end of file diff --git a/components/NavDropDown/index.js b/components/NavDropDown/index.js new file mode 100644 index 0000000..f2e8ee4 --- /dev/null +++ b/components/NavDropDown/index.js @@ -0,0 +1,13 @@ +import React from 'react' +import { AiFillPhone, AiOutlineMail } from 'react-icons/ai' +import { FaLocationArrow } from "react-icons/fa" + +import { DropDownContainer, DropDownIcon, DropDownItem, DropDownItemDesc, DropDownItemTitle, DropDownTextContainer } from './NavDropDown' + +const NavDropDown = (props) => ( +
    + NavDropDown +
    +); + +export default NavDropDown diff --git a/components/Projects/Projects.js b/components/Projects/Projects.js new file mode 100644 index 0000000..d4433fb --- /dev/null +++ b/components/Projects/Projects.js @@ -0,0 +1,38 @@ +import React from 'react'; + +import { BlogCard, CardInfo, ExternalLinks, GridContainer, HeaderThree, Hr, Tag, TagList, TitleContent, UtilityList, Img } from './ProjectsStyles'; +import { Section, SectionDivider, SectionTitle } from '../../styles/GlobalComponents'; +import { projects } from '../../constants/constants'; + + +const Projects = () => ( +
    + + Projects + + {projects.map(({ id, image, title, description, tags, source, visit }) => ( + + + + {title} +
    +
    + {description} +
    + Stack + + {tags.map((tag, i) => ( + {tag} + ) )} + +
    + + Code + Live + +
    + ))}
    +
    +); + +export default Projects; \ No newline at end of file diff --git a/components/Projects/ProjectsStyles.js b/components/Projects/ProjectsStyles.js new file mode 100644 index 0000000..c3eab89 --- /dev/null +++ b/components/Projects/ProjectsStyles.js @@ -0,0 +1,112 @@ +import styled from 'styled-components'; + +export const Img = styled.img` + width:100%; + height:100%; + object-fit: cover; + overflow: hidden; +` + +export const GridContainer = styled.section` +display: grid; +grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); +padding: 3rem; +place-items: center; +column-gap: 2rem; +row-gap: 3rem; +@media ${(props) => props.theme.breakpoints.sm} { + display: flex; + flex-direction: column; + padding: 2rem; + padding-bottom: 0; +} + +` +export const BlogCard = styled.div` + border-radius: 10px; + box-shadow: 3px 3px 20px rgba(80, 78, 78, 0.5); + text-align: center; + width: 400px; + @media ${(props) => props.theme.breakpoints.sm} { + width: 100%; + } +`; +export const TitleContent = styled.div` + text-align: center; + z-index: 20; + width: 100%; + +`; + + +export const HeaderThree = styled.h3` + font-weight: 500; + letter-spacing: 2px; + color: #9cc9e3; + padding: .5rem 0; + font-size: ${(props) => props.title ? '3rem' : '2rem'}; +`; + +export const Hr = styled.hr` + width: 50px; + height: 3px; + margin: 20px auto; + border: 0; + background: #d0bb57; +`; + +export const Intro = styled.div` + width: 170px; + margin: 0 auto; + color: #dce3e7; + font-family: 'Droid Serif', serif; + font-size: 13px; + font-style: italic; + line-height: 18px; +`; + + +export const CardInfo = styled.p` + width: 100%; + padding: 0 50px; + color: #e4e6e7; + font-style: 2rem; + line-height: 24px; + text-align: justify; + @media ${(props) => props.theme.breakpoints.sm} { + padding:.3rem + +} +`; + + +export const UtilityList = styled.ul` + list-style-type: none; + padding: 0; + display: flex; + justify-content: space-around; + margin: 2.5rem 0; +`; + +export const ExternalLinks = styled.a` +color:#d4c0c0; +font-size: 1.6rem; +padding:1rem 1.5rem; +background: #6b3030; +border-radius: 15px; +transition: 0.5s; +&:hover{ + background: #801414; + +} +`; + +export const TagList = styled.ul` +display: flex; +justify-content: space-around; +padding: 2rem; +` +export const Tag = styled.li` +color: #d8bfbf; +font-size: 1.5rem; +` \ No newline at end of file diff --git a/components/Technologies/Technologies.js b/components/Technologies/Technologies.js new file mode 100644 index 0000000..e55905c --- /dev/null +++ b/components/Technologies/Technologies.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { DiFirebase, DiReact, DiZend } from 'react-icons/di'; +import { Section, SectionDivider, SectionText, SectionTitle } from '../../styles/GlobalComponents'; +import { List, ListContainer, ListItem, ListParagraph, ListTitle } from './TechnologiesStyles'; + +const Technologies = () => ( +
    + +
    + Technologies + + I've worked with a range of technologies in the web development world. + From Front-end to Back-end. + + + + + + Front-End + + Experience with
    + React.js +
    +
    +
    + + + + Back-End + + Experience with
    + Node and Databases +
    +
    +
    + + + + UI/UX + + Experience with
    + tools like Figma +
    +
    +
    +
    +
    +); + +export default Technologies; diff --git a/components/Technologies/TechnologiesStyles.js b/components/Technologies/TechnologiesStyles.js new file mode 100644 index 0000000..11959ad --- /dev/null +++ b/components/Technologies/TechnologiesStyles.js @@ -0,0 +1,133 @@ +import styled from 'styled-components' + +export const ImageContainer = styled.div` + text-align: center; + background-image: radial-gradient(50% 50% at 50% 50%, rgba(79, 108, 176, 0.25) 53.8%, rgba(79, 108, 176, 0) 100%); + width: 100%; + padding: 60px; + margin-top: 48px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + @media ${props => props.theme.breakpoints.lg} { + background-image: none; + padding: 0; + margin-top: 40px; + } + @media ${props => props.theme.breakpoints.md} { + background-image: none; + padding: 0; + margin-top: 16px; + } +` + +export const MainImage = styled.img` + width: 100%; +` + +export const List = styled.ul` + list-style-type: none; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 40px; + margin: 3rem 0; + + @media ${props => props.theme.breakpoints.lg}{ + margin: 64px 0; + } + + @media ${props => props.theme.breakpoints.md}{ + margin: 64px 0; + gap: 24px + } + + @media ${props => props.theme.breakpoints.sm}{ + display: flex; + flex-direction: column; + margin: 32px 0; + } +` + +export const ListContainer = styled.div` + display: flex; + flex-direction: column; + + @media ${props => props.theme.breakpoints.sm}{ + display: flex; + margin-left: 18px; + } +` + +export const ListTitle = styled.h4` + font-weight: 700; + font-size: 28px; + line-height: 32px; + letter-spacing: 0.02em; + color: #FFFFFF; + margin-bottom: 8px; + +@media ${props => props.theme.breakpoints.md}{ + font-size: 24px; + line-height: 28px; +} + +@media ${props => props.theme.breakpoints.sm}{ + font-size: 20px; + line-height: 28px; + letter-spacing: 0.02em; + margin-bottom: 4px; +} +` + +export const ListParagraph = styled.p` + font-size: 18px; + line-height: 30px; + color: rgba(255, 255, 255, 0.75); + + @media ${props => props.theme.breakpoints.md}{ + font-size: 16px; + line-height: 28px; + } + + @media ${props => props.theme.breakpoints.sm}{ + font-size: 14px; + line-height: 22px; + } +` + +export const ListItem = styled.li` + max-width: 320px; + display: flex; + flex-direction: column; + +@media ${props => props.theme.breakpoints.md}{ + max-width: 203px; +} + +@media ${props => props.theme.breakpoints.sm}{ + margin-bottom: 14px; + max-width: 320px; + flex-direction: row; +} +` + +export const ListIcon = styled.img` + display: block; + width: 48px; + height: 48px; + margin-bottom: 10px; + + @media ${props => props.theme.breakpoints.md}{ + width: 40px; + height: 40px; + margin-bottom: 8px; + } + + @media ${props => props.theme.breakpoints.sm}{ + width: 32px; + height: 32px; + margin-bottom: 0px; + } +` diff --git a/components/TimeLine/TimeLine.js b/components/TimeLine/TimeLine.js new file mode 100644 index 0000000..160a9e3 --- /dev/null +++ b/components/TimeLine/TimeLine.js @@ -0,0 +1,117 @@ +import React, { useState, useRef, useEffect } from 'react'; + +import { CarouselButton, CarouselButtonDot, CarouselButtons, CarouselContainer, CarouselItem, CarouselItemImg, CarouselItemText, CarouselItemTitle, CarouselMobileScrollNode } from './TimeLineStyles'; +import { Section, SectionDivider, SectionText, SectionTitle } from '../../styles/GlobalComponents'; +import { TimeLineData } from '../../constants/constants'; + +const TOTAL_CAROUSEL_COUNT = TimeLineData.length; + +const Timeline = () => { + const [activeItem, setActiveItem] = useState(0); + const carouselRef = useRef(); + + const scroll = (node, left) => { + return node.scrollTo({ left, behavior: 'smooth' }); + } + + const handleClick = (e, i) => { + e.preventDefault(); + + if (carouselRef.current) { + const scrollLeft = Math.floor(carouselRef.current.scrollWidth * 0.7 * (i / TimeLineData.length)); + + scroll(carouselRef.current, scrollLeft); + } + } + + const handleScroll = () => { + if (carouselRef.current) { + const index = Math.round((carouselRef.current.scrollLeft / (carouselRef.current.scrollWidth * 0.7)) * TimeLineData.length); + + setActiveItem(index); + } + } + + // snap back to beginning of scroll when window is resized + // avoids a bug where content is covered up if coming from smaller screen + useEffect(() => { + const handleResize = () => { + scroll(carouselRef.current, 0); + } + + window.addEventListener('resize', handleResize); + }, []); + + return ( +
    + About Me + + I’m Modupe, but people call me “Goke.” I’m a frontend developer, and I specialize in efficient React apps and CSS & HTML that just work across all platforms and browsers. I care deeply about building interfaces that are usable and pleasant for the most number of people possible. + + My professional life has been 100% driven by my passion for design and structure. I’ve had the opportunity to intern at a talent development agency "Zuri", where I was able to utilise skills learnt to collaborate with developers, provide solutions to problems and work on projects. After that, I was a front-end developer at Techaton, where I worked on projects weekly that involved bringing beautiful modern UI/UX designs to life. + + Right now, I’m excited about the still very complicated Web3, and working towards becoming a React senior. In the following years, I also plan to explore the “server-side” more and become a better-rounded full-stack dev. + + {/* + <> + {TimeLineData.map((item, index) => ( + + handleClick(e, index)}> + + {item.year} + + + + + + + + + + + {item.text} + + + ))} + + + + {TimeLineData.map((item, index) => ( + handleClick(e, index)} + type="button" + > + + + ))} + */} + {/* */} +
    + ); +}; + +export default Timeline; diff --git a/components/TimeLine/TimeLineStyles.js b/components/TimeLine/TimeLineStyles.js new file mode 100644 index 0000000..61a8ccd --- /dev/null +++ b/components/TimeLine/TimeLineStyles.js @@ -0,0 +1,154 @@ + +import styled from 'styled-components' + +export const CarouselContainer = styled.ul` + max-width: 1040px; + background: #0F1624; + padding: 0rem; + list-style:none; + display: flex; + justify-content: space-between; + /* overflow-x: hidden; */ + + margin-left: 32px; + &:first-of-type{ + margin-left: 0px; + } + + margin-bottom: 80px; + + //remove scrollbar + scrollbar-width: none; + &::-webkit-scrollbar { + display: none; + } + + @media ${props => props.theme.breakpoints.sm} { + overflow-x: scroll; + -webkit-overflow-scrolling: touch; + scroll-snap-type: x mandatory; + touch-action: pan-x; + justify-content: initial; + margin-bottom: 8px; + } +` +export const CarouselMobileScrollNode = styled.div` + @media ${props => props.theme.breakpoints.sm} { + display: flex; + min-width: ${({ final }) => final ? `120%;` : `min-content`} + } +` + +export const CarouselItem = styled.div` + background: #0F1624; + border-radius: 3px; + max-width: 196px; + + @media ${props => props.theme.breakpoints.md} { + max-width: 124px; + } + + @media ${props => props.theme.breakpoints.sm} { + margin-left: 32px; + min-width: 120px; + background: #0E131F; + padding: 4px; + align-content: start; + scroll-snap-align: start; + border-radius: 3px; + overflow: visible; + position: relative; + height: fit-content; + + ${(props) => props.active === props.index ? `opacity: 1` : `opacity: 0.5`}; + } +` + +export const CarouselItemTitle = styled.h4` + font-weight: bold; + font-size: 24px; + line-height: 32px; + letter-spacing: 0.02em; + display: flex; + /* This gradient is different due to the size of the Title container, it must transition sooner to be visible on the text */ + background: linear-gradient(121.57deg, #FFFFFF 10%, rgba(255, 255, 255, 0.66) 30.15%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + margin-bottom: 8px; + + @media ${props => props.theme.breakpoints.md} { + font-size: 20px; + line-height: 28px; + margin-bottom: 4px; + } + + @media ${props => props.theme.breakpoints.sm} { + font-size: 16px; + line-height: 24px; + } +` +export const CarouselItemImg = styled.svg` + margin-left: 21px; + -webkit-mask-image: linear-gradient(to right, rgba(0,0,0,1), rgba(0,0,0,0)); + width: 100%; + + @media ${props => props.theme.breakpoints.sm} { + -webkit-mask-image: none; + margin-left: 16px; + overflow: visible; + } +` + +export const CarouselItemText = styled.p` + font-size: 14px; + line-height: 22px; + letter-spacing: 0.02em; + color: rgba(255, 255, 255, 0.75); + padding-right: 16px; + + @media ${props => props.theme.breakpoints.md} { + font-size: 12px; + line-height: 18px; + padding-right: 32px; + } + @media ${props => props.theme.breakpoints.sm} { + font-size: 10px; + line-height: 16px; + padding-right: 0; + } +` +export const CarouselButtons = styled.div` + width: 288px; + + display: none; + visibility: hidden; + + @media ${props => props.theme.breakpoints.sm} { + display: flex; + visibility: visible; + margin-bottom: 48px; + } +` + +export const CarouselButton = styled.button` + box-sizing: border-box; + background: none; + padding: 4px; + border: none; + cursor: pointer; + margin-right: 4px; + opacity: ${(props) => props.active === props.index ? `1` : `.33`}; + transform: ${(props) => props.active === props.index ? `scale(1.6)` : `scale(1)`}; + + &:focus { + outline: none; + } +` + +export const CarouselButtonDot = styled.div` + background-color: white; + border-radius: 10px; + margin: auto; + width: 3px; + height: 3px; +` diff --git a/constants/constants.js b/constants/constants.js new file mode 100644 index 0000000..0fe3f29 --- /dev/null +++ b/constants/constants.js @@ -0,0 +1,46 @@ +export const projects = [ + { + title: 'Hoo Bank', + description: "Using React and Tailwind, I built a mobile responsive bank website by transforming a UI/UX design into reality.", + image: '/images/screenshot (88).png', + tags: ['React', 'Node', 'Vite'], + source: 'https://github.com/Goketech/bank_modern_app', + visit: 'https://bank-modern-app-r9rw.vercel.app/', + id: 0, + }, + { + title: 'Restaurant', + description:"Created a beautiful frontend restaurant site. It contains Hero Section, About, History, Menu, Chef, full screen video and lot's more.", + image: '/images/screenshot (89).png', + tags: ['React', 'JavaScript'], + source: 'https://github.com/Goketech/gerich-restaurant', + visit: 'https://gerich-restaurant-chi.vercel.app/', + id: 1, + }, + { + title: 'AI Website', + description: "This is a .", + image: '/images/screenshot (90).png', + tags: ['React'], + source: 'https://github.com/Goketech/gpt3_goke', + visit: 'https://gpt3-goke.vercel.app/', + id: 2, + }, + { + title: 'Netflix-clone', + description: "Created a Netflix movie Web App that fetches current and Trending using the movie database API.", + image: '/images/screenshot (91).png', + tags: ['React', 'Tailwind', 'Firebase', 'TMD API'], + source: 'https://github.com/Goketech/netflix', + visit: 'https://netflix-ten-iota.vercel.app/', + id: 3, + }, +]; + +export const TimeLineData = [ + { year: 2017, text: 'Started my journey', }, + { year: 2018, text: 'Worked as a freelance developer', }, + { year: 2019, text: 'Founded JavaScript Mastery', }, + { year: 2020, text: 'Shared my projects with the world', }, + { year: 2021, text: 'Started my own platform', }, +]; \ No newline at end of file diff --git a/layout/Layout.js b/layout/Layout.js new file mode 100644 index 0000000..43fd0a6 --- /dev/null +++ b/layout/Layout.js @@ -0,0 +1,15 @@ +import React from 'react' + +import Footer from '../components/Footer/Footer' +import Header from '../components/Header/Header' +import { Container } from './LayoutStyles' + +export const Layout = ({children}) => { + return ( + +
    +
    {children}
    +