day 18 has been added

pull/72/head
asabeneh 5 years ago
parent ce21ceead6
commit 6821f7c680

File diff suppressed because it is too large Load Diff

@ -1,134 +1,300 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import axios from 'axios'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import moment from 'moment'
import styled from 'styled-components'
import { import {
TiSocialLinkedinCircular, BrowserRouter as Router,
TiSocialGithubCircular, Route,
TiSocialTwitterCircular, Switch,
} from 'react-icons/ti' NavLink,
Redirect,
Prompt,
} from 'react-router-dom'
const Title = styled.h1` // Home component
font-size: 70px; const Home = (props) => <h1>Welcome Home</h1>
font-weight: 300; // About component
` const About = (props) => <h1>About Us</h1>
const SubTitle = styled.h2` // Contact component
font-weight: 300; const Contact = (props) => <h1>Contact us</h1>
` // Challenge component
const Header = styled.header` const challenges = [
background-color: #61dbfb; {
padding: 25; name: '30 Days Of Python',
padding: 10px; description:
margin: 0; '30 Days of Python challenge is a step by step guide to learn Python in 30 days.',
` status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '20 Nov 2019 - 20 Dec 2019',
slug: 'pyhton',
url:
'https://github.com/https://https://github.com/Asabeneh/30-Days-Of-Python.com/Asabeneh/30-Days-Of-JavaScript/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of JavaScript',
description:
'30 Days of JavaScript challenge is a step by step guide to learn JavaScript in 30 days.',
status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Jan 2020 - 30 Jan 2020',
slug: 'javascript',
url: 'https://github.com/Asabeneh/30-Days-Of-JavaScript',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of React',
description:
'30 Days of React challenge is a step by step guide to learn React in 30 days.',
status: 'ongoing',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Oct 2020- 30 Oct 2020',
slug: 'react',
url: 'https://github.com/Asabeneh/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 HTML and CSS',
description:
'30 Days of HTML and CSS challenge is a step by step guide to learn HTML and CSS in 30 days.',
class App extends Component { status: 'coming',
constructor(props) { days: 30,
super(props) level: 'Beginners to Advanced',
console.log('I am the constructor and I will be the first to run.') duration: '',
this.state = { slug: 'html-and-css',
firstName: 'John', url: '',
data: [], author: {
day: 1, firstName: 'Asabeneh',
congratulate: '', lastName: 'Yetayeh',
} },
} },
{
name: '30 ReactNative',
description:
'30 Days of ReactNative challenge is a step by step guide to learn ReactNative in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'reactnative',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Data Analysis',
description:
'30 Days of Data Analysis challenge is a step by step guide to learn about data, data visualization and data analysis in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'data-analysis',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Machine Learning',
description:
'30 Days of Machine learning challenge is a step by step guide to learn data cleaning, machine learning models and predictions in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'machine-learning',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
]
componentDidMount() { const Challenge = ({
const API_URL = 'https://restcountries.eu/rest/v2/all' challenge: {
axios name,
.get(API_URL) description,
.then((response) => { status,
this.setState({ days,
data: response.data, level,
}) duration,
}) author: { firstName, lastName },
.catch((error) => { },
console.log(error) }) => (
}) <div>
<h1>{name}</h1>
<p>{level}</p>
<p>
Author: {firstName} {lastName}
</p>
{duration && (
<>
{' '}
<small>{duration}</small> <br />
</>
)}
<small>Number of days: {days}</small>
} <p>{description}</p>
static getDerivedStateFromProps(props, state) { </div>
return { firstName: props.firstName } )
}
shouldComponentUpdate(nextProps, nextState) {
console.log(nextProps, nextState)
console.log(nextState.day)
if (nextState.day > 31) {
return false
} else {
return true
}
}
doChallenge = () => { const Challenges = (props) => {
this.setState({ const path = props.location.pathname
day: this.state.day + 1, const slug = path.split('/').slice(path.split('/').length - 1)[0]
}) const challenge = challenges.find((challenge) => challenge.slug === slug)
return (
<div>
<h1>30 Days Of React Challenge</h1>
<ul>
{challenges.map(({ name, slug }) => (
<li key={slug}>
<NavLink to={`/challenges/${slug}`}>{name}</NavLink>
</li>
))}
</ul>
<Switch>
<Route
exact
path={'/challenges'}
component={() => <h1>Choose any of the challenges</h1>}
/>
<Route
path={path}
component={(props) => <Challenge challenge={challenge} />}
/>
</Switch>
</div>
)
}
const NotFound = (props) => <h1>The page your looking for not found</h1>
const Navbar = ({ username }) => (
<ul>
<li>
<NavLink to='/'>Home</NavLink>
</li>
<li>
<NavLink to='/about'>About</NavLink>
</li>
<li>
<NavLink to='/contact'>Contact</NavLink>
</li>
<li>
<NavLink to={`/user/${username}`}>User</NavLink>
</li>
<li>
<NavLink to='/challenges'>Challenges</NavLink>
</li>
</ul>
)
const User = ({ match, isLoggedIn, handleLogin }) => {
const username = match.params.username
return (
<div>
{isLoggedIn ? (
<>
<h1>Welcome {username} to the challenge</h1>
<small>Now, you can navigate through all the challenges</small> <br />
</>
) : (
<p>Please login in to access the challenges </p>
)}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
const Welcome = ({ handleLogin, isLoggedIn }) => {
return (
<div>
{isLoggedIn ? 'Welcome to the challenge' : <p>Please login in </p>}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
class App extends Component {
state = {
isLoggedIn: false,
firstName: 'Asabeneh',
} }
renderCountries = () => { handleLogin = () => {
return this.state.data.map((country) => { this.setState({
const languageOrLanguages = isLoggedIn: !this.state.isLoggedIn,
country.languages.length > 1 ? 'Langauges' : 'Language'
const formatLanguages = country.languages
.map(({ name }) => name)
.join(', ')
return (
<div>
<div>
{' '}
<img src={country.flag} alt={country.name} />{' '}
</div>
<div>
<h1>{country.name}</h1>
<p>Capital: {country.capital}</p>
<p>
{languageOrLanguages}: {formatLanguages}
</p>
<p>Population: {country.population}</p>
</div>
</div>
)
}) })
} }
componentDidUpdate(prevProps, prevState) {
if (prevState.day == 30) {
this.setState({
congratulate: 'Congratulations,Challenge has been completed',
})
}
console.log(prevState, prevProps)
}
render() { render() {
return ( return (
<div className='App'> <Router>
<Header> <div className='App'>
<Title>30 Days Of React</Title> <Navbar username={this.state.firstName} />
<h2>Getting Started React</h2>
<h3>JavaScript Library</h3> <Prompt
<p>Instructor: Asabeneh Yetayey</p> message={({ pathname }) => {
<small>Oct 15, 2020</small> return this.state.isLoggedIn &&
</Header> pathname.includes('/user/Asabeneh')
<p>This challenge was started {moment('2020-10-01').fromNow()}</p> ? 'Are you sure you want to logout?'
<p>The challenge will be over in {moment('2020-10-30').fromNow()}</p> : true
<p>Today is {moment(new Date()).format('MMMM DD, YYYY HH:mm')}</p> }}
<h1>React Component Life Cycle</h1> />
<h1>Calling API</h1>
<TiSocialLinkedinCircular />
<TiSocialGithubCircular />
<TiSocialTwitterCircular />
<button onClick={this.doChallenge}>Do Challenge</button> <Switch>
<p>Challenge: Day {this.state.day}</p> <Route path='/about' component={About} />
{this.state.congratulate && <h2>{this.state.congratulate}</h2>} <Route path='/contact' component={Contact} />
<div> <Route
<p>There are {this.state.data.length} countries in the api</p> path='/user/:username'
<div className='countries-wrapper'>{this.renderCountries()}</div> component={(props) => (
<User
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/login'
component={(props) => (
<Welcome
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/challenges'
component={(props) => {
return this.state.isLoggedIn ? (
<Challenges {...props} />
) : (
<Redirect to='/user/asabeneh' />
)
}}
/>
<Route exact path='/' component={Home} />
<Route component={NotFound} />
</Switch>
</div> </div>
</div> </Router>
) )
} }
} }

@ -0,0 +1,45 @@
<div align="center">
<h1> 30 Days Of React: Projects</h1>
<a class="header-badge" target="_blank" href="https://www.linkedin.com/in/asabeneh/">
<img src="https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social">
</a>
<a class="header-badge" target="_blank" href="https://twitter.com/Asabeneh">
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/asabeneh?style=social">
</a>
<sub>Author:
<a href="https://www.linkedin.com/in/asabeneh/" target="_blank">Asabeneh Yetayeh</a><br>
<small> October, 2020</small>
</sub>
</div>
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()
![30 Days of React banner](../images/30_days_of_react_banner_day_18.jpg)
- [Projects](#projects)
- [Exercises](#exercises)
- [Exercises: Level 1](#exercises-level-1)
- [Exercises: Level 2](#exercises-level-2)
- [Exercises: Level 3](#exercises-level-3)
# Projects
Congratulations for making it to this far. Now, you have a solid understanding of React. I believe we have cover most of the feature of React and your are ready to work on projects. What we have cover so far is the old version of React. Starting from Day 20 we will learn React Hooks. In the next three days you will work on only projects.
# Exercises
## Exercises: Level 1
## Exercises: Level 2
coming
## Exercises: Level 3
coming
🎉 CONGRATULATIONS ! 🎉
[<< Day 17](../17_React_Router/17_react_router.md) | [Day 19>>]()

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -0,0 +1,5 @@
# 30 Days of React App: Day 17
In the project directory, you can run to start the project
### `npm start`

@ -0,0 +1,34 @@
{
"name": "30-days-of-react",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500|Roboto:300,400,500&display=swap"
rel="stylesheet"
/>
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>30 Days Of React App</title>
<style>
/* == General style === */
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
line-height: 1.5;
font-family: 'Montserrat';
font-weight: 300;
color: black;
}
.root {
min-height: 100%;
position: relative;
}
.header-wrapper,
.main-wrapper,
.footer-wrapper {
width: 85%;
margin: auto;
}
.header-wrapper,
.main-wrapper {
padding: 10px;
margin: 2px auto;
}
h1 {
font-size: 70px;
font-weight: 300;
}
h2,
h3 {
font-weight: 300;
}
header {
background-color: #61dbfb;
padding: 25;
padding: 10px;
}
main {
padding: 10px;
padding-bottom: 60px;
/* Height of the footer */
}
ul {
margin-left: 15px;
}
ul li {
list-style: none;
}
footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
/* Height of the footer */
background: #6cf;
}
.footer-wrapper {
font-weight: 400;
text-align: center;
line-height: 60px;
}
.user-card {
margin-top: 10px;
}
.user-card > img {
border-radius: 50%;
width: 14%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
export const tenHighestPopulation = [
{ country: 'World', population: 7693165599 },
{ country: 'China', population: 1377422166 },
{ country: 'India', population: 1295210000 },
{ country: 'United States of America', population: 323947000 },
{ country: 'Indonesia', population: 258705000 },
{ country: 'Brazil', population: 206135893 },
{ country: 'Pakistan', population: 194125062 },
{ country: 'Nigeria', population: 186988000 },
{ country: 'Bangladesh', population: 161006790 },
{ country: 'Russian Federation', population: 146599183 },
{ country: 'Japan', population: 126960000 },
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@ -0,0 +1,303 @@
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import {
BrowserRouter as Router,
Route,
Switch,
NavLink,
Redirect,
Prompt,
} from 'react-router-dom'
// Home component
const Home = (props) => <h1>Welcome Home</h1>
// About component
const About = (props) => <h1>About Us</h1>
// Contact component
const Contact = (props) => <h1>Contact us</h1>
// Challenge component
const challenges = [
{
name: '30 Days Of Python',
description:
'30 Days of Python challenge is a step by step guide to learn Python in 30 days.',
status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '20 Nov 2019 - 20 Dec 2019',
slug: 'pyhton',
url:
'https://github.com/https://https://github.com/Asabeneh/30-Days-Of-Python.com/Asabeneh/30-Days-Of-JavaScript/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of JavaScript',
description:
'30 Days of JavaScript challenge is a step by step guide to learn JavaScript in 30 days.',
status: 'completed',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Jan 2020 - 30 Jan 2020',
slug: 'javascript',
url: 'https://github.com/Asabeneh/30-Days-Of-JavaScript',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Days Of React',
description:
'30 Days of React challenge is a step by step guide to learn React in 30 days.',
status: 'ongoing',
days: 30,
level: 'Beginners to Advanced',
duration: '1 Oct 2020- 30 Oct 2020',
slug: 'react',
url: 'https://github.com/Asabeneh/30-Days-Of-React',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 HTML and CSS',
description:
'30 Days of HTML and CSS challenge is a step by step guide to learn HTML and CSS in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'html-and-css',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 ReactNative',
description:
'30 Days of ReactNative challenge is a step by step guide to learn ReactNative in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'reactnative',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Data Analysis',
description:
'30 Days of Data Analysis challenge is a step by step guide to learn about data, data visualization and data analysis in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'data-analysis',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
{
name: '30 Machine Learning',
description:
'30 Days of Machine learning challenge is a step by step guide to learn data cleaning, machine learning models and predictions in 30 days.',
status: 'coming',
days: 30,
level: 'Beginners to Advanced',
duration: '',
slug: 'machine-learning',
url: '',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
},
]
const Challenge = ({
challenge: {
name,
description,
status,
days,
level,
duration,
author: { firstName, lastName },
},
}) => (
<div>
<h1>{name}</h1>
<p>{level}</p>
<p>
Author: {firstName} {lastName}
</p>
{duration && (
<>
{' '}
<small>{duration}</small> <br />
</>
)}
<small>Number of days: {days}</small>
<p>{description}</p>
</div>
)
const Challenges = (props) => {
const path = props.location.pathname
const slug = path.split('/').slice(path.split('/').length - 1)[0]
const challenge = challenges.find((challenge) => challenge.slug === slug)
return (
<div>
<h1>30 Days Of React Challenge</h1>
<ul>
{challenges.map(({ name, slug }) => (
<li key={slug}>
<NavLink to={`/challenges/${slug}`}>{name}</NavLink>
</li>
))}
</ul>
<Switch>
<Route
exact
path={'/challenges'}
component={() => <h1>Choose any of the challenges</h1>}
/>
<Route
path={path}
component={(props) => <Challenge challenge={challenge} />}
/>
</Switch>
</div>
)
}
const NotFound = (props) => <h1>The page your looking for not found</h1>
const Navbar = ({ username }) => (
<ul>
<li>
<NavLink to='/'>Home</NavLink>
</li>
<li>
<NavLink to='/about'>About</NavLink>
</li>
<li>
<NavLink to='/contact'>Contact</NavLink>
</li>
<li>
<NavLink to={`/user/${username}`}>User</NavLink>
</li>
<li>
<NavLink to='/challenges'>Challenges</NavLink>
</li>
</ul>
)
const User = ({ match, isLoggedIn, handleLogin }) => {
const username = match.params.username
return (
<div>
{isLoggedIn ? (
<>
<h1>Welcome {username} to the challenge</h1>
<small>Now, you can navigate through all the challenges</small> <br />
</>
) : (
<p>Please login in to access the challenges </p>
)}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
const Welcome = ({ handleLogin, isLoggedIn }) => {
return (
<div>
{isLoggedIn ? 'Welcome to the challenge' : <p>Please login in </p>}
<button onClick={handleLogin}>{isLoggedIn ? 'Logout' : 'Login'}</button>
</div>
)
}
class App extends Component {
state = {
isLoggedIn: false,
firstName: 'Asabeneh',
}
handleLogin = () => {
this.setState({
isLoggedIn: !this.state.isLoggedIn,
})
}
render() {
return (
<Router>
<div className='App'>
<Navbar username={this.state.firstName} />
<Prompt
message={({ pathname }) => {
return this.state.isLoggedIn &&
pathname.includes('/user/Asabeneh')
? 'Are you sure you want to logout?'
: true
}}
/>
<Switch>
<Route path='/about' component={About} />
<Route path='/contact' component={Contact} />
<Route
path='/user/:username'
component={(props) => (
<User
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/login'
component={(props) => (
<Welcome
{...props}
isLoggedIn={this.state.isLoggedIn}
handleLogin={this.handleLogin}
/>
)}
/>
<Route
path='/challenges'
component={(props) => {
return this.state.isLoggedIn ? (
<Challenges {...props} />
) : (
<Redirect to='/user/asabeneh' />
)
}}
/>
<Route exact path='/' component={Home} />
<Route component={NotFound} />
</Switch>
</div>
</Router>
)
}
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

File diff suppressed because it is too large Load Diff

@ -40,10 +40,9 @@
|15|[Third Party Packages](./15_Third_Party_Packages/15_third_party_packages.md)| |15|[Third Party Packages](./15_Third_Party_Packages/15_third_party_packages.md)|
|16|[Higher Order Components](./16_Higher_Order_Component/16_higher_order_component.md)| |16|[Higher Order Components](./16_Higher_Order_Component/16_higher_order_component.md)|
|17|[React Router](./17_React_Router/17_react_router.md)| |17|[React Router](./17_React_Router/17_react_router.md)|
|17|[Projects](./18_projects/18_projects.md)|
CONGRATULATIONS FOR MAKING TO THIS FAR
🧡🧡🧡 HAPPY CODING 🧡🧡🧡 🧡🧡🧡 HAPPY CODING 🧡🧡🧡
<div> <div>

Loading…
Cancel
Save