├── .env.example ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── package-lock.json ├── package.json ├── public ├── 404.png ├── _redirects ├── avatar.svg ├── black_logo.png ├── companies │ ├── colorbeats.png │ ├── ela-sustentable.png │ ├── horus-sc.svg │ ├── koombea.png │ ├── powerpay.png │ └── simple-legal.jpg ├── favicon.png ├── favicon.svg ├── hero.svg ├── hover_avatar.svg ├── index.html ├── manifest.json ├── projects │ ├── horushotel.png │ └── shopylive.png ├── robots.txt ├── success.svg └── white_logo.png ├── src ├── App.js ├── App.test.js ├── components │ ├── avatar │ │ └── index.js │ ├── button │ │ └── index.js │ ├── container │ │ └── index.js │ ├── footer │ │ └── index.js │ ├── header │ │ ├── drawer.js │ │ └── index.js │ ├── image │ │ └── index.js │ ├── layout │ │ └── index.js │ ├── link │ │ └── index.js │ ├── list │ │ └── index.js │ ├── seo │ │ └── index.js │ └── typography │ │ └── index.js ├── index.css ├── index.js ├── pages │ ├── 404 │ │ └── index.js │ ├── about │ │ ├── card.js │ │ └── index.js │ ├── contact │ │ └── index.js │ ├── landing │ │ ├── index.js │ │ └── paper.js │ └── success │ │ └── index.js ├── serviceWorker.js ├── services │ ├── careerInfo.js │ ├── companies.js │ ├── projects.js │ └── router.js └── setupTests.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | REACT_APP_BASE_URL = http://localhost:3000 2 | REACT_APP_REQUEST_URL = https://getform.io/ 3 | REACT_APP_RESUME_URL = https://docs.google.com/ 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | 2 | src/registerServiceWorker.js 3 | node_modules/* 4 | public/* 5 | build/* 6 | config/* 7 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['airbnb', 'plugin:prettier/recommended', 'prettier/react'], 3 | env: { 4 | browser: true, 5 | commonjs: true, 6 | es6: true, 7 | jest: true, 8 | node: true, 9 | }, 10 | rules: { 11 | 'import/prefer-default-export': 'off', 12 | 'react/prop-types': 'off', 13 | 'react/jsx-props-no-spreading': 'off', 14 | 'no-nested-ternary': 'off', 15 | 'jsx-a11y/href-no-hash': ['off'], 16 | 'react/jsx-filename-extension': ['warn', { extensions: ['.js', '.jsx'] }], 17 | 'max-len': [ 18 | 'warn', 19 | { 20 | code: 80, 21 | tabWidth: 2, 22 | comments: 80, 23 | ignoreComments: false, 24 | ignoreTrailingComments: true, 25 | ignoreUrls: true, 26 | ignoreStrings: true, 27 | ignoreTemplateLiterals: true, 28 | ignoreRegExpLiterals: true, 29 | }, 30 | ], 31 | 'no-use-before-define': 'off', 32 | 'import/no-unresolved': 'off', 33 | 'import/extensions': 'off', 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "singleQuote": true, 4 | "trailingComma": "all" 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ## Deployment 16 | 17 | This website is deployed through Netlify in [https://dsantiagomj.dev](dsantiagomj.dev). 18 | 19 | ## ENV File 20 | 21 | This project has 3 env variables. When cloned, the project will contain an env.example file with the variables, for security reasons they have default values, this won't prevent the project to launch, but will limit it's 22 | functionallity, although you can assign your own values to the variables in order to the project fully works. 23 | 24 | - **REACT_APP_BASE_URL**: localhost:3000 by default, you can replace it with your custom domain URL. 25 | 26 | - **REACT_APP_REQUEST_URL**: this project uses [https://getform.io/](getform) as endpoint for the contact page, you can create your own endpoint and set it in this variable or use another service. 27 | 28 | - **REACT_APP_RESUME_URL**: Link to your CV. 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-portfolio", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@reach/router": "^1.3.3", 7 | "@testing-library/jest-dom": "^4.2.4", 8 | "@testing-library/react": "^9.3.2", 9 | "@testing-library/user-event": "^7.1.2", 10 | "eslint-config-prettier": "^6.11.0", 11 | "eslint-import-resolver-webpack": "^0.12.1", 12 | "eslint-plugin-prettier": "^3.1.3", 13 | "prettier": "^2.0.5", 14 | "prop-types": "^15.7.2", 15 | "react": "^16.13.1", 16 | "react-dom": "^16.13.1", 17 | "react-helmet": "^6.1.0", 18 | "react-icons": "^3.10.0", 19 | "react-scripts": "3.4.1", 20 | "styled-components": "^5.1.1" 21 | }, 22 | "scripts": { 23 | "start": "react-scripts start", 24 | "build": "react-scripts build", 25 | "test": "react-scripts test", 26 | "lint": "eslint src -c .eslintrc.json --ext js,jsx", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": "react-app" 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.2%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | }, 44 | "devDependencies": { 45 | "eslint": "^6.8.0", 46 | "eslint-config-airbnb": "^18.1.0", 47 | "eslint-plugin-import": "^2.21.2", 48 | "eslint-plugin-jsx-a11y": "^6.2.3", 49 | "eslint-plugin-react": "^7.20.0", 50 | "eslint-plugin-react-hooks": "^2.5.1" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /public/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/404.png -------------------------------------------------------------------------------- /public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | -------------------------------------------------------------------------------- /public/avatar.svg: -------------------------------------------------------------------------------- 1 | Created with getavataaars.com 2 | -------------------------------------------------------------------------------- /public/black_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/black_logo.png -------------------------------------------------------------------------------- /public/companies/colorbeats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/companies/colorbeats.png -------------------------------------------------------------------------------- /public/companies/ela-sustentable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/companies/ela-sustentable.png -------------------------------------------------------------------------------- /public/companies/horus-sc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 14 | 15 | 17 | 20 | 24 | 26 | 31 | 32 | 33 | 37 | 39 | 41 | 44 | 45 | 47 | 50 | 52 | 53 | 56 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 68 | 81 | 86 | 90 | 91 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /public/companies/koombea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/companies/koombea.png -------------------------------------------------------------------------------- /public/companies/powerpay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/companies/powerpay.png -------------------------------------------------------------------------------- /public/companies/simple-legal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/companies/simple-legal.jpg -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/favicon.png -------------------------------------------------------------------------------- /public/hero.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 32 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /public/hover_avatar.svg: -------------------------------------------------------------------------------- 1 | Created with getavataaars.com 2 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Santiago M | Software developer 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.svg", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "favicon.svg", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "favicon.svg", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/projects/horushotel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/projects/horushotel.png -------------------------------------------------------------------------------- /public/projects/shopylive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/projects/shopylive.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/success.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /public/white_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dsantiagomj/react-portfolio/894b6b96ea69398c3c314b8fca4ecfba1242bffb/public/white_logo.png -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import Router from './services/router'; 4 | 5 | function App() { 6 | return ; 7 | } 8 | 9 | export default App; 10 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /src/components/avatar/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | const Avatar = styled.div` 7 | background-image: url(${(props) => props.defaultImage}); 8 | height: 280px; 9 | margin: 0 auto; 10 | margin-top: 2rem; 11 | transition: background-image 0.2s ease-in-out; 12 | width: 260px; 13 | &:hover { 14 | background-image url(${(props) => props.hoverImage || props.defaultImage}); 15 | } 16 | `; 17 | 18 | const AvatarComponent = ({ defaultImage, hoverImage }) => ( 19 | 20 | ); 21 | 22 | AvatarComponent.propTypes = { 23 | defaultImage: PropTypes.string.isRequired, 24 | hoverImage: PropTypes.string, 25 | }; 26 | 27 | AvatarComponent.defaultProps = { 28 | hoverImage: '', 29 | }; 30 | 31 | export default AvatarComponent; 32 | -------------------------------------------------------------------------------- /src/components/button/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | const DefaultButtonComponent = styled.input` 7 | background: transparent; 8 | border: solid 2px #0bd8a2; 9 | border-radius: 0.25rem; 10 | color: #0bd8a2; 11 | margin: 0 auto; 12 | min-width: ${(props) => props.minWidth}; 13 | padding: 0.5rem; 14 | &:hover { 15 | background: #0bd8a2; 16 | color: white; 17 | cursor: pointer; 18 | } 19 | `; 20 | 21 | const TransitionButtonComponent = styled(DefaultButtonComponent)` 22 | transition: padding 0.3s ease-in-out; 23 | &:hover { 24 | padding: 0.5rem 1rem; 25 | } 26 | `; 27 | 28 | export const DefaultButton = ({ value, type, minWidth }) => ( 29 | 30 | ); 31 | 32 | DefaultButton.propTypes = { 33 | value: PropTypes.string.isRequired, 34 | type: PropTypes.string, 35 | minWidth: PropTypes.string, 36 | }; 37 | 38 | DefaultButton.defaultProps = { 39 | type: 'submit', 40 | minWidth: 'auto', 41 | }; 42 | 43 | export const TransitionButton = ({ value, type, minWidth }) => ( 44 | 45 | ); 46 | 47 | TransitionButton.propTypes = { 48 | value: PropTypes.string.isRequired, 49 | type: PropTypes.string, 50 | minWidth: PropTypes.string, 51 | }; 52 | 53 | TransitionButton.defaultProps = { 54 | type: 'submit', 55 | minWidth: 'auto', 56 | }; 57 | -------------------------------------------------------------------------------- /src/components/container/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | const ContentWrapperComponent = styled.div` 7 | animation: fadeInAnimation ease 0.75s; 8 | animation-iteration-count: 1; 9 | animation-fill-mode: forwards; 10 | display: flex; 11 | flex-direction: column; 12 | height: 100vh; 13 | justify-content: space-between; 14 | width: 100vw; 15 | @keyframes fadeInAnimation { 16 | 0% { 17 | opacity: 0; 18 | } 19 | 100% { 20 | opacity: 1; 21 | } 22 | } 23 | `; 24 | 25 | const CenterContentWrapperComponent = styled(ContentWrapperComponent)` 26 | animation: fadeInAnimation ease 1s; 27 | align-items: center; 28 | justify-content: center; 29 | overflow: hidden; 30 | `; 31 | 32 | export const ContentWrapper = ({ children }) => ( 33 | {children} 34 | ); 35 | ContentWrapper.propTypes = { 36 | children: PropTypes.node.isRequired, 37 | }; 38 | 39 | export const CenterContentWrapper = ({ children }) => ( 40 | {children} 41 | ); 42 | CenterContentWrapper.propTypes = { 43 | children: PropTypes.node.isRequired, 44 | }; 45 | -------------------------------------------------------------------------------- /src/components/footer/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from '@reach/router'; 3 | 4 | import styled from 'styled-components'; 5 | import { AiOutlineMail, AiOutlineLinkedin, AiFillGithub } from 'react-icons/ai'; 6 | import { GrReactjs } from 'react-icons/gr'; 7 | 8 | import Image from '../image'; 9 | import { DefaultButton } from '../button'; 10 | import { Typography } from '../typography'; 11 | 12 | const Container = styled.div` 13 | background-color: #00343d; 14 | margin-top: 5rem; 15 | padding: 4rem 0; 16 | `; 17 | const Paper = styled.div` 18 | align-items: center; 19 | background: #141c3a; 20 | border-radius: 12px; 21 | box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px #141c3a; 22 | display: flex; 23 | flex-direction: column; 24 | justify-content: space-evenly; 25 | margin: 0 auto; 26 | margin-top: -9rem; 27 | padding: 3.5rem 1.25rem; 28 | max-width: 60rem; 29 | width: 90%; 30 | @media (min-width: 1024px) { 31 | flex-direction: row; 32 | } 33 | `; 34 | const ImageWrapper = styled.div` 35 | display: flex; 36 | justify-content: center; 37 | margin-top: 5rem; 38 | margin-bottom: 1rem; 39 | width: 100vw; 40 | `; 41 | 42 | const List = styled.ul` 43 | align-items: center; 44 | display: flex; 45 | justify-content: space-evenly; 46 | list-style: none; 47 | margin: auto; 48 | margin-bottom: 2rem; 49 | margin-top: 2rem; 50 | max-width: 25rem; 51 | `; 52 | const ListItem = styled.li` 53 | border: solid 2px rgba(255, 255, 255, 0.3); 54 | border-radius: 100%; 55 | color: white; 56 | height: 48px; 57 | position: relative; 58 | transition: background-color 0.1s ease-in-out; 59 | width: 48px; 60 | &:hover { 61 | background-color: white; 62 | color: #0bd8a2; 63 | } 64 | `; 65 | const Icon = styled.div` 66 | align-items: center; 67 | display: inline-flex; 68 | font-size: 1.25rem; 69 | justify-content: center; 70 | position: absolute; 71 | top: 12px; 72 | left: 12px; 73 | @media (min-width: 768px) { 74 | top: 10px; 75 | left: 10px; 76 | } 77 | `; 78 | const Copyright = styled.div` 79 | align-items: center; 80 | display: flex; 81 | font-weight: 600; 82 | justify-content: center; 83 | `; 84 | 85 | const Footer = ({ location }) => { 86 | const date = new Date(); 87 | const currentYear = date.getFullYear(); 88 | 89 | return ( 90 | 91 | {location !== '/contact' && ( 92 | 93 | 99 | Start a project 100 | 101 | 107 | Interested in working together? Let's schedule a call. 108 | 109 | 110 | 111 | 112 | 113 | )} 114 | 115 | DS Software Developer logo 121 | 122 | 123 | Living, learning & leveling up one day at a time. 124 | 125 | 126 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | Handcrafted by @dsantiagomj - © {currentYear} 159 | 160 | 161 | 162 | 163 | Made with{' '} 164 | 165 | 174 | 175 | 176 | ); 177 | }; 178 | 179 | export default Footer; 180 | -------------------------------------------------------------------------------- /src/components/header/drawer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from '@reach/router'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | import { DefaultButton } from '../button'; 7 | 8 | const ResponsiveMenu = styled.ul` 9 | align-items: center; 10 | background: white; 11 | box-shadow: 0 5px 5px 0 rgba(233, 240, 243, 0.5), 0 1px 0 0 #e6ecf8; 12 | display: flex; 13 | flex-direction: column; 14 | height: calc(40vh - 6rem); 15 | justify-content: space-evenly; 16 | left: 0; 17 | list-style: none; 18 | margin: ${(props) => (props.isOpen ? '0 auto' : '-2500px')}; 19 | position: absolute; 20 | top: 5rem; 21 | transition: margin 0.5s ease-in-out; 22 | width: 100vw; 23 | z-index: 2; 24 | @media (min-width: 1024px) { 25 | display: none; 26 | } 27 | `; 28 | 29 | const ResponsiveItem = styled.li` 30 | text-align: center; 31 | width: 100vw; 32 | &:hover { 33 | color: #0bd8a2; 34 | cursor: pointer; 35 | } 36 | `; 37 | 38 | const Drawer = ({ isOpen }) => ( 39 | 40 | 47 | About 48 | 49 | 56 | 57 | 58 | 59 | 60 | 61 | ); 62 | 63 | export default Drawer; 64 | -------------------------------------------------------------------------------- /src/components/header/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { Link } from '@reach/router'; 3 | 4 | import styled from 'styled-components'; 5 | import { AiOutlineMenu, AiOutlineClose } from 'react-icons/ai'; 6 | 7 | import Drawer from './drawer'; 8 | import { DefaultButton } from '../button'; 9 | 10 | const Container = styled.div` 11 | align-items: center; 12 | background: white; 13 | display: flex; 14 | height: 5rem; 15 | justify-content: space-between; 16 | margin: 0 auto; 17 | margin-bottom: 1.45rem; 18 | max-width: 80rem; 19 | padding: 0 0.5rem; 20 | padding-top: 3rem; 21 | width: 100%; 22 | zindex: 3; 23 | @media (min-width: 1024px) { 24 | padding-top: 2.5rem; 25 | } 26 | `; 27 | 28 | const Menu = styled.ul` 29 | display: none; 30 | list-style: none; 31 | margin: 0; 32 | width: 16rem; 33 | @media (min-width: 1024px) { 34 | align-items: center; 35 | display: flex; 36 | justify-content: space-around; 37 | } 38 | `; 39 | 40 | const MenuItem = styled.li` 41 | color: #00343d; 42 | font-size: 0.875rem; 43 | margin: 0; 44 | text-decoration: none; 45 | &:hover { 46 | color: #0bd8a2; 47 | cursor: pointer; 48 | } 49 | `; 50 | 51 | const ResponsiveButton = styled.button` 52 | background: transparent; 53 | border: none; 54 | cursor: pointer; 55 | display: block; 56 | font-size: 1.5rem; 57 | z-index: 3; 58 | @media (min-width: 1024px) { 59 | display: none; 60 | } 61 | `; 62 | 63 | const Header = () => { 64 | // responsive navbar status 65 | const [navbarStatus, setNavbarStatus] = useState(false); 66 | 67 | return ( 68 | 69 | 77 | DS Logo 83 | 84 | 85 | 92 | About me 93 | 94 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | setNavbarStatus(!navbarStatus)}> 108 | {navbarStatus ? : } 109 | 110 | 111 | 112 | 113 | ); 114 | }; 115 | 116 | export default Header; 117 | -------------------------------------------------------------------------------- /src/components/image/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | const ImageComponent = styled.img` 7 | height: ${(props) => props.height}; 8 | margin: 0; 9 | max-height: ${(props) => props.maxHeight}; 10 | max-width: ${(props) => props.maxWidth}; 11 | min-height: ${(props) => props.minHeight}; 12 | min-width: ${(props) => props.minWidth}; 13 | padding: 0; 14 | width: ${(props) => props.width}; 15 | `; 16 | 17 | const Image = ({ 18 | src, 19 | alt, 20 | height, 21 | width, 22 | maxHeight, 23 | maxWidth, 24 | minHeight, 25 | minWidth, 26 | }) => ( 27 | 37 | ); 38 | 39 | Image.propTypes = { 40 | src: PropTypes.string.isRequired, 41 | alt: PropTypes.string.isRequired, 42 | }; 43 | 44 | Image.defaultProps = { 45 | height: 'auto', 46 | maxHeight: 'auto', 47 | minHeight: 'auto', 48 | maxWidth: 'auto', 49 | minWidth: 'auto', 50 | width: 'auto', 51 | }; 52 | 53 | export default Image; 54 | -------------------------------------------------------------------------------- /src/components/layout/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import styled from 'styled-components'; 5 | 6 | import Header from '../header'; 7 | import Footer from '../footer'; 8 | import { ContentWrapper } from '../container'; 9 | 10 | const Main = styled.main` 11 | margin: 0 auto; 12 | `; 13 | 14 | const Layout = ({ children, location }) => { 15 | return ( 16 | 17 |
18 |
{children}
19 |