From e2064e69f37ac36453e8c98d7d9ed9881429f4f8 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sat, 13 Oct 2018 23:57:18 +0200 Subject: [PATCH 01/10] feature: add avatar atom component --- src/atoms/avatar/avatar.js | 28 ++++++++++++++++++++++++++++ src/atoms/avatar/elements.js | 25 +++++++++++++++++++++++++ src/atoms/avatar/index.js | 1 + 3 files changed, 54 insertions(+) create mode 100644 src/atoms/avatar/avatar.js create mode 100644 src/atoms/avatar/elements.js create mode 100644 src/atoms/avatar/index.js diff --git a/src/atoms/avatar/avatar.js b/src/atoms/avatar/avatar.js new file mode 100644 index 0000000..6f16338 --- /dev/null +++ b/src/atoms/avatar/avatar.js @@ -0,0 +1,28 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { AvatarContainer, AvatarImage } from './elements'; + +export default function AvatarAtom(props) { + return ( + + + + ); +} + +AvatarAtom.propTypes = { + /** The absolute URL to the image. */ + url: PropTypes.string.isRequired, + /** The name of the person who is displayed, to use as the alternative text for the image. */ + name: PropTypes.string.isRequired, + /** The title to display when hovering the avatar. */ + title: PropTypes.string, +}; + +AvatarAtom.propTypes = { + title: undefined, +}; diff --git a/src/atoms/avatar/elements.js b/src/atoms/avatar/elements.js new file mode 100644 index 0000000..7b619d7 --- /dev/null +++ b/src/atoms/avatar/elements.js @@ -0,0 +1,25 @@ +import styled from 'styled-components'; + +/** + * The avatar container "masks" the underlying image and makes it circular. + * It creates an element with rounded corners with overflow hidden. + */ +export const AvatarContainer = styled.div` + display: block; + border-radius: 50%; + background: currentColor; + width: 3.75em; + height: 3.75em; + overflow: hidden; + user-select: none; +`; + +/** + * The avatar image contains the actual image to display, set to fully "cover" the element. + * To fully cover the avatar the image will be scaled and cropped maintaining aspect ratio. + */ +export const AvatarImage = styled.img` + width: 100%; + height: 100%; + object-fit: cover; +`; diff --git a/src/atoms/avatar/index.js b/src/atoms/avatar/index.js new file mode 100644 index 0000000..5681a65 --- /dev/null +++ b/src/atoms/avatar/index.js @@ -0,0 +1 @@ +export { default } from './avatar'; From 5b5d14579cd0d1ab5373d653e784947641cb4fc4 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:05:45 +0200 Subject: [PATCH 02/10] feature: add user molecule component --- src/molecules/user/elements.js | 54 ++++++++++++++++++++++++++++++++++ src/molecules/user/index.js | 1 + src/molecules/user/user.js | 47 +++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/molecules/user/elements.js create mode 100644 src/molecules/user/index.js create mode 100644 src/molecules/user/user.js diff --git a/src/molecules/user/elements.js b/src/molecules/user/elements.js new file mode 100644 index 0000000..0a632c7 --- /dev/null +++ b/src/molecules/user/elements.js @@ -0,0 +1,54 @@ +import styled from 'styled-components'; + +/** + * The user container creates a vertical-directed flexbox. + * It also centers the content to connect the otherwise unrelated content visually. + */ +export const UserContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; + color: #6a737d; +`; + +/** + * The user avatar aligns the user's avatar with the name, using flexbox. + * This technique is also applied for the description to center the user's name correctly. + */ +export const UserAvatar = styled.div` + display: flex; + flex: 1; + align-items: flex-end; + padding: 0.5rem; + font-size: 1.5em; +`; + +/** + * The user's name is also the title of the app and is therefore vertically centered. + * It's positioned with flexbox to achieve this without knowing the sizes of both the avatar and description. + */ +export const UserName = styled.h1` + flex: 0; + margin: 0; + padding: 0.5rem; + line-height: 1.5; + color: #24292e; + font-size: 2em; +`; + +/** + * The user description aligns the user's description with the name, using flexbox. + * Because of this flexbox positioning, the size of the text has no impact on the alignment. + * This technique is also applied for the avatar to center the name correctly. + */ +export const UserDescription = styled.p` + display: flex; + flex: 1; + align-items: flex-start; + margin: 0; + padding: 0.5rem; + width: 100%; + max-width: 24em; + text-align: center; + line-height: 1.5; +`; diff --git a/src/molecules/user/index.js b/src/molecules/user/index.js new file mode 100644 index 0000000..e66fd7e --- /dev/null +++ b/src/molecules/user/index.js @@ -0,0 +1 @@ +export { default } from './user'; diff --git a/src/molecules/user/user.js b/src/molecules/user/user.js new file mode 100644 index 0000000..e3b12bb --- /dev/null +++ b/src/molecules/user/user.js @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Avatar from 'src/atoms/avatar'; + +import { + UserContainer, + UserAvatar, + UserName, + UserDescription, +} from './elements'; + +export default function UserMolecule(props) { + const identifier = `${props.name} (${props.username})`; + + return ( + + + + + + {props.name} + + + {props.description} + + + ); +} + +UserMolecule.propTypes = { + /** The full name of the person who is displayed. */ + name: PropTypes.string.isRequired, + /** The username of the person who is displayed. */ + username: PropTypes.string.isRequired, + /** The absolute URL of the person's avatar. */ + avatarUrl: PropTypes.string.isRequired, + /** An optional description of this person. */ + description: PropTypes.string, +}; + +UserMolecule.defaultProps = { + description: '', +}; From 9902b10df06d2b9864a659b1e45c6af6f41d99c4 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:10:54 +0200 Subject: [PATCH 03/10] feature: add github provider and user organism --- src/organisms/github-user/github-user.js | 20 ++++++++++++++++++ src/organisms/github-user/index.js | 1 + src/providers/github.js | 26 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 src/organisms/github-user/github-user.js create mode 100644 src/organisms/github-user/index.js create mode 100644 src/providers/github.js diff --git a/src/organisms/github-user/github-user.js b/src/organisms/github-user/github-user.js new file mode 100644 index 0000000..4bf2873 --- /dev/null +++ b/src/organisms/github-user/github-user.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { AsyncUser } from 'src/providers/github'; +import User from 'src/molecules/user'; + +export default function GithubUserOrganism() { + return ( + + + {data => ( + + )} + + + ); +} diff --git a/src/organisms/github-user/index.js b/src/organisms/github-user/index.js new file mode 100644 index 0000000..389738b --- /dev/null +++ b/src/organisms/github-user/index.js @@ -0,0 +1 @@ +export { default } from './github-user'; diff --git a/src/providers/github.js b/src/providers/github.js new file mode 100644 index 0000000..07cb273 --- /dev/null +++ b/src/providers/github.js @@ -0,0 +1,26 @@ +import { createInstance } from 'react-async'; + +/** + * The GitHub username to fetch information from. + */ +export const username = process.env.GITHUB_USERNAME || 'byCedric'; + +/** + * Fetch the user information from the GitHub API. + * + * @see https://developer.github.com/v3/users/#get-a-single-user + * @return {Promise} + */ +export const fetchUser = () => ( + fetch(`https://api.github.com/users/${username}`) + .then(response => response.json()) +) + +/** + * Export a predefined React Async component instance. + * This creates a custom context for improved nesting and predefines the promise. + * + * @see https://github.com/ghengeveld/react-async + * @return {React.Component} + */ +export const AsyncUser = createInstance({ promiseFn: fetchUser }); From de8e837da5cb93523296fb91055ed22e424a8505 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:11:49 +0200 Subject: [PATCH 04/10] refactor: remove default app page --- src/pages/app/App.css | 32 -------------------------------- src/pages/app/App.js | 28 ---------------------------- src/pages/app/App.test.js | 9 --------- src/pages/app/index.js | 1 - 4 files changed, 70 deletions(-) delete mode 100644 src/pages/app/App.css delete mode 100644 src/pages/app/App.js delete mode 100644 src/pages/app/App.test.js delete mode 100644 src/pages/app/index.js diff --git a/src/pages/app/App.css b/src/pages/app/App.css deleted file mode 100644 index 1a32fce..0000000 --- a/src/pages/app/App.css +++ /dev/null @@ -1,32 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 40vmin; -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/pages/app/App.js b/src/pages/app/App.js deleted file mode 100644 index 4d6521e..0000000 --- a/src/pages/app/App.js +++ /dev/null @@ -1,28 +0,0 @@ -import React, { Component } from 'react'; -import logo from 'src/assets/logo.svg'; -import './App.css'; - -class App extends Component { - render() { - return ( -
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
-
- ); - } -} - -export default App; diff --git a/src/pages/app/App.test.js b/src/pages/app/App.test.js deleted file mode 100644 index 52d874c..0000000 --- a/src/pages/app/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; - -it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/src/pages/app/index.js b/src/pages/app/index.js deleted file mode 100644 index 9122fa1..0000000 --- a/src/pages/app/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './App'; From c7a27d4ea77ef2b3ca5c2513622c067092140ce3 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:12:27 +0200 Subject: [PATCH 05/10] feature: add primary app page --- src/pages/app/app.js | 11 +++++++++++ src/pages/app/elements.js | 11 +++++++++++ src/pages/app/index.js | 1 + 3 files changed, 23 insertions(+) create mode 100644 src/pages/app/app.js create mode 100644 src/pages/app/elements.js create mode 100644 src/pages/app/index.js diff --git a/src/pages/app/app.js b/src/pages/app/app.js new file mode 100644 index 0000000..ff6e865 --- /dev/null +++ b/src/pages/app/app.js @@ -0,0 +1,11 @@ +import React from 'react'; +import GithubUser from 'src/organisms/github-user'; +import { AppContainer } from './elements'; + +export default function AppPage() { + return ( + + + + ); +} diff --git a/src/pages/app/elements.js b/src/pages/app/elements.js new file mode 100644 index 0000000..ef66d9a --- /dev/null +++ b/src/pages/app/elements.js @@ -0,0 +1,11 @@ +import styled from 'styled-components'; + +/** + * The app container wraps the content and centers it both horizontally and vertically. + */ +export const AppContainer = styled.div` + display: flex; + justify-content: center; + width: 100%; + height: 100%; +`; diff --git a/src/pages/app/index.js b/src/pages/app/index.js new file mode 100644 index 0000000..12e3617 --- /dev/null +++ b/src/pages/app/index.js @@ -0,0 +1 @@ +export { default } from './app'; From 593d3f5c061783ca027ac5592d592656f3a4421f Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:14:32 +0200 Subject: [PATCH 06/10] chore: update package file with used dependencies --- package.json | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 91e386a..f8bad6a 100644 --- a/package.json +++ b/package.json @@ -7,24 +7,26 @@ "type": "git", "url": "https://github.com/bycedric/github-website.git" }, - "dependencies": { - "react": "^16.5.2", - "react-dom": "^16.5.2", - "react-scripts": "2.0.1" - }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, + "dependencies": { + "prop-types": "^15.6.2", + "react": "^16.5.2", + "react-async": "^3.8.1", + "react-dom": "^16.5.2", + "styled-components": "^3.4.10" + }, "devDependencies": { "@commitlint/travis-cli": "^7.1.2", "@peakfijn/config-commitlint": "^0.8.0", "@semantic-release/changelog": "^3.0.0", "codecov": "^3.1.0", "conventional-changelog-peakfijn": "^0.8.0", - "flow-bin": "^0.81.0", + "react-scripts": "2.0.4", "release-rules-peakfijn": "^0.8.0", "semantic-release": "^15.9.16", "semantic-release-git-branches": "^1.2.1", @@ -48,7 +50,10 @@ "eslintConfig": { "extends": "react-app", "rules": { - "indent": ["error", "tab"] + "indent": [ + "error", + "tab" + ] } }, "stylelint": { From 81dbf4644736e3bf6db7ac27c64b89b5db359a80 Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:15:04 +0200 Subject: [PATCH 07/10] chore: disabled service workers for first version --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index ea2282b..98a7531 100644 --- a/src/index.js +++ b/src/index.js @@ -1,2 +1,2 @@ import 'src/providers/react'; -import 'src/providers/service-worker'; +// import 'src/providers/service-worker'; From b76e3a7b17e0525fa2d4325c686e489d855a409f Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:15:32 +0200 Subject: [PATCH 08/10] chore: add basic styling rules to template --- public/index.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 04c8d5d..28b1faf 100644 --- a/public/index.html +++ b/public/index.html @@ -21,6 +21,10 @@ --> React App From 8841eb3e4207d347c0613a40e2bc5d71d72bd89b Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:16:27 +0200 Subject: [PATCH 09/10] style: remove white line in import statements --- src/molecules/user/user.js | 1 - src/providers/react.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/molecules/user/user.js b/src/molecules/user/user.js index e3b12bb..f4c754c 100644 --- a/src/molecules/user/user.js +++ b/src/molecules/user/user.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import Avatar from 'src/atoms/avatar'; - import { UserContainer, UserAvatar, diff --git a/src/providers/react.js b/src/providers/react.js index 87d54b5..cb8fb2e 100644 --- a/src/providers/react.js +++ b/src/providers/react.js @@ -1,6 +1,5 @@ import React from 'react'; import { render } from 'react-dom'; - import App from 'src/pages/app'; render(, document.getElementById('root')); From fd26c077fb8f5e68132982e40f24fb84d0f5322b Mon Sep 17 00:00:00 2001 From: Cedric van Putten Date: Sun, 14 Oct 2018 00:27:56 +0200 Subject: [PATCH 10/10] pipeline: clean up flow and temporary disable tests --- .travis.yml | 1 - package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2582946..f4a96a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,6 @@ script: - npx commitlint-travis - npx stylelint ./src/**/*.js - npx eslint ./src - - npx flow - npm test -- --coverage after_success: - npx codecov diff --git a/package.json b/package.json index f8bad6a..00bc53b 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", + "test": "echo 'No tests specified (yet)'; exit 0", "eject": "react-scripts eject" }, "dependencies": {