Darsh Tulsiyan commited on
Commit
2e0de0f
·
1 Parent(s): 5d1504a

manual course form

Browse files
Files changed (5) hide show
  1. app.py +346 -276
  2. create_course.py +55 -2
  3. live_polls.py +6 -4
  4. poll_db_operations.py +4 -2
  5. session_page.py +8 -5
app.py CHANGED
@@ -16,7 +16,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
16
  import os
17
  from openai import OpenAI
18
  from dotenv import load_dotenv
19
- from create_course2 import create_course, courses_collection, generate_perplexity_response, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
20
  import json
21
  from bson import ObjectId
22
  client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
@@ -233,35 +233,110 @@ def create_session(new_session, course_id):
233
  return False
234
 
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  def create_session_form(course_id):
237
  """Display form to create a new session and perform the creation operation"""
238
  st.title("Create New Session")
239
 
240
- if 'session_time' not in st.session_state:
241
  st.session_state.session_time = datetime.now().time()
242
- if 'show_create_session_form' not in st.session_state:
 
243
  st.session_state.show_create_session_form = False
244
 
 
 
 
245
  with st.form("create_session_form"):
246
  session_title = st.text_input("Session Title")
247
  session_date = st.date_input("Session Date", date.today(), key="session_date")
248
- session_time = st.time_input(
249
- "Session Time", st.session_state.session_time, key="session_time"
250
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
- new_session_id = None
253
  # Generate new session ID
 
254
  course = courses_collection.find_one({"course_id": course_id})
255
  if course and "sessions" in course and course["sessions"]:
256
- last_session_id = max(
257
- int(session["session_id"][1:]) for session in course["sessions"]
258
- )
259
  new_session_id = last_session_id + 1
260
  else:
261
  new_session_id = 1
262
 
 
263
  if st.form_submit_button("Create Session"):
264
- clicked = True
265
  new_session = {
266
  "session_id": f"S{new_session_id}",
267
  "course_id": course_id,
@@ -269,24 +344,23 @@ def create_session_form(course_id):
269
  "date": datetime.combine(session_date, session_time),
270
  "status": "upcoming",
271
  "created_at": datetime.utcnow(),
272
- "pre_class": {
273
- "resources": [],
274
- "completetion_required": True,
275
- },
276
- "in_class": {
277
- "topics": [],
278
- "quiz": {"title": "", "questions": 0, "duration": 0},
279
- "polls": [],
280
- },
281
- "post_class": {
282
- "assignments": [],
283
- },
284
  }
285
- courses_collection.update_one(
286
- {"course_id": course_id}, {"$push": {"sessions": new_session}}
287
- )
288
  st.success("Session created successfully!")
 
289
  st.session_state.show_create_session_form = False
 
290
 
291
  # new_session_id = None
292
  # creation_success = False
@@ -866,282 +940,278 @@ def create_course_form(faculty_name, faculty_id):
866
  with col2:
867
  duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
868
  start_date = st.date_input("Start Date")
 
 
869
 
870
  generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
871
 
872
  if generate_button and course_name:
873
- with st.spinner("Generating course structure and resources..."):
874
- try:
875
- # Generate course plan with resources
876
- course_plan = generate_perplexity_response(
877
- PERPLEXITY_API_KEY,
878
- course_name,
879
- duration_weeks,
880
- sessions_per_week
881
- )
882
- try:
883
- course_plan_json = json.loads(course_plan)
884
- validate_course_plan(course_plan_json)
885
- st.session_state.course_plan = course_plan_json
886
- except (json.JSONDecodeError, ValueError) as e:
887
- st.error(f"Error in course plan structure: {e}")
888
- return
889
- st.session_state.start_date = start_date
890
- st.session_state.duration_weeks = duration_weeks
891
- st.session_state.sessions_per_week = sessions_per_week
 
 
 
 
892
 
893
- # Generate resources for all sessions
894
- session_titles = []
895
- for module in st.session_state.course_plan['modules']:
896
- for sub_module in module['sub_modules']:
897
- for topic in sub_module['topics']:
898
- # session_titles.append(topic['title'])
899
- # session_titles.append(topic)
900
- if isinstance(topic, dict):
901
- session_titles.append(topic['title'])
902
- else:
903
- session_titles.append(topic)
904
- # In generate_session_resources function, add validation:
905
- if not session_titles:
906
- return json.dumps({"session_resources": []})
907
- resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
908
- without_backticks = remove_json_backticks(resources_response)
909
- resources = json.loads(without_backticks)
910
- st.session_state.resources_map = {
911
- resource['session_title']: resource['resources']
912
- for resource in resources['session_resources']
913
- }
914
- # Add error handling for the resources map
915
- # if st.session_state.resources_map is None:
916
- # st.session_state.resources_map = {}
917
-
918
- st.rerun()
919
- except Exception as e:
920
- st.error(f"Error generating course structure: {e}")
921
 
922
- # Display and Edit Generated Course Content
923
- if st.session_state.course_plan:
924
- with st.expander("Course Overview", expanded=True):
925
- if not st.session_state.edit_mode:
926
- st.subheader(st.session_state.course_plan['course_title'])
927
- st.write(st.session_state.course_plan['course_description'])
928
- col1, col2, col3 = st.columns(3)
929
- with col1:
930
- st.write(f"**Start Date:** {st.session_state.start_date}")
931
- with col2:
932
- st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
933
- with col3:
934
- st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
935
-
936
- edit_button = st.button("Edit Course Details", use_container_width=True)
937
- if edit_button:
938
- st.session_state.edit_mode = True
939
- st.rerun()
940
- else:
941
- with st.form("edit_course_details"):
942
- st.session_state.course_plan['course_title'] = st.text_input(
943
- "Course Title",
944
- value=st.session_state.course_plan['course_title']
945
- )
946
- st.session_state.course_plan['course_description'] = st.text_area(
947
- "Course Description",
948
- value=st.session_state.course_plan['course_description']
949
- )
950
- if st.form_submit_button("Save Course Details"):
951
- st.session_state.edit_mode = False
952
- st.rerun()
953
 
954
- # Display Modules and Sessions
955
- st.subheader("Course Modules and Sessions")
956
 
957
- start_date = st.session_state.start_date
958
- current_date = start_date
959
 
960
- all_sessions = []
961
- for module_idx, module in enumerate(st.session_state.course_plan['modules']):
962
- with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
963
- # Edit module title
964
- new_module_title = st.text_input(
965
- f"Edit Module Title",
966
- value=module['module_title'],
967
- key=f"module_{module_idx}"
968
- )
969
- module['module_title'] = new_module_title
970
 
971
- for sub_idx, sub_module in enumerate(module['sub_modules']):
972
- st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
973
- # st.markdown(f"### 📖 {sub_module['title']}")
974
- st.markdown(f'<h3 style="font-size: 1.25rem;">📖 Chapter {sub_idx + 1}: {sub_module["title"]}</h3>', unsafe_allow_html=True)
975
- # Possible fix:
976
- # Inside the loop where topics are being processed:
977
-
978
- for topic_idx, topic in enumerate(sub_module['topics']):
979
- st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
980
- session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
981
 
982
- # Get topic title based on type
983
- if isinstance(topic, dict):
984
- current_topic_title = topic.get('title', '')
985
- current_topic_display = current_topic_title
986
- else:
987
- current_topic_title = str(topic)
988
- current_topic_display = current_topic_title
989
-
990
- with st.container():
991
- # Session Details
992
- col1, col2, col3 = st.columns([3, 2, 1])
993
- with col1:
994
- new_topic = st.text_input(
995
- f"Session {topic_idx + 1} Title",
996
- value=current_topic_display,
997
- key=f"{session_key}_topic"
998
- )
999
- # Update the topic in the data structure
1000
- if isinstance(topic, dict):
1001
- topic['title'] = new_topic
1002
- else:
1003
- sub_module['topics'][topic_idx] = new_topic
1004
 
1005
- with col2:
1006
- session_date = st.date_input(
1007
- "Session Date",
1008
- value=current_date,
1009
- key=f"{session_key}_date"
1010
- )
1011
 
1012
- with col3:
1013
- session_status = st.selectbox(
1014
- "Status",
1015
- options=["upcoming", "in-progress", "completed"],
1016
- key=f"{session_key}_status"
1017
- )
1018
 
1019
- # Display Resources
1020
- if st.session_state.resources_map:
1021
- # Try both the full topic title and the display title
1022
- resources = None
1023
- if isinstance(topic, dict) and topic.get('title') in st.session_state.resources_map:
1024
- resources = st.session_state.resources_map[topic['title']]
1025
- elif current_topic_title in st.session_state.resources_map:
1026
- resources = st.session_state.resources_map[current_topic_title]
1027
 
1028
- if resources:
1029
- with st.container():
1030
- # st.markdown("#### 📚 Session Resources")
1031
- st.markdown(f'<h4 style="font-size: 1.25rem;">📚 Session Resources</h4>', unsafe_allow_html=True)
1032
- # Readings Tab
1033
- if resources.get('readings'):
1034
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📖 External Resources</h5>', unsafe_allow_html=True)
1035
- col1, col2 = st.columns(2)
1036
- for idx, reading in enumerate(resources['readings']):
1037
- with col1 if idx % 2 == 0 else col2:
1038
- st.markdown(f"""
1039
- - **{reading['title']}**
1040
- - Type: {reading['type']}
1041
- - Estimated reading time: {reading['estimated_read_time']}
1042
- - [Access Resource]({reading['url']})
1043
- """)
1044
 
1045
- # Books Tab and Additional Resources Tab side-by-side
1046
- col1, col2 = st.columns(2)
1047
 
1048
- with col1:
1049
- if resources.get('books'):
1050
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📚 Reference Books</h5>', unsafe_allow_html=True)
1051
- for book in resources['books']:
1052
- with st.container():
1053
- st.markdown(f"""
1054
- - **{book['title']}**
1055
- - Author: {book['author']}
1056
- - ISBN: {book['isbn']}
1057
- - Chapters: {book['chapters']}
1058
- """)
1059
 
1060
- with col2:
1061
- if resources.get('additional_resources'):
1062
- st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">🔗 Additional Study Resources</h5>', unsafe_allow_html=True)
1063
- for resource in resources['additional_resources']:
1064
- with st.container():
1065
- st.markdown(f"""
1066
- - **{resource['title']}**
1067
- - Type: {resource['type']}
1068
- - Description: {resource['description']}
1069
- - [Access Resource]({resource['url']})
1070
- """)
1071
 
1072
- # Create session object
1073
- session = {
1074
- "session_id": str(ObjectId()),
1075
- "title": new_topic,
1076
- "date": datetime.combine(session_date, datetime.min.time()),
1077
- "status": session_status,
1078
- "module_name": module['module_title'],
1079
- "created_at": datetime.utcnow(),
1080
- "pre_class": {
1081
- "resources": [],
1082
- "completion_required": True
1083
- },
1084
- "in_class": {
1085
- "quiz": [],
1086
- "polls": []
1087
- },
1088
- "post_class": {
1089
- "assignments": []
1090
- },
1091
- "external_resources": st.session_state.resources_map.get(current_topic_title, {})
1092
- }
1093
- all_sessions.append(session)
1094
- current_date = session_date + timedelta(days=7)
1095
 
1096
 
1097
- new_course_id = get_new_course_id()
1098
- course_title = st.session_state.course_plan['course_title']
1099
-
1100
- # Final Save Button
1101
- if st.button("Save Course", type="primary", use_container_width=True):
1102
- try:
1103
- course_doc = {
1104
- "course_id": new_course_id,
1105
- "title": course_title,
1106
- "description": st.session_state.course_plan['course_description'],
1107
- "faculty": faculty_name,
1108
- "faculty_id": faculty_id,
1109
- "duration": f"{st.session_state.duration_weeks} weeks",
1110
- "sessions_per_week": st.session_state.sessions_per_week,
1111
- "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
1112
- "created_at": datetime.utcnow(),
1113
- "sessions": all_sessions
1114
- }
1115
 
1116
- # Insert into database
1117
- courses_collection.insert_one(course_doc)
1118
- st.success("Course successfully created!")
1119
 
1120
- # Update faculty collection
1121
- faculty_collection.update_one(
1122
- {"_id": st.session_state.user_id},
1123
- {
1124
- "$push": {
1125
- "courses_taught": {
1126
- "course_id": new_course_id,
1127
- "title": course_title,
1128
- }
1129
- }
1130
- }
1131
- )
1132
 
1133
- # Clear session state
1134
- st.session_state.course_plan = None
1135
- st.session_state.edit_mode = False
1136
- st.session_state.resources_map = {}
1137
 
1138
- # Optional: Add a button to view the created course
1139
- if st.button("View Course"):
1140
- # Add navigation logic here
1141
- pass
1142
 
1143
- except Exception as e:
1144
- st.error(f"Error saving course: {e}")
1145
 
1146
 
1147
 
 
16
  import os
17
  from openai import OpenAI
18
  from dotenv import load_dotenv
19
+ from create_course import create_course, courses_collection, generate_perplexity_response #, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
20
  import json
21
  from bson import ObjectId
22
  client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
 
233
  return False
234
 
235
 
236
+ # def create_session_form(course_id):
237
+ # """Display form to create a new session and perform the creation operation"""
238
+ # st.title("Create New Session")
239
+
240
+ # if 'session_time' not in st.session_state:
241
+ # st.session_state.session_time = datetime.now().time()
242
+ # if 'show_create_session_form' not in st.session_state:
243
+ # st.session_state.show_create_session_form = False
244
+
245
+ # with st.form("create_session_form"):
246
+ # session_title = st.text_input("Session Title")
247
+ # session_date = st.date_input("Session Date", date.today(), key="session_date")
248
+ # session_time = st.time_input(
249
+ # "Session Time", st.session_state.session_time, key="session_time"
250
+ # )
251
+
252
+ # new_session_id = None
253
+ # # Generate new session ID
254
+ # course = courses_collection.find_one({"course_id": course_id})
255
+ # if course and "sessions" in course and course["sessions"]:
256
+ # last_session_id = max(
257
+ # int(session["session_id"][1:]) for session in course["sessions"]
258
+ # )
259
+ # new_session_id = last_session_id + 1
260
+ # else:
261
+ # new_session_id = 1
262
+
263
+ # if st.form_submit_button("Create Session"):
264
+ # clicked = True
265
+ # new_session = {
266
+ # "session_id": f"S{new_session_id}",
267
+ # "course_id": course_id,
268
+ # "title": session_title,
269
+ # "date": datetime.combine(session_date, session_time),
270
+ # "status": "upcoming",
271
+ # "created_at": datetime.utcnow(),
272
+ # "pre_class": {
273
+ # "resources": [],
274
+ # "completetion_required": True,
275
+ # },
276
+ # "in_class": {
277
+ # "topics": [],
278
+ # "quiz": {"title": "", "questions": 0, "duration": 0},
279
+ # "polls": [],
280
+ # },
281
+ # "post_class": {
282
+ # "assignments": [],
283
+ # },
284
+ # }
285
+ # courses_collection.update_one(
286
+ # {"course_id": course_id}, {"$push": {"sessions": new_session}}
287
+ # )
288
+ # st.success("Session created successfully!")
289
+ # st.session_state.show_create_session_form = False
290
+
291
+
292
  def create_session_form(course_id):
293
  """Display form to create a new session and perform the creation operation"""
294
  st.title("Create New Session")
295
 
296
+ if "session_time" not in st.session_state:
297
  st.session_state.session_time = datetime.now().time()
298
+
299
+ if "show_create_session_form" not in st.session_state:
300
  st.session_state.show_create_session_form = False
301
 
302
+ if "outcomes" not in st.session_state:
303
+ st.session_state.outcomes = [] # List to store outcomes dynamically
304
+
305
  with st.form("create_session_form"):
306
  session_title = st.text_input("Session Title")
307
  session_date = st.date_input("Session Date", date.today(), key="session_date")
308
+ session_time = st.time_input("Session Time", st.session_state.session_time, key="session_time")
309
+
310
+ st.subheader("Session Learning Outcomes")
311
+
312
+ # Display all outcomes dynamically
313
+ for idx, outcome in enumerate(st.session_state.outcomes):
314
+ st.text_input(f"Outcome {idx + 1} Description", key=f"outcome_desc_{idx}")
315
+ st.selectbox(
316
+ f"Bloom's Taxonomy Level {idx + 1}",
317
+ ["Remember", "Understand", "Apply", "Analyze", "Evaluate", "Create"],
318
+ key=f"bloom_level_{idx}"
319
+ )
320
+
321
+ # Button to add new outcome fields
322
+ if st.form_submit_button("Add Outcome"):
323
+ new_index = len(st.session_state.outcomes)
324
+ st.session_state.outcomes.append(
325
+ {"outcome_number": new_index + 1, "outcome_description": "", "bloom_taxanomy_level": ""}
326
+ )
327
+ st.rerun() # Refresh the form to display new fields
328
 
 
329
  # Generate new session ID
330
+ new_session_id = None
331
  course = courses_collection.find_one({"course_id": course_id})
332
  if course and "sessions" in course and course["sessions"]:
333
+ last_session_id = max(int(session["session_id"][1:]) for session in course["sessions"])
 
 
334
  new_session_id = last_session_id + 1
335
  else:
336
  new_session_id = 1
337
 
338
+ # Submit session
339
  if st.form_submit_button("Create Session"):
 
340
  new_session = {
341
  "session_id": f"S{new_session_id}",
342
  "course_id": course_id,
 
344
  "date": datetime.combine(session_date, session_time),
345
  "status": "upcoming",
346
  "created_at": datetime.utcnow(),
347
+ "pre_class": {"resources": [], "completetion_required": True},
348
+ "in_class": {"topics": [], "quiz": {"title": "", "questions": 0, "duration": 0}, "polls": []},
349
+ "post_class": {"assignments": []},
350
+ "session_learning_outcomes": [
351
+ {
352
+ "outcome_number": idx + 1,
353
+ "outcome_description": st.session_state[f"outcome_desc_{idx}"],
354
+ "bloom_taxanomy_level": st.session_state[f"bloom_level_{idx}"]
355
+ }
356
+ for idx in range(len(st.session_state.outcomes))
357
+ ]
 
358
  }
359
+ courses_collection.update_one({"course_id": course_id}, {"$push": {"sessions": new_session}})
 
 
360
  st.success("Session created successfully!")
361
+ st.session_state.outcomes = [] # Clear outcomes after submission
362
  st.session_state.show_create_session_form = False
363
+ st.rerun()
364
 
365
  # new_session_id = None
366
  # creation_success = False
 
940
  with col2:
941
  duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
942
  start_date = st.date_input("Start Date")
943
+ course_description = st.text_area("Course Description", placeholder="Enter a brief course description here")
944
+
945
 
946
  generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
947
 
948
  if generate_button and course_name:
949
+ create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date, course_description, faculty_id)
950
+
951
+ #update faculty list of courses
952
+
953
+ # with st.spinner("Generating course structure and resources..."):
954
+ # try:
955
+ # # Generate course plan with resources
956
+ # course_plan = generate_perplexity_response(
957
+ # PERPLEXITY_API_KEY,
958
+ # course_name,
959
+ # duration_weeks,
960
+ # sessions_per_week
961
+ # )
962
+ # try:
963
+ # course_plan_json = json.loads(course_plan)
964
+ # validate_course_plan(course_plan_json)
965
+ # st.session_state.course_plan = course_plan_json
966
+ # except (json.JSONDecodeError, ValueError) as e:
967
+ # st.error(f"Error in course plan structure: {e}")
968
+ # return
969
+ # st.session_state.start_date = start_date
970
+ # st.session_state.duration_weeks = duration_weeks
971
+ # st.session_state.sessions_per_week = sessions_per_week
972
 
