From 711c0fc5ee65dd16055dc30cc3cc3f165cdb0641 Mon Sep 17 00:00:00 2001 From: Ben Elferink Date: Tue, 19 Jan 2021 22:33:49 +0200 Subject: [PATCH] refactored template --- README.md | 2 +- client/.gitignore | 1 + client/package.json | 17 +++++++--- client/src/App.js | 11 +++++++ client/src/api/index.js | 32 ++----------------- client/src/components/App/App.js | 12 ------- .../src/components/HelloWorld/HelloWorld.jsx | 9 ------ .../HelloWorld/HelloWorld.module.css | 6 ---- client/src/index.js | 4 +-- client/src/styles/App.css | 19 +++++++++++ client/src/{style => styles}/reset.css | 7 ---- server/.env.example | 3 +- server/.gitignore | 4 +-- server/api/controllers/exampleControllers.js | 28 ---------------- server/api/controllers/usersControllers.js | 29 +++++++++++++++++ server/api/models/{Example.js => User.js} | 16 +++++++--- server/api/routes/exampleRoutes.js | 19 ----------- server/api/routes/usersRoutes.js | 22 +++++++++++++ server/server.js | 26 +++++++-------- 19 files changed, 126 insertions(+), 141 deletions(-) create mode 100644 client/src/App.js delete mode 100644 client/src/components/App/App.js delete mode 100644 client/src/components/HelloWorld/HelloWorld.jsx delete mode 100644 client/src/components/HelloWorld/HelloWorld.module.css create mode 100644 client/src/styles/App.css rename client/src/{style => styles}/reset.css (95%) delete mode 100644 server/api/controllers/exampleControllers.js create mode 100644 server/api/controllers/usersControllers.js rename server/api/models/{Example.js => User.js} (63%) delete mode 100644 server/api/routes/exampleRoutes.js create mode 100644 server/api/routes/usersRoutes.js diff --git a/README.md b/README.md index aeae015..096aa0d 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Then go to your server folder (backend), and set your database within `server.js ###### Client: -> axios: ^0.21.0     --->     Use the API
react: ^17.0.1 +> axios: ^0.21.1     --->     Use the API
react: ^17.0.1 >     --->     UI framework
react-dom: ^17.0.1 >     --->     UI framework
react-scripts: ^4.0.1 >     --->     Quickly launch local service diff --git a/client/.gitignore b/client/.gitignore index b1b8d4b..3238358 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -1,3 +1,4 @@ /node_modules +.env .DS_Store .eslintcache \ No newline at end of file diff --git a/client/package.json b/client/package.json index 1763e3f..d3dbb87 100644 --- a/client/package.json +++ b/client/package.json @@ -1,15 +1,24 @@ { "name": "client", "version": "1.0.0", + "private": true, "main": "index.js", - "scripts": { - "start": "react-scripts start" - }, "license": "ISC", + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "eject": "react-scripts eject" + }, "dependencies": { - "axios": "^0.21.0", + "axios": "^0.21.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "^4.0.1" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] } } diff --git a/client/src/App.js b/client/src/App.js new file mode 100644 index 0000000..b0ecb7f --- /dev/null +++ b/client/src/App.js @@ -0,0 +1,11 @@ +import './styles/App.css'; + +function App() { + return ( +
+

Hello World - React.js

+
+ ); +} + +export default App; diff --git a/client/src/api/index.js b/client/src/api/index.js index 173292e..4fb56ff 100644 --- a/client/src/api/index.js +++ b/client/src/api/index.js @@ -5,36 +5,8 @@ const url = 'http://localhost:8080/api/v1'; // current method: GET // current path: http://localhost:8080/api/v1/example -export const getExample = () => axios.get(`${url}/example`); +export const getPeople = () => axios.get(`${url}/people`); // current method: POST // current path: http://localhost:8080/api/v1/example/upload -export const uploadExample = (form) => axios.post(`${url}/example/upload`, form); - -// Example using your API: -// -// -// -// 1) in your Component file, import a method from above like so: -// -// import { getExample } from './api'; -// -// -// -// 2) Then call the method and handle it's errors/response, like so: -// -// function ExampleFetching() { -// const [data, setData] = React.useState([]); -// -// React.useEffect(() => { -// getExample() -// .then((response) => setData(response.data)) -// .catch((error) => console.log(error)); -// }, []); -// -// return ( -//
-// {data} -//
-// ); -// } +export const newPerson = (form) => axios.post(`${url}/people/new`, form); diff --git a/client/src/components/App/App.js b/client/src/components/App/App.js deleted file mode 100644 index 528a8d4..0000000 --- a/client/src/components/App/App.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import HelloWorld from './../HelloWorld/HelloWorld'; - -function App() { - return ( -
- -
- ); -} - -export default App; diff --git a/client/src/components/HelloWorld/HelloWorld.jsx b/client/src/components/HelloWorld/HelloWorld.jsx deleted file mode 100644 index f6e4924..0000000 --- a/client/src/components/HelloWorld/HelloWorld.jsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import styles from './HelloWorld.module.css'; -// CSS module -> className={styles.App} (AKA styled components) - -function HelloWorld() { - return
Hello World - React.js
; -} - -export default HelloWorld; diff --git a/client/src/components/HelloWorld/HelloWorld.module.css b/client/src/components/HelloWorld/HelloWorld.module.css deleted file mode 100644 index f3f4dce..0000000 --- a/client/src/components/HelloWorld/HelloWorld.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.HelloWorld { - width: 100%; - min-height: 100vh; - display: grid; - place-items: center; -} diff --git a/client/src/index.js b/client/src/index.js index 390ebc7..8e9ccc1 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import App from './components/App/App'; -import './style/reset.css'; +import './styles/reset.css'; +import App from './App'; ReactDOM.render( diff --git a/client/src/styles/App.css b/client/src/styles/App.css new file mode 100644 index 0000000..af61db1 --- /dev/null +++ b/client/src/styles/App.css @@ -0,0 +1,19 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', + 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.App { + width: 100%; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.App > p { + text-align: center; +} diff --git a/client/src/style/reset.css b/client/src/styles/reset.css similarity index 95% rename from client/src/style/reset.css rename to client/src/styles/reset.css index ee28b36..0486183 100644 --- a/client/src/style/reset.css +++ b/client/src/styles/reset.css @@ -1,10 +1,3 @@ -body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', - 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - /* HTML5 Reset :: style.css ---------------------------------------------------------- diff --git a/server/.env.example b/server/.env.example index ca9ab8a..9a3aaa0 100644 --- a/server/.env.example +++ b/server/.env.example @@ -1 +1,2 @@ -CONNECTION_URL = "URL" +CONNECTION_URL = "MongoDB connection URL" +PORT = "4 digits" \ No newline at end of file diff --git a/server/.gitignore b/server/.gitignore index e1ce161..8321ac4 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -1,3 +1,3 @@ /node_modules -.DS_Store -.env \ No newline at end of file +.env +.DS_Store \ No newline at end of file diff --git a/server/api/controllers/exampleControllers.js b/server/api/controllers/exampleControllers.js deleted file mode 100644 index 064c87e..0000000 --- a/server/api/controllers/exampleControllers.js +++ /dev/null @@ -1,28 +0,0 @@ -import mongoose from 'mongoose'; -import Example from '../models/Example.js'; -// more about response status codes ---> https://restapitutorial.com/httpstatuscodes.html - -export async function getExamples(request, response, next) { - try { - const allExamples = await Example.find(); - response.status(200).json(allExamples); - } catch (error) { - console.log(error); - response.status(500).json(error); - } -} - -export const uploadExample = async (request, response, next) => { - try { - let newExample = new Example({ - _id: mongoose.Types.ObjectId(), // _id is set by default, (you can remove this line) - name: request.body.fieldName, // fieldName === name used on client side - }); - - const savedExample = await newExample.save(); - response.status(201).json(savedExample); - } catch (error) { - console.log(error); - response.status(500).json(error); - } -}; diff --git a/server/api/controllers/usersControllers.js b/server/api/controllers/usersControllers.js new file mode 100644 index 0000000..d15124a --- /dev/null +++ b/server/api/controllers/usersControllers.js @@ -0,0 +1,29 @@ +import mongoose from 'mongoose'; +import User from '../models/User.js'; +// more about response status codes ---> https://restapitutorial.com/httpstatuscodes.html + +export async function getAllUsers(request, response, next) { + try { + const allUsers = await User.find(); // finds all in 'users' collection + + response.status(200).json(allUsers); + } catch (error) { + console.log(error); + response.status(500).json(error); + } +} + +export const createNewUser = async (request, response, next) => { + try { + let newUser = new User({ + _id: mongoose.Types.ObjectId(), // _id is set by default, (you can remove this line) + name: request.body.userName, // userName === name used on client side + }); + const savedUser = await newUser.save(); + + response.status(201).json(savedUser); + } catch (error) { + console.log(error); + response.status(500).json(error); + } +}; diff --git a/server/api/models/Example.js b/server/api/models/User.js similarity index 63% rename from server/api/models/Example.js rename to server/api/models/User.js index 2985a8a..d967407 100644 --- a/server/api/models/Example.js +++ b/server/api/models/User.js @@ -3,19 +3,25 @@ import mongoose from 'mongoose'; const instance = new mongoose.Schema( { _id: mongoose.Schema.Types.ObjectId, // _id is set by default, (you can remove this line) - name: String, + /* - name = property of document object - String = type of value ---> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures + name = Object key + String = Type */ + name: String, }, { timestamps: true, + // this creates and maintains: + // { + // createdAt: Date, + // updatedAt: Date, + // } }, ); // NOTE! use a singular model name, mongoose automatically creates a collection like so: -// model: 'Person' === collection: 'people' -const modelName = 'Example'; +// model: 'User' === collection: 'users' +const modelName = 'User'; export default mongoose.model(modelName, instance); diff --git a/server/api/routes/exampleRoutes.js b/server/api/routes/exampleRoutes.js deleted file mode 100644 index 96b7180..0000000 --- a/server/api/routes/exampleRoutes.js +++ /dev/null @@ -1,19 +0,0 @@ -import express from 'express'; -import { getExamples, uploadExample } from '../controllers/exampleControllers.js'; // import request & response function - -// initialize router -const router = express.Router(); -/* - request methods ---> https://www.tutorialspoint.com/http/http_methods.htm - 1st param = extended url path - 2nd param = middlewares (optional) - 3rd param = request & response function (controller) -*/ - -// current path: http://localhost:8080/api/v1/example -router.get('/', (request, response, next) => next(), getExamples); - -// current path: http://localhost:8080/api/v1/example/upload -router.post('/upload', (request, response, next) => next(), uploadExample); - -export default router; diff --git a/server/api/routes/usersRoutes.js b/server/api/routes/usersRoutes.js new file mode 100644 index 0000000..a2ae9cf --- /dev/null +++ b/server/api/routes/usersRoutes.js @@ -0,0 +1,22 @@ +import express from 'express'; +import { getAllUsers, createNewUser } from '../controllers/peopleControllers.js'; // import request & response function + +// initialize router +const router = express.Router(); + +/* + request methods ---> https://www.tutorialspoint.com/http/http_methods.htm + 1st param = extended url path + 2nd param = middlewares (optional) + 3rd param = request & response function (controller) +*/ + +// current method: GET +// current path: http://localhost:8080/api/v1/users +router.get('/', (request, response, next) => next(), getAllUsers); + +// current method: POST +// current path: http://localhost:8080/api/v1/users/new +router.post('/new', (request, response, next) => next(), createNewUser); + +export default router; diff --git a/server/server.js b/server/server.js index 2ac61f3..aa71cc0 100644 --- a/server/server.js +++ b/server/server.js @@ -3,28 +3,24 @@ import express from 'express'; // Backend App (server) import cors from 'cors'; // HTTP headers (enable requests) import morgan from 'morgan'; // Logs incoming requests import dotenv from 'dotenv'; // Secures variables - -// import IMPORTED_ROUTES from './api/routes/route.js'; +// import usersRoutes from './api/routes/usersRoutes.js'; // ^ ^ ^ un-comment this to use imported route(s) -// doing this will link the following files: server.js -> exampleRoutes.js -> exampleControllers.js -> Example.js +// doing this will link the following files: server.js -> usersRoutes.js -> usersControllers.js -> User.js // initialize app const app = express(); // middlewares -app.use(express.json({ limit: '10mb', extended: true })); // body parser -app.use(express.urlencoded({ limit: '10mb', extended: true })); // url parser +app.use(express.json({ limit: '10mb', extended: false })); // body parser +app.use(express.urlencoded({ limit: '10mb', extended: false })); // url parser app.use(cors({ origin: 'http://localhost:3000' })); // enables http requests on react development server app.use(morgan('common')); // logs requests dotenv.config(); // protected variables // configure db: -// if you want to connect to cloud server (atlas): edit "CONNECTION_URL" in -> .env file -// if you want to use local server (community): edit "DB_NAME" -const DB_NAME = 'exampleDB'; -const CONNECTION_URL = process.env.CONNECTION_URL || `mongodb://localhost:27017/${DB_NAME}`; -const PORT = process.env.PORT || 8080; // 8080 === development port -const DEPRECATED_FIX = { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true }; // update this with (possible) deprecated warnings +// for "atlas" edit CONNECTION_URL in -> .env file || for "community server" edit +const CONNECTION_URL = process.env.CONNECTION_URL || 'mongodb://localhost:27017/'; +const DEPRECATED_FIX = { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true }; // connect to db mongoose @@ -32,13 +28,13 @@ mongoose .catch((error) => console.log('❌ MongoDB connection error', error)); // listen for errors on initial connection mongoose.connection.on('connected', () => console.log('✅ MongoDB connected')); // connected mongoose.connection.on('disconnected', () => console.log('❌ MongoDB disconnected')); // disconnected -mongoose.connection.on('error', (error) => console.log('❌ MongoDB connection error', error)); // listen for errors after the connection is established (errors during the session) +mongoose.connection.on('error', (error) => console.log('❌ MongoDB connection error', error)); // listen for errors during the session // routes -app.get('/', (request, response, next) => response.send('Hello World - Express.js')); - -// app.use('/api/v1/example', IMPORTED_ROUTES); +app.get('/', (request, response, next) => response.status(200).json('Hello World - Express.js')); +// app.use('/api/v1/users', usersRoutes); // ^ ^ ^ un-comment this to use imported route(s) // server is listening for requests +const PORT = process.env.PORT || 8080; app.listen(PORT, () => console.log(`✅ Server is listening on port: ${PORT}`));