leelanjan commited on
Commit
5103c2a
·
verified ·
1 Parent(s): 4fa4192

Upload 21 files

Browse files
Dockerfile ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.10
2
+ FROM python:3.10
3
+
4
+ # Set the working directory
5
+ WORKDIR /code
6
+
7
+ # Copy requirements and install them
8
+ COPY ./requirements.txt /code/requirements.txt
9
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
10
+
11
+ # Copy all your code files
12
+ COPY . /code
13
+
14
+ # Create a folder for the database so it can write to it
15
+ RUN mkdir -p /code/data
16
+ RUN chmod 777 /code/data
17
+
18
+ # Start the server on port 7860 (Required for Hugging Face)
19
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
app/__pycache__/database.cpython-314.pyc ADDED
Binary file (783 Bytes). View file
 
app/__pycache__/main.cpython-314.pyc ADDED
Binary file (1.43 kB). View file
 
app/__pycache__/models.cpython-314.pyc ADDED
Binary file (1.55 kB). View file
 
app/__pycache__/schemas.cpython-314.pyc ADDED
Binary file (1.53 kB). View file
 
app/database.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import create_engine
2
+ from sqlalchemy.orm import declarative_base, sessionmaker
3
+
4
+ DATABASE_URL = "sqlite:///./course.db"
5
+
6
+ engine = create_engine(
7
+ DATABASE_URL, connect_args={"check_same_thread": False}
8
+ )
9
+
10
+ SessionLocal = sessionmaker(bind=engine)
11
+ Base = declarative_base()
12
+
13
+ def get_db():
14
+ db = SessionLocal()
15
+ try:
16
+ yield db
17
+ finally:
18
+ db.close()
app/main.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.staticfiles import StaticFiles
3
+ from fastapi.responses import HTMLResponse
4
+ from pathlib import Path
5
+
6
+ from app.database import Base, engine
7
+ from app.routes import users, courses, enrollments
8
+
9
+ Base.metadata.create_all(bind=engine)
10
+
11
+ app = FastAPI()
12
+
13
+ app.include_router(users.router)
14
+ app.include_router(courses.router)
15
+ app.include_router(enrollments.router)
16
+
17
+ app.mount("/static", StaticFiles(directory="static"), name="static")
18
+
19
+ BASE_DIR = Path(__file__).resolve().parent.parent
20
+
21
+ @app.get("/", response_class=HTMLResponse)
22
+ def home():
23
+ return (BASE_DIR / "templates/index.html").read_text()
app/models.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sqlalchemy import Column, Integer, String, ForeignKey
2
+ from sqlalchemy.orm import relationship
3
+ from app.database import Base
4
+
5
+ class User(Base):
6
+ __tablename__ = "users"
7
+ id = Column(Integer, primary_key=True, index=True)
8
+ name = Column(String)
9
+ email = Column(String)
10
+ role = Column(String)
11
+
12
+ class Course(Base):
13
+ __tablename__ = "courses"
14
+ id = Column(Integer, primary_key=True, index=True)
15
+ title = Column(String)
16
+ teacher_id = Column(Integer, ForeignKey("users.id"))
17
+
18
+ class Enrollment(Base):
19
+ __tablename__ = "enrollments"
20
+ id = Column(Integer, primary_key=True, index=True)
21
+ student_id = Column(Integer, ForeignKey("users.id"))
22
+ course_id = Column(Integer, ForeignKey("courses.id"))
app/routes/__pycache__/courses.cpython-314.pyc ADDED
Binary file (3.53 kB). View file
 
app/routes/__pycache__/enrollments.cpython-314.pyc ADDED
Binary file (3.85 kB). View file
 
app/routes/__pycache__/student.cpython-314.pyc ADDED
Binary file (1.1 kB). View file
 
app/routes/__pycache__/teacher.cpython-314.pyc ADDED
Binary file (1.73 kB). View file
 
app/routes/__pycache__/users.cpython-314.pyc ADDED
Binary file (2.92 kB). View file
 