973
+ # # Generate resources for all sessions
974
+ # session_titles = []
975
+ # for module in st.session_state.course_plan['modules']:
976
+ # for sub_module in module['sub_modules']:
977
+ # for topic in sub_module['topics']:
978
+ # # session_titles.append(topic['title'])
979
+ # # session_titles.append(topic)
980
+ # if isinstance(topic, dict):
981
+ # session_titles.append(topic['title'])
982
+ # else:
983
+ # session_titles.append(topic)
984
+ # # In generate_session_resources function, add validation:
985
+ # if not session_titles:
986
+ # return json.dumps({"session_resources": []})
987
+ # resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
988
+ # without_backticks = remove_json_backticks(resources_response)
989
+ # resources = json.loads(without_backticks)
990
+ # st.session_state.resources_map = {
991
+ # resource['session_title']: resource['resources']
992
+ # for resource in resources['session_resources']
993
+ # }
994
+ # # Add error handling for the resources map
995
+ # # if st.session_state.resources_map is None:
996
+ # # st.session_state.resources_map = {}
997
+
998
+ # st.rerun()
999
+ # except Exception as e:
1000
+ # st.error(f"Error generating course structure: {e}")
1001
 
1002
+ # # Display and Edit Generated Course Content
1003
+ # if st.session_state.course_plan:
1004
+ # with st.expander("Course Overview", expanded=True):
1005
+ # if not st.session_state.edit_mode:
1006
+ # st.subheader(st.session_state.course_plan['course_title'])
1007
+ # st.write(st.session_state.course_plan['course_description'])
1008
+ # col1, col2, col3 = st.columns(3)
1009
+ # with col1:
1010
+ # st.write(f"**Start Date:** {st.session_state.start_date}")
1011
+ # with col2:
1012
+ # st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
1013
+ # with col3:
1014
+ # st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
1015
+
1016
+ # edit_button = st.button("Edit Course Details", use_container_width=True)
1017
+ # if edit_button:
1018
+ # st.session_state.edit_mode = True
1019
+ # st.rerun()
1020
+ # else:
1021
+ # with st.form("edit_course_details"):
1022
+ # st.session_state.course_plan['course_title'] = st.text_input(
1023
+ # "Course Title",
1024
+ # value=st.session_state.course_plan['course_title']
1025
+ # )
1026
+ # st.session_state.course_plan['course_description'] = st.text_area(
1027
+ # "Course Description",
1028
+ # value=st.session_state.course_plan['course_description']
1029
+ # )
1030
+ # if st.form_submit_button("Save Course Details"):
1031
+ # st.session_state.edit_mode = False
1032
+ # st.rerun()
1033
 
