Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Boundaries solution #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions solutions/src/error-boundaries/api/repos.js
Original file line number Diff line number Diff line change
@@ -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
};
});
};
16 changes: 16 additions & 0 deletions solutions/src/error-boundaries/api/user.js
Original file line number Diff line number Diff line change
@@ -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 };
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from "react";
import errorImage from "../../img/error.jpg";

const ErrorImage = () => <img alt="error" src={errorImage} />;

export default ErrorImage;
21 changes: 21 additions & 0 deletions solutions/src/error-boundaries/components/common/link.js
Original file line number Diff line number Diff line change
@@ -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 <A href={props.url}>{props.children}</A>;
else return <Loading />;
};
5 changes: 5 additions & 0 deletions solutions/src/error-boundaries/components/common/logo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";
import githubLogo from "../../img/github-logo.png";
const Logo = () => <img alt="github" src={githubLogo} />;

export default Logo;
41 changes: 41 additions & 0 deletions solutions/src/error-boundaries/components/common/nav.js
Original file line number Diff line number Diff line change
@@ -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 = () => (
<NavBar>
<Helmet
title="react-error"
link={[
{
href: "https://fonts.googleapis.com/css?family=Nunito",
rel: "stylesheet"
}
]}
/>
<Logo />
</NavBar>
);

export default Nav;
10 changes: 10 additions & 0 deletions solutions/src/error-boundaries/components/library/anchor.js
Original file line number Diff line number Diff line change
@@ -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;
15 changes: 15 additions & 0 deletions solutions/src/error-boundaries/components/library/avatar.js
Original file line number Diff line number Diff line change
@@ -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 => <Avatar src={props.url} />
9 changes: 9 additions & 0 deletions solutions/src/error-boundaries/components/library/blink.js
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions solutions/src/error-boundaries/components/library/button.js
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 10 additions & 0 deletions solutions/src/error-boundaries/components/library/card.js
Original file line number Diff line number Diff line change
@@ -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
7 changes: 7 additions & 0 deletions solutions/src/error-boundaries/components/library/clear.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from 'styled-components'

const Clear = styled.div`
clear: both;
`

export default Clear
18 changes: 18 additions & 0 deletions solutions/src/error-boundaries/components/library/input.js
Original file line number Diff line number Diff line change
@@ -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;
10 changes: 10 additions & 0 deletions solutions/src/error-boundaries/components/library/label.js
Original file line number Diff line number Diff line change
@@ -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;
11 changes: 11 additions & 0 deletions solutions/src/error-boundaries/components/library/star.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components'

const Star = styled.span`
margin: 10px;
&::after {
content: ' \\2605';
color: gold;
}
`

export default Star
Binary file added solutions/src/error-boundaries/img/error.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions solutions/src/error-boundaries/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<ErrorBoundary>
<Profile />
</ErrorBoundary>
);
}
}

export default App;
47 changes: 47 additions & 0 deletions solutions/src/error-boundaries/modules/ErrorBoundary/index.js
Original file line number Diff line number Diff line change
@@ -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 (
<ErrorCard>
<Label>Ahhh! Something went wrong.</Label>
<ErrorImage />
<Button onClick={this.reloadPage}>Reload</Button>
</ErrorCard>
);
}
return this.props.children;
}
}
8 changes: 8 additions & 0 deletions solutions/src/error-boundaries/modules/Profile/description.js
Original file line number Diff line number Diff line change
@@ -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 => <Description>{props.content}</Description>
52 changes: 52 additions & 0 deletions solutions/src/error-boundaries/modules/Profile/index.js
Original file line number Diff line number Diff line change
@@ -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 = (
<RepositoriesCard>
<UserProfile userProfile={userProfile} />
<Repositories repos={userRepos} />
</RepositoriesCard>
);

if (!userProfile.url) {
RepositoriesData = <RepositoriesCard>No Data Found..</RepositoriesCard>;
}
return (
<Fragment>
<ProfileInput getUserInfo={this.getUserInfo} />
{RepositoriesData}
</Fragment>
);
}
}
Loading