react-express-mongodb: clean frontend code
- apply prettier style on every js file - remove mutation on immutable variables - remove wrapper on top of axios - fix form handling - remove useless port definition in dockerfile Signed-off-by: Jérémie Drouet <jeremie.drouet@gmail.com>master
parent
be7f09b6ba
commit
e5828ad1bf
@ -1 +0,0 @@
|
|||||||
server/node_modules
|
|
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
@ -1,27 +1,14 @@
|
|||||||
FROM node:13.13.0-stretch-slim
|
FROM node:lts-buster-slim
|
||||||
|
|
||||||
#Argument that is passed from docer-compose.yaml file
|
|
||||||
ARG NODE_PORT
|
|
||||||
|
|
||||||
#Echo the argument to check passed argument loaded here correctly
|
|
||||||
RUN echo "Argument port is : $NODE_PORT"
|
|
||||||
|
|
||||||
# Create app directory
|
# Create app directory
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
#COPY . .
|
COPY package.json /usr/src/app/package.json
|
||||||
COPY . .
|
COPY package-lock.json /usr/src/app/package-lock.json
|
||||||
|
RUN npm ci
|
||||||
# Install app dependencies
|
|
||||||
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
|
||||||
# where available (npm@5+)
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
|
|
||||||
#In my case my app binds to port NODE_PORT so you'll use the EXPOSE instruction to have it mapped by the docker daemon:
|
|
||||||
|
|
||||||
EXPOSE ${NODE_PORT}
|
|
||||||
|
|
||||||
CMD npm run dev
|
COPY . /usr/src/app
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD [ "npm", "run", "dev" ]
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
server/logs/
|
|
@ -1,56 +1,55 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
import {request} from './utilities/httpRequestHandler'
|
import axios from "axios";
|
||||||
import './App.scss';
|
import "./App.scss";
|
||||||
import AddTodo from "./components/AddTodo";
|
import AddTodo from "./components/AddTodo";
|
||||||
import TodoList from "./components/TodoList";
|
import TodoList from "./components/TodoList";
|
||||||
|
|
||||||
export default class App extends React.Component{
|
export default class App extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
constructor(props){
|
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
todos: []
|
todos: [],
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
request('get','/api')
|
axios
|
||||||
.then((response) => {
|
.get("/api")
|
||||||
this.setState({
|
.then((response) => {
|
||||||
todos: response.data.data
|
this.setState({
|
||||||
})
|
todos: response.data.data,
|
||||||
}).catch((e) => console.log('Error : ', e))
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => console.log("Error : ", e));
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleAddTodo = (value) => {
|
handleAddTodo = (value) => {
|
||||||
request('post', '/api/todos', {text:value})
|
axios
|
||||||
.then((response) => {
|
.post("/api/todos", { text: value })
|
||||||
let todosCopy = this.state.todos;
|
.then(() => {
|
||||||
todosCopy.unshift({text:value});
|
this.setState({
|
||||||
this.setState({
|
todos: [...this.state.todos, { text: value }],
|
||||||
todos : todosCopy
|
});
|
||||||
});
|
})
|
||||||
this.refs.todo.value = ""
|
.catch((e) => console.log("Error : ", e));
|
||||||
}).catch((e) => console.log('Error : ', e));
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="App container">
|
<div className="App container">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-xs-12 col-sm-8 col-md-8 offset-md-2">
|
<div className="col-xs-12 col-sm-8 col-md-8 offset-md-2">
|
||||||
<h1>Todos</h1>
|
<h1>Todos</h1>
|
||||||
<div className="todo-app">
|
<div className="todo-app">
|
||||||
<AddTodo handleAddTodo={(value) => {this._handleAddTodo(value)}}/>
|
<AddTodo handleAddTodo={this.handleAddTodo} />
|
||||||
<TodoList todos={this.state.todos}/>
|
<TodoList todos={this.state.todos} />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,33 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
export default class AddTodo extends React.Component {
|
export default class AddTodo extends React.Component {
|
||||||
|
handleSubmit = (e) => {
|
||||||
_onAddTodo = () => {
|
e.preventDefault();
|
||||||
if(this.refs.todo.value.length > 0) {
|
const { value } = e.target.elements.value;
|
||||||
this.props.handleAddTodo(this.refs.todo.value);
|
if (value.length > 0) {
|
||||||
this.refs.todo.value = '';
|
this.props.handleAddTodo(value);
|
||||||
}
|
e.target.reset();
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div className="new-todo form-group">
|
|
||||||
<input type="text" className="form-control" ref="todo"/>
|
|
||||||
<button className="btn btn-primary" onClick={this._onAddTodo}>
|
|
||||||
Add Todo
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
noValidate
|
||||||
|
onSubmit={this.handleSubmit}
|
||||||
|
className="new-todo form-group"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="value"
|
||||||
|
required
|
||||||
|
minLength={1}
|
||||||
|
className="form-control"
|
||||||
|
/>
|
||||||
|
<button className="btn btn-primary" type="submit">
|
||||||
|
Add Todo
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,48 +1,49 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
export default class TodoList extends React.Component {
|
export default class TodoList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
constructor(props){
|
this.state = {
|
||||||
super(props);
|
activeIndex: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
handleActive(index) {
|
||||||
activeIndex:0,
|
this.setState({
|
||||||
}
|
activeIndex: index,
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_handleActive(index) {
|
renderTodos(todos) {
|
||||||
this.setState({
|
return (
|
||||||
activeIndex: index
|
<ul className="list-group">
|
||||||
})
|
{todos.map((todo, i) => (
|
||||||
}
|
<li
|
||||||
|
className={
|
||||||
|
"list-group-item cursor-pointer " +
|
||||||
|
(i === this.state.activeIndex ? "active" : "")
|
||||||
|
}
|
||||||
|
key={i}
|
||||||
|
onClick={() => {
|
||||||
|
this.handleActive(i);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{todo.text}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
_renderTodos(todos) {
|
render() {
|
||||||
return (
|
let { todos } = this.props;
|
||||||
<ul className="list-group">
|
return todos.length > 0 ? (
|
||||||
{
|
this.renderTodos(todos)
|
||||||
todos.map((todo, i) => {
|
) : (
|
||||||
return (<li className={'list-group-item cursor-pointer ' + (i===this.state.activeIndex ? 'active' : '')}
|
<div className="alert alert-primary" role="alert">
|
||||||
key={i}
|
No Todos to display
|
||||||
onClick={() => {this._handleActive(i)}}
|
</div>
|
||||||
>
|
);
|
||||||
{todo.text}
|
}
|
||||||
</li>)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</ul>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let { todos } = this.props;
|
|
||||||
return (
|
|
||||||
todos.length > 0 ?
|
|
||||||
this._renderTodos(todos)
|
|
||||||
:
|
|
||||||
<div className="alert alert-primary" role="alert">
|
|
||||||
No Todos to display
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,16 +0,0 @@
|
|||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
|
|
||||||
export function request (method, uri, data, headers = null, params = null) {
|
|
||||||
let query = {
|
|
||||||
method,
|
|
||||||
url: uri
|
|
||||||
};
|
|
||||||
if (headers !== null)
|
|
||||||
query.headers = headers;
|
|
||||||
if (params !== null)
|
|
||||||
query.params = params;
|
|
||||||
if (method === 'post' || method === 'put' || method === 'delete' || method === 'patch')
|
|
||||||
query.data = data;
|
|
||||||
return axios(query);
|
|
||||||
}
|
|
Loading…
Reference in New Issue