feat(react-crud): add delete and home page

This commit is contained in:
dancingCycle 2023-04-05 19:13:28 +02:00
parent 174cd6383a
commit 23e30ac60e
12 changed files with 212 additions and 98 deletions

View File

@ -13,6 +13,7 @@
* [React Router](https://www.w3schools.com/react/react_router.asp)
* [React form](https://www.w3schools.com/react/react_forms.asp)
* [React CRUD](https://www.freecodecamp.org/news/how-to-perform-crud-operations-using-react/)
* [React Router](https://www.digitalocean.com/community/tutorials/how-to-handle-routing-in-react-apps-with-react-router)
* [React setup with webpack for beginners](https://dev.to/deepanjangh/react-setup-with-webpack-for-beginners-2a8k)
* [Production](https://webpack.js.org/guides/production/)
* [Setup Development and Production Environment for React App](https://medium.com/freestoneinfotech/setup-development-and-production-environment-for-react-app-397c4cc9e382)

View File

@ -1,13 +1,45 @@
import React from 'react';
//BrowserRouter: base configuration
//Route: configure specific routes and wrap component
import {
BrowserRouter as Router,
Routes,
Route,
Link
} from 'react-router-dom';
import Home from './components/home';
import Create from './components/create';
import Read from './components/read';
import Update from './components/update';
import Delete from './components/delete';
export default function App() {
return (
<>
<Create />
<Read />
<Update />
</>
);
return (
<div className="wrapper">
{/*h1: global page title*/}
{/*template: wrapper and h1 is rendered on every page*/}
{/*TODO Navigation or header on every page?*/}
<h1>App</h1>
<Router>
<div className="App">
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/create">Create</Link></li>
<li><Link to="/read">Read</Link></li>
<li><Link to="/update">Update</Link></li>
<li><Link to="/delete">Delete</Link></li>
</ul>
<Routes>
{/*exact: match the exact value with the URL*/}
<Route exact path='/' element={< Home />}></Route>
<Route exact path='/create' element ={<Create />}></Route>
<Route exact path='/read' element={<Read />}></Route>
<Route exact path='/update' element={<Update />}></Route>
<Route exact path='/delete' element={<Delete />}></Route>
</Routes>
</div>
</Router>
</div>
);
};

View File

@ -1,19 +1,29 @@
import React, { useState } from 'react'
import axios from 'axios';
import axios from 'axios';
export default function Create() {
const [name, setName] = useState('');
const postData = (e) => {
e.preventDefault();
console.log('name: '+name);
axios.post(
'http://85.223.94.182:65535/entities/create',
{
name:{name}
//console.log('name: '+name);
const url='http://83.223.94.182:65535/entities/create';
//console.log('url: '+url);
let data = new FormData();
data.append('name',name);
let config = {
method: 'post',
maxBodyLength: Infinity,
url: url,
data : data
};
axios.request(config)
.catch((error)=>{
console.error('create:axios error: '+error);
});
};
return (
<div>
<p>Create</p>
<h1>Create</h1>
<form onSubmit={postData}>
<label>
Enter name (input:{name}):

View File

@ -0,0 +1,60 @@
import React, { useState } from 'react'
import axios from 'axios';
export default function Delete() {
const [id, setId] = useState('');
const postData = (e) => {
e.preventDefault();
console.log('id: '+id);
/*
const url='http://83.223.94.182:65535/entities/'+id+'/delete';
console.log('url: '+url);
let config = {
method: 'delete',
maxBodyLength: Infinity,
url: url,
headers: {}
};
axios.request(config)
.catch((error) => {
console.error('create:axios error: '+error);
});
*/
/*
let config = {
method: 'delete',
maxBodyLength: Infinity,
url: 'http://83.223.94.182:65535/entities/20/delete',
headers: { }
};
axios.request(config)
.then((response) => {
console.log('rsp.data: '+response.data);
})
.catch((error) => {
console.log(error);
});
*/
axios.delete('http://83.223.94.182:65535/entities/20/delete')
.catch(error => {
console.error('There was an error!', error);
});
};
return (
<div>
<h1>Delete</h1>
<form onSubmit={postData}>
<label>
Enter id (input:{id}):
<input
placeholder='Id'
type="text"
value={id}
onChange={(e) => setId(e.target.value)}
/>
</label>
<input
type="submit" />
</form>
</div>
);
};

View File

@ -1,17 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
//destructure props
const Hello = ({msg}) => {
return (
<>
<div>{msg}</div>
</>
);
}
export default Hello
Hello.propTypes = {
msg: PropTypes.string,
};

View File

@ -0,0 +1,5 @@
import React from 'react';
export default function Home (){
return <h1>Home</h1>
};

View File

@ -1,23 +1,41 @@
import React, {useEffect,useState} from 'react'
import axios from 'axios';
import {Link} from 'react-router-dom';
export default function Read() {
//create state containing incoming data array
const [apiData,setApiData]=useState([]);
//useEffect Hook, cos we need data when app loads
useEffect(()=>{
//get data
const getData=()=>{
axios.get('http://83.223.94.182:65535/entities/info')
.then((response)=>{
setApiData(response.data);
});
};
//create state containing incoming data array
const [apiData,setApiData]=useState([]);
//useEffect Hook, cos we need data when app loads
useEffect(()=>{
//console.log('Read calls useEffect()');
getData();
},[]);
//handle update button
const setData=(data)=>{
console.log('data: '+data);
};
//handle delete button
const onDelete=(id)=>{
console.log('read:onDelete() id: '+id);
getData()
};
return (
<div>
<p>Read</p>
<h1>Read</h1>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@ -29,6 +47,24 @@ export default function Read() {
>
<td>{value[0]}</td>
<td>{value[1]}</td>
<td>
<Link to='/update'>
<button
type="button"
onClick={()=>setData(data)}
>
Update
</button>
</Link>
</td>
<td>
<button
type="button"
onClick={()=>onDelete(data.id)}
>
Delete
</button>
</td>
</tr>
);
})}

View File

@ -1,8 +1,52 @@
import React from 'react'
import React, { useState } from 'react'
import axios from 'axios';
export default function Update() {
const [name, setName] = useState('');
const [id, setId] = useState('');
const postData = (e) => {
e.preventDefault();
console.log('id: '+id);
console.log('name: '+name);
const url='http://83.223.94.182:65535/entities/'+id+'/update';
console.log('url: '+url);
let data = new FormData();
data.append('name',name);
let config = {
method: 'post',
maxBodyLength: Infinity,
url: url,
data : data
};
axios.request(config)
.catch((error) => {
console.error('create:axios error: '+error);
});
};
return (
<div>
<p>Update</p>
<h1>Update</h1>
<form onSubmit={postData}>
<label>
Enter id (input:{id}):
<input
placeholder='Id'
type="text"
value={id}
onChange={(e) => setId(e.target.value)}
/>
</label>
<label>
Enter name (input:{name}):
<input
placeholder='Name'
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<input
type="submit" />
</form>
</div>
);
};

View File

@ -1,10 +0,0 @@
import React from 'react';
import Hello from '../components/hello';
import '../style.css';
export default function Home() {
return (
<>
<Hello />
</>
);
};

View File

@ -1,3 +0,0 @@
h1 { color: red; }
h2 { color: green; }
h3 { color: blue; }

View File

@ -10,10 +10,9 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"axios": "1.3.4",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.10.0"
"react-router-dom": "6.10.0"
},
"devDependencies": {
"@babel/core": "7.18.13",
@ -4581,14 +4580,6 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@ -4958,16 +4949,6 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -5084,11 +5065,6 @@
"react": "^18.2.0"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",
@ -9849,11 +9825,6 @@
"boolbase": "^1.0.0"
}
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
},
"object-inspect": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
@ -10118,16 +10089,6 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true
},
"prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"requires": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
"react-is": "^16.13.1"
}
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -10218,11 +10179,6 @@
"scheduler": "^0.23.0"
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-router": {
"version": "6.10.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.10.0.tgz",

View File

@ -32,8 +32,8 @@
},
"dependencies": {
"axios": "1.3.4",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0"
"react-dom": "18.2.0",
"react-router-dom": "6.10.0"
}
}