Browse Source

appointment creator added times array

liontix 10 months ago
parent
commit
6e87e6e986
7 changed files with 47 additions and 16 deletions
  1. 0 0
      .env-example copy
  2. 3 0
      package.json
  3. 4 2
      routes/appointments.js
  4. 14 5
      routes/members.js
  5. 4 4
      schemas/appointmentSchema.js
  6. 22 4
      utils.js
  7. 0 1
      views/error.pug

+ 0 - 0
.env-example → .env-example copy


+ 3 - 0
package.json

@@ -15,7 +15,10 @@
     "eslinter": "^3.1.0",
     "express": "^4.21.2",
     "http-errors": "~1.6.3",
+    "joi": "^17.13.3",
     "jsonwebtoken": "^9.0.2",
+    "moment": "^2.30.1",
+    "momentjs": "^2.0.0",
     "mongoose": "^8.9.0",
     "morgan": "~1.9.1",
     "nodemon": "^3.1.9",

+ 4 - 2
routes/appointments.js

@@ -15,15 +15,17 @@ const router = express.Router();
  * Create a new appointment and associate it with a booking.
  */
 router.post('/create', async function(req, res, next) {
-    const { appointment, email, firstname, lastname } = req.body;
+    const { appointment, email, firstname, lastname, times } = req.body;
 
     const appointmentId = appointment;
 
-    if (!appointmentId || !firstname || !lastname || !email) {
+    if (!appointmentId || !firstname || !lastname || !email || !times) {
         res.status(400).json({ 'message': 'Parameters are incomplete' });
         return;
     }
 
+    // TODO validate times
+
     if (!isValidEmail(email)) {
         res.status(400).json({ 'message': 'Email is invalid' });
         return;

+ 14 - 5
routes/members.js

@@ -3,7 +3,7 @@ import passport from "passport";
 import {mongoose} from "mongoose";
 import Appointment from "../schemas/appointmentSchema.js";
 import Booking from "../schemas/bookingSchema.js";
-import {validateDates} from "../utils.js";
+import {appointmentTimeSchema, isDueDatePassed, isValidAppointmentTimes, validateDates} from "../utils.js";
 
 /**
  * Router for handling appointments.
@@ -30,18 +30,27 @@ router.use((req, res, next) => {
  */
 router.post('/create', function(req, res, next) {
     const user = req.userId;
-    const { title, description, dueDate, place, startDate, endDate } = req.body;
+    const { title, description, dueDate, place, duration, times } = req.body;
 
-    if (!title || title.length === 0 || !dueDate || !description || !startDate || !endDate || !place) {
+    if (!title || title.length === 0 || !dueDate || !description || !duration || !place || !times) {
         res.status(400).json({ 'message': 'Empty parameter' });
         return;
     }
+    ///
+    if (!isDueDatePassed(dueDate)) {
+        res.status(400).json({ 'message': 'Due date is in the future' });
+        return;
+    }
 
-    if (!validateDates(res, startDate, endDate, dueDate)) {
+    console.log(times);
+
+    // validate times
+    if (!isValidAppointmentTimes(times)) {
+        res.status(400).json({ 'message': 'Appointment times are invalid' });
         return;
     }
 
-    const newTask = new Appointment({ user, title, description, dueDate, place, startDate, endDate });
+    const newTask = new Appointment({ user, title, description, dueDate, place, duration, times });
 
     newTask.save()
         .then(doc => res.json({ "id": doc._id }))

+ 4 - 4
schemas/appointmentSchema.js

@@ -42,12 +42,12 @@ const appointmentSchema = new mongoose.Schema({
         type: String,
         required: true
     },
-    startDate: {
-        type: Date,
+    duration: {
+        type: Number,
         required: true
     },
-    endDate: {
-        type: Date,
+    times: {
+        type: Array,
         required: true
     }
 });

+ 22 - 4
utils.js

@@ -1,3 +1,10 @@
+import Joi from "joi";
+import moment from "moment";
+
+const appointmentTimeSchema = Joi.object().keys({
+    date: Joi.date().required(),
+    available: Joi.boolean().required()
+  });
 
 function isValidEmail(email) {
     const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -5,9 +12,7 @@ function isValidEmail(email) {
 }
 
 function isDueDatePassed(dueDate) {
-    const now = new Date();
-    const dueDateTime = new Date(dueDate);
-    return dueDateTime < now;
+    return moment(dueDate, 'YYYY-MM-DD', true).isAfter();
 }
 
 function isDatePassed(dateA, dateB) {
@@ -16,6 +21,19 @@ function isDatePassed(dateA, dateB) {
     return dueDateA < dueDateB;
 }
 
+function isValidAppointmentTimes(data) {
+    return data.every(item => {
+      try {
+        if (!moment(item.date, 'YYYY-MM-DDTHH:mm', true).isValid() || appointmentTimeSchema.validate(item)['error']) {
+            return false;
+        }
+      } catch (e) {
+        return false;
+      }
+      return true;
+    });
+}
+
 function validateDates(res, startDate, endDate, dueDate) {
     if (isDatePassed(startDate, dueDate)) {
         res.status(400).json({ 'message': 'Due date is after start date' });
@@ -35,4 +53,4 @@ function validateDates(res, startDate, endDate, dueDate) {
     return true;
 }
 
-export {isValidEmail, isDueDatePassed, isDatePassed, validateDates};
+export {isValidEmail, isDueDatePassed, isDatePassed, validateDates, isValidAppointmentTimes, appointmentTimeSchema};

+ 0 - 1
views/error.pug

@@ -3,4 +3,3 @@ extends layout
 block content
   h1= message
   h2= error.status
-  pre #{error.stack}