Procházet zdrojové kódy

Add ability to create courses.
Created backend and frontend.

Lee Morgan před 5 roky
rodič
revize
f658f3b203
7 změnil soubory, kde provedl 161 přidání a 37 odebrání
  1. 1 0
      .gitignore
  2. 4 0
      app.js
  3. 26 35
      controllers/learn.js
  4. 72 0
      package-lock.json
  5. 2 0
      package.json
  6. 4 2
      routes.js
  7. 52 0
      views/learn/newCourse.html

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 /node_modules
 /content/*
 *.swp
+/thumbNails/

+ 4 - 0
app.js

@@ -5,6 +5,8 @@ const compression = require("compression");
 const mongoose = require("mongoose");
 const https = require("https");
 const fs = require("fs");
+const bodyParser = require("body-parser");
+const fileUpload = require("express-fileupload");
 
 const app = express();
 htmlCreator(app);
@@ -41,6 +43,8 @@ mongoose.connect("mongodb://127.0.0.1/leemorgan", mongooseOptions);
 app.use(express.static(__dirname + "/content"));
 app.use(compression());
 app.use(express.json());
+app.use(bodyParser.urlencoded({extended: false}))
+app.use(fileUpload({limits: { fileSize: 5 * 1024 * 1024 }}));
 require("./routes.js")(app);
 
 if(process.env.NODE_ENV === "production") httpsServer.listen(process.env.HTTPS_PORT);

+ 26 - 35
controllers/learn.js

@@ -1,54 +1,45 @@
+const Uploader = require("../models/uploader.js");
 const Course = require("../models/course.js");
+const Lecture = require("../models/lecture.js");
 
 module.exports = {
     /*
-    POST: creates a new course
+    POST: create a new course
     req.body = {
-        groupTitle: String,
-        title: String,
-        video: String,
-        description: String,
-        documents: [{
-            title: String,
-            link: String
-        }],
-        exercises: [String]
+        uploaderId: String,
+        password: String,
+        courseId:  String,
+        title: String
+        thumbNail: String,
+        description: String
     }
+    redirect to home
     */
-    createLecture: function(req, res){
-        Course.find({groupTitle: req.body.groupTitle})
-            .then((courses)=>{
-                let max = 0;
-                for(let i = 0; i < courses.length; i++){
-                    let num = parseInt(courses[i].courseId.split("-")[1]);
+    createCourse: function(req, res){
+        Uploader.findOne({_id: req.body.uploaderId})
+            .then((uploader)=>{
+                if(uploader === null) throw "uploader";
+                if(req.body.password !== uploader.password) throw "pass";
+                let imgString = `./thumbNails/${req.files.thumbNail.name}`;
+                req.files.thumbNail.mv(imgString);
 
-                    if(num > max) max = num;
-                }
-
-                //from StackOverflow user "RobG"
-                function pad(n, length) {
-                    var len = length - (''+n).length;
-                    return (len > 0 ? new Array(++len).join('0') : '') + n;
-                }
-
-                let newCourse = new Course({
-                    courseId: `${courses[0].courseId.split("-")[0]}-${pad(max++)}`,
-                    groupTitle: courses[0].groupTitle,
+                let course = new Course({
+                    owner: uploader._id,
+                    courseId: req.body.courseId,
                     title: req.body.title,
-                    video: req.body.video,
-                    thumbNail: courses[0].thumbNail,
-                    description: req.body.description,
-                    documents: req.body.documents,
-                    exercises: req.body.exercises
+                    thumbNail: imgString,
+                    description: req.body.description
                 });
 
-                return newCourse.save();
+                return course.save();
             })
             .then((course)=>{
                 return res.redirect("/");
             })
             .catch((err)=>{
-                return res.json("Something went wrong");
+                if(err === "uploader") return res.json("Uploader doesn't exist");
+                if(err === "pass") return res.json("Incorrect password");
+                return res.json("Something went wrong on the backend");
             });
     },
 

+ 72 - 0
package-lock.json

@@ -8,8 +8,10 @@
       "version": "1.0.0",
       "license": "ISC",
       "dependencies": {
+        "body-parser": "^1.19.0",
         "compression": "^1.7.4",
         "express": "^4.17.1",
+        "express-fileupload": "^1.2.1",
         "mongoose": "^5.12.3"
       }
     },
@@ -94,6 +96,17 @@
         "node": ">=0.6.19"
       }
     },
+    "node_modules/busboy": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
+      "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
+      "dependencies": {
+        "dicer": "0.3.0"
+      },
+      "engines": {
+        "node": ">=4.5.0"
+      }
+    },
     "node_modules/bytes": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -204,6 +217,17 @@
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
+    "node_modules/dicer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
+      "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
+      "dependencies": {
+        "streamsearch": "0.1.2"
+      },
+      "engines": {
+        "node": ">=4.5.0"
+      }
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -270,6 +294,17 @@
         "node": ">= 0.10.0"
       }
     },
