From 3fc7df398159c6793784dc26e4bc03266390d62a Mon Sep 17 00:00:00 2001 From: kamleshchandnani Date: Sat, 31 Mar 2018 12:17:21 +0530 Subject: [PATCH] Error Boundaries solution --- solutions/src/error-boundaries/api/repos.js | 23 ++++++ solutions/src/error-boundaries/api/user.js | 16 +++++ .../components/common/errorImage.js | 6 ++ .../components/common/link.js | 21 ++++++ .../components/common/logo.js | 5 ++ .../error-boundaries/components/common/nav.js | 41 +++++++++++ .../components/library/anchor.js | 10 +++ .../components/library/avatar.js | 15 ++++ .../components/library/blink.js | 9 +++ .../components/library/button.js | 18 +++++ .../components/library/card.js | 10 +++ .../components/library/clear.js | 7 ++ .../components/library/input.js | 18 +++++ .../components/library/label.js | 10 +++ .../components/library/star.js | 11 +++ solutions/src/error-boundaries/img/error.jpg | Bin 0 -> 55229 bytes .../src/error-boundaries/img/github-logo.png | Bin 0 -> 8136 bytes solutions/src/error-boundaries/index.js | 15 ++++ .../modules/ErrorBoundary/index.js | 47 ++++++++++++ .../modules/Profile/description.js | 8 +++ .../error-boundaries/modules/Profile/index.js | 52 ++++++++++++++ .../modules/Profile/profile-input.js | 67 ++++++++++++++++++ .../modules/Profile/profile.js | 30 ++++++++ .../modules/Profile/repositories.js | 40 +++++++++++ 24 files changed, 479 insertions(+) create mode 100644 solutions/src/error-boundaries/api/repos.js create mode 100644 solutions/src/error-boundaries/api/user.js create mode 100644 solutions/src/error-boundaries/components/common/errorImage.js create mode 100644 solutions/src/error-boundaries/components/common/link.js create mode 100644 solutions/src/error-boundaries/components/common/logo.js create mode 100644 solutions/src/error-boundaries/components/common/nav.js create mode 100644 solutions/src/error-boundaries/components/library/anchor.js create mode 100644 solutions/src/error-boundaries/components/library/avatar.js create mode 100644 solutions/src/error-boundaries/components/library/blink.js create mode 100644 solutions/src/error-boundaries/components/library/button.js create mode 100644 solutions/src/error-boundaries/components/library/card.js create mode 100644 solutions/src/error-boundaries/components/library/clear.js create mode 100644 solutions/src/error-boundaries/components/library/input.js create mode 100644 solutions/src/error-boundaries/components/library/label.js create mode 100644 solutions/src/error-boundaries/components/library/star.js create mode 100644 solutions/src/error-boundaries/img/error.jpg create mode 100644 solutions/src/error-boundaries/img/github-logo.png create mode 100644 solutions/src/error-boundaries/index.js create mode 100644 solutions/src/error-boundaries/modules/ErrorBoundary/index.js create mode 100644 solutions/src/error-boundaries/modules/Profile/description.js create mode 100644 solutions/src/error-boundaries/modules/Profile/index.js create mode 100644 solutions/src/error-boundaries/modules/Profile/profile-input.js create mode 100644 solutions/src/error-boundaries/modules/Profile/profile.js create mode 100644 solutions/src/error-boundaries/modules/Profile/repositories.js diff --git a/solutions/src/error-boundaries/api/repos.js b/solutions/src/error-boundaries/api/repos.js new file mode 100644 index 0000000..1a3080a --- /dev/null +++ b/solutions/src/error-boundaries/api/repos.js @@ -0,0 +1,23 @@ +export const getRepos = username => { + return fetch(`https://api.github.com/users/${username}/repos?sort=updated`) + .then(response => response.json()) + .then(data => { + let repos = data.map(repo => { + return { + id: repo.id, + name: repo.name, + stars: repo.stargazers_count, + description: repo.description, + url: repo.html_url + }; + }); + repos = repos.sort((a, b) => b.stars - a.stars).slice(0, 5); + return repos; + }) + .catch(error => { + /* Error handling */ + return { + error + }; + }); +}; diff --git a/solutions/src/error-boundaries/api/user.js b/solutions/src/error-boundaries/api/user.js new file mode 100644 index 0000000..7eb946a --- /dev/null +++ b/solutions/src/error-boundaries/api/user.js @@ -0,0 +1,16 @@ +export const getUser = username => { + return fetch(`https://api.github.com/users/${username}`) + .then(response => response.json()) + .then(data => { + return { + username: data.login, + name: data.name, + photo: data.avatar_url, + bio: data.bio || "no description", + url: data.html_url + }; + }) + .catch(error => { + return { error }; + }); +}; diff --git a/solutions/src/error-boundaries/components/common/errorImage.js b/solutions/src/error-boundaries/components/common/errorImage.js new file mode 100644 index 0000000..432ae59 --- /dev/null +++ b/solutions/src/error-boundaries/components/common/errorImage.js @@ -0,0 +1,6 @@ +import React from "react"; +import errorImage from "../../img/error.jpg"; + +const ErrorImage = () => error; + +export default ErrorImage; diff --git a/solutions/src/error-boundaries/components/common/link.js b/solutions/src/error-boundaries/components/common/link.js new file mode 100644 index 0000000..3ce633d --- /dev/null +++ b/solutions/src/error-boundaries/components/common/link.js @@ -0,0 +1,21 @@ +import React from "react"; +import styled from "styled-components"; + +import A from "../library/anchor"; +import Blink from "../library/blink"; + +const Loading = styled(A)` + background: #6ed396; + width: 40%; + height: 22px; + margin-top: 10px; + &::before { + content: "x"; + } + animation: ${Blink} 2s linear infinite; +`; + +export default props => { + if (props.url) return {props.children}; + else return ; +}; diff --git a/solutions/src/error-boundaries/components/common/logo.js b/solutions/src/error-boundaries/components/common/logo.js new file mode 100644 index 0000000..16b3796 --- /dev/null +++ b/solutions/src/error-boundaries/components/common/logo.js @@ -0,0 +1,5 @@ +import React from "react"; +import githubLogo from "../../img/github-logo.png"; +const Logo = () => github; + +export default Logo; diff --git a/solutions/src/error-boundaries/components/common/nav.js b/solutions/src/error-boundaries/components/common/nav.js new file mode 100644 index 0000000..98a943a --- /dev/null +++ b/solutions/src/error-boundaries/components/common/nav.js @@ -0,0 +1,41 @@ +import React from "react"; +import styled, { injectGlobal } from "styled-components"; +import Logo from "./logo"; +import Helmet from "react-helmet"; + +injectGlobal` + body { + margin: 0; + padding: 0; + background: #EEE; + font-family: 'Nunito', sans-serif; + } +`; + +const NavBar = styled.div` + height: 30px; + padding: 10px; + background: #fff; + border-bottom: 1px solid #ddd; + text-align: center; + > img { + height: 30px; + } +`; + +const Nav = () => ( + + + + +); + +export default Nav; diff --git a/solutions/src/error-boundaries/components/library/anchor.js b/solutions/src/error-boundaries/components/library/anchor.js new file mode 100644 index 0000000..7a60833 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/anchor.js @@ -0,0 +1,10 @@ +import styled from "styled-components"; + +const A = styled.a` + text-decoration: none; + color: #6ed396; + display: inline-block; + width: "20px"; +`; + +export default A; diff --git a/solutions/src/error-boundaries/components/library/avatar.js b/solutions/src/error-boundaries/components/library/avatar.js new file mode 100644 index 0000000..f563d31 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/avatar.js @@ -0,0 +1,15 @@ +import React from 'react' +import styled from 'styled-components' + +const Avatar = styled.span` + display: inline-block; + height: 100px; + width: 100px; + border-radius: 50%; + border: 5px solid #EEE; + background-color: #EEE; + ${props => (props.src ? `background-image: url(${props.src})` : '')}; + background-size: cover; +` + +export default props => diff --git a/solutions/src/error-boundaries/components/library/blink.js b/solutions/src/error-boundaries/components/library/blink.js new file mode 100644 index 0000000..9a8f46d --- /dev/null +++ b/solutions/src/error-boundaries/components/library/blink.js @@ -0,0 +1,9 @@ +import { keyframes } from 'styled-components' + +const Blink = keyframes` + 0% {opacity: 0.1} + 50% {opacity: 0.3} + 100% {opacity: 0.1} +` + +export default Blink diff --git a/solutions/src/error-boundaries/components/library/button.js b/solutions/src/error-boundaries/components/library/button.js new file mode 100644 index 0000000..daaa889 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/button.js @@ -0,0 +1,18 @@ +import styled from "styled-components"; + +const Button = styled.button` + background: #0eb550; + color: #fff; + border: 1px solid #1d99bd; + border-radius: 2px; + padding: 10px; + margin-top: 20px; + width: 100%; + outline: none; + font-size: 16px; + &:active { + background: #6ed396; + } +`; + +export default Button; diff --git a/solutions/src/error-boundaries/components/library/card.js b/solutions/src/error-boundaries/components/library/card.js new file mode 100644 index 0000000..3070808 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/card.js @@ -0,0 +1,10 @@ +import styled from 'styled-components' + +const Card = styled.div` + background: #FFF; + border: 1px solid #DDD; + border-radius: 2px; + padding: 10px; +` + +export default Card diff --git a/solutions/src/error-boundaries/components/library/clear.js b/solutions/src/error-boundaries/components/library/clear.js new file mode 100644 index 0000000..67b0b93 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/clear.js @@ -0,0 +1,7 @@ +import styled from 'styled-components' + +const Clear = styled.div` + clear: both; +` + +export default Clear diff --git a/solutions/src/error-boundaries/components/library/input.js b/solutions/src/error-boundaries/components/library/input.js new file mode 100644 index 0000000..00ff788 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/input.js @@ -0,0 +1,18 @@ +import styled from "styled-components"; + +const Input = styled.input` + background: #fff; + border: 1px solid #ddd; + border-radius: 2px; + padding: 10px; + width: calc(100% - 20px); + outline: none; + font-size: 16px; + + &:hover, + &:focus { + border-color: #6ed396; + } +`; + +export default Input; diff --git a/solutions/src/error-boundaries/components/library/label.js b/solutions/src/error-boundaries/components/library/label.js new file mode 100644 index 0000000..a59b655 --- /dev/null +++ b/solutions/src/error-boundaries/components/library/label.js @@ -0,0 +1,10 @@ +import styled from "styled-components"; + +const Label = styled.div` + height: 30px; + padding: 10px; + text-align: center; + color: ${props => props.color || "#0EB550"}; +`; + +export default Label; diff --git a/solutions/src/error-boundaries/components/library/star.js b/solutions/src/error-boundaries/components/library/star.js new file mode 100644 index 0000000..015aeac --- /dev/null +++ b/solutions/src/error-boundaries/components/library/star.js @@ -0,0 +1,11 @@ +import styled from 'styled-components' + +const Star = styled.span` + margin: 10px; + &::after { + content: ' \\2605'; + color: gold; + } +` + +export default Star diff --git a/solutions/src/error-boundaries/img/error.jpg b/solutions/src/error-boundaries/img/error.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f45d01e01af18e5eabab05984e6d8dd8fe9bef0 GIT binary patch literal 55229 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 V!%f|5^`HN8SxH5SYB8hW{{eSumKXp4 literal 0 HcmV?d00001 diff --git a/solutions/src/error-boundaries/index.js b/solutions/src/error-boundaries/index.js new file mode 100644 index 0000000..53932a3 --- /dev/null +++ b/solutions/src/error-boundaries/index.js @@ -0,0 +1,15 @@ +import React, { Component } from "react"; +import Profile from "./modules/Profile"; +import ErrorBoundary from "./modules/ErrorBoundary"; + +class App extends Component { + render() { + return ( + + + + ); + } +} + +export default App; diff --git a/solutions/src/error-boundaries/modules/ErrorBoundary/index.js b/solutions/src/error-boundaries/modules/ErrorBoundary/index.js new file mode 100644 index 0000000..b370586 --- /dev/null +++ b/solutions/src/error-boundaries/modules/ErrorBoundary/index.js @@ -0,0 +1,47 @@ +import React, { Component } from "react"; +import styled from "styled-components"; +import ErrorImage from "../../components/common/errorImage"; +import Card from "../../components/library/card"; +import Button from "../../components/library/button"; +import Label from "../../components/library/label"; +const ErrorCard = styled(Card)` + text-align: center; + box-sizing: border-box; + margin: 20px auto 0; + padding: 30px 50px; + width: 500px; + min-height: 100px; + color: #000000; + + @media (max-width: 600px) { + width: 90%; + } +`; + +export default class ErrorBoundary extends Component { + state = { hasError: false }; + + componentDidCatch(error, info) { + // Display fallback UI + this.setState({ hasError: true }); + // You can also log the error to an error reporting service + // logErrorToMyService(error, info); + } + reloadPage = () => { + window.location.reload(); + }; + render() { + console.log("chekc here", this.state); + if (this.state.hasError) { + // You can render any custom fallback UI + return ( + + + + + + ); + } + return this.props.children; + } +} diff --git a/solutions/src/error-boundaries/modules/Profile/description.js b/solutions/src/error-boundaries/modules/Profile/description.js new file mode 100644 index 0000000..f3efc3f --- /dev/null +++ b/solutions/src/error-boundaries/modules/Profile/description.js @@ -0,0 +1,8 @@ +import React from 'react' +import styled from 'styled-components' +const Description = styled.div` + color: #999; + font-size: 12px; +` + +export default props => {props.content} diff --git a/solutions/src/error-boundaries/modules/Profile/index.js b/solutions/src/error-boundaries/modules/Profile/index.js new file mode 100644 index 0000000..2c0e7e9 --- /dev/null +++ b/solutions/src/error-boundaries/modules/Profile/index.js @@ -0,0 +1,52 @@ +import React, { Component, Fragment } from "react"; +import { getRepos } from "../../api/repos"; +import { getUser } from "../../api/user"; +import ProfileInput from "./profile-input"; +import UserProfile from "./profile"; +import Repositories from "./repositories"; +import Card from "../../components/library/card"; +import Nav from "../../components/common/nav"; +import styled from "styled-components"; + +const RepositoriesCard = styled(Card)` + text-align: center; + box-sizing: border-box; + margin: 20px auto 0; + padding: 30px 50px; + width: 500px; + min-height: 100px; + color: #000000; + + @media (max-width: 600px) { + width: 90%; + } +`; +export default class Profile extends Component { + state = { + userRepos: [{}, {}, {}, {}, {}], + userProfile: {} + }; + getUserInfo = userName => { + getUser(userName).then(userProfile => this.setState({ userProfile })); + getRepos(userName).then(userRepos => this.setState({ userRepos })); + }; + render() { + const { userRepos, userProfile } = this.state; + let RepositoriesData = ( + + + + + ); + + if (!userProfile.url) { + RepositoriesData = No Data Found..; + } + return ( + + + {RepositoriesData} + + ); + } +} diff --git a/solutions/src/error-boundaries/modules/Profile/profile-input.js b/solutions/src/error-boundaries/modules/Profile/profile-input.js new file mode 100644 index 0000000..f8b5926 --- /dev/null +++ b/solutions/src/error-boundaries/modules/Profile/profile-input.js @@ -0,0 +1,67 @@ +import React from "react"; +import styled from "styled-components"; +import Card from "../../components/library/card"; +import Input from "../../components/library/input"; +import Button from "../../components/library/button"; +import Logo from "../../components/common/logo"; + +const ProfileInput = styled(Card)` + text-align: center; + box-sizing: border-box; + width: 500px; + margin: 20px auto 0; + padding: 30px 50px; + min-height: 100px; + + @media (max-width: 600px) { + width: 90%; + } + + > input { + margin-top: 30px; + } + + > a { + width: 100%; + margin-top: 10px; + } +`; + +export default class extends React.Component { + /* Set initial state */ + state = { username: "" }; + /* Change state on change */ + onChange = event => { + this.setState({ username: event.target.value }); + }; + /* Trigger submit on enter key */ + onKeyUp = event => { + if (event.which === 13) this.setState({ username: event.target.value }); + }; + /* Pick value from input on focus */ + onFocus = event => { + this.setState({ username: event.target.value }); + }; + getUserInfo = () => { + this.props.getUserInfo(this.state.username); + }; + /* + Compose presentation components inside our + ProfileInput components + */ + render() { + return ( + + + + + + ); + } +} diff --git a/solutions/src/error-boundaries/modules/Profile/profile.js b/solutions/src/error-boundaries/modules/Profile/profile.js new file mode 100644 index 0000000..ebc76d7 --- /dev/null +++ b/solutions/src/error-boundaries/modules/Profile/profile.js @@ -0,0 +1,30 @@ +import React from "react"; +import styled from "styled-components"; +import Card from "../../components/library/card"; +import Link from "../../components/common/link"; + +import Avatar from "../../components/library/avatar"; +import Description from "./description"; + +const ProfileCard = styled(Card)` + text-align: center; + box-sizing: border-box; + margin: 50px auto 0; + min-height: 180px; + + @media (max-width: 600px) { + width: 90%; + } +`; +const Profile = ({ userProfile }) => { + return ( + + +
    + {userProfile.name} +
    + +
    + ); +}; +export default Profile; diff --git a/solutions/src/error-boundaries/modules/Profile/repositories.js b/solutions/src/error-boundaries/modules/Profile/repositories.js new file mode 100644 index 0000000..35680d5 --- /dev/null +++ b/solutions/src/error-boundaries/modules/Profile/repositories.js @@ -0,0 +1,40 @@ +import React from "react"; +import styled from "styled-components"; +import Card from "../../components/library/card"; +import Star from "../../components/library/star"; +import Clear from "../../components/library/clear"; +import Link from "../../components/common/link"; + +const RepoList = styled(Card)` + margin: 10px auto; + box-sizing: border-box; + min-height: 215px; + + @media (max-width: 600px) { + width: 90%; + } +`; + +const Repo = styled.div` + color: #777; + > a { + float: left; + margin-top: 10px; + } + > span { + float: right; + } +`; + +export default props => ( + + {props.repos && + props.repos.map((repo, index) => ( + + {repo.name} + {repo.stars} + + + ))} + +);