1034
+ # # Display Modules and Sessions
1035
+ # st.subheader("Course Modules and Sessions")
1036
 
1037
+ # start_date = st.session_state.start_date
1038
+ # current_date = start_date
1039
 
1040
+ # all_sessions = []
1041
+ # for module_idx, module in enumerate(st.session_state.course_plan['modules']):
1042
+ # with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
1043
+ # # Edit module title
1044
+ # new_module_title = st.text_input(
1045
+ # f"Edit Module Title",
1046
+ # value=module['module_title'],
1047
+ # key=f"module_{module_idx}"
1048
+ # )
1049
+ # module['module_title'] = new_module_title
1050
 
1051
+ # for sub_idx, sub_module in enumerate(module['sub_modules']):
1052
+ # st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1053
+ # # st.markdown(f"### 📖 {sub_module['title']}")
1054
+ # st.markdown(f'<h3 style="font-size: 1.25rem;">📖 Chapter {sub_idx + 1}: {sub_module["title"]}</h3>', unsafe_allow_html=True)
1055
+ # # Possible fix:
1056
+ # # Inside the loop where topics are being processed:
1057
+
1058
+ # for topic_idx, topic in enumerate(sub_module['topics']):
1059
+ # st.markdown("<br>", unsafe_allow_html=True) # Add gap between sessions
1060
+ # session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
1061
 
