├── .babelrc ├── .eslintrc ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .huskyrc ├── .prettierrc ├── LICENSE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── data.json ├── package-lock.json ├── package.json ├── public └── index.html ├── screenshot.png ├── src ├── __mocks__ │ └── styleMock.js ├── __test__ │ ├── Utils │ │ └── AgetData.test.js │ ├── components │ │ ├── About.test.js │ │ ├── Academic.test.js │ │ ├── Experience.test.js │ │ ├── Header.test.js │ │ ├── Interest.test.js │ │ ├── Languages.test.js │ │ ├── Profile.test.js │ │ └── Skills.test.js │ └── setupTest.js ├── containers │ └── App.jsx ├── index.js ├── styles │ └── components │ │ └── App.styl └── utils │ └── getData.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@babel/preset-env", 4 | "@babel/preset-react" 5 | ] 6 | } -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "airbnb" 9 | ], 10 | "globals": { 11 | "document": false, 12 | "escape": false, 13 | "navigator": false, 14 | "unescape": false, 15 | "window": false, 16 | "describe": true, 17 | "before": true, 18 | "it": true, 19 | "expect": true, 20 | "sinon": true 21 | }, 22 | "parser": "babel-eslint", 23 | "plugins": [ 24 | "react", 25 | "jsx-a11y", 26 | "import" 27 | ], 28 | "rules": { 29 | "react/jsx-filename-extension": 0, 30 | "array-bracket-spacing": 2, 31 | "arrow-body-style": 0, 32 | "block-scoped-var": 2, 33 | "brace-style": [ 34 | 2, 35 | "1tbs", 36 | { 37 | "allowSingleLine": true 38 | } 39 | ], 40 | "comma-spacing": [ 41 | 2, 42 | { 43 | "before": false, 44 | "after": true 45 | } 46 | ], 47 | "comma-style": [ 48 | 2, 49 | "last" 50 | ], 51 | "complexity": 0, 52 | "consistent-return": 1, 53 | "consistent-this": 0, 54 | "curly": [ 55 | 2, 56 | "multi-line" 57 | ], 58 | "default-case": 0, 59 | "dot-location": [ 60 | 2, 61 | "property" 62 | ], 63 | "dot-notation": 0, 64 | "eol-last": 2, 65 | "eqeqeq": [ 66 | 2, 67 | "allow-null" 68 | ], 69 | "func-names": 0, 70 | "func-style": 0, 71 | "generator-star-spacing": [ 72 | 2, 73 | "both" 74 | ], 75 | "guard-for-in": 0, 76 | "handle-callback-err": [ 77 | 2, 78 | "^(err|error|anySpecificError)$" 79 | ], 80 | "indent": [ 81 | 2, 82 | 2, 83 | { 84 | "SwitchCase": 1 85 | } 86 | ], 87 | "key-spacing": [ 88 | 2, 89 | { 90 | "beforeColon": false, 91 | "afterColon": true 92 | } 93 | ], 94 | "linebreak-style": 0, 95 | "max-depth": 0, 96 | "max-len": [ 97 | 2, 98 | 1550, 99 | 4 100 | ], 101 | "max-nested-callbacks": 0, 102 | "max-params": 0, 103 | "max-statements": 0, 104 | "new-cap": [ 105 | 2, 106 | { 107 | "newIsCap": true, 108 | "capIsNew": false 109 | } 110 | ], 111 | "newline-after-var": [ 112 | 0, 113 | "never" 114 | ], 115 | "new-parens": 2, 116 | "no-alert": 0, 117 | "no-array-constructor": 2, 118 | "no-bitwise": 0, 119 | "no-caller": 2, 120 | "no-catch-shadow": 0, 121 | "no-cond-assign": 2, 122 | "no-console": 0, 123 | "no-constant-condition": 0, 124 | "no-continue": 0, 125 | "no-control-regex": 2, 126 | "no-debugger": 0, 127 | "no-delete-var": 2, 128 | "no-div-regex": 0, 129 | "no-dupe-args": 2, 130 | "no-dupe-keys": 2, 131 | "no-duplicate-case": 2, 132 | "no-else-return": 2, 133 | "no-empty": 0, 134 | "no-empty-character-class": 2, 135 | "no-labels": 2, 136 | "no-eq-null": 0, 137 | "no-eval": 2, 138 | "no-ex-assign": 2, 139 | "no-extend-native": 2, 140 | "no-extra-bind": 2, 141 | "no-extra-boolean-cast": 2, 142 | "no-extra-parens": 0, 143 | "no-extra-semi": 0, 144 | "no-extra-strict": 0, 145 | "no-fallthrough": 2, 146 | "no-floating-decimal": 2, 147 | "no-func-assign": 2, 148 | "no-implied-eval": 2, 149 | "no-inline-comments": 0, 150 | "no-inner-declarations": [ 151 | 2, 152 | "functions" 153 | ], 154 | "no-invalid-regexp": 2, 155 | "no-irregular-whitespace": 2, 156 | "no-iterator": 2, 157 | "no-label-var": 2, 158 | "no-lone-blocks": 0, 159 | "no-lonely-if": 0, 160 | "no-loop-func": 0, 161 | "no-mixed-requires": 0, 162 | "no-mixed-spaces-and-tabs": [ 163 | 2, 164 | false 165 | ], 166 | "no-multi-spaces": 2, 167 | "no-multi-str": 0, 168 | "no-multiple-empty-lines": [ 169 | 2, 170 | { 171 | "max": 1 172 | } 173 | ], 174 | "no-native-reassign": 2, 175 | "no-negated-in-lhs": 2, 176 | "no-nested-ternary": 0, 177 | "no-new": 2, 178 | "no-new-func": 2, 179 | "no-new-object": 2, 180 | "no-new-require": 2, 181 | "no-new-wrappers": 2, 182 | "no-obj-calls": 2, 183 | "no-octal": 2, 184 | "no-octal-escape": 2, 185 | "no-path-concat": 0, 186 | "no-plusplus": 0, 187 | "no-process-env": 0, 188 | "no-process-exit": 0, 189 | "no-proto": 2, 190 | "no-redeclare": 2, 191 | "no-regex-spaces": 2, 192 | "no-reserved-keys": 0, 193 | "no-restricted-modules": 0, 194 | "no-script-url": 0, 195 | "no-self-compare": 2, 196 | "no-sequences": 2, 197 | "no-shadow": 0, 198 | "no-shadow-restricted-names": 2, 199 | "no-spaced-func": 2, 200 | "no-sparse-arrays": 2, 201 | "no-sync": 0, 202 | "no-ternary": 0, 203 | "no-throw-literal": 2, 204 | "no-trailing-spaces": 2, 205 | "no-undef": 0, 206 | "no-undef-init": 2, 207 | "no-undefined": 0, 208 | "no-underscore-dangle": 0, 209 | "no-unneeded-ternary": 2, 210 | "no-unreachable": 2, 211 | "no-unused-expressions": 0, 212 | "no-unused-vars": [ 213 | 2, 214 | { 215 | "vars": "all", 216 | "args": "none" 217 | } 218 | ], 219 | "no-var": 2, 220 | "no-void": 0, 221 | "no-warning-comments": 0, 222 | "no-with": 2, 223 | "object-curly-newline": 0, 224 | "object-curly-spacing": [ 225 | 2, 226 | "always" 227 | ], 228 | "one-var": 0, 229 | "operator-assignment": 0, 230 | "operator-linebreak": [ 231 | 2, 232 | "after" 233 | ], 234 | "padded-blocks": 0, 235 | "prefer-const": 2, 236 | "quote-props": 0, 237 | "quotes": [ 238 | 2, 239 | "single", 240 | "avoid-escape" 241 | ], 242 | "radix": 2, 243 | "jsx-quotes": [ 244 | 2, 245 | "prefer-single" 246 | ], 247 | "jsx-a11y/click-events-have-key-events": 0, 248 | "jsx-a11y/no-noninteractive-element-interactions": 0, 249 | "jsx-a11y/media-has-caption": 0, 250 | "react/display-name": 0, 251 | "react/jsx-boolean-value": 0, 252 | "react/jsx-closing-bracket-location": 2, 253 | "react/jsx-curly-spacing": [ 254 | 2, 255 | "never" 256 | ], 257 | "react/jsx-equals-spacing": [ 258 | 2, 259 | "never" 260 | ], 261 | "react/jsx-indent-props": [ 262 | 2, 263 | 2 264 | ], 265 | "react/jsx-no-bind": [ 266 | 2, 267 | { 268 | "allowArrowFunctions": true 269 | } 270 | ], 271 | "react/jsx-no-undef": 2, 272 | "react/jsx-pascal-case": 2, 273 | "react/jsx-sort-prop-types": 0, 274 | "react/jsx-sort-props": 0, 275 | "react/jsx-uses-react": 2, 276 | "react/jsx-uses-vars": 2, 277 | "react/no-did-mount-set-state": 2, 278 | "react/no-did-update-set-state": 2, 279 | "react/no-multi-comp": 0, 280 | "react/no-unknown-property": 2, 281 | "react/prop-types": 0, 282 | "react/forbid-prop-types": 0, 283 | "react/prefer-stateless-function": 0, 284 | "react/require-default-props": 0, 285 | "react/react-in-jsx-scope": 2, 286 | "react/self-closing-comp": 2, 287 | "react/sort-comp": 0, 288 | "react/jsx-wrap-multilines": 2, 289 | "semi-spacing": 0, 290 | "sort-vars": 0, 291 | "space-before-blocks": [ 292 | 2, 293 | "always" 294 | ], 295 | "space-before-function-paren": [ 296 | 2, 297 | { 298 | "anonymous": "always", 299 | "named": "never" 300 | } 301 | ], 302 | "space-in-parens": [ 303 | 2, 304 | "never" 305 | ], 306 | "space-infix-ops": 2, 307 | "keyword-spacing": 2, 308 | "space-unary-ops": [ 309 | 2, 310 | { 311 | "words": true, 312 | "nonwords": false 313 | } 314 | ], 315 | "spaced-comment": [ 316 | 0, 317 | "always" 318 | ], 319 | "strict": 0, 320 | "use-isnan": 2, 321 | "valid-jsdoc": 0, 322 | "valid-typeof": 2, 323 | "vars-on-top": 2, 324 | "wrap-iife": [ 325 | 2, 326 | "any" 327 | ], 328 | "wrap-regex": 0, 329 | "yoda": [ 330 | 2, 331 | "never" 332 | ] 333 | } 334 | } -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: jest 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2.4.2 10 | - name: Install modules 11 | run: yarn 12 | - name: Run tests 13 | run: yarn test 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "npm run lint && npm run test" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "semi": true, 4 | "singleQuote": true 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Platzi Master 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## DESCRIPTION 2 | 3 | Solución al reto: 4 | 5 | Nombre: 6 | Usuario Platzi: 7 | 8 | ## Reto: 9 | 10 | - [ ] Primer problema 11 | - [ ] Segundo problema 12 | - [ ] Tercer problema 13 | - [ ] Cuarto Problema 14 | - [ ] Quinto Problema 15 | - [ ] Sexto Problema 16 | - [ ] Septimo Problema 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-eth-challenge 2 | 3 | ## React Curriculum vitae 4 | 5 | Crear tu curriculum vitae en React, analiza la estructura propuesta e inspirate para mostrar tu información. 6 | 7 | ![react-cv](https://github.com/gndx/react-eth-challenge/blob/440befcbc257b886015bd050666a21a3bec6c244/screenshot.png) 8 | 9 | ### Retos 10 | 11 | 1. [Crear los componentes del proyecto](https://github.com/gndx/react-eth-challenge/issues/1) 12 | 2. [Añadir estilos](https://github.com/gndx/react-eth-challenge/issues/2) 13 | 3. [Crear función getData.js](https://github.com/gndx/react-eth-challenge/issues/3) 14 | 4. [Integrar API](https://github.com/gndx/react-eth-challenge/issues/4) 15 | 5. [Personalizar API](https://github.com/gndx/react-eth-challenge/issues/5) 16 | 6. [Documentar](https://github.com/gndx/react-eth-challenge/issues/6) 17 | 7. [Deploy](https://github.com/gndx/react-eth-challenge/issues/7) 18 | 19 | ### Instalación 20 | 21 | ``` 22 | npm install 23 | ``` 24 | 25 | ### Ejecución 26 | 27 | ``` 28 | npm run start 29 | ``` 30 | 31 | ### Server 32 | 33 | ``` 34 | npm run server 35 | ``` 36 | 37 | ### Compilar 38 | 39 | ``` 40 | npm run build 41 | ``` 42 | 43 | ### Pruebas Unitarias 44 | 45 | ``` 46 | npm run test 47 | ``` 48 | 49 | ### ESlint 50 | 51 | ``` 52 | npm run lint 53 | ``` 54 | 55 | ### Enviar solución de reto 56 | 57 | Debes de crear un "Fork" de este proyecto, revolver los problemas y crear un Pull Request hacia tu repositorio. 58 | 59 | ### Contribuir 60 | 61 | Si alguien quiere agregar o mejorar algo, lo invito a colaborar directamente en este repositorio: [react-eth-challenge](https://github.com/gndx/react-eth-challenge/) 62 | 63 | ### Licencia 64 | 65 | frontend se lanza bajo la licencia [MIT](https://opensource.org/licenses/MIT). 66 | -------------------------------------------------------------------------------- /data.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "name": "Melissa Walsh", 4 | "profession": "FrontEnd Developer", 5 | "address": "Bogotá, Colombia.", 6 | "email": "melissa@example.com", 7 | "website": "https://example.com", 8 | "phone": "3042034240", 9 | "avatar": "https://arepa.s3.amazonaws.com/melissa.jpg", 10 | "Profile": "Ignore the squirrels, you'll never catch them anyway hack, for floof tum, tickle bum, jellybean footies curly toes climb leg roll over and sun my belly, ", 11 | "certificate": [ 12 | { 13 | "date": "Jan 2021", 14 | "description": "Hack up furballs try to jump onto window and fall while scratching at wall. ", 15 | "institution": "Platzi", 16 | "name": "FrontEnd Developer" 17 | }, 18 | { 19 | "date": "Jan 2021", 20 | "description": "Scratch at the door then walk away wack the mini furry mouse", 21 | "institution": "Platzi", 22 | "name": "Backend Developer" 23 | } 24 | ], 25 | "Academic": [ 26 | { 27 | "degree": "Atomic Master", 28 | "description": " I’m so hungry i’m so hungry but ew not for that pelt around the house and up and down stairs chasing phantoms", 29 | "endDate": "Jan 2017", 30 | "institution": "MIT", 31 | "startDate": "Jan 2018" 32 | }, 33 | { 34 | "degree": "Space Engineering", 35 | "description": "Meow in empty rooms. Find empty spot in cupboard and sleep all day check cat door for ambush 10 times before coming in for hack. ", 36 | "endDate": "Decenber 2015", 37 | "institution": "Harvard", 38 | "startDate": "Jan 2017" 39 | } 40 | ], 41 | "experience": [ 42 | { 43 | "company": "PugStar", 44 | "endDate": "Present", 45 | "jobDescription": "scratch the furniture. Good now the other hand, too lay on arms while you're using the keyboard.", 46 | "jobTitle": "Frontend", 47 | "startDate": "Jan 2020" 48 | }, 49 | { 50 | "company": "CatStore", 51 | "endDate": "Jan 2016", 52 | "jobDescription": "Meow in empty rooms lick left leg for ninety minutes, still dirty.", 53 | "jobTitle": "Backend", 54 | "startDate": "Sept 2019" 55 | } 56 | ], 57 | "skills": [ 58 | { 59 | "name": "HTML5", 60 | "percentage": "75%" 61 | }, 62 | { 63 | "name": "CSS", 64 | "percentage": "25%" 65 | }, 66 | { 67 | "name": "JavaScript", 68 | "percentage": "55%" 69 | }, 70 | { 71 | "name": "React", 72 | "percentage": "90%" 73 | } 74 | ], 75 | "interest": [ 76 | "javascript", 77 | "develop", 78 | "backend", 79 | "frontend" 80 | ], 81 | "languages": [ 82 | { 83 | "name": "Spanish", 84 | "percentage": "90%" 85 | }, 86 | { 87 | "name": "English", 88 | "percentage": "50%" 89 | } 90 | ], 91 | "social": [ 92 | { 93 | "name": "facebook", 94 | "url": "https://facebook.com/" 95 | }, 96 | { 97 | "name": "twitter", 98 | "url": "https://twitter.com/" 99 | }, 100 | { 101 | "name": "github", 102 | "url": "https://github.com/" 103 | }, 104 | { 105 | "name": "linkedin", 106 | "url": "https://www.linkedin.com/" 107 | } 108 | ] 109 | } 110 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-eth-challenge", 3 | "version": "1.0.0", 4 | "description": "React Eth Challenge", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "webpack --mode production", 8 | "start": "webpack-dev-server --open --mode development", 9 | "server": "json-server data.json", 10 | "format": "prettier --write '{*.js,src/**/*.{js,jsx}}'", 11 | "lint": "eslint src/ --fix", 12 | "test": "jest" 13 | }, 14 | "keywords": [ 15 | "react", 16 | "webpack" 17 | ], 18 | "author": "Oscar Barajas ", 19 | "license": "MIT", 20 | "dependencies": { 21 | "@babel/core": "7.18.6", 22 | "@babel/preset-env": "7.18.6", 23 | "@babel/preset-react": "7.18.6", 24 | "babel-loader": "8.2.5", 25 | "enzyme": "3.11.0", 26 | "enzyme-adapter-react-16": "1.15.6", 27 | "html-loader": "3.1.2", 28 | "html-webpack-plugin": "5.5.0", 29 | "jest-fetch-mock": "3.0.3", 30 | "react": "18.2.0", 31 | "react-dom": "18.2.0", 32 | "webpack": "5.73.0", 33 | "webpack-cli": "4.10.0", 34 | "webpack-dev-server": "4.9.3" 35 | }, 36 | "devDependencies": { 37 | "babel-eslint": "10.1.0", 38 | "css-loader": "6.7.1", 39 | "eslint": "8.19.0", 40 | "eslint-config-airbnb": "19.0.4", 41 | "eslint-config-prettier": "8.5.0", 42 | "eslint-plugin-import": "2.26.0", 43 | "eslint-plugin-jest": "26.5.3", 44 | "eslint-plugin-jsx-a11y": "6.6.0", 45 | "eslint-plugin-prettier": "3.1.2", 46 | "eslint-plugin-react": "7.30.1", 47 | "husky": "8.0.1", 48 | "jest": "28.1.2", 49 | "json-server": "^0.17.0", 50 | "mini-css-extract-plugin": "2.6.1", 51 | "prettier": "2.7.1", 52 | "style-loader": "3.3.1", 53 | "stylus": "0.58.1", 54 | "stylus-loader": "7.0.0" 55 | }, 56 | "jest": { 57 | "verbose": true, 58 | "moduleNameMapper": { 59 | "\\.(styl|css)$": "/src/__mocks__/styleMock.js" 60 | }, 61 | "setupFilesAfterEnv": [ 62 | "/src/__test__/setupTest.js" 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Base 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gndx/react-eth-challenge/8c8cff915e5373bbbcf8aa9f95f29952ff1769d6/screenshot.png -------------------------------------------------------------------------------- /src/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {}; 2 | -------------------------------------------------------------------------------- /src/__test__/Utils/AgetData.test.js: -------------------------------------------------------------------------------- 1 | import getData from '../../utils/getData'; 2 | 3 | describe('Fetch API', () => { 4 | beforeEach(() => { 5 | fetch.resetMocks(); 6 | }); 7 | 8 | test('Test API', () => { 9 | fetch.mockResponseOnce(JSON.stringify({ data: '12345' })); 10 | 11 | getData('https://google.com').then((res) => { 12 | expect(res.data).toEqual('12345'); 13 | }); 14 | expect(fetch.mock.calls.length).toEqual(1); 15 | expect(fetch.mock.calls[0][0]).toEqual('https://google.com'); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/__test__/components/About.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import About from '../../components/About'; 4 | 5 | describe('', () => { 6 | const about = mount(); 7 | 8 | test('About render', () => { 9 | expect(about.length).toEqual(1); 10 | }); 11 | 12 | test('About title', () => { 13 | expect(about.find('.About-title').length).toEqual(1); 14 | }); 15 | 16 | test('About haves 3 items', () => { 17 | expect(about.find('.About-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Academic.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Academic from '../../components/Academic'; 4 | 5 | describe('', () => { 6 | const academic = mount(); 7 | 8 | test('Academic render', () => { 9 | expect(academic.length).toEqual(1); 10 | }); 11 | 12 | test('Academic title', () => { 13 | expect(academic.find('.Academic-title').length).toEqual(1); 14 | }); 15 | 16 | test('Academic has 3 items', () => { 17 | expect(academic.find('.Academic-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Experience.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Experience from '../../components/Experience'; 4 | 5 | describe('', () => { 6 | const experience = mount(); 7 | 8 | test('Experience render', () => { 9 | expect(experience.length).toEqual(1); 10 | }); 11 | 12 | test('Experience title', () => { 13 | expect(experience.find('.Experience-title').length).toEqual(1); 14 | }); 15 | 16 | test('Experience haves 3 items', () => { 17 | expect(experience.find('.Experience-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Header.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Header from '../../components/Header'; 4 | 5 | describe('
', () => { 6 | const header = mount(
); 7 | 8 | test('Header render', () => { 9 | expect(header.length).toEqual(1); 10 | }); 11 | 12 | test('Header title', () => { 13 | expect(header.find('.Header-title').length).toEqual(1); 14 | }); 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /src/__test__/components/Interest.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Interest from '../../components/Interest'; 4 | 5 | describe('', () => { 6 | const interest = mount(); 7 | 8 | test('Interest render', () => { 9 | expect(interest.length).toEqual(1); 10 | }); 11 | 12 | test('Interest title', () => { 13 | expect(interest.find('.Interest-title').length).toEqual(1); 14 | }); 15 | 16 | test('Interest has 3 items', () => { 17 | expect(interest.find('.Interest-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Languages.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Languages from '../../components/Languages'; 4 | 5 | describe('', () => { 6 | const languages = mount(); 7 | 8 | test('Languages render', () => { 9 | expect(languages.length).toEqual(1); 10 | }); 11 | 12 | test('Languages title', () => { 13 | expect(languages.find('.Languages-title').length).toEqual(1); 14 | }); 15 | 16 | test('Languages has 3 items', () => { 17 | expect(languages.find('.Languages-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Profile.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Profile from '../../components/Profile'; 4 | 5 | describe('', () => { 6 | const profile = mount(); 7 | 8 | test('Profile render', () => { 9 | expect(profile.length).toEqual(1); 10 | }); 11 | 12 | test('Profile title', () => { 13 | expect(profile.find('.Profile-title').length).toEqual(1); 14 | }); 15 | 16 | test('Profile have a description', () => { 17 | expect(profile.find('.Profile-desc').length).toEqual(1); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/components/Skills.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'enzyme'; 3 | import Skills from '../../components/Skills'; 4 | 5 | describe('', () => { 6 | const skills = mount(); 7 | 8 | test('Skills render', () => { 9 | expect(skills.length).toEqual(1); 10 | }); 11 | 12 | test('Skills title', () => { 13 | expect(skills.find('.Skills-title').length).toEqual(1); 14 | }); 15 | 16 | test('Skills has 3 items', () => { 17 | expect(skills.find('.Skills-item').length).toBeGreaterThan(2); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/__test__/setupTest.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | global.fetch = require('jest-fetch-mock'); 6 | -------------------------------------------------------------------------------- /src/containers/App.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../styles/components/App.styl'; 3 | import Header from '../components/Header'; 4 | import About from '../components/About'; 5 | import Profile from '../components/Profile'; 6 | import Experience from '../components/Experience'; 7 | import Academic from '../components/Academic'; 8 | import Skills from '../components/Skills'; 9 | import Interest from '../components/Interest'; 10 | import Languages from '../components/Languages'; 11 | 12 | const App = () => { 13 | return ( 14 | <> 15 |
16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ) 26 | }; 27 | 28 | export default App; 29 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './containers/App'; 4 | 5 | ReactDOM.render(, document.getElementById('app')); 6 | -------------------------------------------------------------------------------- /src/styles/components/App.styl: -------------------------------------------------------------------------------- 1 | body 2 | background-color blue -------------------------------------------------------------------------------- /src/utils/getData.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gndx/react-eth-challenge/8c8cff915e5373bbbcf8aa9f95f29952ff1769d6/src/utils/getData.js -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebPackPlugin = require('html-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | 5 | module.exports = { 6 | entry: './src/index.js', 7 | output: { 8 | path: path.resolve(__dirname, 'dist'), 9 | filename: 'bundle.js', 10 | }, 11 | resolve: { 12 | extensions: ['.js', '.jsx'], 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.(js|jsx)$/, 18 | exclude: /node_modules/, 19 | use: { 20 | loader: 'babel-loader', 21 | }, 22 | }, 23 | { 24 | test: /\.html$/, 25 | use: [ 26 | { 27 | loader: 'html-loader', 28 | }, 29 | ], 30 | }, 31 | { 32 | test: /\.css|.styl$/, 33 | use: [ 34 | { 35 | loader: MiniCssExtractPlugin.loader, 36 | }, 37 | 'css-loader', 38 | 'stylus-loader', 39 | ], 40 | }, 41 | ], 42 | }, 43 | plugins: [ 44 | new HtmlWebPackPlugin({ 45 | template: './public/index.html', 46 | filename: './index.html', 47 | }), 48 | new MiniCssExtractPlugin({ 49 | filename: 'assets/[name].css', 50 | }), 51 | ], 52 | }; 53 | --------------------------------------------------------------------------------