app/routes/courses.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException, Depends
2
+ from sqlalchemy.orm import Session
3
+ from app.models import Course, User, Enrollment
4
+ from app.schemas import CourseCreate
5
+ from app.database import get_db
6
+
7
+ router = APIRouter(prefix="/courses", tags=["Courses"])
8
+
9
+ @router.post("/")
10
+ def create_course(course: CourseCreate, db: Session = Depends(get_db)):
11
+ if not course.title or course.title.strip() == "":
12
+ raise HTTPException(status_code=400, detail="Course title cannot be empty")
13
+
14
+ c = Course(**course.dict())
15
+ db.add(c)
16
+ db.commit()
17
+ return {"message": "Course created"}
18
+
19
+ @router.get("/")
20
+ def list_courses(db: Session = Depends(get_db)):
21
+ results = (
22
+ db.query(Course.id, Course.title, User.name.label("teacher"))
23
+ .join(User, Course.teacher_id == User.id)
24
+ .filter(Course.title != "")
25
+ .all()
26
+ )
27
+ return [{"id": r.id, "title": r.title, "teacher": r.teacher} for r in results]
28
+
29
+ @router.delete("/{course_id}")
30
+ def delete_course(course_id: int, db: Session = Depends(get_db)):
31
+ course = db.query(Course).filter(Course.id == course_id).first()
32
+ if not course:
33
+ raise HTTPException(status_code=404, detail="Course not found")
34
+
35
+ db.query(Enrollment).filter(Enrollment.course_id == course_id).delete()
36
+
37
+ db.delete(course)
38
+ db.commit()
39
+ return {"message": "Course deleted"}
app/routes/enrollments.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException, Depends
2
+ from sqlalchemy.orm import aliased, Session
3
+ from app.models import Enrollment, User, Course
4
+ from app.database import get_db
5
+
6
+ router = APIRouter(prefix="/enrollments", tags=["Enrollments"])
7
+
8
+ @router.post("/")
9
+ def enroll(student_id: int, course_id: int, db: Session = Depends(get_db)):
10
+ exists = db.query(Enrollment).filter_by(student_id=student_id, course_id=course_id).first()
11
+ if exists:
12
+ return {"message": "Student is already enrolled!"}
13
+
14
+ e = Enrollment(student_id=student_id, course_id=course_id)
15
+ db.add(e)
16
+ db.commit()
17
+ return {"message": "Student enrolled"}
18
+
19
+ @router.get("/")
20
+ def view_enrollments(db: Session = Depends(get_db)):
21
+ StudentUser = aliased(User)
22
+ TeacherUser = aliased(User)
23
+
24
+ results = (
25
+ db.query(
26
+ Enrollment.id,
27
+ StudentUser.name.label("student"),
28
+ Course.title.label("course"),
29
+ TeacherUser.name.label("teacher")
30
+ )
31
+ .select_from(Enrollment)
32
+ .join(Course, Course.id == Enrollment.course_id)
33
+ .join(TeacherUser, TeacherUser.id == Course.teacher_id)
34
+ .join(StudentUser, StudentUser.id == Enrollment.student_id)
35
+ .all()
36
+ )
37
+
38
+ return [
39
+ {"id": row.id, "student": row.student, "course": row.course, "teacher": row.teacher}
40
+ for row in results
41
+ ]
42
+
43
+ @router.delete("/{enrollment_id}")
44
+ def delete_enrollment(enrollment_id: int, db: Session = Depends(get_db)):
45
+ e = db.query(Enrollment).filter(Enrollment.id == enrollment_id).first()
46
+ if not e:
47
+ raise HTTPException(status_code=404, detail="Enrollment not found")
48
+
49
+ db.delete(e)
50
+ db.commit()
51
+ return {"message": "Enrollment deleted"}
app/routes/users.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException, Depends
2
+ from sqlalchemy.orm import Session
3
+ from app.models import User, Course, Enrollment
4
+ from app.schemas import UserCreate
5
+ from app.database import get_db
6
+
7
+ router = APIRouter(prefix="/users", tags=["Users"])
8
+
9
+ @router.post("/")
10
+ def add_user(user: UserCreate, db: Session = Depends(get_db)):
11
+ u = User(name=user.name, email=user.email, role=user.role)
12
+ db.add(u)
13
+ db.commit()
14
+ return {"message": "User added"}
15
+
16
+ @router.get("/")
17
+ def list_users(db: Session = Depends(get_db)):
18
+ return db.query(User).all()
19
+
20
+ @router.delete("/{user_id}")
21
+ def delete_user(user_id: int, db: Session = Depends(get_db)):
22
+ user = db.query(User).filter(User.id == user_id).first()
23
+ if not user:
24
+ raise HTTPException(status_code=404, detail="User not found")
25
+
26
+ db.query(Course).filter(Course.teacher_id == user_id).delete()
27
+ db.query(Enrollment).filter(Enrollment.student_id == user_id).delete()
28
+
29
+ db.delete(user)
30
+ db.commit()
31
+ return {"message": "User deleted"}
app/schemas.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+ class UserCreate(BaseModel):
4
+ name: str
5
+ email: str
6
+ role: str
7
+
8
+ class CourseCreate(BaseModel):
9
+ title: str
10
+ teacher_id: int
11
+
12
+ class EnrollCreate(BaseModel):
13
+ student_id: int
14
+ course_id: int
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ sqlalchemy
4
+ pydantic
5
+ jinja2
6
+ python-multipart
7
+ a2wsgi
static/script.js ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const usersTable = document.getElementById("usersTable");
2
+ const teacherSelect = document.getElementById("teacherSelect");
3
+ const studentSelect = document.getElementById("studentSelect");
4
+ const coursesTable = document.getElementById("coursesTable");
5
+ const courseSelect = document.getElementById("courseSelect");
6
+ const enrollmentsTable = document.getElementById("enrollmentsTable");
7
+
8
+ // --- USERS ---
9
+ async function fetchUsers() {
10
+ const res = await fetch("/users");
11
+ const users = await res.json();
12
+
13
+ usersTable.innerHTML = `<tr><th>ID</th><th>Name</th><th>Email</th><th>Role</th><th>Action</th></tr>`;
14
+ teacherSelect.innerHTML = `<option disabled selected>Select Teacher</option>`;
15
+ studentSelect.innerHTML = `<option disabled selected>Select Student</option>`;
16
+
17
+ users.forEach(u => {
18
+ usersTable.innerHTML += `
19
+ <tr>
20
+ <td>${u.id}</td>
21
+ <td><strong>${u.name}</strong></td>
22
+ <td>${u.email}</td>
23
+ <td><span style="background:${u.role === 'Teacher' ? '#e0e7ff' : '#d1fae5'}; color:${u.role === 'Teacher' ? '#4338ca' : '#065f46'}; padding: 2px 8px; border-radius: 10px; font-size: 0.8em;">${u.role}</span></td>
24
+ <td><button class="btn-danger" onclick="deleteUser(${u.id})">Delete</button></td>
25
+ </tr>`;
26
+
27
+ if (u.role === "Teacher") teacherSelect.innerHTML += `<option value="${u.id}">${u.name}</option>`;
28
+ if (u.role === "Student") studentSelect.innerHTML += `<option value="${u.id}">${u.name}</option>`;
29
+ });
30
+ }
31
+
32
+ async function addUser() {
33
+ const name = document.getElementById("name").value;
34
+ const email = document.getElementById("email").value;
35
+ const role = document.getElementById("role").value;
36
+ if(!name || !email) return alert("Fill details");
37
+
38
+ await fetch("/users", {
39
+ method: "POST",
40
+ headers: {"Content-Type": "application/json"},
41
+ body: JSON.stringify({ name, email, role })
42
+ });
43
+ fetchUsers();
44
+ }
45
+
46
+ async function deleteUser(id) {
47
+ if(!confirm("Are you sure? This will delete their courses/enrollments too.")) return;
48
+ await fetch(`/users/${id}`, { method: "DELETE" });
49
+ fetchUsers();
50
+ fetchCourses();
51
+ fetchEnrollments();
52
+ }
53
+
54
+ // --- COURSES ---
55
+ async function fetchCourses() {
56
+ const res = await fetch("/courses");
57
+ const courses = await res.json();
58
+
59
+ coursesTable.innerHTML = `<tr><th>ID</th><th>Title</th><th>Teacher</th><th>Action</th></tr>`;
60
+ courseSelect.innerHTML = `<option disabled selected>Select Course</option>`;
61
+
62
+ courses.forEach(c => {
63
+ coursesTable.innerHTML += `
64
+ <tr>
65
+ <td>${c.id}</td>
66
+ <td><strong>${c.title}</strong></td>
67
+ <td>${c.teacher}</td>
68
+ <td><button class="btn-danger" onclick="deleteCourse(${c.id})">Delete</button></td>
69
+ </tr>`;
70
+ courseSelect.innerHTML += `<option value="${c.id}">${c.title}</option>`;
71
+ });
72
+ }
73
+
74
+ async function createCourse() {
75
+ const title = document.getElementById("courseTitle").value;
76
+ const teacher_id = teacherSelect.value;
77
+ if (!title.trim()) return alert("Title required");
78
+
79
+ await fetch("/courses", {
80
+ method: "POST",
81
+ headers: {"Content-Type": "application/json"},
82
+ body: JSON.stringify({ title, teacher_id })
83
+ });
84
+ fetchCourses();
85
+ }
86
+
87
+ async function deleteCourse(id) {
88
+ if(!confirm("Delete this course?")) return;
89
+ await fetch(`/courses/${id}`, { method: "DELETE" });
90
+ fetchCourses();
91
+ fetchEnrollments();
92
+ }
93
+
94
+ // --- ENROLLMENTS ---
95
+ async function fetchEnrollments() {
96
+ const res = await fetch("/enrollments");
97
+ const data = await res.json();
98
+
99
+ enrollmentsTable.innerHTML = `<tr><th>Student</th><th>Course</th><th>Teacher</th><th>Action</th></tr>`;
100
+
101
+ data.forEach(e => {
102
+ enrollmentsTable.innerHTML += `
103
+ <tr>
104
+ <td><strong>${e.student}</strong></td>
105
+ <td>${e.course}</td>
106
+ <td>${e.teacher}</td>
107
+ <td><button class="btn-danger" onclick="deleteEnrollment(${e.id})">Un-enroll</button></td>
108
+ </tr>`;
109
+ });
110
+ }
111
+
112
+ async function enrollStudent() {
113
+ const s_id = studentSelect.value;
114
+ const c_id = courseSelect.value;
115
+ await fetch(`/enrollments?student_id=${s_id}&course_id=${c_id}`, { method: "POST" });
116
+ fetchEnrollments();
117
+ }
118
+
119
+ async function deleteEnrollment(id) {
120
+ await fetch(`/enrollments/${id}`, { method: "DELETE" });
121
+ fetchEnrollments();
122
+ }
123
+
124
+ fetchUsers();
125
+ fetchCourses();
126
+ fetchEnrollments();
static/style.css ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --primary: #4f46e5;
3
+ --primary-hover: #4338ca;
4
+ --danger: #ef4444;
5
+ --danger-hover: #dc2626;
6
+ --bg: #f3f4f6;
7
+ --surface: #ffffff;
8
+ --text: #1f2937;
9
+ --text-light: #6b7280;
10
+ --border: #e5e7eb;
11
+ }
12
+
13
+ * {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ font-family: 'Inter', sans-serif;
19
+ background: var(--bg);
20
+ color: var(--text);
21
+ margin: 0;
22
+ padding: 40px 20px;
23
+ }
24
+
25
+ .container {
26
+ max-width: 1000px;
27
+ margin: 0 auto;
28
+ }
29
+
30
+ header {
31
+ text-align: center;
32
+ margin-bottom: 40px;
33
+ }
34
+
35
+ header h1 {
36
+ margin: 0;
37
+ color: var(--primary);
38
+ font-size: 2.2rem;
39
+ }
40
+
41
+ header p {
42
+ color: var(--text-light);
43
+ margin-top: 5px;
44
+ }
45
+
46
+ /* CARDS */
47
+ .card {
48
+ background: var(--surface);
49
+ border-radius: 12px;
50
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
51
+ margin-bottom: 30px;
52
+ overflow: hidden;
53
+ border: 1px solid var(--border);
54
+ }
55
+
56
+ .card-header {
57
+ background: #f9fafb;
58
+ padding: 15px 25px;
59
+ border-bottom: 1px solid var(--border);
60
+ }
61
+
62
+ .card-header h2 {
63
+ margin: 0;
64
+ font-size: 1.25rem;
65
+ font-weight: 600;
66
+ color: var(--text);
67
+ }
68
+
69
+ .card-body {
70
+ padding: 25px;
71
+ }
72
+
73
+ /* FORMS */
74
+ .form-row {
75
+ display: flex;
76
+ gap: 10px;
77
+ margin-bottom: 20px;
78
+ flex-wrap: wrap;
79
+ }
80
+
81
+ input, select {
82
+ padding: 10px 15px;
83
+ border: 1px solid var(--border);
84
+ border-radius: 6px;
85
+ font-size: 0.95rem;
86
+ flex: 1;
87
+ min-width: 200px;
88
+ transition: border-color 0.2s;
89
+ }
90
+
91
+ input:focus, select:focus {
92
+ outline: none;
93
+ border-color: var(--primary);
94
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
95
+ }
96
+
97
+ /* BUTTONS */
98
+ button {
99
+ padding: 10px 20px;
100
+ border: none;
101
+ border-radius: 6px;
102
+ font-weight: 500;
103
+ cursor: pointer;
104
+ transition: background 0.2s;
105
+ font-size: 0.95rem;
106
+ }
107
+
108
+ .btn-primary {
109
+ background: var(--primary);
110
+ color: white;
111
+ }
112
+
113
+ .btn-primary:hover {
114
+ background: var(--primary-hover);
115
+ }
116
+
117
+ .btn-danger {
118
+ background: #fee2e2;
119
+ color: var(--danger);
120
+ padding: 6px 12px;
121
+ font-size: 0.85rem;
122
+ }
123
+
124
+ .btn-danger:hover {
125
+ background: var(--danger);
126
+ color: white;
127
+ }
128
+
129
+ /* TABLES */
130
+ .table-wrapper {
131
+ overflow-x: auto;
132
+ }
133
+
134
+ table {
135
+ width: 100%;
136
+ border-collapse: collapse;
137
+ font-size: 0.95rem;
138
+ }
139
+
140
+ th {
141
+ background: #f9fafb;
142
+ text-align: left;
143
+ padding: 12px 15px;
144
+ font-weight: 600;
145
+ color: var(--text-light);
146
+ border-bottom: 1px solid var(--border);
147
+ text-transform: uppercase;
148
+ font-size: 0.75rem;
149
+ letter-spacing: 0.05em;
150
+ }
151
+
152
+ td {
153
+ padding: 12px 15px;
154
+ border-bottom: 1px solid var(--border);
155
+ color: var(--text);
156
+ }
157
+
158
+ tr:last-child td {
159
+ border-bottom: none;
160
+ }
templates/index.html ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Online Course System</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <link rel="stylesheet" href="/static/style.css">
9
+ <script src="/static/script.js" defer></script>
10
+ </head>
11
+ <body>
12
+
13
+ <div class="container">
14
+ <header>
15
+ <h1>🎓 Online Course System</h1>
16
+ <p>Admin Dashboard</p>
17
+ </header>
18
+
19
+ <div class="card">
20
+ <div class="card-header">
21
+ <h2>Manage Users</h2>
22
+ </div>
23
+ <div class="card-body">
24
+ <div class="form-row">
25
+ <input id="name" placeholder="Full Name">
26
+ <input id="email" placeholder="Email Address">
27
+ <select id="role">
28
+ <option>Student</option>
29
+ <option>Teacher</option>
30
+ </select>
31
+ <button class="btn-primary" onclick="addUser()">+ Add User</button>
32
+ </div>
33
+ <div class="table-wrapper">
34
+ <table id="usersTable"></table>
35
+ </div>
36
+ </div>
37
+ </div>
38
+
39
+ <div class="card">
40
+ <div class="card-header">
41
+ <h2>Manage Courses</h2>
42
+ </div>
43
+ <div class="card-body">
44
+ <div class="form-row">
45
+ <input id="courseTitle" placeholder="Course Title">
46
+ <select id="teacherSelect">
47
+ <option disabled selected>Select Teacher</option>
48
+ </select>
49
+ <button class="btn-primary" onclick="createCourse()">+ Create Course</button>
50
+ </div>
51
+ <div class="table-wrapper">
52
+ <table id="coursesTable"></table>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <div class="card">
58
+ <div class="card-header">
59
+ <h2>Enrollments</h2>
60
+ </div>
61
+ <div class="card-body">
62
+ <div class="form-row">
63
+ <select id="studentSelect">
64
+ <option disabled selected>Select Student</option>
65
+ </select>
66
+ <select id="courseSelect">
67
+ <option disabled selected>Select Course</option>
68
+ </select>
69
+ <button class="btn-primary" onclick="enrollStudent()">Enroll Student</button>
70
+ </div>
71
+ <div class="table-wrapper">
72
+ <table id="enrollmentsTable"></table>
73
+ </div>
74
+ </div>
75
+ </div>
76
+
77
+ </div>
78
+
79
+ </body>
80
+ </html>