1062
+ # # Get topic title based on type
1063
+ # if isinstance(topic, dict):
1064
+ # current_topic_title = topic.get('title', '')
1065
+ # current_topic_display = current_topic_title
1066
+ # else:
1067
+ # current_topic_title = str(topic)
1068
+ # current_topic_display = current_topic_title
1069
+
1070
+ # with st.container():
1071
+ # # Session Details
1072
+ # col1, col2, col3 = st.columns([3, 2, 1])
1073
+ # with col1:
1074
+ # new_topic = st.text_input(
1075
+ # f"Session {topic_idx + 1} Title",
1076
+ # value=current_topic_display,
1077
+ # key=f"{session_key}_topic"
1078
+ # )
1079
+ # # Update the topic in the data structure
1080
+ # if isinstance(topic, dict):
1081
+ # topic['title'] = new_topic
1082
+ # else:
1083
+ # sub_module['topics'][topic_idx] = new_topic
1084
 
1085
+ # with col2:
1086
+ # session_date = st.date_input(
1087
+ # "Session Date",
1088
+ # value=current_date,
1089
+ # key=f"{session_key}_date"
1090
+ # )
1091
 
1092
+ # with col3:
1093
+ # session_status = st.selectbox(
1094
+ # "Status",
1095
+ # options=["upcoming", "in-progress", "completed"],
1096
+ # key=f"{session_key}_status"
1097
+ # )
1098
 
