Skip to content

Commit

Permalink
ft(user): Implement error view for user experience
Browse files Browse the repository at this point in the history
  • Loading branch information
Blessing Makaraba authored and Blessing Makaraba committed Sep 26, 2021
1 parent 2827c5d commit 26f25a1
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 68 deletions.
53 changes: 22 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,37 @@
# Description
# GitHub-Users

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
GitHub Users is a React Web Application that enables customers to search for repositories and view details of contributors respectively. It is powered by [GITHUB-REST-API](https://docs.github.com/en/free-pro-team@latest/rest).

## Available Scripts
[Web-Application-Published-Link](https://github-users-blessing.netlify.app)

In the project directory, you can run:
#### Features

### `yarn start`
#### Required Features

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
- Search for repositories.
- View Contributors details in a repository.

The page will reload if you make edits.\
You will also see any lint errors in the console.
#### User Features

### `yarn test`
- Search for repositories.
- View Contributors details in a repository.

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
#### Tools

### `yarn build`
##### Dev Tools

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
- React
- TypeScript

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
### Getting Started

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
#### Installations

### `yarn eject`
- Install Node js

**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
#### Running the web app

If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).
- Clone this repo
- Open terminal
- Run `yarn install`
- Run `yarn start`
9 changes: 9 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[build]
command = "yarn build --prod"
publish = "build"
base = "/"

[[redirects]]
from = "/*"
to = "/index.html"
status = 200
2 changes: 1 addition & 1 deletion src/UI/atoms/Title/Title.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { StyledTitle } from "./Title.styles";

const Title: React.FC<{ children: string }> = ({ children }) => (
const Title: React.FC<{ children: any }> = ({ children }) => (
<StyledTitle>{children}</StyledTitle>
);

Expand Down
47 changes: 30 additions & 17 deletions src/UI/pages/Contributors/Contributors.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
import useDataContext from "hooks/useDataContext";
import { Item, ItemII } from "interfaces/dataItem";
import { ItemII } from "interfaces/dataItem";
import React, { useEffect } from "react";
import Title from "UI/atoms/Title/Title";
import { CardII } from "UI/templates/Card/Card";
import { CardDisplayWrapper } from "../Home/Home.styles";

import Skeleton from "react-skeleton-loading";
import NotFound from "UI/templates/NotFound/NotFound";

const Contributors: React.FC<{}> = (props: any) => {
const { data, error, loading, makeRequest } = useDataContext();
let { data, error, loading, makeRequest } = useDataContext();

let datum = data.find(
(data: any) => data.owner?.id === +props.match.params.id
);
const repositoryFullName = props.location.pathname.slice(14);

useEffect(() => {
if (datum) {
if (repositoryFullName) {
makeRequest(
`https://api.github.com/repos/${datum.full_name}/contributors`,
`https://api.github.com/repos/${repositoryFullName}/contributors`,
"contributors"
);
}
}, [makeRequest, datum]);
}, [makeRequest, repositoryFullName]);

console.log({ data });
const attributedData = loading ? Array(6).fill(null) : data;

const attributedData = loading ? Array(20).fill(null) : data;
const cardDisplay =
Array.isArray(attributedData) &&
attributedData.length > 0 &&
attributedData.map((item: ItemII, index: number) => (
<CardII key={index} datum={item} state={loading} />
));

const cardDisplay = attributedData.map((item: ItemII, index: number) => (
<CardII key={index} datum={item} state={loading} />
));
const renderCondition = attributedData.length > 0;

return (
<>
<Title>
{datum ? `${datum.full_name} Contributors` : "Retrieving Contributors"}
</Title>
<CardDisplayWrapper>{cardDisplay}</CardDisplayWrapper>
{repositoryFullName ? (
<Title>{`${repositoryFullName} Contributors`} </Title>
) : (
<Skeleton width={200} height={100} />
)}

{renderCondition ? (
<CardDisplayWrapper>{cardDisplay}</CardDisplayWrapper>
) : (
<NotFound
message={`${error ? "An error occured" : "No Result Found"}`}
/>
)}
</>
);
};
Expand Down
30 changes: 23 additions & 7 deletions src/UI/pages/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Title from "UI/atoms/Title/Title";
import Search from "UI/molecules/Search/Search";
import Card from "UI/templates/Card/Card";
import { CardDisplayWrapper } from "./Home.styles";
import NotFound from "UI/templates/NotFound/NotFound";

const Home: React.FC<{}> = () => {
const [searchValue, setSearchValue] = useState<string>("");
Expand Down Expand Up @@ -40,9 +41,14 @@ const Home: React.FC<{}> = () => {

const attributedData = loading ? Array(30).fill(null) : data;

const cardDisplay = attributedData.map((item: Item, index: number) => (
<Card key={index} datum={item} state={loading} />
));
const cardDisplay =
Array.isArray(attributedData) &&
attributedData.length > 0 &&
attributedData.map((item: Item, index: number) => (
<Card key={index} datum={item} state={loading} />
));

const renderCondition = attributedData.length > 0;

return (
<>
Expand All @@ -53,10 +59,20 @@ const Home: React.FC<{}> = () => {
loading={loading}
/>
</form>
<Title>
{justMounted.current ? "Popular Repositories" : "Searched Repositories"}
</Title>
<CardDisplayWrapper>{cardDisplay}</CardDisplayWrapper>
{renderCondition ? (
<>
<Title>
{justMounted.current
? "Popular Repositories"
: "Searched Repositories"}
</Title>
<CardDisplayWrapper>{cardDisplay}</CardDisplayWrapper>{" "}
</>
) : (
<NotFound
message={`${error ? "An error occured" : "No Result Found"}`}
/>
)}
</>
);
};
Expand Down
2 changes: 0 additions & 2 deletions src/UI/templates/Card/Card.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { Link } from "react-router-dom";

export const StyledCard = styled.div`
background-color: white;
border: 1px solid #272b36;
padding: 3rem 3rem;
flex-basis: 80%;
margin-top: 2rem;
Expand Down
2 changes: 1 addition & 1 deletion src/UI/templates/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const Card: React.FC<{ datum: Item; state: boolean }> = ({ datum, state }) => (
)}

{!state ? (
<StyledLink to={`contributors/${datum.owner?.id}`}>
<StyledLink to={`contributors/${datum.full_name}`}>
View Contributors
</StyledLink>
) : (
Expand Down
13 changes: 13 additions & 0 deletions src/UI/templates/NotFound/NotFound.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styled from "styled-components";

export const NotFoundImageContainer = styled.div`
display: flex;
align-items: center;
flex-direction: column;
padding: 0.5rem;
margin-top: 15rem;
`;

export const NotFoundImage = styled.img`
max-width: 100%;
`;
13 changes: 13 additions & 0 deletions src/UI/templates/NotFound/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { NotFoundImage, NotFoundImageContainer } from "./NotFound.styles";
import notFoundImage from "assets/not found.svg";

const NotFound: React.FC<{ message: string }> = ({ message }) => {
return (
<NotFoundImageContainer>
<h2> {message} </h2>
<NotFoundImage src={notFoundImage} />
</NotFoundImageContainer>
);
};

export default NotFound;
51 changes: 51 additions & 0 deletions src/assets/not found.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/context/dataProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import useRequest from "hooks/request";
import useRequest from "hooks/useRequest";

import DataContext from "./dataContext";

Expand Down
8 changes: 2 additions & 6 deletions src/hooks/request.ts → src/hooks/useRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { objectLiteral } from "interfaces/dataItem";
import { Item, ItemII } from "interfaces/dataItem";
import { useCallback, useReducer } from "react";

const initialState = {
Expand All @@ -10,7 +10,7 @@ const initialState = {
type reducerState = {
error: string;
loading: boolean;
data: Array<objectLiteral>;
data: Array<Item> | Array<ItemII>;
};

type actionType = {
Expand Down Expand Up @@ -44,17 +44,13 @@ function useRequest() {
try {
const response = await (await fetch(url)).json();

console.log({ response });

if (type === "contributors") {
dispatch({ type: "data", payload: response });
} else {
dispatch({ type: "data", payload: response.items });
}
} catch (err: any) {
dispatch({ type: "error", error: err.message });

console.log({ err });
}
},
[dispatch]
Expand Down
4 changes: 2 additions & 2 deletions src/index.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export const GlobalStyle = createGlobalStyle`
html {
box-sizing: border-box;
font-size: 62.5%;
font-size: 70%;
@media screen and (min-width: 900px) {
font-size: 80%;
font-size: 90%;
}
}
Expand Down

0 comments on commit 26f25a1

Please sign in to comment.