Initial commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets" : ["@babel/preset-react"]
|
||||
}
|
||||
Generated
+4243
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.19.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.3",
|
||||
"@babel/preset-react": "^7.10.1",
|
||||
"babel-loader": "^8.1.0",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<html>
|
||||
<head>
|
||||
<base href="/" />
|
||||
<title>Scotch Todo</title>
|
||||
<!--Stylesheet-->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!--Container for React rendering-->
|
||||
<div class="container">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--Bundled file-->
|
||||
<script src="bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,108 @@
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
console.clear();
|
||||
|
||||
const Title = ({todoCount}) => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1>to-do ({todoCount})</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const TodoForm = ({addTodo}) => {
|
||||
// Input Tracker
|
||||
let input;
|
||||
// Return JSX
|
||||
return (
|
||||
<form onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
addTodo(input.value);
|
||||
input.value = '';
|
||||
}}>
|
||||
<input className="form-control col-md-12" ref={node => {
|
||||
input = node;
|
||||
}} />
|
||||
<br />
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
const Todo = ({todo, remove}) => {
|
||||
// Each Todo
|
||||
return (<a href="#" className="list-group-item" onClick={() => {remove(todo.id)}}>{todo.text}</a>);
|
||||
}
|
||||
|
||||
const TodoList = ({todos, remove}) => {
|
||||
// Map through the todos
|
||||
const todoNode = todos.map((todo) => {
|
||||
return (<Todo todo={todo} key={todo.id} remove={remove}/>)
|
||||
});
|
||||
return (<div className="list-group" style={{marginTop:'30px'}}>{todoNode}</div>);
|
||||
}
|
||||
|
||||
// Contaner Component
|
||||
// Todo Id
|
||||
window.id = 0;
|
||||
class TodoApp extends React.Component{
|
||||
constructor(props){
|
||||
// Pass props to parent class
|
||||
super(props);
|
||||
// Set initial state
|
||||
this.state = {
|
||||
data: []
|
||||
}
|
||||
this.apiUrl = 'https://57b1924b46b57d1100a3c3f8.mockapi.io/api/todos'
|
||||
}
|
||||
// Lifecycle method
|
||||
componentDidMount(){
|
||||
// Make HTTP reques with Axios
|
||||
axios.get(this.apiUrl)
|
||||
.then((res) => {
|
||||
// Set state with result
|
||||
this.setState({data:res.data});
|
||||
});
|
||||
}
|
||||
// Add todo handler
|
||||
addTodo(val){
|
||||
// Assemble data
|
||||
const todo = {text: val}
|
||||
// Update data
|
||||
axios.post(this.apiUrl, todo)
|
||||
.then((res) => {
|
||||
this.state.data.push(res.data);
|
||||
this.setState({data: this.state.data});
|
||||
});
|
||||
}
|
||||
// Handle remove
|
||||
handleRemove(id){
|
||||
// Filter all todos except the one to be removed
|
||||
const remainder = this.state.data.filter((todo) => {
|
||||
if(todo.id !== id) return todo;
|
||||
});
|
||||
// Update state with filter
|
||||
axios.delete(this.apiUrl+'/'+id)
|
||||
.then((res) => {
|
||||
this.setState({data: remainder});
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
// Render JSX
|
||||
return (
|
||||
<div>
|
||||
<Title todoCount={this.state.data.length}/>
|
||||
<TodoForm addTodo={this.addTodo.bind(this)}/>
|
||||
<TodoList
|
||||
todos={this.state.data}
|
||||
remove={this.handleRemove.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
render(<TodoApp />, document.getElementById('container'));
|
||||
@@ -0,0 +1,24 @@
|
||||
const webpack = require('webpack');
|
||||
const path = require('path');
|
||||
|
||||
const BUILD_DIR = path.resolve(__dirname, 'public');
|
||||
const APP_DIR = path.resolve(__dirname, 'src');
|
||||
|
||||
const config = {
|
||||
entry: APP_DIR + '/index.js',
|
||||
output: {
|
||||
path: BUILD_DIR,
|
||||
filename: 'bundle.js'
|
||||
},
|
||||
module: {
|
||||
rules : [
|
||||
{
|
||||
test : /\.js?/,
|
||||
include : APP_DIR,
|
||||
loader : 'babel-loader'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
Reference in New Issue
Block a user