Spaces:
Build error
Build error
import os | |
import streamlit as st | |
import pandas as pd | |
import google.generativeai as genai | |
from google.generativeai.types import GenerationConfig | |
import datetime | |
import uuid | |
import json | |
import smtplib | |
from email.mime.text import MIMEText | |
from email.mime.multipart import MIMEMultipart | |
# Configuration | |
os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY', 'your_key_here') | |
genai.configure(api_key=os.environ['GOOGLE_API_KEY']) | |
# Load and prepare data | |
def load_scholarships(): | |
try: | |
df = pd.read_csv("scholarships_data.csv", quotechar='"', quoting=1) | |
df = df.map(lambda x: x.strip() if isinstance(x, str) else x) | |
df.rename(columns=lambda x: x.strip(), inplace=True) | |
return df | |
except Exception as e: | |
st.error(f"Error loading data: {str(e)}") | |
st.stop() | |
# Convert CSV to RAG context | |
def create_rag_context(df): | |
context = "Scholarship Database:\n\n" | |
for _, row in df.iterrows(): | |
context += f"""Scholarship Name: {row['Scholarship Name']} | |
Eligibility: {row['Eligibility']} | |
Deadline: {row['Deadline']} | |
Link: {row['Link']}\n\n""" | |
return context | |
# Initialize Gemini model | |
def get_rag_model(): | |
return genai.GenerativeModel('gemini-1.5-pro') | |
# Custom CSS for styling | |
def load_css(): | |
st.markdown(""" | |
<style> | |
/* Custom color for results */ | |
.stMarkdown p, .stMarkdown ul, .stMarkdown ol { | |
color: rgb(1, 27, 29); /* Custom color for results */ | |
} | |
/* Card styling */ | |
.scholarship-card { | |
background-color: #f8f9fa; | |
border-radius: 10px; | |
padding: 20px; | |
margin-bottom: 20px; | |
border-left: 5px solid #4CAF50; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
} | |
/* Tabs styling */ | |
.stTabs [data-baseweb="tab-list"] { | |
gap: 8px; | |
} | |
.stTabs [data-baseweb="tab"] { | |
height: 50px; | |
white-space: pre-wrap; | |
background-color: #f0f2f6; | |
border-radius: 4px 4px 0px 0px; | |
gap: 1px; | |
padding-top: 10px; | |
padding-bottom: 10px; | |
} | |
.stTabs [aria-selected="true"] { | |
background-color: #4CAF50; | |
color: white; | |
} | |
/* Button styling */ | |
.stButton>button { | |
border-radius: 20px; | |
font-weight: 500; | |
} | |
/* Progress indicator */ | |
.progress-container { | |
display: flex; | |
justify-content: space-between; | |
margin-bottom: 30px; | |
} | |
.progress-step { | |
text-align: center; | |
flex: 1; | |
} | |
.progress-step-number { | |
width: 30px; | |
height: 30px; | |
border-radius: 50%; | |
background-color: #ddd; | |
color: white; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
margin: 0 auto 10px auto; | |
} | |
.progress-step.active .progress-step-number { | |
background-color: #4CAF50; | |
} | |
.progress-step-title { | |
font-size: 0.8rem; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# User management functions | |
def load_users(): | |
try: | |
with open("users.json", "r") as f: | |
return json.load(f) | |
except (FileNotFoundError, json.JSONDecodeError): | |
return {} | |
def save_users(users): | |
with open("users.json", "w") as f: | |
json.dump(users, f) | |
def authenticate(username, password): | |
users = load_users() | |
if username in users and users[username]["password"] == password: | |
return True | |
return False | |
def register_user(username, password, email): | |
users = load_users() | |
if username in users: | |
return False | |
users[username] = { | |
"password": password, | |
"email": email, | |
"profile": {}, | |
"saved_scholarships": [], | |
"applications": {}, | |
"created_at": datetime.datetime.now().isoformat() | |
} | |
save_users(users) | |
return True | |
# Saved scholarship functions | |
def save_scholarship(username, scholarship_name, deadline): | |
users = load_users() | |
if username in users: | |
# Check if already saved | |
if scholarship_name not in [s["name"] for s in users[username]["saved_scholarships"]]: | |
users[username]["saved_scholarships"].append({ | |
"name": scholarship_name, | |
"deadline": deadline, | |
"saved_at": datetime.datetime.now().isoformat(), | |
"status": "Saved" | |
}) | |
save_users(users) | |
return True | |
return False | |
def get_saved_scholarships(username): | |
users = load_users() | |
if username in users: | |
return users[username]["saved_scholarships"] | |
return [] | |
def update_scholarship_status(username, scholarship_name, status): | |
users = load_users() | |
if username in users: | |
for scholarship in users[username]["saved_scholarships"]: | |
if scholarship["name"] == scholarship_name: | |
scholarship["status"] = status | |
save_users(users) | |
return True | |
return False | |
# Application tracking functions | |
def track_application(username, scholarship_name, status="Started"): | |
users = load_users() | |
if username in users: | |
if scholarship_name not in users[username]["applications"]: | |
users[username]["applications"][scholarship_name] = { | |
"status": status, | |
"progress": 0, | |
"started_at": datetime.datetime.now().isoformat(), | |
"form_data": {} | |
} | |
save_users(users) | |
return True | |
return False | |
def update_application(username, scholarship_name, form_data, progress): | |
users = load_users() | |
if username in users and scholarship_name in users[username]["applications"]: | |
users[username]["applications"][scholarship_name]["form_data"] = form_data | |
users[username]["applications"][scholarship_name]["progress"] = progress | |
users[username]["applications"][scholarship_name]["updated_at"] = datetime.datetime.now().isoformat() | |
save_users(users) | |
return True | |
return False | |
def get_application_progress(username, scholarship_name): | |
users = load_users() | |
if username in users and scholarship_name in users[username]["applications"]: | |
return users[username]["applications"][scholarship_name] | |
return None | |
# Email notification function | |
def send_deadline_notification(email, scholarship_name, deadline_date): | |
try: | |
sender_email = os.getenv('APP_EMAIL', '[email protected]') | |
password = os.getenv('APP_EMAIL_PASSWORD', 'app_password') | |
msg = MIMEMultipart() | |
msg['From'] = sender_email | |
msg['To'] = email | |
msg['Subject'] = f"Deadline Reminder: {scholarship_name}" | |
body = f""" | |
<html> | |
<body> | |
<h2>Deadline Reminder</h2> | |
<p>Hello,</p> | |
<p>This is a reminder that the application deadline for <b>{scholarship_name}</b> is approaching.</p> | |
<p>Deadline: <b>{deadline_date}</b></p> | |
<p>Please log in to the AI Scholarship Advisor to complete your application.</p> | |
<p>Best of luck!</p> | |
</body> | |
</html> | |
""" | |
msg.attach(MIMEText(body, 'html')) | |
server = smtplib.SMTP('smtp.gmail.com', 587) | |
server.starttls() | |
server.login(sender_email, password) | |
server.send_message(msg) | |
server.quit() | |
return True | |
except Exception as e: | |
st.error(f"Failed to send email: {str(e)}") | |
return False | |
# Profile management | |
def update_user_profile(username, profile_data): | |
users = load_users() | |
if username in users: | |
users[username]["profile"] = profile_data | |
save_users(users) | |
return True | |
return False | |
def get_user_profile(username): | |
users = load_users() | |
if username in users: | |
return users[username]["profile"] | |
return {} | |
# Forum functions | |
def load_forum_posts(): | |
try: | |
with open("forum_posts.json", "r") as f: | |
return json.load(f) | |
except (FileNotFoundError, json.JSONDecodeError): | |
return [] | |
def save_forum_posts(posts): | |
with open("forum_posts.json", "w") as f: | |
json.dump(posts, f) | |
def add_forum_post(username, title, content, category): | |
posts = load_forum_posts() | |
post_id = str(uuid.uuid4()) | |
posts.append({ | |
"id": post_id, | |
"username": username, | |
"title": title, | |
"content": content, | |
"category": category, | |
"created_at": datetime.datetime.now().isoformat(), | |
"replies": [] | |
}) | |
save_forum_posts(posts) | |
return post_id | |
def add_forum_reply(post_id, username, content): | |
posts = load_forum_posts() | |
for post in posts: | |
if post["id"] == post_id: | |
reply_id = str(uuid.uuid4()) | |
post["replies"].append({ | |
"id": reply_id, | |
"username": username, | |
"content": content, | |
"created_at": datetime.datetime.now().isoformat() | |
}) | |
save_forum_posts(posts) | |
return reply_id | |
return None | |
# Create profile completion wizard | |
def render_profile_wizard(username): | |
st.markdown("### Complete Your Profile") | |
# Progress indicator | |
st.markdown(""" | |
<div class="progress-container"> | |
<div class="progress-step active"> | |
<div class="progress-step-number">1</div> | |
<div class="progress-step-title">Personal Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">2</div> | |
<div class="progress-step-title">Academic Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">3</div> | |
<div class="progress-step-title">Financial Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">4</div> | |
<div class="progress-step-title">Preferences</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
profile = get_user_profile(username) | |
step = st.session_state.get("profile_step", 1) | |
if step == 1: | |
with st.form("personal_info"): | |
st.markdown("#### Step 1: Personal Information") | |
first_name = st.text_input("First Name", profile.get("first_name", "")) | |
last_name = st.text_input("Last Name", profile.get("last_name", "")) | |
dob = st.date_input("Date of Birth", value=datetime.datetime.strptime(profile.get("dob", "2000-01-01"), "%Y-%m-%d").date() if "dob" in profile else datetime.date(2000, 1, 1)) | |
gender = st.selectbox("Gender", ["Male", "Female", "Other", "Prefer not to say"], index=["Male", "Female", "Other", "Prefer not to say"].index(profile.get("gender", "Prefer not to say")) if "gender" in profile else 3) | |
citizenship = st.selectbox("Citizenship", ["India", "Other"], index=["India", "Other"].index(profile.get("citizenship", "India")) if "citizenship" in profile else 0) | |
if st.form_submit_button("Next"): | |
profile.update({ | |
"first_name": first_name, | |
"last_name": last_name, | |
"dob": dob.strftime("%Y-%m-%d"), | |
"gender": gender, | |
"citizenship": citizenship | |
}) | |
update_user_profile(username, profile) | |
st.session_state.profile_step = 2 | |
st.rerun() | |
elif step == 2: | |
st.markdown(""" | |
<div class="progress-container"> | |
<div class="progress-step active"> | |
<div class="progress-step-number">1</div> | |
<div class="progress-step-title">Personal Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">2</div> | |
<div class="progress-step-title">Academic Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">3</div> | |
<div class="progress-step-title">Financial Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">4</div> | |
<div class="progress-step-title">Preferences</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
with st.form("academic_info"): | |
st.markdown("#### Step 2: Academic Information") | |
education = st.selectbox("Education Level", | |
["High School", "Undergraduate", "Postgraduate", "PhD"], | |
index=["High School", "Undergraduate", "Postgraduate", "PhD"].index(profile.get("education", "Undergraduate")) if "education" in profile else 1) | |
institution = st.text_input("Current Institution", profile.get("institution", "")) | |
field_of_study = st.text_input("Field of Study", profile.get("field_of_study", "")) | |
cgpa = st.number_input("CGPA (out of 10)", 0.0, 10.0, float(profile.get("cgpa", 8.0)) if "cgpa" in profile else 8.0, 0.1) | |
achievements = st.text_area("Academic Achievements", profile.get("achievements", "")) | |
col1, col2 = st.columns(2) | |
with col1: | |
if st.form_submit_button("Previous"): | |
st.session_state.profile_step = 1 | |
st.rerun() | |
with col2: | |
if st.form_submit_button("Next"): | |
profile.update({ | |
"education": education, | |
"institution": institution, | |
"field_of_study": field_of_study, | |
"cgpa": cgpa, | |
"achievements": achievements | |
}) | |
update_user_profile(username, profile) | |
st.session_state.profile_step = 3 | |
st.rerun() | |
elif step == 3: | |
st.markdown(""" | |
<div class="progress-container"> | |
<div class="progress-step active"> | |
<div class="progress-step-number">1</div> | |
<div class="progress-step-title">Personal Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">2</div> | |
<div class="progress-step-title">Academic Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">3</div> | |
<div class="progress-step-title">Financial Info</div> | |
</div> | |
<div class="progress-step"> | |
<div class="progress-step-number">4</div> | |
<div class="progress-step-title">Preferences</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
with st.form("financial_info"): | |
st.markdown("#### Step 3: Financial Information") | |
income = st.number_input("Annual Family Income (₹)", 0, 10000000, int(profile.get("income", 300000)) if "income" in profile else 300000, 10000) | |
category = st.selectbox("Category", | |
["General", "OBC", "SC", "ST", "EWS", "Minority"], | |
index=["General", "OBC", "SC", "ST", "EWS", "Minority"].index(profile.get("category", "General")) if "category" in profile else 0) | |
financial_need = st.slider("Financial Need Level", 1, 10, int(profile.get("financial_need", 5)) if "financial_need" in profile else 5) | |
col1, col2 = st.columns(2) | |
with col1: | |
if st.form_submit_button("Previous"): | |
st.session_state.profile_step = 2 | |
st.rerun() | |
with col2: | |
if st.form_submit_button("Next"): | |
profile.update({ | |
"income": income, | |
"category": category, | |
"financial_need": financial_need | |
}) | |
update_user_profile(username, profile) | |
st.session_state.profile_step = 4 | |
st.rerun() | |
elif step == 4: | |
st.markdown(""" | |
<div class="progress-container"> | |
<div class="progress-step active"> | |
<div class="progress-step-number">1</div> | |
<div class="progress-step-title">Personal Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">2</div> | |
<div class="progress-step-title">Academic Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">3</div> | |
<div class="progress-step-title">Financial Info</div> | |
</div> | |
<div class="progress-step active"> | |
<div class="progress-step-number">4</div> | |
<div class="progress-step-title">Preferences</div> | |
</div> | |
</div> | |
""", unsafe_allow_html=True) | |
with st.form("preferences"): | |
st.markdown("#### Step 4: Preferences") | |
preferred_locations = st.multiselect( | |
"Preferred Study Locations", | |
["India", "USA", "UK", "Canada", "Australia", "Germany", "Japan", "Singapore", "Other"], | |
profile.get("preferred_locations", ["India"]) | |
) | |
study_interests = st.multiselect( | |
"Fields of Interest", | |
["Engineering", "Medicine", "Law", "Business", "Arts", "Science", "Humanities", "Social Sciences", "Other"], | |
profile.get("study_interests", ["Engineering"]) | |
) | |
career_goals = st.text_area("Career Goals", profile.get("career_goals", "")) | |
extracurricular = st.text_area("Extracurricular Activities", profile.get("extracurricular", "")) | |
notification_preference = st.checkbox("Receive Email Notifications", value=profile.get("notification_preference", True)) | |
col1, col2 = st.columns(2) | |
with col1: | |
if st.form_submit_button("Previous"): | |
st.session_state.profile_step = 3 | |
st.rerun() | |
with col2: | |
if st.form_submit_button("Complete Profile"): | |
profile.update({ | |
"preferred_locations": preferred_locations, | |
"study_interests": study_interests, | |
"career_goals": career_goals, | |
"extracurricular": extracurricular, | |
"notification_preference": notification_preference, | |
"profile_completed": True, | |
"completed_at": datetime.datetime.now().isoformat() | |
}) | |
update_user_profile(username, profile) | |
st.session_state.profile_complete = True | |
st.success("Profile completed successfully!") | |
st.rerun() | |
# Auto-fill application form | |
def render_application_form(username, scholarship_name, df): | |
st.markdown(f"### Application Form: {scholarship_name}") | |
# Get scholarship details | |
scholarship_row = df[df['Scholarship Name'] == scholarship_name].iloc[0] | |
deadline = scholarship_row['Deadline'] | |
eligibility = scholarship_row['Eligibility'] | |
link = scholarship_row['Link'] | |
st.info(f"Deadline: {deadline}") | |
st.markdown(f"Eligibility: {eligibility}") | |
# Get user profile for auto-fill | |
profile = get_user_profile(username) | |
# Get existing application data if any | |
app_data = get_application_progress(username, scholarship_name) | |
form_data = app_data["form_data"] if app_data and "form_data" in app_data else {} | |
with st.form("application_form"): | |
st.markdown("#### Personal Information") | |
col1, col2 = st.columns(2) | |
with col1: | |
first_name = st.text_input("First Name", value=form_data.get("first_name", profile.get("first_name", ""))) | |
last_name = st.text_input("Last Name", value=form_data.get("last_name", profile.get("last_name", ""))) | |
with col2: | |
email = st.text_input("Email", value=form_data.get("email", profile.get("email", ""))) | |
phone = st.text_input("Phone Number", value=form_data.get("phone", "")) | |
st.markdown("#### Academic Information") | |
col1, col2 = st.columns(2) | |
with col1: | |
institution = st.text_input("Institution", value=form_data.get("institution", profile.get("institution", ""))) | |
education = st.selectbox("Education Level", | |
["High School", "Undergraduate", "Postgraduate", "PhD"], | |
index=["High School", "Undergraduate", "Postgraduate", "PhD"].index(form_data.get("education", profile.get("education", "Undergraduate"))) if "education" in form_data or "education" in profile else 1) | |
with col2: | |
field_of_study = st.text_input("Field of Study", value=form_data.get("field_of_study", profile.get("field_of_study", ""))) | |
cgpa = st.number_input("CGPA", 0.0, 10.0, float(form_data.get("cgpa", profile.get("cgpa", 8.0))) if "cgpa" in form_data or "cgpa" in profile else 8.0, 0.1) | |
st.markdown("#### Essay Questions") | |
why_deserve = st.text_area("Why do you deserve this scholarship? (200-300 words)", value=form_data.get("why_deserve", "")) | |
career_goals = st.text_area("Describe your career goals (200-300 words)", value=form_data.get("career_goals", profile.get("career_goals", ""))) | |
st.markdown("#### Additional Documents") | |
st.file_uploader("Upload Resume/CV (PDF)", type=["pdf"]) | |
st.file_uploader("Upload Transcripts (PDF)", type=["pdf"]) | |
st.file_uploader("Upload Recommendation Letter (PDF)", type=["pdf"]) | |
# Form actions | |
col1, col2, col3 = st.columns(3) | |
with col1: | |
save_draft = st.form_submit_button("Save as Draft") | |
with col2: | |
submit_later = st.form_submit_button("Submit Later") | |
with col3: | |
submit_app = st.form_submit_button("Submit Application") | |
# Handle form submission | |
if save_draft or submit_later or submit_app: | |
new_form_data = { | |
"first_name": first_name, | |
"last_name": last_name, | |
"email": email, | |
"phone": phone, | |
"institution": institution, | |
"education": education, | |
"field_of_study": field_of_study, | |
"cgpa": cgpa, | |
"why_deserve": why_deserve, | |
"career_goals": career_goals | |
} | |
progress = 25 # Initial progress | |
# Calculate form completion progress | |
if first_name and last_name and email and phone: | |
progress += 25 | |
if institution and field_of_study: | |
progress += 25 | |
if why_deserve and len(why_deserve) > 100: | |
progress += 15 | |
if career_goals and len(career_goals) > 100: | |
progress += 10 | |
# Update application status | |
status = "Draft" | |
if submit_app: | |
status = "Submitted" | |
progress = 100 | |
elif submit_later: | |
status = "In Progress" | |
# Create or update application tracking | |
if app_data: | |
update_application(username, scholarship_name, new_form_data, progress) | |
else: | |
track_application(username, scholarship_name, status) | |
update_application(username, scholarship_name, new_form_data, progress) | |
# Update scholarship status in saved list | |
update_scholarship_status(username, scholarship_name, status) | |
if submit_app: | |
st.success("Application submitted successfully!") | |
elif save_draft: | |
st.info("Draft saved successfully.") | |
elif submit_later: | |
st.info("Application saved. You can continue later.") | |
# Only refresh if not exiting | |
if not submit_app: | |
st.rerun() | |
# Forum feature | |
def render_forum(username): | |
st.markdown("### Scholarship Community Forum") | |
tab1, tab2 = st.tabs(["Browse Discussions", "Create New Post"]) | |
with tab1: | |
posts = load_forum_posts() | |
# Filter options | |
categories = ["All Categories", "Application Tips", "Scholarship Advice", "University Selection", "Financial Aid", "Study Abroad", "Career Guidance"] | |
filter_category = st.selectbox("Filter by Category", categories) | |
# Sort options | |
sort_option = st.selectbox("Sort by", ["Newest First", "Oldest First", "Most Replies"]) | |
# Apply filters and sorting | |
if filter_category != "All Categories": | |
filtered_posts = [post for post in posts if post["category"] == filter_category] | |
else: | |
filtered_posts = posts | |
if sort_option == "Newest First": | |
filtered_posts.sort(key=lambda x: x["created_at"], reverse=True) | |
elif sort_option == "Oldest First": | |
filtered_posts.sort(key=lambda x: x["created_at"]) | |
elif sort_option == "Most Replies": | |
filtered_posts.sort(key=lambda x: len(x["replies"]), reverse=True) | |
# Display posts | |
if not filtered_posts: | |
st.info("No discussions found. Be the first to start a conversation!") | |
for post in filtered_posts: | |
with st.expander(f"{post['title']} - by {post['username']} - {post['category']}"): | |
st.markdown(f"**{post['title']}**") | |
st.markdown(post['content']) | |
st.markdown(f"*Posted on: {datetime.datetime.fromisoformat(post['created_at']).strftime('%Y-%m-%d %H:%M')}*") | |
st.divider() | |
# Display replies | |
if post["replies"]: | |
st.markdown("#### Replies") | |
for reply in post["replies"]: | |
st.markdown(f"**{reply['username']}**: {reply['content']}") | |
st.markdown(f"*{datetime.datetime.fromisoformat(reply['created_at']).strftime('%Y-%m-%d %H:%M')}*") | |
st.divider() | |
# Reply form | |
with st.form(f"reply_form_{post['id']}"): | |
reply_content = st.text_area("Reply to this post", key=f"reply_{post['id']}") | |
if st.form_submit_button("Post Reply"): | |
if reply_content: | |
add_forum_reply(post["id"], username, reply_content) | |
st.success("Reply posted successfully!") | |
st.rerun() | |
with tab2: | |
with st.form("new_post_form"): | |
st.markdown("#### Create New Discussion") | |
post_title = st.text_input("Title") | |
post_category = st.selectbox("Category", categories[1:]) # Exclude "All Categories" | |
post_content = st.text_area("Content", height=200) | |
if st.form_submit_button("Post Discussion"): | |
if post_title and post_content: | |
add_forum_post(username, post_title, post_content, post_category) | |
st.success("Discussion posted successfully!") | |
st.rerun() | |
else: | |
st.error("Please fill in all required fields.") | |
# Mentorship and skill development (future scope preview) | |
def render_mentorship_preview(): | |
st.markdown("### 🚀 Coming Soon: Mentorship & Skill Development") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown(""" | |
#### 👨🏫 Mentorship Program | |
- Connect with experienced mentors in your field | |
- Get personalized guidance for scholarship applications | |
- Weekly 1:1 mentorship sessions | |
- Career planning and academic advice | |
""") | |
with col2: | |
st.markdown(""" | |
#### 🧠 Skill Development | |
- Free courses tailored to scholarship requirements | |
- Interview preparation workshops | |
- Essay writing masterclasses | |
- Language proficiency training | |
""") | |
st.info("These features are coming soon! Join our waitlist to be notified when they launch.") | |
with st.form("waitlist_form"): | |
waitlist_email = st.text_input("Email address") | |
interests = st.multiselect("I'm interested in", ["Mentorship", "Skill Development", "Both"]) | |
if st.form_submit_button("Join Waitlist"): | |
if waitlist_email: | |
st.success("Thank you for joining our waitlist! We'll notify you when these features launch.") | |
else: | |
st.error("Please enter your email address.") | |
# Financial planning feature (future scope preview) | |
def render_financial_planning_preview(): | |
st.markdown("### 💰 Financial Planning Tools") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown(""" | |
#### 📊 Scholarship Budget Planner | |
- Calculate total education expenses | |
- Track scholarship applications and potential funding | |
- Gap analysis between costs and available funding | |
- Prioritize applications based on financial need | |
""") | |
with col2: | |
st.markdown(""" | |
#### 💸 Financial Literacy Resources | |
- Educational content on managing scholarship funds | |
- Tax implications of scholarships | |
- Combining scholarships with student loans | |
- Building credit history as a student | |
""") | |
st.info("These financial planning tools are coming soon! Join our waitlist to be notified when they launch.") | |
# Sample financial planning calculator preview | |
st.markdown("#### 🔍 Education Cost Calculator Preview") | |
with st.form("cost_calculator"): | |
tuition = st.number_input("Estimated Annual Tuition (₹)", 0, 2000000, 100000, 10000) | |
living = st.number_input("Annual Living Expenses (₹)", 0, 1000000, 120000, 10000) | |
books = st.number_input("Books and Supplies (₹)", 0, 100000, 15000, 1000) | |
travel = st.number_input("Travel Expenses (₹)", 0, 100000, 20000, 1000) | |
years = st.number_input("Program Duration (years)", 1, 6, 4, 1) | |
if st.form_submit_button("Calculate Total Cost"): | |
annual_cost = tuition + living + books + travel | |
total_cost = annual_cost * years | |
st.markdown(f"**Annual Cost:** ₹{annual_cost:,}") | |
st.markdown(f"**Total Program Cost:** ₹{total_cost:,}") | |
# Display funding gap visualization | |
st.markdown("#### Funding Gap Analysis") | |
st.progress(0.2) | |
st.markdown("20% of costs currently covered by identified scholarships") | |
# Career alignment feature (future scope preview) | |
def render_career_alignment_preview(): | |
st.markdown("### 🎯 Career Alignment Tools") | |
st.markdown(""" | |
Our upcoming Career Alignment feature will help you connect your scholarship journey with your long-term career goals. | |
""") | |
col1, col2 = st.columns(2) | |
with col1: | |
st.markdown(""" | |
#### 🧭 Career Pathway Mapping | |
- Personalized career roadmap based on your profile | |
- Identify skills gaps and development opportunities | |
- Connect with industry professionals | |
- Internship and job placement assistance | |
""") | |
with col2: | |
st.markdown(""" | |
#### 🏆 Post-Scholarship Success | |
- Resume and portfolio building workshops | |
- Interview preparation specifically for scholars | |
- Alumni network access | |
- Scholarship to job transition guidance | |
""") | |
# AI Career Recommendation Preview | |
st.markdown("#### 🤖 AI Career Recommendation (Preview)") | |
with st.form("career_recommendation"): | |
interests = st.multiselect( | |
"Select your interests", | |
["Technology", "Healthcare", "Business", "Arts", "Sciences", "Education", "Law", "Engineering"] | |
) | |
skills = st.multiselect( | |
"Select your top skills", | |
["Programming", "Data Analysis", "Writing", "Research", "Design", "Leadership", "Problem-Solving", "Communication"] | |
) | |
values = st.multiselect( | |
"What do you value in a career?", | |
["Work-Life Balance", "High Income", "Making an Impact", "Creativity", "Recognition", "Stability", "Independence", "Growth"] | |
) | |
if st.form_submit_button("Get AI Career Recommendations"): | |
if interests and skills and values: | |
st.info("Based on your profile, we recommend exploring these career paths:") | |
if "Technology" in interests and "Programming" in skills: | |
st.markdown("1. **Software Development Engineer** - Aligned with your technical interests and problem-solving skills") | |
elif "Healthcare" in interests: | |
st.markdown("1. **Healthcare Researcher** - Combines your interest in healthcare with analytical skills") | |
elif "Business" in interests: | |
st.markdown("1. **Business Analyst** - Leverages your data analysis skills in a business context") | |
else: | |
st.markdown("1. **Research Specialist** - Aligns with your analytical mindset and subject interests") | |
st.markdown("*Full career alignment features coming soon!*") | |
else: | |
st.error("Please fill in all fields to get personalized recommendations.") | |
# Streamlit app | |
def main(): | |
# Load custom CSS | |
load_css() | |
# Initialize session state | |
if "authenticated" not in st.session_state: | |
st.session_state.authenticated = False | |
if "username" not in st.session_state: | |
st.session_state.username = None | |
if "profile_complete" not in st.session_state: | |
st.session_state.profile_complete = False | |
# Hero Section | |
st.markdown(""" | |
<div style="text-align: center; padding: 50px 0;"> | |
<h1 style="color: #2c3e50; font-size: 3rem;">🎓 AI Scholarship Advisor</h1> | |
<p style="color: #34495e; font-size: 1.2rem;">Find the best scholarships tailored just for you!</p> | |
</div> | |
""", unsafe_allow_html=True) | |
# User Authentication | |
if not st.session_state.authenticated: | |
tab1, tab2 = st.tabs(["Login", "Register"]) | |
with tab1: | |
with st.form("login_form"): | |
username = st.text_input("Username") | |
password = st.text_input("Password", type="password") | |
if st.form_submit_button("Login"): | |
if authenticate(username, password): | |
st.session_state.authenticated = True | |
st.session_state.username = username | |
# Check if profile is complete | |
profile = get_user_profile(username) | |
if profile and profile.get("profile_completed", False): | |
st.session_state.profile_complete = True | |
st.rerun() | |
else: | |
st.error("Invalid username or password") | |
with tab2: | |
with st.form("register_form"): | |
new_username = st.text_input("Username", key="reg_username") | |
new_password = st.text_input("Password", type="password", key="reg_password") | |
confirm_password = st.text_input("Confirm Password", type="password") | |
email = st.text_input("Email Address") | |
if st.form_submit_button("Register"): | |
if new_password != confirm_password: | |
st.error("Passwords do not match") | |
elif not new_username or not new_password or not email: | |
st.error("All fields are required") | |
else: | |
if register_user(new_username, new_password, email): | |
st.success("Registration successful! Please login.") | |
else: | |
st.error("Username already exists") | |
else: | |
# User is authenticated | |
username = st.session_state.username | |
# Check profile completion | |
profile = get_user_profile(username) | |
profile_complete = profile.get("profile_completed", False) | |
if not profile_complete and not st.session_state.profile_complete: | |
# User profile needs to be completed | |
render_profile_wizard(username) | |
else: | |
# Main application tabs | |
tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([ | |
"💡 Recommendations", | |
"📋 Saved Scholarships", | |
"📝 Applications", | |
"💬 Community Forum", | |
"🧠 Skill Development", | |
"💰 Financial Planning" | |
]) | |
# Load data | |
df = load_scholarships() | |
with tab1: | |
st.markdown("### 🎯 Get Personalized Recommendations") | |
# Get user profile for recommendations | |
profile = get_user_profile(username) | |
# User can modify certain profile elements for this search | |
with st.form("profile_form"): | |
st.markdown("### 📝 Customize Search Criteria") | |
col1, col2 = st.columns(2) | |
with col1: | |
age = st.number_input("Age", 16, 50, int(profile.get("age", 20)) if "age" in profile else 20) | |
citizenship = st.selectbox( | |
"Citizenship", | |
["India", "Other"], | |
index=0 if profile.get("citizenship", "India") == "India" else 1 | |
) | |
income = st.number_input( | |
"Annual Family Income (₹)", | |
0, 10000000, | |
int(profile.get("income", 300000)) if "income" in profile else 300000 | |
) | |
with col2: | |
education = st.selectbox( | |
"Education Level", | |
["High School", "Undergraduate", "Postgraduate", "PhD"], | |
index=["High School", "Undergraduate", "Postgraduate", "PhD"].index(profile.get("education", "Undergraduate")) if "education" in profile else 1 | |
) | |
category = st.selectbox( | |
"Category", | |
["General", "OBC", "SC", "ST", "EWS", "Minority"], | |
index=["General", "OBC", "SC", "ST", "EWS", "Minority"].index(profile.get("category", "General")) if "category" in profile else 0 | |
) | |
submitted = st.form_submit_button("🚀 Get Recommendations") | |
if submitted: | |
# Create user profile | |
user_profile = f""" | |
Student Profile: | |
- Age: {age} | |
- Citizenship: {citizenship} | |
- Annual Income: ₹{income} | |
- Education Level: {education} | |
- Category: {category} | |
""" | |
# Create RAG context | |
rag_context = create_rag_context(df) | |
# Generate response using RAG | |
model = get_rag_model() | |
prompt = f""" | |
{rag_context} | |
{user_profile} | |
Task: | |
1. Analyze the student profile against all scholarships | |
2. Identify top 5 most relevant scholarships with priority order | |
3. For each scholarship: | |
- List matching eligibility criteria | |
- Explain why it's a good match | |
- Provide direct application link | |
4. Format response with markdown headers and bullet points | |
Important: | |
- Be specific about eligibility matches | |
- Highlight deadlines if available | |
- Never invent scholarships not in the database | |
""" | |
with st.spinner("🔍 Analyzing 50+ scholarships..."): | |
response = model.generate_content( | |
prompt, | |
generation_config=GenerationConfig( | |
temperature=0.3, | |
top_p=0.95, | |
max_output_tokens=2000 | |
) | |
) | |
# Display recommendations | |
st.markdown("### 🎉 Personalized Recommendations") | |
# Process the response to add save buttons | |
recommendations_text = response.text | |
# Split the recommendations into sections | |
scholarship_sections = recommendations_text.split("##")[1:] # Skip the first split which is empty | |
for section in scholarship_sections: | |
if not section.strip(): | |
continue | |
# Extract scholarship name from the header | |
lines = section.strip().split("\n") | |
scholarship_name = lines[0].strip() | |
# Find deadline if mentioned | |
deadline = "Not specified" | |
for line in lines: | |
if "deadline" in line.lower(): | |
deadline = line.split(":", 1)[1].strip() if ":" in line else line | |
break | |
# Create a card for this scholarship | |
st.markdown(f""" | |
<div class="scholarship-card"> | |
<h3>{scholarship_name}</h3> | |
{"".join([f"<p>{line}</p>" for line in lines[1:]])} | |
</div> | |
""", unsafe_allow_html=True) | |
# Add a button to save this scholarship | |
if st.button(f"Save this scholarship", key=f"save_{scholarship_name}"): | |
if save_scholarship(username, scholarship_name, deadline): | |
st.success(f"Saved {scholarship_name} to your list!") | |
else: | |
st.info("This scholarship is already in your saved list.") | |
# Show raw data for transparency | |
with st.expander("📊 View Full Scholarship Database"): | |
st.dataframe(df) | |
with tab2: | |
st.markdown("### 📋 Your Saved Scholarships") | |
saved = get_saved_scholarships(username) | |
if not saved: | |
st.info("You haven't saved any scholarships yet. Go to the Recommendations tab to find and save scholarships.") | |
else: | |
# Group by status | |
saved_by_status = {} | |
for s in saved: | |
status = s.get("status", "Saved") | |
if status not in saved_by_status: | |
saved_by_status[status] = [] | |
saved_by_status[status].append(s) | |
# Create tabs for different statuses | |
status_tabs = st.tabs(list(saved_by_status.keys())) | |
for i, (status, scholarships) in enumerate(saved_by_status.items()): | |
with status_tabs[i]: | |
for scholarship in scholarships: | |
with st.expander(f"{scholarship['name']} (Deadline: {scholarship['deadline']})"): | |
st.markdown(f"**{scholarship['name']}**") | |
st.markdown(f"Deadline: {scholarship['deadline']}") | |
st.markdown(f"Saved on: {datetime.datetime.fromisoformat(scholarship['saved_at']).strftime('%Y-%m-%d')}") | |
# Find full details in the dataframe | |
scholarship_details = df[df['Scholarship Name'] == scholarship['name']] | |
if not scholarship_details.empty: | |
st.markdown(f"Eligibility: {scholarship_details.iloc[0]['Eligibility']}") | |
st.markdown(f"Link: {scholarship_details.iloc[0]['Link']}") | |
col1, col2 = st.columns(2) | |
with col1: | |
if st.button("Start Application", key=f"apply_{scholarship['name']}"): | |
track_application(username, scholarship['name']) | |
update_scholarship_status(username, scholarship['name'], "Started") | |
st.session_state.current_application = scholarship['name'] | |
st.rerun() | |
with col2: | |
if st.button("Set Reminder", key=f"remind_{scholarship['name']}"): | |
# Get user email | |
users = load_users() | |
email = users[username]["email"] | |
# Send notification | |
if send_deadline_notification(email, scholarship['name'], scholarship['deadline']): | |
st.success("Reminder email sent!") | |
else: | |
st.error("Failed to send reminder email.") | |
with tab3: | |
st.markdown("### 📝 Your Applications") | |
# Check if a specific application is being viewed | |
if "current_application" in st.session_state: | |
render_application_form(username, st.session_state.current_application, df) | |
if st.button("Back to All Applications"): | |
del st.session_state.current_application | |
st.rerun() | |
else: | |
# Get user's applications | |
users = load_users() | |
applications = users[username]["applications"] if username in users else {} | |
if not applications: | |
st.info("You haven't started any applications yet. Save a scholarship and click 'Start Application' to begin.") | |
else: | |
# Group by status/progress | |
in_progress = [] | |
completed = [] | |
drafts = [] | |
for name, app in applications.items(): | |
if app["progress"] == 100: | |
completed.append((name, app)) | |
elif app["status"] == "Draft": | |
drafts.append((name, app)) | |
else: | |
in_progress.append((name, app)) | |
# Create tabs for different statuses | |
app_tabs = st.tabs(["In Progress", "Drafts", "Completed"]) | |
with app_tabs[0]: | |
if not in_progress: | |
st.info("No applications in progress.") | |
else: | |
for name, app in in_progress: | |
col1, col2 = st.columns([3, 1]) | |
with col1: | |
st.markdown(f"**{name}**") | |
st.progress(app["progress"] / 100) | |
st.markdown(f"Progress: {app['progress']}% complete") | |
with col2: | |
if st.button("Continue", key=f"continue_{name}"): | |
st.session_state.current_application = name | |
st.rerun() | |
with app_tabs[1]: | |
if not drafts: | |
st.info("No draft applications.") | |
else: | |
for name, app in drafts: | |
col1, col2 = st.columns([3, 1]) | |
with col1: | |
st.markdown(f"**{name}**") | |
st.markdown(f"Last updated: {datetime.datetime.fromisoformat(app.get('updated_at', app['started_at'])).strftime('%Y-%m-%d')}") | |
with col2: | |
if st.button("Edit Draft", key=f"edit_{name}"): | |
st.session_state.current_application = name | |
st.rerun() | |
with app_tabs[2]: | |
if not completed: | |
st.info("No completed applications.") | |
else: | |
for name, app in completed: | |
st.markdown(f"**{name}**") | |
st.markdown(f"Submitted on: {datetime.datetime.fromisoformat(app.get('updated_at', app['started_at'])).strftime('%Y-%m-%d')}") | |
st.success("Application completed and submitted!") | |
with tab4: | |
render_forum(username) | |
with tab5: | |
render_mentorship_preview() | |
with tab6: | |
st.markdown("### Financial Planning Tools") | |
tab1, tab2 = st.tabs(["Education Financing", "Career Planning"]) | |
with tab1: | |
render_financial_planning_preview() | |
with tab2: | |
render_career_alignment_preview() | |
# Logout button | |
if st.sidebar.button("Logout"): | |
st.session_state.authenticated = False | |
st.session_state.username = None | |
st.session_state.profile_complete = False | |
if "current_application" in st.session_state: | |
del st.session_state.current_application | |
if "profile_step" in st.session_state: | |
del st.session_state.profile_step | |
st.rerun() | |
if __name__ == "__main__": | |
main() |