+    "node_modules/express-fileupload": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.1.tgz",
+      "integrity": "sha512-fWPNAkBj+Azt9Itmcz/Reqdg3LeBfaXptDEev2JM8bCC0yDptglCnlizhf0YZauyU5X/g6v7v4Xxqhg8tmEfEA==",
+      "dependencies": {
+        "busboy": "^0.3.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/finalhandler": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -768,6 +803,14 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/streamsearch": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+      "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
     "node_modules/string_decoder": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -899,6 +942,14 @@
       "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz",
       "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg=="
     },
+    "busboy": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
+      "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
+      "requires": {
+        "dicer": "0.3.0"
+      }
+    },
     "bytes": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@@ -984,6 +1035,14 @@
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
+    "dicer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
+      "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
+      "requires": {
+        "streamsearch": "0.1.2"
+      }
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1041,6 +1100,14 @@
         "vary": "~1.1.2"
       }
     },
+    "express-fileupload": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.2.1.tgz",
+      "integrity": "sha512-fWPNAkBj+Azt9Itmcz/Reqdg3LeBfaXptDEev2JM8bCC0yDptglCnlizhf0YZauyU5X/g6v7v4Xxqhg8tmEfEA==",
+      "requires": {
+        "busboy": "^0.3.1"
+      }
+    },
     "finalhandler": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
@@ -1413,6 +1480,11 @@
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
       "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
     },
+    "streamsearch": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
+      "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
+    },
     "string_decoder": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",

+ 2 - 0
package.json

@@ -9,8 +9,10 @@
   "author": "Lee Morgan",
   "license": "ISC",
   "dependencies": {
+    "body-parser": "^1.19.0",
     "compression": "^1.7.4",
     "express": "^4.17.1",
+    "express-fileupload": "^1.2.1",
     "mongoose": "^5.12.3"
   }
 }

+ 4 - 2
routes.js

@@ -42,8 +42,10 @@ module.exports = function(app){
     app.get("/travel/*", (req, res)=>res.sendFile(`${views}/travel/index.html`));
 
     //LEARN
-    app.get("/learn/new", (req, res)=>{res.sendFile(`${views}/learn/new.html`)});
+    app.get("/learn/course/new", (req, res)=>{res.sendFile(`${views}/learn/newCourse.html`)});
+    app.post("/learn/course/new", learn.createCourse);
+    // app.get("/learn/lecture", (req, res)=>{res.sendFile(`${views}/learn/newLecture.html`)});
+    // app.post("/learn/lecture", (learn.createLecture));
     app.get("/learn/style", (req, res)=>res.sendFile(`${views}/learn/index.css`));
     app.get("/learn/web", (req, res)=>{res.sendFile(`${views}/learn/web.html`)});
-    app.get("/learn/courses", learn.getCourseGroups);
 }

+ 52 - 0
views/learn/newCourse.html

@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <title>Create Course</title>
+        <style>
+            form{
+                display: flex;
+                flex-direction: column;
+            }
+
+            form > *{
+                margin: 10px 0;
+            }
+
+            input[type=submit]{
+                max-width: 250px;
+            }
+        </style>
+    </head>
+    <body>
+        <h1>Enter course details</h1>
+
+        <form action="/learn/course/new" method="post" encType="multipart/form-data">
+            <label>Uploader ID
+                <input name="uploaderId" type="text" required>
+            </label>
+
+            <label>Password
+                <input name="password" type="password" required>
+            </label>
+
+            <label>Course Title
+                <input name="title" type="text" required>
+            </label>
+
+            <label>Course URL string(i.e. "design", "js", "html")
+                <input name="courseId" type="text" required>
+            </label>
+
+            <label>ThumbNail
+                <input name="thumbNail" type="file" required>
+            </label>
+            
+            <label>Description
+                <textarea name="description" minlength="25" required></textarea>
+            </label>
+
+            <input type="submit" value="Submit">
+        </form>
+    </body>
+</html>