1099
+ # # Display Resources
1100
+ # if st.session_state.resources_map:
1101
+ # # Try both the full topic title and the display title
1102
+ # resources = None
1103
+ # if isinstance(topic, dict) and topic.get('title') in st.session_state.resources_map:
1104
+ # resources = st.session_state.resources_map[topic['title']]
1105
+ # elif current_topic_title in st.session_state.resources_map:
1106
+ # resources = st.session_state.resources_map[current_topic_title]
1107
 
1108
+ # if resources:
1109
+ # with st.container():
1110
+ # # st.markdown("#### 📚 Session Resources")
1111
+ # st.markdown(f'<h4 style="font-size: 1.25rem;">📚 Session Resources</h4>', unsafe_allow_html=True)
1112
+ # # Readings Tab
1113
+ # if resources.get('readings'):
1114
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📖 External Resources</h5>', unsafe_allow_html=True)
1115
+ # col1, col2 = st.columns(2)
1116
+ # for idx, reading in enumerate(resources['readings']):
1117
+ # with col1 if idx % 2 == 0 else col2:
1118
+ # st.markdown(f"""
1119
+ # - **{reading['title']}**
1120
+ # - Type: {reading['type']}
1121
+ # - Estimated reading time: {reading['estimated_read_time']}
1122
+ # - [Access Resource]({reading['url']})
1123
+ # """)
1124
 
