An Online Learning System through which individuals can attend pre-recorded courses online that have been created and uploaded on the website by their instructors.
This project is part of Advanced Computer Lab course studied at The German University in Cairo in the fourth year of Computer Science and Engineering bachelor degree, and the following are the Project Objectives:
- Handle all aspects of web development projects, and greatly expanding our career opportunities by using MERN stack.
- Learn how to properly use the Agile Methodology to plan out a project and develop the software.
- Learn the process of following a given set of System Requirements to develop a software.
- Learn how to work together as a team on GitHub.
- The website currently fulfil the requirements in Features section.
- For reporting bugs or offering contributions or enhancements please check our Contribute section below.
- Following Single-responsibility principle
- Single quotes are preferred over double. Reason: HTML uses double quotes.
- Use
void 0
instead ofundefined
, becauseundefined
could have been redefined. - Write code in functional style with minimum side effects.
- Don't use function statements. Instead, create anonymous functions and assing them to vars for consistency with other vars.
- Keep your repository clean. Don’t commit big files unless they absolutely require git. Even in this case, prefer storing all big files in a separate submodule. That’s because git history can become very big and it will be pain for others to use the repo.
- Commit message:
- Capitalize the first word and do not end in punctuation
- Complte the sentence "This commit will"
- Branch naming:
- Use slashes as word separator.
- Use namespaces, for example,
[ContributerName]/[SprintNumber]/Feature/[FeatureName]
or[ContributerName]/[SprintNumber]/Bug/[BugFixed]
- like:
Ragaa/Sprint2/Feature/Quiz
The project is implemented using the MERN Stack, a free and open-source JavaScript software stack for building dynamic web sites and web applications, MERN stands for MongoDB, Express, React, Node, after the four key technologies that make up the stack.
- Mongo DB is an open-source NoSQL cross-platform document-oriented database.
- Express JS is a web-based application framework work with Node JS, It helps to build web apps and RESTful APIs.
- React is a JavaScript library created by Facebook. React is a User Interface (UI) library. React is a tool for building UI components.
- Node JS is a free JavaScript run-time environment, It executes JavaScript code outside of a browser. It is available for macOS, Windows, Linux, and Unix.
You can view the full project requirements from here.
const getCourses = asyncHandler(async (req, res) => {
const courses = await Course.find({})
if (courses) {
res.json(courses)
} else {
res.status(404)
throw new Error('Courses not found')
}
})
const logout = async (req, res) => {
const token = generateToken ("");
res.cookie('jwt', token, { httpOnly: true, maxAge: 1 });
res.status(200).json({message: "You have logged out!"})
}
const addGrade = asyncHandler(async (req, res) => {
const taskid = req.body.taskid
const grade = req.body.grade
const task = await Task.findById(taskid)
if (task) {
task.grade = grade
await task.save()
res.json(task)
}
else {
res.status(404)
throw new Error('Task not found')
}
})
useEffect(() => {
const fetchData = async () => {
await axios.get(`http://localhost:5000/api/questions/getQuestions?taskid=${taskid}`)
.then((res) => {
console.log(res.data);
setQuestions(res.data);
})
.catch((err) => {
console.log(err);
});
}
fetchData();
}, []);
// Increment the score
if (isCorrect) {
setScore(score + 1);
}
if (currentQuestion + 1 < questions.length) {
setCurrentQuestion(currentQuestion + 1);
} else {
setShowResults(true);
}
};
export default function MostPopular() {
const [courses, setCourses] = useState([])
const navigate = useNavigate();
useEffect(() => {
const fecthPopular = async () => {
await axios.get(`http://localhost:5000/api/courses/popular`).then(
(res) => {
const courses = res.data
if (courses) {
setCourses(courses)
console.log("courses in fetch:" + courses)
}
else
console.log("no courses")
}
);
}
fecthPopular()
}, [])
const addContent = asyncHandler(async(req,res)=>{
const subtitle_id = req.params.subtitleid ;
const idArray = subtitle_id.split("\n")
const newid = idArray[0];
const content = req.body.content;
const update = {content:content};
const subtitleupdated = await Subtitle.findOneAndUpdate({_id :newid},update,{new : true});
if(subtitleupdated){
res.json(subtitleupdated);
}
else{
res.json({message:"This subtitle is not found"})
}
})
- Clone the repo
> git clone https://github.com/Advanced-Computer-Lab-2022/Sprintful.git
- Navigate to the frontend folder
> cd Sprintful/frontend
- Install frontend packages required
> npm install
- Navigate back to the parent directory
> cd ..
- Navigate to the backend folder
> cd backend
- Install backend packeage required
> npm install
- Run the server
> npm run dev
Backend is divided into different routes, and each route has a set of APIs, here are some routes examples :
- Add Course
- Route
/api/courses/addCourse
- Request Type
POST
- Request Body
{
title: 'Advanced Computer Lab',
subject: 'Computer Science',
price: 500,
totalhours: 4,
shortsummary: 'best course ever',
instructor: '63a6af07df4b397c30130fba',
previewvideolink: 'videolink',
discount: 0.1,
}
- Response Body
{
success: false,
message: "Course could not be added. Error : ",
err
}
or
{
success: true,
message: "You have added a new course successfully"
}
- Get Instructor Profile
- Route
/api/instructor/profile?id=63ac0000010ff17395982f50
- Request type
GET
- Response Body
{
"_id":"63ac0000010ff17395982f50",
"username":"slim",
"password":"$2a$10$5FkHQDkHOVauYEayMLRd2uEZ6B24vUNieMLsLx8YvKwlizlAFpc1C",
"firstName":"slim",
"lastName":"slim",
"email":"slim",
"rating":5,
"ratingsArray":[],
"courses":[],
"reviews":[],
"money":0,
"biography":"",
"contract":false,
"createdAt":"2022-12-28T08:36:16.751Z",
"updatedAt":"2022-12-28T08:36:16.751Z","__v":0
}
- Admin Login
- Route
/api/admin/loginAdmin
- Request Type
POST
- Request Body
{
username:'hakimi',
password: 1234
}
- Redirects to
/AdminHome
- Response Body
{
success: true,
}
or
{
success: false,
message: "Invalid credentials"
}
- Corporate Trainee Log Out
- Route
/api/corporateTrainee/logout
- Request Type
GET
- Response Body
{ success: true, msg: "You have logged out!" }
- Route
- Get Report By ID
- Route
/api/report/63a48f7cf31cb909b00acfe4
- Request Type
GET
- Response Body
{ "_id": "63a87323dc654a91b0db3dfc", "subject": "you", "body": "me", "status": "resolved", "type": "Other", "instructorId": "63a80e444837f02169da6da5", "__v": 3, "followups": [ "workkk", "resolve it now" ] }
- Request Type
- Instructor Review Ratings
- Route
/api/instructor/reviewsnratings?id=63abfeb254c7c7d8f72cc2b6
- Request Type
GET
- Response Body
{ "rating" : 141.66666666666666, "allReviews":["too","",null,null,null,"rtyui","","","","","",null] }
- Request Type
- Admin Add Corporate
- Route
/api/admin/addCorporate/
- Request Type
POST
- Request Body
{
"name": "hopaa",
"subject": "Physics"
}
- Response Body
{
"_id": "63b8886efb7ab4d53675c03d",
"name": "hopaa",
"subject": "Physics"
}
- Instructor Edit Profile
- Route
/api/instructor/editProfile?id=639a3e79453a18405648e8cb
- Request Type
PUT
- Request Body
- Route
{
"email": "[email protected]"
}
- Response Body
{
"firstName": "",
"lastName": "",
"_id": "639a3e79453a18405648e8cb",
"username": "Gerizmann",
"password": "$2a$10$QZyZ2k8ussE0ILataCuWC.jidAP7ev.aicliNPyjCDiuyqnXDeVCe",
"email": "[email protected]",
"rating": 0,
"ratingsArray": [],
"courses": [
"6383d46a6d33730b4cfece29",
"6385c9f46f6bb55a030163d4",
"63a43a046ff5971f842dafd4",
"63a43a066ff5971f842dafd8",
"63a43a066ff5971f842dafdc",
"63a43a076ff5971f842dafdf",
"63a43a076ff5971f842dafe3",
"63a43a076ff5971f842dafe7",
"63a43a106ff5971f842dafec",
"63a4c60967f7793f16cdb40f",
"63a4c6f667f7793f16cdb413",
"63a4c85a67f7793f16cdb433",
"63a4d35d67f7793f16cdb46b",
"63a60fc09541bfc68a6017e2",
"63a623077e4f73ca2837c7d6",
"63a62491b59f7565817f4aef",
"63a629b927f2c563366f19ae",
"63a633427fbd245488274a4e",
"63a634b57fbd245488274aa7",
"63a637f57fbd245488274ce8",
"63a74edb317263b1c7f4ffef",
"63a8359440ab36a05ecb4069",
"63a85122b701bb9b6e222d0d",
"63a85129b701bb9b6e222d11",
"63b59f3f3e59ccdc64290295",
"63b59f433e59ccdc64290299",
"63b5e9e93dc6c3d7f204a018",
"63b609e64f918637464a0b82",
"63b60b49df6234929072aded",
"63b60f3e8646f603f75e82cd",
"63b6117539e56e413385997d",
"63b61548fc7e0737289aac17",
"63b62ddf027ef91946b85d16",
"63b6354d2a42de50479bbafd",
"63b65e6468c3a395507382c5",
"63b65fde9eadd0bff377cf71",
"63b665760944c339dffd2094",
"63b6ebe785156d9053f9328f",
"63b6fca9cd77a7348d0c14fa"
],
"reviews": [],
"money": 0,
"biography": "ana batates m7amamra",
"createdAt": "2022-12-14T21:22:01.804Z",
"updatedAt": "2023-01-06T21:29:52.822Z",
"__v": 0,
"contract": true,
"policy": true
}
- Instructor Change Password
- Route
/api/instructor/changePassword?id=639a3e79453a18405648e8cb
- Request Type
PUT
- Request Body
- Route
{
"currentPassword": "123456789",
"password": "1234"
}
- Response Body
{
"firstName": "",
"lastName": "",
"_id": "639a3e79453a18405648e8cb",
"username": "Gerizmann",
"password": "$2a$10$hdz0axlbFe3OsAZEVyBUn.I/vfHyy4rSbcVbTEcZbpX2HM7CwSpLK",
"email": "[email protected]",
"rating": 0,
"ratingsArray": [],
"courses": [
"6383d46a6d33730b4cfece29",
"6385c9f46f6bb55a030163d4",
"63a43a046ff5971f842dafd4",
"63a43a066ff5971f842dafd8",
"63a43a066ff5971f842dafdc",
"63a43a076ff5971f842dafdf",
"63a43a076ff5971f842dafe3",
"63a43a076ff5971f842dafe7",
"63a43a106ff5971f842dafec",
"63a4c60967f7793f16cdb40f",
"63a4c6f667f7793f16cdb413",
"63a4c85a67f7793f16cdb433",
"63a4d35d67f7793f16cdb46b",
"63a60fc09541bfc68a6017e2",
"63a623077e4f73ca2837c7d6",
"63a62491b59f7565817f4aef",
"63a629b927f2c563366f19ae",
"63a633427fbd245488274a4e",
"63a634b57fbd245488274aa7",
"63a637f57fbd245488274ce8",
"63a74edb317263b1c7f4ffef",
"63a8359440ab36a05ecb4069",
"63a85122b701bb9b6e222d0d",
"63a85129b701bb9b6e222d11",
"63b59f3f3e59ccdc64290295",
"63b59f433e59ccdc64290299",
"63b5e9e93dc6c3d7f204a018",
"63b609e64f918637464a0b82",
"63b60b49df6234929072aded",
"63b60f3e8646f603f75e82cd",
"63b6117539e56e413385997d",
"63b61548fc7e0737289aac17",
"63b62ddf027ef91946b85d16",
"63b6354d2a42de50479bbafd",
"63b65e6468c3a395507382c5",
"63b65fde9eadd0bff377cf71",
"63b665760944c339dffd2094",
"63b6ebe785156d9053f9328f",
"63b6fca9cd77a7348d0c14fa"
],
"reviews": [],
"money": 0,
"biography": "ana batates m7amamra",
"createdAt": "2022-12-14T21:22:01.804Z",
"updatedAt": "2023-01-06T21:31:51.765Z",
"__v": 0,
"contract": true,
"policy": true
}
- Add Course
- Route
/api/courses/getSubtitles?courseId=63b6ebe785156d9053f9328f
- Request Type
GET
- Response Body
[
{
"_id": "63b6ec0585156d9053f93294",
"title": "WEEK1",
"totalHours": 12,
"course": "63b6ebe785156d9053f9328f",
"content": "this is batates",
"tasks": [
"63b6ec1585156d9053f932a0"
],
"videos": [],
"createdAt": "2023-01-05T15:25:57.840Z",
"updatedAt": "2023-01-05T15:26:13.791Z",
"__v": 1
}
]
- Get Subtitles
- Route
/api/subtitles/63b6ec0585156d9053f93294
- Request Type
GET
- Response Body
{
"_id": "63b6ec0585156d9053f93294",
"title": "WEEK1",
"totalHours": 12,
"course": "63b6ebe785156d9053f9328f",
"content": "this is batates",
"tasks": [
{
"_id": "63b6ec1585156d9053f932a0",
"title": "task1",
"questions": [
"63b6ec3f85156d9053f932a5",
"63b6ec7b85156d9053f932d6"
],
"subtitle": "63b6ec0585156d9053f93294",
"grade": 0,
"createdAt": "2023-01-05T15:26:13.670Z",
"updatedAt": "2023-01-05T15:27:55.485Z",
"__v": 2
}
],
"videos": [],
"createdAt": "2023-01-05T15:25:57.840Z",
"updatedAt": "2023-01-05T15:26:13.791Z",
"__v": 1
}
Open http://localhost:3000 to view the guest homepage.
You can navigate to all admin functionalities through the side nav bar in Admin Home Page.
The following is a set of guidelines for contributing to Sprintful.
Send us your question via '[email protected]'
- Reporting Bugs or Suggesting Enhancements via '[email protected]'
- Pull Requests on GitHub
Useful resources and youtube channels helped us building our project:
Distributed under the MIT License.