diff --git a/app.js b/app.js index 7e0543a..1d054e3 100644 --- a/app.js +++ b/app.js @@ -1,35 +1,26 @@ -// ℹ️ Gets access to environment variables/settings -// https://www.npmjs.com/package/dotenv require('dotenv/config'); - -// ℹ️ Connects to the database require('./db'); -// Handles http requests (express is node js framework) -// https://www.npmjs.com/package/express const express = require('express'); - -// Handles the handlebars -// https://www.npmjs.com/package/hbs const hbs = require('hbs'); const app = express(); +app.use(express.static('public')); -// ℹ️ This function is getting exported from the config folder. It runs most middlewares +// This function is getting exported from the config folder. It runs most middlewares require('./config')(app); // default value for title local const projectName = 'lab-express-drones'; const capitalized = string => string[0].toUpperCase() + string.slice(1).toLowerCase(); - -app.locals.title = `${capitalized(projectName)}- Generated with Rootlauncher`; +app.locals.title = `${capitalized(projectName)}`; // 👇 Start handling routes here const index = require('./routes/index'); -app.use('/', index); +app.use('/', index); // Home page route -const droneRoutes = require('./routes/drones') -app.use('/', droneRoutes) +const droneRoutes = require('./routes/drones'); +app.use('/', droneRoutes); // Drone-related routes // ❗ To handle errors. Routes that don't exist or errors that you handle in specific routes require('./error-handling')(app); diff --git a/db/index.js b/db/index.js index 873910d..f9c0675 100644 --- a/db/index.js +++ b/db/index.js @@ -5,7 +5,7 @@ const mongoose = require("mongoose"); // ℹ️ Sets the MongoDB URI for our app to have access to it. // If no env has been set, we dynamically set it to whatever the folder name was upon the creation of the app -const MONGO_URI = process.env.MONGODB_URI || "mongodb://localhost/lab-express-drones"; +const MONGO_URI = process.env.MONGODB_URI || "mongodb://127.0.0.1:27017/lab-express-drones"; mongoose .connect(MONGO_URI) diff --git a/models/Drone.model.js b/models/Drone.model.js index 93e3ea9..dfa73d8 100644 --- a/models/Drone.model.js +++ b/models/Drone.model.js @@ -1 +1,14 @@ -// Iteration #1 \ No newline at end of file +// Iteration #1 +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +//create Schema of drones to seed the db +const droneSchema = new Schema({ + name: String, + propellers: Number, + maxSpeed: Number, +}); + +const Drone = mongoose.model('Drone', droneSchema); + +module.exports = Drone; diff --git a/public/images/drone.jpg b/public/images/drone.jpg new file mode 100644 index 0000000..ba6f2ab Binary files /dev/null and b/public/images/drone.jpg differ diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 05a1470..fc44ab2 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -1,8 +1,199 @@ +/* General body styling */ body { - padding: 50px; - font: 14px 'Lucida Grande', Helvetica, Arial, sans-serif; + font-family: "Bebas Neue", sans-serif; + font-weight: 400; + font-style: normal; + margin: 0; + padding: 0; } + +.layout-container{ + height: 100vh; +background-size: cover; +margin: 0; +padding: 0; +background-repeat: no-repeat; +background-image: url("../images/drone.jpg"); +display: flex; +justify-content: space-between; + +} +.welcome-layout{ +text-align: left; +} + +.btnOfMoreDrones{ + text-align: right; + padding: 0 2rem 0 0; + font-size: 2rem; + align-items: flex-end; + +} + +.btnOfMoreDrones>p{ + margin:0; +} + +.btnOfMoreDrones>a{ + text-decoration: none; + +} + +.welcome-layout>h1{ + font-size: 7.5rem; + line-height: 7rem; + margin: 0; + text-align: left; + + padding: 0 0 0 2rem; +} + +.container-list{ + margin: 2rem; + width: 90vw; + padding: 2rem; + height: auto; + + box-shadow: 2px 2px 10px 2px black; + border-radius: 10px; +} + +.container-list>h1{ + padding: 0; + margin: 0; +} + + +/* Header Style */ +h1 { + font-size: 2.5em; + margin-bottom: 20px; + text-align: center; + color: #2c3e50; +} + +/* Drones List Style */ +.drones-list { + list-style: none; + padding: 0; + display: grid; + gap: 1rem; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); +} + +.drones-list li { + box-shadow: 1px 1px 1px 1px #4f4f4f; + border-radius: 20px; + min-width: 15rem; + display:flex; + justify-content: center; +align-items: flex-start; +flex-direction: column; +text-align: left; + padding:1rem; +} + + +/* Drone Details */ +.drones-list h2 { + font-size: 1.8em; + margin: 0 0 10px 0; + color: #2980b9; +} + +.drones-list p { + margin: 5px 0; + font-size: 1.1em; +} + +/* Edit Button */ a { - color: #00b7ff; + background-color: #2c3e50; + text-decoration: none; + padding: 5px 12px; + color: #ffffff; + border-radius: 4px; +margin: 0 0.3rem 0 0; + font-weight: bold; + transition: color 0.3s; + letter-spacing: 1px; +} + +a:hover { + background-color: #333c9f80; +} + +/* Delete Button */ +button { + font-weight: bold; + + padding: 8px 12px; + background-color: #0d4f7a; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.3s; +} + +button:hover { + background-color: #052941; +} + +/* Add New Drone Link */ +.container-list a:last-child { + display: inline-block; + margin: 20px 0 0; + padding: 10px 15px; + display: flex; + justify-content: center; + align-items: center; + background-color: #27ae60; + color: white; + text-decoration: none; + border-radius: 4px; + text-align: center; + transition: background-color 0.3s; +} +.btn-edit-delete{ + margin: 0.7rem 0 0 0; + display: flex; + justify-content: center; + align-items: center; +} +.container-list a:last-child:hover { + background-color: #219653; +} + +.create-form-container{ + margin: 2rem; + padding: 3rem; + box-shadow: 2px 2px 10px 2px black; + border-radius: 10px; + display: flex; + flex-direction: column; + text-align: left; + justify-content: center; + align-items: center; +} +.create-form-form{ + display: flex; + margin: 1rem 0 0 ; + flex-direction: column; + text-align: left; + + } +.h1-create-form{ + padding: 0; + margin: 0; +} +.input-create-form{ +margin: 0 0 1rem 0; +} + +.create-form-container>h1{ + padding: 0; + margin: 0; +} \ No newline at end of file diff --git a/routes/drones.js b/routes/drones.js index 51da515..741de15 100644 --- a/routes/drones.js +++ b/routes/drones.js @@ -1,36 +1,87 @@ const express = require('express'); const router = express.Router(); - +const Drone = require("../models/Drone.model"); // Import the drone model schema // require the Drone model here router.get('/drones', (req, res, next) => { - // Iteration #2: List the drones - // ... your code here + Drone.find() + .then(drones => { + res.render('drones/list', { drones }) //pass drones list from views folder + }) + .catch(err =>next(err)) //handle errors }); router.get('/drones/create', (req, res, next) => { - // Iteration #3: Add a new drone - // ... your code here + res.render("drones/create-form") + //going to render the form from views, to get input data from the user + + }); router.post('/drones/create', (req, res, next) => { - // Iteration #3: Add a new drone - // ... your code here + //post to db in the following way: + //1. get info from req.boy + //(posted by user in a form w action: route and method:post) + const { name, propellers, maxSpeed } = req.body; + + //create the element in the db + Drone.create({ name, propellers, maxSpeed }) + .then(() => { + res.redirect('/drones'); + // Redirect to the list of drones(views folder) + // after creating it, for user to see it. + }) + //catch errors + .catch(err => { + console.log('Error while creating drone:', err); + res.render('drones/create-form'); + }); + }); router.get('/drones/:id/edit', (req, res, next) => { - // Iteration #4: Update the drone - // ... your code here + //get the drone to edit decontructuring the id in the req.params + const { id } = req.params; + + + + //search by id and display form to edit + Drone.findById(id) + .then(drone => { + if (!drone) { // if drone not to be found, display error + return res.status(404).render("not-found"); + } + //else display the form to edit; + res.render('drones/update-form', { drone }) + })//catch errors + .catch(err => next(err)) }); router.post('/drones/:id/edit', (req, res, next) => { - // Iteration #4: Update the drone - // ... your code here + //get id so we can find it + const { id } = req.params; + //get the info from users input in form + const { name, propellers, maxSpeed } = req.body; + + //search by id - update the list {} + Drone.findByIdAndUpdate(id, { name, propellers, maxSpeed }, { new: true }) + .then(() => { + res.redirect('/drones'); //show drones after updating + }) + .catch(err => { + console.log('Error while updating drone:', err); + res.render('drones/update-form', { drone: { _id: id, name, propellers, maxSpeed } }); + }); }); router.post('/drones/:id/delete', (req, res, next) => { - // Iteration #5: Delete the drone - // ... your code here + const { id } = req.params; + + Drone.findByIdAndDelete(id) + .then(() => { + res.redirect('/drones'); + }) + .catch(err => next(err)); }); module.exports = router; diff --git a/seeds/drones.seed.js b/seeds/drones.seed.js index 4b29ecb..f0f5767 100644 --- a/seeds/drones.seed.js +++ b/seeds/drones.seed.js @@ -1 +1,22 @@ // Iteration #1 +const mongoose = require('mongoose'); +const Drone = require('../models/Drone.model'); // Import the model of the schema + +const MONGO_URI = 'mongodb://127.0.0.1:27017/lab-express-drones'; // connect to the db where we need to seed + +const drones = [ + { name: 'Creeper XL 500', propellers: 3, maxSpeed: 12 }, + { name: 'Racer 57', propellers: 4, maxSpeed: 20 }, + { name: 'Courier 3000i', propellers: 6, maxSpeed: 18 } +]; + +mongoose + .connect(MONGO_URI) + .then(() => { + return Drone.create(drones); + }) + .then(createdDrones => { + console.log(`Created ${createdDrones.length} drones`); + return mongoose.connection.close(); // Close the connection + }) + .catch(err => console.log('Error seeding the database:', err)); diff --git a/views/drones/create-form.hbs b/views/drones/create-form.hbs index 1a8197f..24979b0 100644 --- a/views/drones/create-form.hbs +++ b/views/drones/create-form.hbs @@ -1 +1,38 @@ -
Propellers: {{this.propellers}}
+Max Speed: {{this.maxSpeed}} km/h
+Welcome to {{title}}
+ + + + + + + +Check out all the drones u have!
+HERE +