1125
+ # # Books Tab and Additional Resources Tab side-by-side
1126
+ # col1, col2 = st.columns(2)
1127
 
1128
+ # with col1:
1129
+ # if resources.get('books'):
1130
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">📚 Reference Books</h5>', unsafe_allow_html=True)
1131
+ # for book in resources['books']:
1132
+ # with st.container():
1133
+ # st.markdown(f"""
1134
+ # - **{book['title']}**
1135
+ # - Author: {book['author']}
1136
+ # - ISBN: {book['isbn']}
1137
+ # - Chapters: {book['chapters']}
1138
+ # """)
1139
 
1140
+ # with col2:
1141
+ # if resources.get('additional_resources'):
1142
+ # st.markdown(f'<h5 style="font-size: 1.1rem; margin-top: 1rem;">🔗 Additional Study Resources</h5>', unsafe_allow_html=True)
1143
+ # for resource in resources['additional_resources']:
1144
+ # with st.container():
1145
+ # st.markdown(f"""
1146
+ # - **{resource['title']}**
1147
+ # - Type: {resource['type']}
1148
+ # - Description: {resource['description']}
1149
+ # - [Access Resource]({resource['url']})
1150
+ # """)
1151
 
1152
+ # # Create session object
1153
+ # session = {
1154
+ # "session_id": str(ObjectId()),
1155
+ # "title": new_topic,
1156
+ # "date": datetime.combine(session_date, datetime.min.time()),
1157
+ # "status": session_status,
1158
+ # "module_name": module['module_title'],
1159
+ # "created_at": datetime.utcnow(),
1160
+ # "pre_class": {
1161
+ # "resources": [],
1162
+ # "completion_required": True
1163
+ # },
1164
+ # "in_class": {
1165
+ # "quiz": [],
1166
+ # "polls": []
1167
+ # },
1168
+ # "post_class": {
1169
+ # "assignments": []
1170
+ # },
1171
+ # "external_resources": st.session_state.resources_map.get(current_topic_title, {})
1172
+ # }
1173
+ # all_sessions.append(session)
1174
+ # current_date = session_date + timedelta(days=7)
1175
 
1176
 
1177
+ # new_course_id = get_new_course_id()
1178
+ # course_title = st.session_state.course_plan['course_title']
1179
+
1180
+ # # Final Save Button
1181
+ # if st.button("Save Course", type="primary", use_container_width=True):
1182
+ # try:
1183
+ # course_doc = {
1184
+ # "course_id": new_course_id,
1185
+ # "title": course_title,
1186
+ # "description": st.session_state.course_plan['course_description'],
1187
+ # "faculty": faculty_name,
1188
+ # "faculty_id": faculty_id,
1189
+ # "duration": f"{st.session_state.duration_weeks} weeks",
1190
+ # "sessions_per_week": st.session_state.sessions_per_week,
1191
+ # "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
1192
+ # "created_at": datetime.utcnow(),
1193
+ # "sessions": all_sessions
1194
+ # }
1195
 
1196
+ # # Insert into database
1197
+ # courses_collection.insert_one(course_doc)
1198
+ # st.success("Course successfully created!")
1199
 
1200
+ # # Update faculty collection
1201
+
 
 
 
 
 
 
 
 
 
 
1202
 
1203
+ # # Clear session state
1204
+ # st.session_state.course_plan = None
1205
+ # st.session_state.edit_mode = False
1206
+ # st.session_state.resources_map = {}
1207
 
1208
+ # # Optional: Add a button to view the created course
1209
+ # if st.button("View Course"):
1210
+ # # Add navigation logic here
1211
+ # pass
1212
 
1213
+ # except Exception as e:
1214
+ # st.error(f"Error saving course: {e}")
1215
 
1216
 
1217
 
create_course.py CHANGED
@@ -1,4 +1,4 @@
1
- from datetime import datetime, timedelta
2
  import os
3
  from typing import Dict, List, Any
4
  from pymongo import MongoClient
@@ -19,6 +19,7 @@ OPENAI_API_KEY = os.getenv("OPENAI_KEY")
19
  client = MongoClient(MONGODB_URI)
20
  db = client['novascholar_db']
21
  courses_collection = db['courses']
 
22
 
23
  def generate_perplexity_response(api_key, course_name):
