Express js backend :- course-app project folder :- under public folder create uploads folder config/multer.js file code:- const multer = require('multer'); const path = require('path'); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'public/uploads/'); }, filename: function (req, file, cb) { cb(null, Date.now() + path.extname(file.originalname)); } }); module.exports = multer({ storage: storage }); models/Course.js file code:- const mongoose = require('mongoose'); const CourseSchema = new mongoose.Schema({ title: String, description: String, }); module.exports = mongoose.model('Course', CourseSchema); model/Lecture.js fiel code:- const mongoose = require('mongoose'); const LectureSchema = new mongoose.Schema({ courseId: { type: mongoose.Schema.Types.ObjectId, ref: 'Course' }, title: String, videoUrl: String, notesUrl: String, }); module.exports = mongoose.model('Lecture', LectureSchema); routes/courses.js :- const express = require('express'); const Course = require('../models/Course'); const router = express.Router(); // Get all courses router.get('/', async (req, res) => { try { const courses = await Course.find(); res.json(courses); } catch (error) { res.status(500).json({ message: error.message }); } }); // Get one course router.get('/:id', async (req, res) => { try { const course = await Course.findById(req.params.id); if (!course) return res.status(404).json({ message: "Course not found" }); res.json(course); } catch (error) { res.status(500).json({ message: error.message }); } }); // Create course router.post('/', async (req, res) => { const { title, description } = req.body; try { const course = new Course({ title, description }); await course.save(); res.status(201).json(course); } catch (error) { res.status(400).json({ message: error.message }); } }); // Update course router.put('/:id', async (req, res) => { const { title, description } = req.body; try { const course = await Course.findByIdAndUpdate( req.params.id, { title, description }, { new: true } ); if (!course) return res.status(404).json({ message: "Course not found" }); res.json(course); } catch (error) { res.status(400).json({ message: error.message }); } }); // Delete course router.delete('/:id', async (req, res) => { try { const course = await Course.findByIdAndDelete(req.params.id); if (!course) return res.status(404).json({ message: "Course not found" }); res.json({ message: "Deleted course" }); } catch (error) { res.status(500).json({ message: error.message }); } }); module.exports = router; routes/lectuers.js file code:- const express = require('express'); const Lecture = require('../models/Lecture'); const multer = require('../config/multer'); const router = express.Router(); // Get all lectures router.get('/', async (req, res) => { try { const lectures = await Lecture.find().populate('courseId'); res.json(lectures); } catch (error) { res.status(500).json({ message: error.message }); } }); // Get one lecture router.get('/:id', async (req, res) => { try { const lecture = await Lecture.findById(req.params.id).populate('courseId'); if (!lecture) return res.status(404).json({ message: "Lecture not found" }); res.json(lecture); } catch (error) { res.status(500).json({ message: error.message }); } }); // Create lecture (with file uploads for video and notes) router.post('/', multer.fields([ { name: 'video', maxCount: 1 }, { name: 'notes', maxCount: 1 } ]), async (req, res) => { const { courseId, title } = req.body; const videoUrl = req.files.video ? `/uploads/${req.files.video[0].filename}` : ''; const notesUrl = req.files.notes ? `/uploads/${req.files.notes[0].filename}` : ''; try { const lecture = new Lecture({ courseId, title, videoUrl, notesUrl }); await lecture.save(); res.status(201).json(lecture); } catch (error) { res.status(400).json({ message: error.message }); } }); // Update lecture (same file upload) router.put('/:id', multer.fields([ { name: 'video', maxCount: 1 }, { name: 'notes', maxCount: 1 } ]), async (req, res) => { const { courseId, title } = req.body; let updateData = { courseId, title }; if (req.files.video) updateData.videoUrl = `/uploads/${req.files.video[0].filename}`; if (req.files.notes) updateData.notesUrl = `/uploads/${req.files.notes[0].filename}`; try { const lecture = await Lecture.findByIdAndUpdate(req.params.id, updateData, { new: true }); if (!lecture) return res.status(404).json({ message: "Lecture not found" }); res.json(lecture); } catch (error) { res.status(400).json({ message: error.message }); } }); // Delete lecture router.delete('/:id', async (req, res) => { try { const lecture = await Lecture.findByIdAndDelete(req.params.id); if (!lecture) return res.status(404).json({ message: "Lecture not found" }); res.json({ message: "Deleted lecture" }); } catch (error) { res.status(500).json({ message: error.message }); } }); module.exports = router; src/server.js file code :- const express = require('express'); const mongoose = require('mongoose'); const methodOverride = require('method-override'); const path = require('path'); const cors = require('cors'); // ADD THIS LINE const courseRoutes = require('./routes/courses'); const lectureRoutes = require('./routes/lectures'); const app = express(); // Middleware app.use(cors()); // ADD THIS LINE app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(methodOverride('_method')); // Static folder for uploaded files app.use('/uploads', express.static(path.join(__dirname, 'public/uploads'))); // MongoDB connection string and port const MONGO_URI = 'mongodb://localhost:27017/courseApp'; const PORT = 5000; // Connect to MongoDB mongoose.connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => console.log('MongoDB connected')) .catch(err => console.log('MongoDB connection error:', err)); // Routes app.use('/api/courses', courseRoutes); app.use('/api/lectures', lectureRoutes); app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); finally run:- node server.js cross check api :- http://localhost:5000/api/courses =============================================== React js front end:- course-app-frontend:- src/api.js fiel code:- import axios from 'axios'; const api = axios.create({ baseURL: 'http://localhost:5000/api', }); export default api; src/components/Courses.js file code:- import React, { useEffect, useState } from 'react'; import api from '../api'; export default function Courses() { const [courses, setCourses] = useState([]); const [form, setForm] = useState({ title: '', description: '' }); const [editId, setEditId] = useState(null); useEffect(() => { fetchCourses(); }, []); const fetchCourses = async () => { try { const res = await api.get('/courses'); setCourses(res.data); } catch (err) { console.error(err); } }; const handleChange = e => setForm({ ...form, [e.target.name]: e.target.value }); const handleSubmit = async e => { e.preventDefault(); try { if (editId) { await api.put(`/courses/${editId}`, form); setEditId(null); } else { await api.post('/courses', form); } setForm({ title: '', description: '' }); fetchCourses(); } catch (err) { console.error(err); } }; const handleEdit = course => { setEditId(course._id); setForm({ title: course.title, description: course.description }); }; const handleDelete = async id => { try { await api.delete(`/courses/${id}`); fetchCourses(); } catch (err) { console.error(err); } }; return (
🎬 Video:
📄 Notes: