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>
This commit is contained in:
parent
be7f09b6ba
commit
e5828ad1bf
@ -1 +0,0 @@
|
|||||||
server/node_modules
|
|
1
react-express-mongodb/backend/.dockerignore
Normal file
1
react-express-mongodb/backend/.dockerignore
Normal file
@ -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
|
COPY . /usr/src/app
|
||||||
# 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
|
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD [ "npm", "run", "dev" ]
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
version: "3.7"
|
version: "3.7"
|
||||||
services:
|
services:
|
||||||
frontend:
|
frontend:
|
||||||
build:
|
build: frontend
|
||||||
context: frontend
|
|
||||||
args:
|
|
||||||
FRONT_END_PORT: 5000
|
|
||||||
ports:
|
ports:
|
||||||
- 5000:5000
|
- 3000:3000
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
volumes:
|
volumes:
|
||||||
- ./frontend:/usr/src/app
|
- ./frontend:/usr/src/app
|
||||||
@ -21,10 +18,7 @@ services:
|
|||||||
backend:
|
backend:
|
||||||
container_name: backend
|
container_name: backend
|
||||||
restart: always
|
restart: always
|
||||||
build:
|
build: backend
|
||||||
context: backend
|
|
||||||
args:
|
|
||||||
NODE_PORT: 3000
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend:/usr/src/app
|
- ./backend:/usr/src/app
|
||||||
- /usr/src/app/node_modules
|
- /usr/src/app/node_modules
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
server/logs/
|
|
@ -1,15 +1,9 @@
|
|||||||
# Create image based on the official Node image from dockerhub
|
# Create image based on the official Node image from dockerhub
|
||||||
FROM node:13.13.0-stretch
|
FROM node:lts-buster-slim
|
||||||
|
|
||||||
#Argument that is passed from docer-compose.yaml file
|
|
||||||
ARG FRONT_END_PORT
|
|
||||||
|
|
||||||
# Create app directory
|
# Create app directory
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
#Echo the argument to check passed argument loaded here correctly
|
|
||||||
RUN echo "Argument port is : $FRONT_END_PORT"
|
|
||||||
|
|
||||||
# Copy dependency definitions
|
# Copy dependency definitions
|
||||||
COPY package.json /usr/src/app
|
COPY package.json /usr/src/app
|
||||||
COPY package-lock.json /usr/src/app
|
COPY package-lock.json /usr/src/app
|
||||||
@ -24,7 +18,7 @@ RUN npm ci
|
|||||||
COPY . /usr/src/app
|
COPY . /usr/src/app
|
||||||
|
|
||||||
# Expose the port the app runs in
|
# Expose the port the app runs in
|
||||||
EXPOSE ${FRONT_END_PORT}
|
EXPOSE 3000
|
||||||
|
|
||||||
# Serve the app
|
# Serve the app
|
||||||
CMD ["npm", "start"]
|
CMD ["npm", "start"]
|
||||||
|
43
react-express-mongodb/frontend/src/App.js
vendored
43
react-express-mongodb/frontend/src/App.js
vendored
@ -1,41 +1,40 @@
|
|||||||
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
|
||||||
|
.get("/api")
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
todos: response.data.data
|
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 : todosCopy
|
todos: [...this.state.todos, { text: value }],
|
||||||
});
|
});
|
||||||
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">
|
||||||
@ -44,8 +43,8 @@ export default class App extends React.Component{
|
|||||||
<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>
|
||||||
|
@ -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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="new-todo form-group">
|
<form
|
||||||
<input type="text" className="form-control" ref="todo"/>
|
noValidate
|
||||||
<button className="btn btn-primary" onClick={this._onAddTodo}>
|
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
|
Add Todo
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</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) {
|
||||||
constructor(props){
|
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
activeIndex:0,
|
activeIndex: 0,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleActive(index) {
|
handleActive(index) {
|
||||||
this.setState({
|
this.setState({
|
||||||
activeIndex: index
|
activeIndex: index,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderTodos(todos) {
|
renderTodos(todos) {
|
||||||
return (
|
return (
|
||||||
<ul className="list-group">
|
<ul className="list-group">
|
||||||
{
|
{todos.map((todo, i) => (
|
||||||
todos.map((todo, i) => {
|
<li
|
||||||
return (<li className={'list-group-item cursor-pointer ' + (i===this.state.activeIndex ? 'active' : '')}
|
className={
|
||||||
|
"list-group-item cursor-pointer " +
|
||||||
|
(i === this.state.activeIndex ? "active" : "")
|
||||||
|
}
|
||||||
key={i}
|
key={i}
|
||||||
onClick={() => {this._handleActive(i)}}
|
onClick={() => {
|
||||||
|
this.handleActive(i);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{todo.text}
|
{todo.text}
|
||||||
</li>)
|
</li>
|
||||||
})
|
))}
|
||||||
}
|
|
||||||
</ul>
|
</ul>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { todos } = this.props;
|
let { todos } = this.props;
|
||||||
return (
|
return todos.length > 0 ? (
|
||||||
todos.length > 0 ?
|
this.renderTodos(todos)
|
||||||
this._renderTodos(todos)
|
) : (
|
||||||
:
|
|
||||||
<div className="alert alert-primary" role="alert">
|
<div className="alert alert-primary" role="alert">
|
||||||
No Todos to display
|
No Todos to display
|
||||||
</div>
|
</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
Block a user