import re
from pymongo import MongoClient
import streamlit as st
from datetime import datetime, date, time, timedelta
from pathlib import Path
from utils.sample_data import SAMPLE_COURSES, SAMPLE_SESSIONS
# from session_page_alt import display_session_content
from session_page import display_session_content
from db import (
courses_collection2,
faculty_collection,
students_collection,
research_assistants_collection,
analysts_collection,
)
from werkzeug.security import generate_password_hash, check_password_hash
import os
from openai import OpenAI
from dotenv import load_dotenv
from create_course import create_course, courses_collection, generate_perplexity_response #, generate_session_resources, PERPLEXITY_API_KEY, validate_course_plan
import json
from bson import ObjectId
client = OpenAI(api_key=os.getenv("OPENAI_KEY"))
from dotenv import load_dotenv
from code_playground import display_code_playground
load_dotenv()
# PERPLEXITY_API_KEY = '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'
def get_research_papers(query):
"""Get research paper recommendations based on query"""
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "system",
"content": "You are a helpful research assistant. Provide 10 relevant research papers with titles, authors, brief descriptions, and DOI/URL links. Format each paper as: \n\n1. **Title**\nAuthors: [names]\nLink: [DOI/URL]\nDescription: [brief summary]",
},
{
"role": "user",
"content": f"Give me 10 research papers about: {query}. Include valid DOI links or URLs to the papers where available.",
},
],
)
return response.choices[0].message.content
except Exception as e:
return f"Error getting recommendations: {str(e)}"
def analyze_research_gaps(papers):
"""Analyze gaps in research based on recommended papers"""
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "system",
"content": "You are a research analysis expert. Based on the provided papers, identify potential research gaps and future research directions.",
},
{
"role": "user",
"content": f"Based on these papers, what are the key areas that need more research?\n\nPapers:\n{papers}",
},
],
)
return response.choices[0].message.content
except Exception as e:
return f"Error analyzing research gaps: {str(e)}"
def init_session_state():
"""Initialize session state variables"""
if "authenticated" not in st.session_state:
st.session_state.authenticated = False
if "user_id" not in st.session_state:
st.session_state.user_id = None
if "user_type" not in st.session_state:
st.session_state.user_type = None
if "username" not in st.session_state:
st.session_state.username = None
if "selected_course" not in st.session_state:
st.session_state.selected_course = None
if "show_create_course_form" not in st.session_state:
st.session_state.show_create_course_form = False
if "show_create_session_form" not in st.session_state:
st.session_state.show_create_session_form = False
if "show_enroll_course_page" not in st.session_state:
st.session_state.show_enroll_course_page = False
if "course_to_enroll" not in st.session_state:
st.session_state.course_to_enroll = None
def login_user(username, password, user_type):
"""Login user based on credentials"""
if user_type == "student":
# user = students_collection.find_one({"full_name": username}) or students_collection.find_one({"username": username})
user = students_collection.find_one({"$or": [{"full_name": username}, {"username": username}]})
elif user_type == "faculty":
user = faculty_collection.find_one({"$or": [{"full_name": username}, {"username": username}]})
elif user_type == "research_assistant":
user = research_assistants_collection.find_one({"full_name": username})
elif user_type == "analyst":
user = analysts_collection.find_one({"full_name": username})
if user and check_password_hash(user["password"], password):
st.session_state.user_id = user["_id"]
print(st.session_state.user_id)
st.session_state.authenticated = True
st.session_state.user_type = user_type
st.session_state.username = username
return True
return False
# def login_form():
# """Display login form"""
# st.title("Welcome to NOVAScholar")
# with st.form("login_form"):
# user_type = st.selectbox(
# "Please select your Role", ["student", "faculty", "research_assistant", "analyst"]
# )
# username = st.text_input("Username")
# password = st.text_input("Password", type="password")
# submit = st.form_submit_button("Login")
# if submit:
# if login_user(username, password, user_type):
# st.success("Login successful!")
# st.rerun()
# else:
# st.error("Invalid credentials!")
def login_form():
"""Display enhanced login form"""
st.title("Welcome to NOVAScholar")
with st.form("login_form"):
# Role selection at the top
user_type = st.selectbox(
"Please select your Role",
["Student", "Faculty", "Research Assistant", "Analyst"]
)
user_type = user_type.lower().replace(" ", "_")
# Username/email and password stacked vertically
username = st.text_input("Username or Email")
password = st.text_input("Password", type="password")
# Login button
submit = st.form_submit_button("Login")
if submit:
# Handle both username and email login
if '@' in username:
username = extract_username(username)
if login_user(username, password, user_type):
st.success("Login successful!")
st.rerun()
else:
st.error("Invalid credentials!")
def get_courses(username, user_type):
if user_type == "student":
student = students_collection.find_one({"$or": [{"full_name": username}, {"username": username}]})
if student:
enrolled_course_ids = [
course["course_id"] for course in student.get("enrolled_courses", [])
]
courses = courses_collection.find(
{"course_id": {"$in": enrolled_course_ids}}
)
# courses += courses_collection2.find(
# {"course_id": {"$in": enrolled_course_ids}}
# )
# # course_titles = [course['title'] for course in courses]
# return list(courses)
# courses_cursor1 = courses_collection.find(
# {"course_id": {"$in": enrolled_course_ids}}
# )
# courses_cursor2 = courses_collection2.find(
# {"course_id": {"$in": enrolled_course_ids}}
# )
# courses = list(courses_cursor1) + list(courses_cursor2)
return list(courses)
elif user_type == "faculty":
faculty = faculty_collection.find_one({"$or": [{"full_name": username}, {"username": username}]})
if faculty:
course_ids = [
course["course_id"] for course in faculty.get("courses_taught", [])
]
# courses_1 = list(courses_collection2.find({"course_id": {"$in": course_ids}}))
courses_2 = list(courses_collection.find({"course_id": {"$in": course_ids}}))
return courses_2
elif user_type == "research_assistant":
research_assistant = research_assistants_collection.find_one(
{"full_name": username}
)
if research_assistant:
course_ids = [
course["course_id"]
for course in research_assistant.get("courses_assisted", [])
]
courses = courses_collection2.find({"course_id": {"$in": course_ids}})
return list(courses)
else:
return []
def get_course_ids():
"""Get course IDs for sample courses"""
return [course["course_id"] for course in SAMPLE_COURSES]
def get_sessions(course_id, course_title):
"""Get sessions for a given course ID"""
course = courses_collection.find_one({"course_id": course_id, "title": course_title})
if course:
return course.get("sessions", [])
return []
def create_session(new_session, course_id):
"""Create a new session for a given course ID"""
course = courses_collection2.find_one({"course_id": course_id}) | courses_collection.find_one({"course_id": course_id})
if course:
last_session_id = max((session["session_id"] for session in course["sessions"]))
last_session_id = int(last_session_id[1:])
new_session_id = last_session_id + 1
new_session["session_id"] = "S" + str(new_session_id)
courses_collection.update_one(
{"course_id": new_session["course_id"]},
{"$push": {"sessions": new_session}},
)
return True
return False
# def create_session_form(course_id):
# """Display form to create a new session and perform the creation operation"""
# st.title("Create New Session")
# if 'session_time' not in st.session_state:
# st.session_state.session_time = datetime.now().time()
# if 'show_create_session_form' not in st.session_state:
# st.session_state.show_create_session_form = False
# with st.form("create_session_form"):
# session_title = st.text_input("Session Title")
# session_date = st.date_input("Session Date", date.today(), key="session_date")
# session_time = st.time_input(
# "Session Time", st.session_state.session_time, key="session_time"
# )
# new_session_id = None
# # Generate new session ID
# course = courses_collection.find_one({"course_id": course_id})
# if course and "sessions" in course and course["sessions"]:
# last_session_id = max(
# int(session["session_id"][1:]) for session in course["sessions"]
# )
# new_session_id = last_session_id + 1
# else:
# new_session_id = 1
# if st.form_submit_button("Create Session"):
# clicked = True
# new_session = {
# "session_id": f"S{new_session_id}",
# "course_id": course_id,
# "title": session_title,
# "date": datetime.combine(session_date, session_time),
# "status": "upcoming",
# "created_at": datetime.utcnow(),
# "pre_class": {
# "resources": [],
# "completetion_required": True,
# },
# "in_class": {
# "topics": [],
# "quiz": {"title": "", "questions": 0, "duration": 0},
# "polls": [],
# },
# "post_class": {
# "assignments": [],
# },
# }
# courses_collection.update_one(
# {"course_id": course_id}, {"$push": {"sessions": new_session}}
# )
# st.success("Session created successfully!")
# st.session_state.show_create_session_form = False
def create_session_form(course_id):
"""Display form to create a new session and perform the creation operation"""
st.title("Create New Session")
if "session_time" not in st.session_state:
st.session_state.session_time = datetime.now().time()
if "show_create_session_form" not in st.session_state:
st.session_state.show_create_session_form = False
if "outcomes" not in st.session_state:
st.session_state.outcomes = [] # List to store outcomes dynamically
with st.form("create_session_form"):
session_title = st.text_input("Session Title")
session_date = st.date_input("Session Date", date.today(), key="session_date")
session_time = st.time_input("Session Time", st.session_state.session_time, key="session_time")
st.subheader("Session Learning Outcomes")
# Display all outcomes dynamically
for idx, outcome in enumerate(st.session_state.outcomes):
st.text_input(f"Outcome {idx + 1} Description", key=f"outcome_desc_{idx}")
st.selectbox(
f"Bloom's Taxonomy Level {idx + 1}",
["Remember", "Understand", "Apply", "Analyze", "Evaluate", "Create"],
key=f"bloom_level_{idx}"
)
# Button to add new outcome fields
if st.form_submit_button("Add Outcome"):
new_index = len(st.session_state.outcomes)
st.session_state.outcomes.append(
{"outcome_number": new_index + 1, "outcome_description": "", "bloom_taxanomy_level": ""}
)
st.rerun() # Refresh the form to display new fields
# Generate new session ID
new_session_id = None
course = courses_collection.find_one({"course_id": course_id})
if course and "sessions" in course and course["sessions"]:
last_session_id = max(int(session["session_id"][1:]) for session in course["sessions"])
new_session_id = last_session_id + 1
else:
new_session_id = 1
# Submit session
if st.form_submit_button("Create Session"):
new_session = {
"session_id": f"S{new_session_id}",
"course_id": course_id,
"title": session_title,
"date": datetime.combine(session_date, session_time),
"status": "upcoming",
"created_at": datetime.utcnow(),
"pre_class": {"resources": [], "completetion_required": True},
"in_class": {"topics": [], "quiz": {"title": "", "questions": 0, "duration": 0}, "polls": []},
"post_class": {"assignments": []},
"session_learning_outcomes": [
{
"outcome_number": idx + 1,
"outcome_description": st.session_state[f"outcome_desc_{idx}"],
"bloom_taxanomy_level": st.session_state[f"bloom_level_{idx}"]
}
for idx in range(len(st.session_state.outcomes))
]
}
courses_collection.update_one({"course_id": course_id}, {"$push": {"sessions": new_session}})
st.success("Session created successfully!")
st.session_state.outcomes = [] # Clear outcomes after submission
st.session_state.show_create_session_form = False
st.rerun()
# new_session_id = None
# creation_success = False
# # Generate new session ID
# course = courses_collection2.find_one({"course_id": course_id})
# if course and 'sessions' in course and course['sessions']:
# last_session_id = max((session['session_id'] for session in course['sessions']))
# last_session_id = int(last_session_id[1:])
# new_session_id = last_session_id + 1
# else:
# new_session_id = 1
# new_session = {
# "session_id": 'S' + new_session_id,
# "title": session_title,
# "date": datetime.datetime.combine(session_date, session_time).isoformat(),
# "status": "upcoming",
# "created_at": datetime.datetime.utcnow().isoformat(),
# "pre_class": {
# "resources": [],
# "completetion_required": True,
# },
# "in_class": {
# "topics": [],
# "quiz":
# {
# "title": '',
# "questions": 0,
# "duration": 0
# },
# "polls": []
# },
# "post_class": {
# "assignments": [],
# }
# }
# courses_collection2.update_one(
# {"course_id": course_id},
# {"$push": {"sessions": new_session}}
# )
# creation_success = True
# st.form_submit_button("Create Session")
# if creation_success == True:
# st.success("Session created successfully!")
# else:
load_dotenv()
MONGO_URI = os.getenv('MONGO_URI')
client = MongoClient(MONGO_URI)
db = client["novascholar_db"]
subjective_tests_collection = db["subjective_tests"]
resources_collection = db['resources']
quizzes_collection = db['quizzes']
chat_history_collection = db['chat_history']
polls_collection = db['polls']
def delete_session(course_id: str, session_id: str) -> bool:
"""Delete a session and all its associated data"""
try:
# Delete all resources for this session
resources_collection.delete_many({
"course_id": course_id,
"session_id": session_id
})
# Delete all quizzes for this session
quizzes_collection.delete_many({
"course_id": course_id,
"session_id": session_id
})
# Delete all subjective tests
subjective_tests_collection.delete_many({
"course_id": course_id,
"session_id": session_id
})
# Delete chat history
chat_history_collection.delete_many({
"course_id": course_id,
"session_id": session_id
})
# Delete session polls
polls_collection.delete_many({
"course_id": course_id,
"session_id": session_id
})
# Finally remove session from course
result = courses_collection.update_one(
{"course_id": course_id},
{"$pull": {"sessions": {"session_id": session_id}}}
)
return result.modified_count > 0
except Exception as e:
print(f"Error deleting session: {e}")
return False
def get_new_student_id():
"""Generate a new student ID by incrementing the last student ID"""
last_student = students_collection.find_one(sort=[("SID", -1)])
if last_student:
last_student_id = int(last_student["SID"][1:])
new_student_id = f"S{last_student_id + 1}"
else:
new_student_id = "S101"
return new_student_id
def get_new_faculty_id():
"""Generate a new faculty ID by incrementing the last faculty ID"""
last_faculty = faculty_collection.find_one(sort=[("TID", -1)])
if last_faculty:
last_faculty_id = int(last_faculty["TID"][1:])
new_faculty_id = f"T{last_faculty_id + 1}"
else:
new_faculty_id = "T101"
return new_faculty_id
def get_new_course_id():
"""Generate a new course ID by incrementing the last course ID"""
last_course = courses_collection2.find_one(sort=[("course_id", -1)])
if last_course:
last_course_id = int(last_course["course_id"][2:])
new_course_id = f"CS{last_course_id + 1}"
else:
new_course_id = "CS101"
return new_course_id
# def register_page():
# st.title("Register")
# if "user_type" not in st.session_state:
# st.session_state.user_type = "student"
# # Select user type
# st.session_state.user_type = st.selectbox(
# "Select User Type", ["student", "faculty", "research_assistant"]
# )
# user_type = st.session_state.user_type
# print(user_type)
# with st.form("register_form"):
# # user_type = st.selectbox("Select User Type", ["student", "faculty", "research_assistant"])
# # print(user_type)
# full_name = st.text_input("Full Name")
# password = st.text_input("Password", type="password")
# confirm_password = st.text_input("Confirm Password", type="password")
# if user_type == "student":
# # Fetch courses for students to select from
# courses = list(courses_collection2.find({}, {"course_id": 1, "title": 1}))
# course_options = [
# f"{course['title']} ({course['course_id']})" for course in courses
# ]
# selected_courses = st.multiselect("Available Courses", course_options)
# submit = st.form_submit_button("Register")
# if submit:
# if password == confirm_password:
# hashed_password = generate_password_hash(password)
# if user_type == "student":
# new_student_id = get_new_student_id()
# enrolled_courses = [
# {
# "course_id": course.split("(")[-1][:-1],
# "title": course.split(" (")[0],
# }
# for course in selected_courses
# ]
# students_collection.insert_one(
# {
# "SID": new_student_id,
# "full_name": full_name,
# "password": hashed_password,
# "enrolled_courses": enrolled_courses,
# "created_at": datetime.utcnow(),
# }
# )
# st.success(
# f"Student registered successfully with ID: {new_student_id}"
# )
# elif user_type == "faculty":
# new_faculty_id = get_new_faculty_id()
# faculty_collection.insert_one(
# {
# "TID": new_faculty_id,
# "full_name": full_name,
# "password": hashed_password,
# "courses_taught": [],
# "created_at": datetime.utcnow(),
# }
# )
# st.success(
# f"Faculty registered successfully with ID: {new_faculty_id}"
# )
# elif user_type == "research_assistant":
# research_assistants_collection.insert_one(
# {
# "full_name": full_name,
# "password": hashed_password,
# "created_at": datetime.utcnow(),
# }
# )
# st.success("Research Assistant registered successfully!")
# else:
# st.error("Passwords do not match")
def get_new_analyst_id():
"""Generate a new analyst ID by incrementing the last analyst ID"""
last_analyst = analysts_collection.find_one(sort=[("AID", -1)])
if last_analyst:
last_id = int(last_analyst["AID"][1:])
new_id = f"A{last_id + 1}"
else:
new_id = "A1"
return new_id
# def register_page():
# st.title("Register")
# if "user_type" not in st.session_state:
# st.session_state.user_type = "student"
# # Select user type
# st.session_state.user_type = st.selectbox(
# "Please select your Role", ["student", "faculty", "research_assistant", "analyst"]
# )
# user_type = st.session_state.user_type
# print(user_type)
# with st.form("register_form"):
# full_name = st.text_input("Full Name")
# password = st.text_input("Password", type="password")
# confirm_password = st.text_input("Confirm Password", type="password")
# if user_type == "student":
# # Fetch courses for students to select from
# courses = list(courses_collection.find({}, {"course_id": 1, "title": 1}))
# course_options = [
# f"{course['title']} ({course['course_id']})" for course in courses
# ]
# selected_courses = st.multiselect("Available Courses", course_options)
# submit = st.form_submit_button("Register")
# if submit:
# if password == confirm_password:
# hashed_password = generate_password_hash(password)
# if user_type == "student":
# new_student_id = get_new_student_id()
# enrolled_courses = [
# {
# "course_id": course.split("(")[-1][:-1],
# "title": course.split(" (")[0],
# }
# for course in selected_courses
# ]
# students_collection.insert_one(
# {
# "SID": new_student_id,
# "full_name": full_name,
# "password": hashed_password,
# "enrolled_courses": enrolled_courses,
# "created_at": datetime.utcnow(),
# }
# )
# st.success(
# f"Student registered successfully with ID: {new_student_id}"
# )
# elif user_type == "faculty":
# new_faculty_id = get_new_faculty_id()
# faculty_collection.insert_one(
# {
# "TID": new_faculty_id,
# "full_name": full_name,
# "password": hashed_password,
# "courses_taught": [],
# "created_at": datetime.utcnow(),
# }
# )
# st.success(
# f"Faculty registered successfully with ID: {new_faculty_id}"
# )
# elif user_type == "research_assistant":
# research_assistants_collection.insert_one(
# {
# "full_name": full_name,
# "password": hashed_password,
# "created_at": datetime.utcnow(),
# }
# )
# st.success("Research Assistant registered successfully!")
# elif user_type == "analyst":
# # new_analyst_id = get_new_analyst_id()
# analysts_collection.insert_one(
# {
# # "AID": new_analyst_id,
# "full_name": full_name,
# "password": hashed_password,
# "created_at": datetime.utcnow(),
# }
# )
# st.success("Analyst registered successfully!")
# else:
# st.error("Passwords do not match")
def register_page():
st.title("Register for NOVAScholar")
if "user_type" not in st.session_state:
st.session_state.user_type = "student"
# Select user type
st.session_state.user_type = st.selectbox(
"Please select your Role",
["Student", "Faculty", "Research Assistant", "Analyst"]
)
user_type = st.session_state.user_type.lower().replace(" ", "_")
with st.form("register_form"):
col1, col2 = st.columns(2)
with col1:
full_name = st.text_input("Full Name")
email = st.text_input("Institutional Email")
phone = st.text_input("Phone Number")
with col2:
password = st.text_input("Password", type="password")
confirm_password = st.text_input("Confirm Password", type="password")
if user_type == "student":
courses = list(courses_collection.find({}, {"course_id": 1, "title": 1}))
course_options = [f"{course['title']} ({course['course_id']})" for course in courses]
selected_courses = st.multiselect("Available Courses", course_options)
submit = st.form_submit_button("Register")
if submit:
# Validate email
email_valid, email_msg = validate_email(email)
if not email_valid:
st.error(email_msg)
return
# Validate phone
phone_valid, phone_msg = validate_phone(phone)
if not phone_valid:
st.error(phone_msg)
return
# Validate password match
if password != confirm_password:
st.error("Passwords do not match")
return
# Extract username from email
username = extract_username(email)
# Check if username already exists
if user_type == "student":
existing_user = students_collection.find_one({"username": username})
elif user_type == "faculty":
existing_user = faculty_collection.find_one({"username": username})
elif user_type == "research_assistant":
existing_user = research_assistants_collection.find_one({"username": username})
elif user_type == "analyst":
existing_user = analysts_collection.find_one({"username": username})
if existing_user:
st.error("A user with this email already exists")
return
# Hash password and create user
hashed_password = generate_password_hash(password)
user_data = {
"username": username,
"full_name": full_name,
"email": email,
"phone": phone,
"password": hashed_password,
"created_at": datetime.utcnow()
}
if user_type == "student":
new_student_id = get_new_student_id()
enrolled_courses = [
{
"course_id": course.split("(")[-1][:-1],
"title": course.split(" (")[0],
}
for course in selected_courses
]
user_data["SID"] = new_student_id
user_data["enrolled_courses"] = enrolled_courses
students_collection.insert_one(user_data)
st.success(f"Student registered successfully! Your username is: {username}")
elif user_type == "faculty":
new_faculty_id = get_new_faculty_id()
user_data["TID"] = new_faculty_id
user_data["courses_taught"] = []
faculty_collection.insert_one(user_data)
st.success(f"Faculty registered successfully! Your username is: {username}")
elif user_type == "research_assistant":
research_assistants_collection.insert_one(user_data)
st.success(f"Research Assistant registered successfully! Your username is: {username}")
elif user_type == "analyst":
analysts_collection.insert_one(user_data)
st.success(f"Analyst registered successfully! Your username is: {username}")
# Create Course feature
# def create_course_form2(faculty_name, faculty_id):
# """Display enhanced form to create a new course with AI-generated content"""
# st.title("Create New Course")
# if 'course_plan' not in st.session_state:
# st.session_state.course_plan = None
# if 'edit_mode' not in st.session_state:
# st.session_state.edit_mode = False
# # Initial Course Creation Form
# if not st.session_state.course_plan:
# with st.form("initial_course_form"):
# col1, col2 = st.columns(2)
# with col1:
# course_name = st.text_input("Course Name", placeholder="e.g., Introduction to Computer Science")
# faculty_info = st.text_input("Faculty", value=faculty_name, disabled=True)
# with col2:
# duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
# start_date = st.date_input("Start Date")
# generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
# if generate_button and course_name:
# with st.spinner("Generating course structure..."):
# try:
# course_plan = generate_perplexity_response(PERPLEXITY_API_KEY, course_name)
# # print(course_plan)
# st.session_state.course_plan = json.loads(course_plan)
# st.session_state.start_date = start_date
# st.session_state.duration_weeks = duration_weeks
# st.rerun()
# except Exception as e:
# st.error(f"Error generating course structure: {e}")
# # Display and Edit Generated Course Content
# if st.session_state.course_plan:
# with st.expander("Course Overview", expanded=True):
# if not st.session_state.edit_mode:
# st.subheader(st.session_state.course_plan['course_title'])
# st.write(st.session_state.course_plan['course_description'])
# edit_button = st.button("Edit Course Details", use_container_width=True)
# if edit_button:
# st.session_state.edit_mode = True
# st.rerun()
# else:
# with st.form("edit_course_details"):
# st.session_state.course_plan['course_title'] = st.text_input(
# "Course Title",
# value=st.session_state.course_plan['course_title']
# )
# st.session_state.course_plan['course_description'] = st.text_area(
# "Course Description",
# value=st.session_state.course_plan['course_description']
# )
# if st.form_submit_button("Save Course Details"):
# st.session_state.edit_mode = False
# st.rerun()
# # Display Modules and Sessions
# st.subheader("Course Modules and Sessions")
# start_date = st.session_state.start_date
# current_date = start_date
# all_sessions = []
# for module_idx, module in enumerate(st.session_state.course_plan['modules']):
# with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
# # Edit module title
# new_module_title = st.text_input(
# f"Module {module_idx + 1} Title",
# value=module['module_title'],
# key=f"module_{module_idx}"
# )
# module['module_title'] = new_module_title
# for sub_idx, sub_module in enumerate(module['sub_modules']):
# st.markdown(f"### 📖 {sub_module['title']}")
# # Create sessions for each topic
# for topic_idx, topic in enumerate(sub_module['topics']):
# session_key = f"session_{module_idx}_{sub_idx}_{topic_idx}"
# with st.container():
# col1, col2, col3 = st.columns([3, 2, 1])
# with col1:
# new_topic = st.text_input(
# "Topic",
# value=topic,
# key=f"{session_key}_topic"
# )
# sub_module['topics'][topic_idx] = new_topic
# with col2:
# session_date = st.date_input(
# "Session Date",
# value=current_date,
# key=f"{session_key}_date"
# )
# with col3:
# session_status = st.selectbox(
# "Status",
# options=["upcoming", "in-progress", "completed"],
# key=f"{session_key}_status"
# )
# # Create session object
# session = {
# "session_id": str(ObjectId()),
# "title": new_topic,
# "date": datetime.combine(session_date, datetime.min.time()),
# "status": session_status,
# "module_name": module['module_title'],
# "created_at": datetime.utcnow(),
# "pre_class": {
# "resources": [],
# "completion_required": True
# },
# "in_class": {
# "quiz": [],
# "polls": []
# },
# "post_class": {
# "assignments": []
# }
# }
# all_sessions.append(session)
# current_date = session_date + timedelta(days=7)
# new_course_id = get_new_course_id()
# course_title = st.session_state.course_plan['course_title']
# # Final Save Button
# if st.button("Save Course", type="primary", use_container_width=True):
# try:
# course_doc = {
# "course_id": new_course_id,
# "title": course_title,
# "description": st.session_state.course_plan['course_description'],
# "faculty": faculty_name,
# "faculty_id": faculty_id,
# "duration": f"{st.session_state.duration_weeks} weeks",
# "start_date": datetime.combine(st.session_state.start_date, datetime.min.time()),
# "created_at": datetime.utcnow(),
# "sessions": all_sessions
# }
# # Insert into database
# courses_collection.insert_one(course_doc)
# st.success("Course successfully created!")
# # Update faculty collection
# faculty_collection.update_one(
# {"_id": st.session_state.user_id},
# {
# "$push": {
# "courses_taught": {
# "course_id": new_course_id,
# "title": course_title,
# }
# }
# },
# )
# # Clear session state
# st.session_state.course_plan = None
# st.session_state.edit_mode = False
# # Optional: Add a button to view the created course
# if st.button("View Course"):
# # Add navigation logic here
# pass
# except Exception as e:
# st.error(f"Error saving course: {e}")
def remove_json_backticks(json_string):
"""Remove backticks and 'json' from the JSON object string"""
return json_string.replace("```json", "").replace("```", "").strip()
def create_course_form(faculty_name, faculty_id):
"""Display enhanced form to create a new course with AI-generated content and resources"""
st.title("Create New Course")
if 'course_plan' not in st.session_state:
st.session_state.course_plan = None
if 'edit_mode' not in st.session_state:
st.session_state.edit_mode = False
if 'resources_map' not in st.session_state:
st.session_state.resources_map = {}
if 'start_date' not in st.session_state:
st.session_state.start_date = None
if 'duration_weeks' not in st.session_state:
st.session_state.duration_weeks = None
if 'sessions_per_week' not in st.session_state:
st.session_state.sessions_per_week = None
# Initial Course Creation Form
if not st.session_state.course_plan:
with st.form("initial_course_form"):
col1, col2 = st.columns(2)
with col1:
course_name = st.text_input("Course Name", placeholder="e.g., Introduction to Computer Science")
faculty_info = st.text_input("Faculty", value=faculty_name, disabled=True)
sessions_per_week = st.number_input("Sessions Per Week", min_value=1, max_value=5, value=2)
with col2:
duration_weeks = st.number_input("Duration (weeks)", min_value=1, max_value=16, value=12)
start_date = st.date_input("Start Date")
course_description = st.text_area("Course Description", placeholder="Enter a brief course description here")
generate_button = st.form_submit_button("Generate Course Structure", use_container_width=True)
if generate_button and course_name:
create_course(course_name, duration_weeks, faculty_name, sessions_per_week, start_date, course_description, faculty_id)
#update faculty list of courses
# with st.spinner("Generating course structure and resources..."):
# try:
# # Generate course plan with resources
# course_plan = generate_perplexity_response(
# PERPLEXITY_API_KEY,
# course_name,
# duration_weeks,
# sessions_per_week
# )
# try:
# course_plan_json = json.loads(course_plan)
# validate_course_plan(course_plan_json)
# st.session_state.course_plan = course_plan_json
# except (json.JSONDecodeError, ValueError) as e:
# st.error(f"Error in course plan structure: {e}")
# return
# st.session_state.start_date = start_date
# st.session_state.duration_weeks = duration_weeks
# st.session_state.sessions_per_week = sessions_per_week
# # Generate resources for all sessions
# session_titles = []
# for module in st.session_state.course_plan['modules']:
# for sub_module in module['sub_modules']:
# for topic in sub_module['topics']:
# # session_titles.append(topic['title'])
# # session_titles.append(topic)
# if isinstance(topic, dict):
# session_titles.append(topic['title'])
# else:
# session_titles.append(topic)
# # In generate_session_resources function, add validation:
# if not session_titles:
# return json.dumps({"session_resources": []})
# resources_response = generate_session_resources(PERPLEXITY_API_KEY, session_titles)
# without_backticks = remove_json_backticks(resources_response)
# resources = json.loads(without_backticks)
# st.session_state.resources_map = {
# resource['session_title']: resource['resources']
# for resource in resources['session_resources']
# }
# # Add error handling for the resources map
# # if st.session_state.resources_map is None:
# # st.session_state.resources_map = {}
# st.rerun()
# except Exception as e:
# st.error(f"Error generating course structure: {e}")
# # Display and Edit Generated Course Content
# if st.session_state.course_plan:
# with st.expander("Course Overview", expanded=True):
# if not st.session_state.edit_mode:
# st.subheader(st.session_state.course_plan['course_title'])
# st.write(st.session_state.course_plan['course_description'])
# col1, col2, col3 = st.columns(3)
# with col1:
# st.write(f"**Start Date:** {st.session_state.start_date}")
# with col2:
# st.write(f"**Duration (weeks):** {st.session_state.duration_weeks}")
# with col3:
# st.write(f"**Sessions Per Week:** {st.session_state.sessions_per_week}")
# edit_button = st.button("Edit Course Details", use_container_width=True)
# if edit_button:
# st.session_state.edit_mode = True
# st.rerun()
# else:
# with st.form("edit_course_details"):
# st.session_state.course_plan['course_title'] = st.text_input(
# "Course Title",
# value=st.session_state.course_plan['course_title']
# )
# st.session_state.course_plan['course_description'] = st.text_area(
# "Course Description",
# value=st.session_state.course_plan['course_description']
# )
# if st.form_submit_button("Save Course Details"):
# st.session_state.edit_mode = False
# st.rerun()
# # Display Modules and Sessions
# st.subheader("Course Modules and Sessions")
# start_date = st.session_state.start_date
# current_date = start_date
# all_sessions = []
# for module_idx, module in enumerate(st.session_state.course_plan['modules']):
# with st.expander(f"📚 Module {module_idx + 1}: {module['module_title']}", expanded=True):
# # Edit module title
# new_module_title = st.text_input(
# f"Edit Module Title",
# value=module['module_title'],
# key=f"module_{module_idx}"
# )
# module['module_title'] = new_module_title
# for sub_idx, sub_module in enumerate(module['sub_modules']):
# st.markdown("
", unsafe_allow_html=True) # Add gap between sessions
# # st.markdown(f"### 📖 {sub_module['title']}")
# st.markdown(f'