Skip to content

Commit

Permalink
Merge branch 'main' into Welcome_Page
Browse files Browse the repository at this point in the history
  • Loading branch information
myix765 committed Dec 8, 2024
2 parents 1b10012 + 755d115 commit 9dede10
Show file tree
Hide file tree
Showing 41 changed files with 1,283 additions and 705 deletions.
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Issue ticket number and link

## Does your code meet the acceptance criteria?
- [] Yes
- [] Yes # put an x in the brackets to checkmark!

## Testing done and screenshots (if relevant)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ npm run client
To run just server:
```
npm run server # in root folder
npm run dev # in backend folder
npm run dev # in api folder
```

## Git Commands Guide
Expand Down
177 changes: 161 additions & 16 deletions backend/server.js → api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const cors = require('cors');
const mongo = require('mongodb');
const mongoose = require('mongoose');
const mongoSanitize = require('express-mongo-sanitize');
const nodemailer = require('nodemailer');

const app = express()
app.use(cors())
Expand Down Expand Up @@ -79,6 +80,7 @@ const UserSchema = new Schema({

const User = mongoose.model("User", UserSchema)


// Contact Schema
const ContactSchema = new Schema({
name: { type: String, required: true },
Expand All @@ -89,11 +91,14 @@ const ContactSchema = new Schema({

const Contact = mongoose.model('Contact', ContactSchema);

// Class Schema

// Schedule Schema
const ScheduleSchema = new Schema({
day: { type: String, required: true },
time: { type: String, required: true },
})

// Class Schema
const ClassSchema = new Schema({
title: { type: String, required: true },
level: { type: String, required: true },
Expand All @@ -105,6 +110,18 @@ const ClassSchema = new Schema({

const Class = mongoose.model("Class", ClassSchema)


// Conversation Schema
const ConversationSchema = new Schema({
instructor: { type: String, required: true },
ageGroup: { type: String, required: true },
schedule: { type: [ScheduleSchema], required: true, default: [] },
roster: { type: [Schema.Types.ObjectId], default: [] }
}, { collection: 'conversations' })

const Conversation = mongoose.model("Conversation", ConversationSchema)


// Level Schema
const LevelSchema = new Schema({
level: { type: Number, required: true },
Expand All @@ -116,6 +133,8 @@ const Level = mongoose.model("Level", LevelSchema)

//------------------ ENDPOINTS ------------------//

/* USER RELATED ENDPOINTS */

// Sign up
app.post('/api/users', async (req, res) => {
try {
Expand Down Expand Up @@ -164,11 +183,10 @@ app.post('/api/login', async (req, res) => {
try {
const user = await User.findOne({ username });
console.log('Database query result:', user);

if (user) {
if (user.password === password) {
console.log('Login successful for user:', username);
res.status(200).send('Login successful!');
res.status(200).json({ user });
} else {
console.log('Login failed: Incorrect password.');
res.status(401).send('Invalid password.');
Expand All @@ -193,49 +211,176 @@ app.get('/api/users', async (req, res) => {
}
})

// Contact

/* CONTACT RELATED ENDPOINTS */

// Post Contact
app.post('/api/contact', async (req, res) => {
const { name, email, subject, message } = req.body

try {
const newContact = new Contact({
name,
email,
subject,
message
})
await newContact.save()
});
await newContact.save();

// Nodemailer setup
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.ADMIN_EMAIL,
pass: process.env.ADMIN_PASSWORD,
},
});

transporter.verify((error, success) => {
if (error) {
console.error('Error initializing transporter:', error);
} else {
console.log('Transporter is ready to send emails', success);
}
});

res.status(201).json({ message: 'Inquiry submitted successfully' })

const mailOptions = {
from: email,
to: process.env.ADMIN_EMAIL,
subject: `Contact Form: ${subject}`,
html: `
<p><strong>From:</strong> ${name} (${email})</p>
<p><strong>Subject:</strong> ${subject}</p>
<p><strong>Message:</strong></p>
<p>${message}</p>
`
};

// Send email
await transporter.sendMail(mailOptions);

res.status(201).json({ message: 'Inquiry and email submitted successfully' });
}
catch (err) {
console.error('Error submitting inquiry:', err);
res.status(500).json({ message: 'Error submitting inquiry' })
res.status(500).json({ message: 'Error submitting inquiry', error: err.message });
}
})
});


/* CLASS RELATED ENDPOINTS */

// Classes
// Get Classes
app.get('/api/classes', async (req, res) => {
try {
const allowedFields = ['level', 'instructor', 'ageGroup'];
const filters = validateInput(req.query, allowedFields);

//apply the filters directly to the database query
const data = await Class.find(filters);
res.json(data)

res.json(data);
} catch (err) {
res.status(500).send(err);
}
})

// Levels
// Get Levels
app.get("/api/levels", async (req, res) => {
try {
const allowedFields = ['level']
const filters = validateInput(req.query, allowedFields)
const allowedFields = ['level'];
const filters = validateInput(req.query, allowedFields);
const data = await Level.find(filters);
res.json(data);
} catch (err) {
res.status(500).send(err);
}
})
})

// Get Conversation classes
app.get("/api/conversations", async (req, res) => {
try {
const data = await Conversation.find();
res.status(200).json(data);
} catch (error) {
res.status(500).send(err);
}
})

// Get Student's classes
app.get('/api/students-classes', async (req, res) => {
try {
const allowedFields = ['_id'];
const filters = validateInput(req.query, allowedFields);

//apply the filters directly to the database query
const data = await User.findOne(filters, { enrolledClasses: 1, _id: 0 });
res.json(data);

} catch (err) {
res.status(500).send(err);
}
})

// Get class by ID
app.get('/api/class', async (req, res) => {
try {
const allowedFields = ['_id'];
const filters = validateInput(req.query, allowedFields);

//apply the filters directly to the database query
const data = await Class.findOne(filters);
res.json(data)

} catch (err) {
res.status(500).send(err);
}
})

// Enroll in a class
app.put('/api/users/:id/enroll', async (req, res) => {
const { classId } = req.body
const studentId = new mongoose.Types.ObjectId('671edb6d31e448b23d0dc384') // hardcode userId
try {
// add class id to user's classes
await User.findByIdAndUpdate(
studentId,
{ $addToSet: { enrolledClasses: classId } },
{ new: true }
)

// add student id to class's roster
await Class.findByIdAndUpdate(
classId,
{ $addToSet: { roster: studentId } },
{ new: true }
)
res.status(201).json({ message: 'Enrolled successfully!' })
} catch (err) {
console.error('Error enrolling into class:', err);
res.status(500).json({ message: 'Error enrolling into class' })
}
})

// Unenroll in a class
app.put('/api/users/:id/unenroll', async (req, res) => {
const { classId } = req.body
const studentId = new mongoose.Types.ObjectId('671edb6d31e448b23d0dc384') // hardcode userId
try {
// remove class id from user's classes
await User.findByIdAndUpdate(
studentId,
{ $pull: { enrolledClasses: classId } },
)

// remove student id from class's roster
await Class.findByIdAndUpdate(
classId,
{ $pull: { roster: studentId } },
)
res.status(201).json({ message: 'Unenrolled successfully!' })
} catch (err) {
console.error('Error unenrolling into class:', err);
res.status(500).json({ message: 'Error unenrolling into class' })
}
})
10 changes: 5 additions & 5 deletions backend/package.json → api/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "backend",
"name": "api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js",
"dev": "nodemon server"
"start": "node index.js",
"dev": "nodemon index"
},
"keywords": [],
"author": "",
Expand All @@ -22,4 +22,4 @@
"devDependencies": {
"nodemon": "^3.1.7"
}
}
}
Loading

0 comments on commit 9dede10

Please sign in to comment.