24
  headers = {
@@ -118,7 +119,7 @@ def get_new_course_id():
118
  return new_course_id
119
 
120
 
121
- def create_course(course_name, start_date, duration_weeks):
122
  # Generate course overview
123
  # overview_prompt = f"""Generate an overview for the undergraduate course {course_name}
124
  # Include all relevant concepts and key topics covered in a typical curriculum.
@@ -246,6 +247,58 @@ def create_course(course_name, start_date, duration_weeks):
246
 
247
  # print(course_plan)
248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  def create_session(title: str, date: datetime, module_name: str):
250
  """Create a session document with pre-class, in-class, and post-class components."""
251
  return {
 
1
+ from datetime import datetime, timedelta, date
2
  import os
3
  from typing import Dict, List, Any
4
  from pymongo import MongoClient
 
19
  client = MongoClient(MONGODB_URI)
20
  db = client['novascholar_db']
21
  courses_collection = db['courses']
22
+ faculty_collection = db['faculty']
23
 
24
  def generate_perplexity_response(api_key, course_name):
25
  headers = {
 
119
  return new_course_id
120
 
121
 
122
+ def create_course_perplexity(course_name, start_date, duration_weeks):
123
  # Generate course overview
124
  # overview_prompt = f"""Generate an overview for the undergraduate course {course_name}
125
  # Include all relevant concepts and key topics covered in a typical curriculum.
 
247
 
248
  # print(course_plan)
249
 
250
+
251
+ def create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date: date, course_description, faculty_id):
252
+ """
253
+ Create a course document in the desired JSON format and insert it into MongoDB.
254
+ """
255
+ try:
256
+ # Count sessions
257
+ # st.write("Number of sessions:", len(all_sessions)
258
+
259
+ # Generate a new course ID
260
+ course_id = get_new_course_id()
261
+
262
+ if isinstance(start_date, date):
263
+ start_date = datetime.combine(start_date, datetime.min.time())
264
+
265
+ # Create the course document
266
+ course_doc = {
267
+ "_id": ObjectId(),
268
+ "course_id": course_id, # Assumes there's a helper function in your code
269
+ "title": course_name,
270
+ "description": course_description,
271
+ "faculty": faculty_name,
272
+ "faculty_id": faculty_id,
273
+ "duration": f"{duration_weeks} weeks",
274
+ "sessions_per_week": sessions_per_week,
275
+ "start_date": start_date,
276
+ "created_at": datetime.utcnow(),
277
+ }
278
+
279
+ # Insert into MongoDB
280
+ courses_collection.insert_one(course_doc)
281
+
282
+ faculty_collection.update_one(
283
+ {"_id": st.session_state.user_id},
284
+ {
285
+ "$push": {
286
+ "courses_taught": {
287
+ "course_id": course_id,
288
+ "title": course_name,
289
+ }
290
+ }
291
+ }
292
+ )
293
+
294
+ st.success("Course created successfully!")
295
+ # st.json(course_doc)
296
+ return course_doc
297
+ except Exception as e:
298
+ st.error(f"Failed to insert course data into the database: {e}")
299
+ return None
300
+
301
+
302
  def create_session(title: str, date: datetime, module_name: str):
303
  """Create a session document with pre-class, in-class, and post-class components."""
304
  return {
live_polls.py CHANGED
@@ -9,7 +9,7 @@ class LivePollFeature:
9
  def __init__(self):
10
  self.db = PollDatabase()
11
 
12
- def display_faculty_interface(self, session_id):
13
  """Display the faculty interface for managing polls"""
14
  st.markdown("#### Live Polls Management")
15
 
@@ -31,6 +31,8 @@ class LivePollFeature:
31
 
32
  if st.button("Create Poll") and question and len(options) >= 2:
33
  self.db.create_poll(
 
 
34
  st.session_state.selected_course,
35
  session_id,
36
  question,
@@ -41,7 +43,7 @@ class LivePollFeature:
41
  st.rerun()
42
 
43
  # Display active polls
44
- active_polls = self.db.get_active_polls(session_id)
45
  if active_polls:
46
  st.subheader("Active Polls")
47
  for poll in active_polls:
@@ -55,11 +57,11 @@ class LivePollFeature:
55
  st.success("Poll closed successfully!")
56
  st.rerun()
57
 
58
- def display_student_interface(self, session_id):
59
  """Display the student interface for participating in polls"""
60
  st.subheader("Live Polls")
61
 
62
- active_polls = self.db.get_active_polls(session_id)
63
  if not active_polls:
64
  st.info("No active polls at the moment.")
65
  return
 
9
  def __init__(self):
10
  self.db = PollDatabase()
11
 
12
+ def display_faculty_interface(self, session_id, course_id):
13
  """Display the faculty interface for managing polls"""
14
  st.markdown("#### Live Polls Management")
15
 
 
31
 
32
  if st.button("Create Poll") and question and len(options) >= 2:
33
  self.db.create_poll(
34
+ course_id,
35
+ # course_id,
36
  st.session_state.selected_course,
37
  session_id,
38
  question,
 
43
  st.rerun()
44
 
45
  # Display active polls
46
+ active_polls = self.db.get_active_polls(session_id, course_id)
47
  if active_polls:
48
  st.subheader("Active Polls")
49
  for poll in active_polls:
 
57
  st.success("Poll closed successfully!")
58
  st.rerun()
59
 
60
+ def display_student_interface(self, session_id, course_id):
61
  """Display the student interface for participating in polls"""
62
  st.subheader("Live Polls")
63
 
64
+ active_polls = self.db.get_active_polls(session_id, course_id)
65
  if not active_polls:
66
  st.info("No active polls at the moment.")
67
  return
poll_db_operations.py CHANGED
@@ -11,10 +11,11 @@ class PollDatabase:
11
  self.client = MongoClient(MONGO_URI)
12
  self.db = self.client["novascholar_db"]
13
 
14
- def create_poll(self, course_id, session_id, question, options, faculty_id):
15
  """Create a new poll"""
16
  poll = {
17
  "course_id": course_id,
 
18
  "session_id": session_id,
19
  "faculty_id": faculty_id,
20
  "question": question,
@@ -25,10 +26,11 @@ class PollDatabase:
25
  }
26
  return self.db.polls.insert_one(poll)
27
 
28
- def get_active_polls(self, session_id):
29
  """Get all active polls for a session"""
30
  return list(self.db.polls.find({
31
  "session_id": session_id,
 
32
  "status": "active"
33
  }))
34
 
 
11
  self.client = MongoClient(MONGO_URI)
12
  self.db = self.client["novascholar_db"]
13
 
14
+ def create_poll(self, course_id, course_name, session_id, question, options, faculty_id):
15
  """Create a new poll"""
16
  poll = {
17
  "course_id": course_id,
18
+ "course_name": course_name,
19
  "session_id": session_id,
20
  "faculty_id": faculty_id,
21
  "question": question,
 
26
  }
27
  return self.db.polls.insert_one(poll)
28
 
29
+ def get_active_polls(self, session_id, course_id):
30
  """Get all active polls for a session"""
31
  return list(self.db.polls.find({
32
  "session_id": session_id,
33
+ "course_id": course_id,
34
  "status": "active"
35
  }))
36
 
session_page.py CHANGED
@@ -154,7 +154,8 @@ def display_preclass_content(session, student_id, course_id):
154
  """Display pre-class materials for a session including external resources"""
155
  st.subheader("Pre-class Materials")
156
  print("Session ID is: ", session['session_id'])
157
-
 
158
  # Display uploaded materials
159
  materials = resources_collection.find({"session_id": session['session_id']})
160
 
@@ -724,6 +725,7 @@ def display_preclass_content(session, student_id, course_id):
724
  if not quiz:
725
  st.info("No practice quizzes created.")
726
  else:
 
727
  with st.expander(f"📝 Practice Quiz", expanded=True):
728
  existing_score = get_student_quiz_score(quiz['_id'], student_id)
729
 
@@ -1282,7 +1284,7 @@ def upload_preclass_materials(session_id, course_id, student_id):
1282
  # Display pre-class materials
1283
  # Group resources by their types
1284
  grouped_resources = defaultdict(list)
1285
- materials = resources_collection.find({"session_id": session_id})
1286
  for material in materials:
1287
  grouped_resources[material['material_type']].append(material)
1288
 
@@ -2441,13 +2443,13 @@ def display_in_class_content(session, user_type, course_id, user_id):
2441
 
2442
  # Display appropriate interface based on user role
2443
  if user_type == 'faculty':
2444
- live_polls.display_faculty_interface(session['session_id'])
2445
  else:
2446
- live_polls.display_student_interface(session['session_id'])
2447
 
2448
  display_live_chat_interface(session, user_id, course_id=course_id)
2449
 
2450
- # Live Presentation Feature
2451
  display_live_presentation(session, user_type, course_id)
2452
 
2453
  def get_current_context(session):
@@ -3737,6 +3739,7 @@ def display_quiz_tab(student_id, course_id, session_id):
3737
  # "quiz_type": {"$ne": "pre_class"}
3738
  # })
3739
  quizzes = list(quizzes_collection.find({
 
3740
  "course_id": course_id,
3741
  "session_id": session_id,
3742
  "status": "active",
 
154
  """Display pre-class materials for a session including external resources"""
155
  st.subheader("Pre-class Materials")
156
  print("Session ID is: ", session['session_id'])
157
+ print(course_id)
158
+
159
  # Display uploaded materials
160
  materials = resources_collection.find({"session_id": session['session_id']})
161
 
 
725
  if not quiz:
726
  st.info("No practice quizzes created.")
727
  else:
728
+ display_quiz_tab(student_id, course_id, session['session_id'])
729
  with st.expander(f"📝 Practice Quiz", expanded=True):
730
  existing_score = get_student_quiz_score(quiz['_id'], student_id)
731
 
 
1284
  # Display pre-class materials
1285
  # Group resources by their types
1286
  grouped_resources = defaultdict(list)
1287
+ materials = resources_collection.find({"session_id": session_id, "course_id": course_id})
1288
  for material in materials:
1289
  grouped_resources[material['material_type']].append(material)
1290
 
 
2443
 
2444
  # Display appropriate interface based on user role
2445
  if user_type == 'faculty':
2446
+ live_polls.display_faculty_interface(session['session_id'], course_id)
2447
  else:
2448
+ live_polls.display_student_interface(session['session_id'], course_id)
2449
 
2450
  display_live_chat_interface(session, user_id, course_id=course_id)
2451
 
2452
+ # Live Presentation Featurer
2453
  display_live_presentation(session, user_type, course_id)
2454
 
2455
  def get_current_context(session):
 
3739
  # "quiz_type": {"$ne": "pre_class"}
3740
  # })
3741
  quizzes = list(quizzes_collection.find({
3742
+ "user_id": ObjectId(student_id),
3743
  "course_id": course_id,
3744
  "session_id": session_id,
3745
  "status": "active",