Akshayram1 commited on
Commit
c9bac47
·
verified ·
1 Parent(s): 9c0039a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1181 -70
app.py CHANGED
@@ -3,6 +3,12 @@ import streamlit as st
3
  import pandas as pd
4
  import google.generativeai as genai
5
  from google.generativeai.types import GenerationConfig
 
 
 
 
 
 
6
 
7
  # Configuration
8
  os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY', 'your_key_here')
@@ -42,92 +48,1197 @@ def load_css():
42
  .stMarkdown p, .stMarkdown ul, .stMarkdown ol {
43
  color: rgb(1, 27, 29); /* Custom color for results */
44
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  </style>
46
  """, unsafe_allow_html=True)
47
 
48
- # Streamlit app
49
- def main():
50
- # Load custom CSS
51
- load_css()
 
 
 
52
 
53
- # Hero Section
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  st.markdown("""
55
- <div style="text-align: center; padding: 50px 0;">
56
- <h1 style="color: #2c3e50; font-size: 3rem;">🎓 AI Scholarship Advisor</h1>
57
- <p style="color: #34495e; font-size: 1.2rem;">Find the best scholarships tailored just for you!</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  </div>
59
  """, unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- # Load data and create RAG context
62
- df = load_scholarships()
63
- rag_context = create_rag_context(df)
64
-
65
- # User input form
66
- with st.form("profile_form"):
67
- st.markdown("### 📝 Student Profile")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  col1, col2 = st.columns(2)
 
69
  with col1:
70
- age = st.number_input("Age", 16, 50, 20)
71
- citizenship = st.selectbox("Citizenship", ["India", "Other"])
72
- income = st.number_input("Annual Family Income (₹)", 0, 10000000, 300000)
73
  with col2:
 
 
 
 
 
 
 
 
74
  education = st.selectbox("Education Level",
75
- ["High School", "Undergraduate", "Postgraduate", "PhD"])
76
- category = st.selectbox("Category",
77
- ["General", "OBC", "SC", "ST", "EWS", "Minority"])
78
-
79
- submitted = st.form_submit_button("🚀 Get Recommendations")
80
-
81
- if submitted:
82
- # Create user profile
83
- user_profile = f"""
84
- Student Profile:
85
- - Age: {age}
86
- - Citizenship: {citizenship}
87
- - Annual Income: ₹{income}
88
- - Education Level: {education}
89
- - Category: {category}
90
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
- # Generate response using RAG
93
- model = get_rag_model()
94
- prompt = f"""
95
- {rag_context}
96
-
97
- {user_profile}
98
-
99
- Task:
100
- 1. Analyze the student profile against all scholarships
101
- 2. Identify top 5 most relevant scholarships with priority order
102
- 3. For each scholarship:
103
- - List matching eligibility criteria
104
- - Explain why it's a good match
105
- - Provide direct application link
106
- 4. Format response with markdown headers and bullet points
107
-
108
- Important:
109
- - Be specific about eligibility matches
110
- - Highlight deadlines if available
111
- - Never invent scholarships not in the database
112
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
- with st.spinner("🔍 Analyzing 50+ scholarships..."):
115
- response = model.generate_content(
116
- prompt,
117
- generation_config=GenerationConfig(
118
- temperature=0.3,
119
- top_p=0.95,
120
- max_output_tokens=2000
121
- )
122
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- # Display recommendations
125
- st.markdown("### 🎉 Personalized Recommendations")
126
- st.markdown(response.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
- # Show raw data for transparency
129
- with st.expander("📊 View Full Scholarship Database"):
130
- st.dataframe(df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  if __name__ == "__main__":
133
  main()
 
3
  import pandas as pd
4
  import google.generativeai as genai
5
  from google.generativeai.types import GenerationConfig
6
+ import datetime
7
+ import uuid
8
+ import json
9
+ import smtplib
10
+ from email.mime.text import MIMEText
11
+ from email.mime.multipart import MIMEMultipart
12
 
13
  # Configuration
14
  os.environ['GOOGLE_API_KEY'] = os.getenv('GOOGLE_API_KEY', 'your_key_here')
 
48
  .stMarkdown p, .stMarkdown ul, .stMarkdown ol {
49
  color: rgb(1, 27, 29); /* Custom color for results */
50
  }
51
+
52
+ /* Card styling */
53
+ .scholarship-card {
54
+ background-color: #f8f9fa;
55
+ border-radius: 10px;
56
+ padding: 20px;
57
+ margin-bottom: 20px;
58
+ border-left: 5px solid #4CAF50;
59
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);
60
+ }
61
+
62
+ /* Tabs styling */
63
+ .stTabs [data-baseweb="tab-list"] {
64
+ gap: 8px;
65
+ }
66
+
67
+ .stTabs [data-baseweb="tab"] {
68
+ height: 50px;
69
+ white-space: pre-wrap;
70
+ background-color: #f0f2f6;
71
+ border-radius: 4px 4px 0px 0px;
72
+ gap: 1px;
73
+ padding-top: 10px;
74
+ padding-bottom: 10px;
75
+ }
76
+
77
+ .stTabs [aria-selected="true"] {
78
+ background-color: #4CAF50;
79
+ color: white;
80
+ }
81
+
82
+ /* Button styling */
83
+ .stButton>button {
84
+ border-radius: 20px;
85
+ font-weight: 500;
86
+ }
87
+
88
+ /* Progress indicator */
89
+ .progress-container {
90
+ display: flex;
91
+ justify-content: space-between;
92
+ margin-bottom: 30px;
93
+ }
94
+
95
+ .progress-step {
96
+ text-align: center;
97
+ flex: 1;
98
+ }
99
+
100
+ .progress-step-number {
101
+ width: 30px;
102
+ height: 30px;
103
+ border-radius: 50%;
104
+ background-color: #ddd;
105
+ color: white;
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ margin: 0 auto 10px auto;
110
+ }
111
+
112
+ .progress-step.active .progress-step-number {
113
+ background-color: #4CAF50;
114
+ }
115
+
116
+ .progress-step-title {
117
+ font-size: 0.8rem;
118
+ }
119
  </style>
120
  """, unsafe_allow_html=True)
121
 
122
+ # User management functions
123
+ def load_users():
124
+ try:
125
+ with open("users.json", "r") as f:
126
+ return json.load(f)
127
+ except (FileNotFoundError, json.JSONDecodeError):
128
+ return {}
129
 
130
+ def save_users(users):
131
+ with open("users.json", "w") as f:
132
+ json.dump(users, f)
133
+
134
+ def authenticate(username, password):
135
+ users = load_users()
136
+ if username in users and users[username]["password"] == password:
137
+ return True
138
+ return False
139
+
140
+ def register_user(username, password, email):
141
+ users = load_users()
142
+ if username in users:
143
+ return False
144
+
145
+ users[username] = {
146
+ "password": password,
147
+ "email": email,
148
+ "profile": {},
149
+ "saved_scholarships": [],
150
+ "applications": {},
151
+ "created_at": datetime.datetime.now().isoformat()
152
+ }
153
+ save_users(users)
154
+ return True
155
+
156
+ # Saved scholarship functions
157
+ def save_scholarship(username, scholarship_name, deadline):
158
+ users = load_users()
159
+ if username in users:
160
+ # Check if already saved
161
+ if scholarship_name not in [s["name"] for s in users[username]["saved_scholarships"]]:
162
+ users[username]["saved_scholarships"].append({
163
+ "name": scholarship_name,
164
+ "deadline": deadline,
165
+ "saved_at": datetime.datetime.now().isoformat(),
166
+ "status": "Saved"
167
+ })
168
+ save_users(users)
169
+ return True
170
+ return False
171
+
172
+ def get_saved_scholarships(username):
173
+ users = load_users()
174
+ if username in users:
175
+ return users[username]["saved_scholarships"]
176
+ return []
177
+
178
+ def update_scholarship_status(username, scholarship_name, status):
179
+ users = load_users()
180
+ if username in users:
181
+ for scholarship in users[username]["saved_scholarships"]:
182
+ if scholarship["name"] == scholarship_name:
183
+ scholarship["status"] = status
184
+ save_users(users)
185
+ return True
186
+ return False
187
+
188
+ # Application tracking functions
189
+ def track_application(username, scholarship_name, status="Started"):
190
+ users = load_users()
191
+ if username in users:
192
+ if scholarship_name not in users[username]["applications"]:
193
+ users[username]["applications"][scholarship_name] = {
194
+ "status": status,
195
+ "progress": 0,
196
+ "started_at": datetime.datetime.now().isoformat(),
197
+ "form_data": {}
198
+ }
199
+ save_users(users)
200
+ return True
201
+ return False
202
+
203
+ def update_application(username, scholarship_name, form_data, progress):
204
+ users = load_users()
205
+ if username in users and scholarship_name in users[username]["applications"]:
206
+ users[username]["applications"][scholarship_name]["form_data"] = form_data
207
+ users[username]["applications"][scholarship_name]["progress"] = progress
208
+ users[username]["applications"][scholarship_name]["updated_at"] = datetime.datetime.now().isoformat()
209
+ save_users(users)
210
+ return True
211
+ return False
212
+
213
+ def get_application_progress(username, scholarship_name):
214
+ users = load_users()
215
+ if username in users and scholarship_name in users[username]["applications"]:
216
+ return users[username]["applications"][scholarship_name]
217
+ return None
218
+
219
+ # Email notification function
220
+ def send_deadline_notification(email, scholarship_name, deadline_date):
221
+ try:
222
+ sender_email = os.getenv('APP_EMAIL', '[email protected]')
223
+ password = os.getenv('APP_EMAIL_PASSWORD', 'app_password')
224
+
225
+ msg = MIMEMultipart()
226
+ msg['From'] = sender_email
227
+ msg['To'] = email
228
+ msg['Subject'] = f"Deadline Reminder: {scholarship_name}"
229
+
230
+ body = f"""
231
+ <html>
232
+ <body>
233
+ <h2>Deadline Reminder</h2>
234
+ <p>Hello,</p>
235
+ <p>This is a reminder that the application deadline for <b>{scholarship_name}</b> is approaching.</p>
236
+ <p>Deadline: <b>{deadline_date}</b></p>
237
+ <p>Please log in to the AI Scholarship Advisor to complete your application.</p>
238
+ <p>Best of luck!</p>
239
+ </body>
240
+ </html>
241
+ """
242
+
243
+ msg.attach(MIMEText(body, 'html'))
244
+
245
+ server = smtplib.SMTP('smtp.gmail.com', 587)
246
+ server.starttls()
247
+ server.login(sender_email, password)
248
+ server.send_message(msg)
249
+ server.quit()
250
+ return True
251
+ except Exception as e:
252
+ st.error(f"Failed to send email: {str(e)}")
253
+ return False
254
+
255
+ # Profile management
256
+ def update_user_profile(username, profile_data):
257
+ users = load_users()
258
+ if username in users:
259
+ users[username]["profile"] = profile_data
260
+ save_users(users)
261
+ return True
262
+ return False
263
+
264
+ def get_user_profile(username):
265
+ users = load_users()
266
+ if username in users:
267
+ return users[username]["profile"]
268
+ return {}
269
+
270
+ # Forum functions
271
+ def load_forum_posts():
272
+ try:
273
+ with open("forum_posts.json", "r") as f:
274
+ return json.load(f)
275
+ except (FileNotFoundError, json.JSONDecodeError):
276
+ return []
277
+
278
+ def save_forum_posts(posts):
279
+ with open("forum_posts.json", "w") as f:
280
+ json.dump(posts, f)
281
+
282
+ def add_forum_post(username, title, content, category):
283
+ posts = load_forum_posts()
284
+ post_id = str(uuid.uuid4())
285
+ posts.append({
286
+ "id": post_id,
287
+ "username": username,
288
+ "title": title,
289
+ "content": content,
290
+ "category": category,
291
+ "created_at": datetime.datetime.now().isoformat(),
292
+ "replies": []
293
+ })
294
+ save_forum_posts(posts)
295
+ return post_id
296
+
297
+ def add_forum_reply(post_id, username, content):
298
+ posts = load_forum_posts()
299
+ for post in posts:
300
+ if post["id"] == post_id:
301
+ reply_id = str(uuid.uuid4())
302
+ post["replies"].append({
303
+ "id": reply_id,
304
+ "username": username,
305
+ "content": content,
306
+ "created_at": datetime.datetime.now().isoformat()
307
+ })
308
+ save_forum_posts(posts)
309
+ return reply_id
310
+ return None
311
+
312
+ # Create profile completion wizard
313
+ def render_profile_wizard(username):
314
+ st.markdown("### Complete Your Profile")
315
+
316
+ # Progress indicator
317
  st.markdown("""
318
+ <div class="progress-container">
319
+ <div class="progress-step active">
320
+ <div class="progress-step-number">1</div>
321
+ <div class="progress-step-title">Personal Info</div>
322
+ </div>
323
+ <div class="progress-step">
324
+ <div class="progress-step-number">2</div>
325
+ <div class="progress-step-title">Academic Info</div>
326
+ </div>
327
+ <div class="progress-step">
328
+ <div class="progress-step-number">3</div>
329
+ <div class="progress-step-title">Financial Info</div>
330
+ </div>
331
+ <div class="progress-step">
332
+ <div class="progress-step-number">4</div>
333
+ <div class="progress-step-title">Preferences</div>
334
+ </div>
335
  </div>
336
  """, unsafe_allow_html=True)
337
+
338
+ profile = get_user_profile(username)
339
+ step = st.session_state.get("profile_step", 1)
340
+
341
+ if step == 1:
342
+ with st.form("personal_info"):
343
+ st.markdown("#### Step 1: Personal Information")
344
+ first_name = st.text_input("First Name", profile.get("first_name", ""))
345
+ last_name = st.text_input("Last Name", profile.get("last_name", ""))
346
+ 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))
347
+ 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)
348
+ citizenship = st.selectbox("Citizenship", ["India", "Other"], index=["India", "Other"].index(profile.get("citizenship", "India")) if "citizenship" in profile else 0)
349
+
350
+ if st.form_submit_button("Next"):
351
+ profile.update({
352
+ "first_name": first_name,
353
+ "last_name": last_name,
354
+ "dob": dob.strftime("%Y-%m-%d"),
355
+ "gender": gender,
356
+ "citizenship": citizenship
357
+ })
358
+ update_user_profile(username, profile)
359
+ st.session_state.profile_step = 2
360
+ st.rerun()
361
+
362
+ elif step == 2:
363
+ st.markdown("""
364
+ <div class="progress-container">
365
+ <div class="progress-step active">
366
+ <div class="progress-step-number">1</div>
367
+ <div class="progress-step-title">Personal Info</div>
368
+ </div>
369
+ <div class="progress-step active">
370
+ <div class="progress-step-number">2</div>
371
+ <div class="progress-step-title">Academic Info</div>
372
+ </div>
373
+ <div class="progress-step">
374
+ <div class="progress-step-number">3</div>
375
+ <div class="progress-step-title">Financial Info</div>
376
+ </div>
377
+ <div class="progress-step">
378
+ <div class="progress-step-number">4</div>
379
+ <div class="progress-step-title">Preferences</div>
380
+ </div>
381
+ </div>
382
+ """, unsafe_allow_html=True)
383
+
384
+ with st.form("academic_info"):
385
+ st.markdown("#### Step 2: Academic Information")
386
+ education = st.selectbox("Education Level",
387
+ ["High School", "Undergraduate", "Postgraduate", "PhD"],
388
+ index=["High School", "Undergraduate", "Postgraduate", "PhD"].index(profile.get("education", "Undergraduate")) if "education" in profile else 1)
389
+
390
+ institution = st.text_input("Current Institution", profile.get("institution", ""))
391
+ field_of_study = st.text_input("Field of Study", profile.get("field_of_study", ""))
392
+
393
+ 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)
394
+
395
+ achievements = st.text_area("Academic Achievements", profile.get("achievements", ""))
396
+
397
+ col1, col2 = st.columns(2)
398
+ with col1:
399
+ if st.form_submit_button("Previous"):
400
+ st.session_state.profile_step = 1
401
+ st.rerun()
402
+
403
+ with col2:
404
+ if st.form_submit_button("Next"):
405
+ profile.update({
406
+ "education": education,
407
+ "institution": institution,
408
+ "field_of_study": field_of_study,
409
+ "cgpa": cgpa,
410
+ "achievements": achievements
411
+ })
412
+ update_user_profile(username, profile)
413
+ st.session_state.profile_step = 3
414
+ st.rerun()
415
+
416
+ elif step == 3:
417
+ st.markdown("""
418
+ <div class="progress-container">
419
+ <div class="progress-step active">
420
+ <div class="progress-step-number">1</div>
421
+ <div class="progress-step-title">Personal Info</div>
422
+ </div>
423
+ <div class="progress-step active">
424
+ <div class="progress-step-number">2</div>
425
+ <div class="progress-step-title">Academic Info</div>
426
+ </div>
427
+ <div class="progress-step active">
428
+ <div class="progress-step-number">3</div>
429
+ <div class="progress-step-title">Financial Info</div>
430
+ </div>
431
+ <div class="progress-step">
432
+ <div class="progress-step-number">4</div>
433
+ <div class="progress-step-title">Preferences</div>
434
+ </div>
435
+ </div>
436
+ """, unsafe_allow_html=True)
437
+
438
+ with st.form("financial_info"):
439
+ st.markdown("#### Step 3: Financial Information")
440
+
441
+ income = st.number_input("Annual Family Income (₹)", 0, 10000000, int(profile.get("income", 300000)) if "income" in profile else 300000, 10000)
442
+
443
+ category = st.selectbox("Category",
444
+ ["General", "OBC", "SC", "ST", "EWS", "Minority"],
445
+ index=["General", "OBC", "SC", "ST", "EWS", "Minority"].index(profile.get("category", "General")) if "category" in profile else 0)
446
+
447
+ financial_need = st.slider("Financial Need Level", 1, 10, int(profile.get("financial_need", 5)) if "financial_need" in profile else 5)
448
+
449
+ col1, col2 = st.columns(2)
450
+ with col1:
451
+ if st.form_submit_button("Previous"):
452
+ st.session_state.profile_step = 2
453
+ st.rerun()
454
+
455
+ with col2:
456
+ if st.form_submit_button("Next"):
457
+ profile.update({
458
+ "income": income,
459
+ "category": category,
460
+ "financial_need": financial_need
461
+ })
462
+ update_user_profile(username, profile)
463
+ st.session_state.profile_step = 4
464
+ st.rerun()
465
+
466
+ elif step == 4:
467
+ st.markdown("""
468
+ <div class="progress-container">
469
+ <div class="progress-step active">
470
+ <div class="progress-step-number">1</div>
471
+ <div class="progress-step-title">Personal Info</div>
472
+ </div>
473
+ <div class="progress-step active">
474
+ <div class="progress-step-number">2</div>
475
+ <div class="progress-step-title">Academic Info</div>
476
+ </div>
477
+ <div class="progress-step active">
478
+ <div class="progress-step-number">3</div>
479
+ <div class="progress-step-title">Financial Info</div>
480
+ </div>
481
+ <div class="progress-step active">
482
+ <div class="progress-step-number">4</div>
483
+ <div class="progress-step-title">Preferences</div>
484
+ </div>
485
+ </div>
486
+ """, unsafe_allow_html=True)
487
+
488
+ with st.form("preferences"):
489
+ st.markdown("#### Step 4: Preferences")
490
+
491
+ preferred_locations = st.multiselect(
492
+ "Preferred Study Locations",
493
+ ["India", "USA", "UK", "Canada", "Australia", "Germany", "Japan", "Singapore", "Other"],
494
+ profile.get("preferred_locations", ["India"])
495
+ )
496
+
497
+ study_interests = st.multiselect(
498
+ "Fields of Interest",
499
+ ["Engineering", "Medicine", "Law", "Business", "Arts", "Science", "Humanities", "Social Sciences", "Other"],
500
+ profile.get("study_interests", ["Engineering"])
501
+ )
502
+
503
+ career_goals = st.text_area("Career Goals", profile.get("career_goals", ""))
504
+
505
+ extracurricular = st.text_area("Extracurricular Activities", profile.get("extracurricular", ""))
506
+
507
+ notification_preference = st.checkbox("Receive Email Notifications", value=profile.get("notification_preference", True))
508
+
509
+ col1, col2 = st.columns(2)
510
+ with col1:
511
+ if st.form_submit_button("Previous"):
512
+ st.session_state.profile_step = 3
513
+ st.rerun()
514
+
515
+ with col2:
516
+ if st.form_submit_button("Complete Profile"):
517
+ profile.update({
518
+ "preferred_locations": preferred_locations,
519
+ "study_interests": study_interests,
520
+ "career_goals": career_goals,
521
+ "extracurricular": extracurricular,
522
+ "notification_preference": notification_preference,
523
+ "profile_completed": True,
524
+ "completed_at": datetime.datetime.now().isoformat()
525
+ })
526
+ update_user_profile(username, profile)
527
+ st.session_state.profile_complete = True
528
+ st.success("Profile completed successfully!")
529
+ st.rerun()
530
 
531
+ # Auto-fill application form
532
+ def render_application_form(username, scholarship_name, df):
533
+ st.markdown(f"### Application Form: {scholarship_name}")
534
+
535
+ # Get scholarship details
536
+ scholarship_row = df[df['Scholarship Name'] == scholarship_name].iloc[0]
537
+ deadline = scholarship_row['Deadline']
538
+ eligibility = scholarship_row['Eligibility']
539
+ link = scholarship_row['Link']
540
+
541
+ st.info(f"Deadline: {deadline}")
542
+ st.markdown(f"Eligibility: {eligibility}")
543
+
544
+ # Get user profile for auto-fill
545
+ profile = get_user_profile(username)
546
+
547
+ # Get existing application data if any
548
+ app_data = get_application_progress(username, scholarship_name)
549
+ form_data = app_data["form_data"] if app_data and "form_data" in app_data else {}
550
+
551
+ with st.form("application_form"):
552
+ st.markdown("#### Personal Information")
553
  col1, col2 = st.columns(2)
554
+
555
  with col1:
556
+ first_name = st.text_input("First Name", value=form_data.get("first_name", profile.get("first_name", "")))
557
+ last_name = st.text_input("Last Name", value=form_data.get("last_name", profile.get("last_name", "")))
558
+
559
  with col2:
560
+ email = st.text_input("Email", value=form_data.get("email", profile.get("email", "")))
561
+ phone = st.text_input("Phone Number", value=form_data.get("phone", ""))
562
+
563
+ st.markdown("#### Academic Information")
564
+ col1, col2 = st.columns(2)
565
+
566
+ with col1:
567
+ institution = st.text_input("Institution", value=form_data.get("institution", profile.get("institution", "")))
568
  education = st.selectbox("Education Level",
569
+ ["High School", "Undergraduate", "Postgraduate", "PhD"],
570
+ 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)
571
+
572
+ with col2:
573
+ field_of_study = st.text_input("Field of Study", value=form_data.get("field_of_study", profile.get("field_of_study", "")))
574
+ 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)
575
+
576
+ st.markdown("#### Essay Questions")
577
+ why_deserve = st.text_area("Why do you deserve this scholarship? (200-300 words)", value=form_data.get("why_deserve", ""))
578
+ career_goals = st.text_area("Describe your career goals (200-300 words)", value=form_data.get("career_goals", profile.get("career_goals", "")))
579
+
580
+ st.markdown("#### Additional Documents")
581
+ st.file_uploader("Upload Resume/CV (PDF)", type=["pdf"])
582
+ st.file_uploader("Upload Transcripts (PDF)", type=["pdf"])
583
+ st.file_uploader("Upload Recommendation Letter (PDF)", type=["pdf"])
584
+
585
+ # Form actions
586
+ col1, col2, col3 = st.columns(3)
587
+
588
+ with col1:
589
+ save_draft = st.form_submit_button("Save as Draft")
590
+
591
+ with col2:
592
+ submit_later = st.form_submit_button("Submit Later")
593
+
594
+ with col3:
595
+ submit_app = st.form_submit_button("Submit Application")
596
+
597
+ # Handle form submission
598
+ if save_draft or submit_later or submit_app:
599
+ new_form_data = {
600
+ "first_name": first_name,
601
+ "last_name": last_name,
602
+ "email": email,
603
+ "phone": phone,
604
+ "institution": institution,
605
+ "education": education,
606
+ "field_of_study": field_of_study,
607
+ "cgpa": cgpa,
608
+ "why_deserve": why_deserve,
609
+ "career_goals": career_goals
610
+ }
611
+
612
+ progress = 25 # Initial progress
613
+
614
+ # Calculate form completion progress
615
+ if first_name and last_name and email and phone:
616
+ progress += 25
617
+
618
+ if institution and field_of_study:
619
+ progress += 25
620
+
621
+ if why_deserve and len(why_deserve) > 100:
622
+ progress += 15
623
+
624
+ if career_goals and len(career_goals) > 100:
625
+ progress += 10
626
+
627
+ # Update application status
628
+ status = "Draft"
629
+ if submit_app:
630
+ status = "Submitted"
631
+ progress = 100
632
+ elif submit_later:
633
+ status = "In Progress"
634
+
635
+ # Create or update application tracking
636
+ if app_data:
637
+ update_application(username, scholarship_name, new_form_data, progress)
638
+ else:
639
+ track_application(username, scholarship_name, status)
640
+ update_application(username, scholarship_name, new_form_data, progress)
641
+
642
+ # Update scholarship status in saved list
643
+ update_scholarship_status(username, scholarship_name, status)
644
+
645
+ if submit_app:
646
+ st.success("Application submitted successfully!")
647
+ elif save_draft:
648
+ st.info("Draft saved successfully.")
649
+ elif submit_later:
650
+ st.info("Application saved. You can continue later.")
651
+
652
+ # Only refresh if not exiting
653
+ if not submit_app:
654
+ st.rerun()
655
 
656
+ # Forum feature
657
+ def render_forum(username):
658
+ st.markdown("### Scholarship Community Forum")
659
+
660
+ tab1, tab2 = st.tabs(["Browse Discussions", "Create New Post"])
661
+
662
+ with tab1:
663
+ posts = load_forum_posts()
664
+
665
+ # Filter options
666
+ categories = ["All Categories", "Application Tips", "Scholarship Advice", "University Selection", "Financial Aid", "Study Abroad", "Career Guidance"]
667
+ filter_category = st.selectbox("Filter by Category", categories)
668
+
669
+ # Sort options
670
+ sort_option = st.selectbox("Sort by", ["Newest First", "Oldest First", "Most Replies"])
671
+
672
+ # Apply filters and sorting
673
+ if filter_category != "All Categories":
674
+ filtered_posts = [post for post in posts if post["category"] == filter_category]
675
+ else:
676
+ filtered_posts = posts
677
+
678
+ if sort_option == "Newest First":
679
+ filtered_posts.sort(key=lambda x: x["created_at"], reverse=True)
680
+ elif sort_option == "Oldest First":
681
+ filtered_posts.sort(key=lambda x: x["created_at"])
682
+ elif sort_option == "Most Replies":
683
+ filtered_posts.sort(key=lambda x: len(x["replies"]), reverse=True)
684
+
685
+ # Display posts
686
+ if not filtered_posts:
687
+ st.info("No discussions found. Be the first to start a conversation!")
688
+
689
+ for post in filtered_posts:
690
+ with st.expander(f"{post['title']} - by {post['username']} - {post['category']}"):
691
+ st.markdown(f"**{post['title']}**")
692
+ st.markdown(post['content'])
693
+ st.markdown(f"*Posted on: {datetime.datetime.fromisoformat(post['created_at']).strftime('%Y-%m-%d %H:%M')}*")
694
+
695
+ st.divider()
696
+
697
+ # Display replies
698
+ if post["replies"]:
699
+ st.markdown("#### Replies")
700
+ for reply in post["replies"]:
701
+ st.markdown(f"**{reply['username']}**: {reply['content']}")
702
+ st.markdown(f"*{datetime.datetime.fromisoformat(reply['created_at']).strftime('%Y-%m-%d %H:%M')}*")
703
+ st.divider()
704
+
705
+ # Reply form
706
+ with st.form(f"reply_form_{post['id']}"):
707
+ reply_content = st.text_area("Reply to this post", key=f"reply_{post['id']}")
708
+ if st.form_submit_button("Post Reply"):
709
+ if reply_content:
710
+ add_forum_reply(post["id"], username, reply_content)
711
+ st.success("Reply posted successfully!")
712
+ st.rerun()
713
+
714
+ with tab2:
715
+ with st.form("new_post_form"):
716
+ st.markdown("#### Create New Discussion")
717
+ post_title = st.text_input("Title")
718
+ post_category = st.selectbox("Category", categories[1:]) # Exclude "All Categories"
719
+ post_content = st.text_area("Content", height=200)
720
+
721
+ if st.form_submit_button("Post Discussion"):
722
+ if post_title and post_content:
723
+ add_forum_post(username, post_title, post_content, post_category)
724
+ st.success("Discussion posted successfully!")
725
+ st.rerun()
726
+ else:
727
+ st.error("Please fill in all required fields.")
728
 
729
+ # Mentorship and skill development (future scope preview)
730
+ def render_mentorship_preview():
731
+ st.markdown("### 🚀 Coming Soon: Mentorship & Skill Development")
732
+
733
+ col1, col2 = st.columns(2)
734
+
735
+ with col1:
736
+ st.markdown("""
737
+ #### 👨‍🏫 Mentorship Program
738
+ - Connect with experienced mentors in your field
739
+ - Get personalized guidance for scholarship applications
740
+ - Weekly 1:1 mentorship sessions
741
+ - Career planning and academic advice
742
+ """)
743
+
744
+ with col2:
745
+ st.markdown("""
746
+ #### 🧠 Skill Development
747
+ - Free courses tailored to scholarship requirements
748
+ - Interview preparation workshops
749
+ - Essay writing masterclasses
750
+ - Language proficiency training
751
+ """)
752
+
753
+ st.info("These features are coming soon! Join our waitlist to be notified when they launch.")
754
+
755
+ with st.form("waitlist_form"):
756
+ waitlist_email = st.text_input("Email address")
757
+ interests = st.multiselect("I'm interested in", ["Mentorship", "Skill Development", "Both"])
758
+
759
+ if st.form_submit_button("Join Waitlist"):
760
+ if waitlist_email:
761
+ st.success("Thank you for joining our waitlist! We'll notify you when these features launch.")
762
+ else:
763
+ st.error("Please enter your email address.")
764
+
765
+ # Financial planning feature (future scope preview)
766
+ def render_financial_planning_preview():
767
+ st.markdown("### 💰 Financial Planning Tools")
768
+
769
+ col1, col2 = st.columns(2)
770
+
771
+ with col1:
772
+ st.markdown("""
773
+ #### 📊 Scholarship Budget Planner
774
+ - Calculate total education expenses
775
+ - Track scholarship applications and potential funding
776
+ - Gap analysis between costs and available funding
777
+ - Prioritize applications based on financial need
778
+ """)
779
+
780
+ with col2:
781
+ st.markdown("""
782
+ #### 💸 Financial Literacy Resources
783
+ - Educational content on managing scholarship funds
784
+ - Tax implications of scholarships
785
+ - Combining scholarships with student loans
786
+ - Building credit history as a student
787
+ """)
788
+
789
+ st.info("These financial planning tools are coming soon! Join our waitlist to be notified when they launch.")
790
+
791
+ # Sample financial planning calculator preview
792
+ st.markdown("#### 🔍 Education Cost Calculator Preview")
793
+
794
+ with st.form("cost_calculator"):
795
+ tuition = st.number_input("Estimated Annual Tuition (₹)", 0, 2000000, 100000, 10000)
796
+ living = st.number_input("Annual Living Expenses (₹)", 0, 1000000, 120000, 10000)
797
+ books = st.number_input("Books and Supplies (₹)", 0, 100000, 15000, 1000)
798
+ travel = st.number_input("Travel Expenses (₹)", 0, 100000, 20000, 1000)
799
+ years = st.number_input("Program Duration (years)", 1, 6, 4, 1)
800
+
801
+ if st.form_submit_button("Calculate Total Cost"):
802
+ annual_cost = tuition + living + books + travel
803
+ total_cost = annual_cost * years
804
+
805
+ st.markdown(f"**Annual Cost:** ₹{annual_cost:,}")
806
+ st.markdown(f"**Total Program Cost:** ₹{total_cost:,}")
807
+
808
+ # Display funding gap visualization
809
+ st.markdown("#### Funding Gap Analysis")
810
+ st.progress(0.2)
811
+ st.markdown("20% of costs currently covered by identified scholarships")
812
 
813
+ # Career alignment feature (future scope preview)
814
+ def render_career_alignment_preview():
815
+ st.markdown("### 🎯 Career Alignment Tools")
816
+
817
+ st.markdown("""
818
+ Our upcoming Career Alignment feature will help you connect your scholarship journey with your long-term career goals.
819
+ """)
820
+
821
+ col1, col2 = st.columns(2)
822
+
823
+ with col1:
824
+ st.markdown("""
825
+ #### 🧭 Career Pathway Mapping
826
+ - Personalized career roadmap based on your profile
827
+ - Identify skills gaps and development opportunities
828
+ - Connect with industry professionals
829
+ - Internship and job placement assistance
830
+ """)
831
+
832
+ with col2:
833
+ st.markdown("""
834
+ #### 🏆 Post-Scholarship Success
835
+ - Resume and portfolio building workshops
836
+ - Interview preparation specifically for scholars
837
+ - Alumni network access
838
+ - Scholarship to job transition guidance
839
+ """)
840
+
841
+ # AI Career Recommendation Preview
842
+ st.markdown("#### 🤖 AI Career Recommendation (Preview)")
843
+
844
+ with st.form("career_recommendation"):
845
+ interests = st.multiselect(
846
+ "Select your interests",
847
+ ["Technology", "Healthcare", "Business", "Arts", "Sciences", "Education", "Law", "Engineering"]
848
+ )
849
+
850
+ skills = st.multiselect(
851
+ "Select your top skills",
852
+ ["Programming", "Data Analysis", "Writing", "Research", "Design", "Leadership", "Problem-Solving", "Communication"]
853
+ )
854
+
855
+ values = st.multiselect(
856
+ "What do you value in a career?",
857
+ ["Work-Life Balance", "High Income", "Making an Impact", "Creativity", "Recognition", "Stability", "Independence", "Growth"]
858
+ )
859
+
860
+ if st.form_submit_button("Get AI Career Recommendations"):
861
+ if interests and skills and values:
862
+ st.info("Based on your profile, we recommend exploring these career paths:")
863
+
864
+ if "Technology" in interests and "Programming" in skills:
865
+ st.markdown("1. **Software Development Engineer** - Aligned with your technical interests and problem-solving skills")
866
+ elif "Healthcare" in interests:
867
+ st.markdown("1. **Healthcare Researcher** - Combines your interest in healthcare with analytical skills")
868
+ elif "Business" in interests:
869
+ st.markdown("1. **Business Analyst** - Leverages your data analysis skills in a business context")
870
+ else:
871
+ st.markdown("1. **Research Specialist** - Aligns with your analytical mindset and subject interests")
872
+
873
+ st.markdown("*Full career alignment features coming soon!*")
874
+ else:
875
+ st.error("Please fill in all fields to get personalized recommendations.")
876
 
877
+ # Streamlit app
878
+ def main():
879
+ # Load custom CSS
880
+ load_css()
881
+
882
+ # Initialize session state
883
+ if "authenticated" not in st.session_state:
884
+ st.session_state.authenticated = False
885
+ if "username" not in st.session_state:
886
+ st.session_state.username = None
887
+ if "profile_complete" not in st.session_state:
888
+ st.session_state.profile_complete = False
889
+
890
+ # Hero Section
891
+ st.markdown("""
892
+ <div style="text-align: center; padding: 50px 0;">
893
+ <h1 style="color: #2c3e50; font-size: 3rem;">🎓 AI Scholarship Advisor</h1>
894
+ <p style="color: #34495e; font-size: 1.2rem;">Find the best scholarships tailored just for you!</p>
895
+ </div>
896
+ """, unsafe_allow_html=True)
897
+
898
+ # User Authentication
899
+ if not st.session_state.authenticated:
900
+ tab1, tab2 = st.tabs(["Login", "Register"])
901
+
902
+ with tab1:
903
+ with st.form("login_form"):
904
+ username = st.text_input("Username")
905
+ password = st.text_input("Password", type="password")
906
+ if st.form_submit_button("Login"):
907
+ if authenticate(username, password):
908
+ st.session_state.authenticated = True
909
+ st.session_state.username = username
910
+
911
+ # Check if profile is complete
912
+ profile = get_user_profile(username)
913
+ if profile and profile.get("profile_completed", False):
914
+ st.session_state.profile_complete = True
915
+
916
+ st.rerun()
917
+ else:
918
+ st.error("Invalid username or password")
919
+
920
+ with tab2:
921
+ with st.form("register_form"):
922
+ new_username = st.text_input("Username", key="reg_username")
923
+ new_password = st.text_input("Password", type="password", key="reg_password")
924
+ confirm_password = st.text_input("Confirm Password", type="password")
925
+ email = st.text_input("Email Address")
926
+
927
+ if st.form_submit_button("Register"):
928
+ if new_password != confirm_password:
929
+ st.error("Passwords do not match")
930
+ elif not new_username or not new_password or not email:
931
+ st.error("All fields are required")
932
+ else:
933
+ if register_user(new_username, new_password, email):
934
+ st.success("Registration successful! Please login.")
935
+ else:
936
+ st.error("Username already exists")
937
+
938
+ else:
939
+ # User is authenticated
940
+ username = st.session_state.username
941
+
942
+ # Check profile completion
943
+ profile = get_user_profile(username)
944
+ profile_complete = profile.get("profile_completed", False)
945
+
946
+ if not profile_complete and not st.session_state.profile_complete:
947
+ # User profile needs to be completed
948
+ render_profile_wizard(username)
949
+ else:
950
+ # Main application tabs
951
+ tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
952
+ "💡 Recommendations",
953
+ "📋 Saved Scholarships",
954
+ "📝 Applications",
955
+ "💬 Community Forum",
956
+ "🧠 Skill Development",
957
+ "💰 Financial Planning"
958
+ ])
959
+
960
+ # Load data
961
+ df = load_scholarships()
962
+
963
+ with tab1:
964
+ st.markdown("### 🎯 Get Personalized Recommendations")
965
+
966
+ # Get user profile for recommendations
967
+ profile = get_user_profile(username)
968
+
969
+ # User can modify certain profile elements for this search
970
+ with st.form("profile_form"):
971
+ st.markdown("### 📝 Customize Search Criteria")
972
+ col1, col2 = st.columns(2)
973
+ with col1:
974
+ age = st.number_input("Age", 16, 50, int(profile.get("age", 20)) if "age" in profile else 20)
975
+ citizenship = st.selectbox(
976
+ "Citizenship",
977
+ ["India", "Other"],
978
+ index=0 if profile.get("citizenship", "India") == "India" else 1
979
+ )
980
+ income = st.number_input(
981
+ "Annual Family Income (₹)",
982
+ 0, 10000000,
983
+ int(profile.get("income", 300000)) if "income" in profile else 300000
984
+ )
985
+ with col2:
986
+ education = st.selectbox(
987
+ "Education Level",
988
+ ["High School", "Undergraduate", "Postgraduate", "PhD"],
989
+ index=["High School", "Undergraduate", "Postgraduate", "PhD"].index(profile.get("education", "Undergraduate")) if "education" in profile else 1
990
+ )
991
+ category = st.selectbox(
992
+ "Category",
993
+ ["General", "OBC", "SC", "ST", "EWS", "Minority"],
994
+ index=["General", "OBC", "SC", "ST", "EWS", "Minority"].index(profile.get("category", "General")) if "category" in profile else 0
995
+ )
996
+
997
+ submitted = st.form_submit_button("🚀 Get Recommendations")
998
+
999
+ if submitted:
1000
+ # Create user profile
1001
+ user_profile = f"""
1002
+ Student Profile:
1003
+ - Age: {age}
1004
+ - Citizenship: {citizenship}
1005
+ - Annual Income: ₹{income}
1006
+ - Education Level: {education}
1007
+ - Category: {category}
1008
+ """
1009
+
1010
+ # Create RAG context
1011
+ rag_context = create_rag_context(df)
1012
+
1013
+ # Generate response using RAG
1014
+ model = get_rag_model()
1015
+ prompt = f"""
1016
+ {rag_context}
1017
+ {user_profile}
1018
+ Task:
1019
+ 1. Analyze the student profile against all scholarships
1020
+ 2. Identify top 5 most relevant scholarships with priority order
1021
+ 3. For each scholarship:
1022
+ - List matching eligibility criteria
1023
+ - Explain why it's a good match
1024
+ - Provide direct application link
1025
+ 4. Format response with markdown headers and bullet points
1026
+ Important:
1027
+ - Be specific about eligibility matches
1028
+ - Highlight deadlines if available
1029
+ - Never invent scholarships not in the database
1030
+ """
1031
+
1032
+ with st.spinner("🔍 Analyzing 50+ scholarships..."):
1033
+ response = model.generate_content(
1034
+ prompt,
1035
+ generation_config=GenerationConfig(
1036
+ temperature=0.3,
1037
+ top_p=0.95,
1038
+ max_output_tokens=2000
1039
+ )
1040
+ )
1041
+
1042
+ # Display recommendations
1043
+ st.markdown("### 🎉 Personalized Recommendations")
1044
+
1045
+ # Process the response to add save buttons
1046
+ recommendations_text = response.text
1047
+
1048
+ # Split the recommendations into sections
1049
+ scholarship_sections = recommendations_text.split("##")[1:] # Skip the first split which is empty
1050
+
1051
+ for section in scholarship_sections:
1052
+ if not section.strip():
1053
+ continue
1054
+
1055
+ # Extract scholarship name from the header
1056
+ lines = section.strip().split("\n")
1057
+ scholarship_name = lines[0].strip()
1058
+
1059
+ # Find deadline if mentioned
1060
+ deadline = "Not specified"
1061
+ for line in lines:
1062
+ if "deadline" in line.lower():
1063
+ deadline = line.split(":", 1)[1].strip() if ":" in line else line
1064
+ break
1065
+
1066
+ # Create a card for this scholarship
1067
+ st.markdown(f"""
1068
+ <div class="scholarship-card">
1069
+ <h3>{scholarship_name}</h3>
1070
+ {"".join([f"<p>{line}</p>" for line in lines[1:]])}
1071
+ </div>
1072
+ """, unsafe_allow_html=True)
1073
+
1074
+ # Add a button to save this scholarship
1075
+ if st.button(f"Save this scholarship", key=f"save_{scholarship_name}"):
1076
+ if save_scholarship(username, scholarship_name, deadline):
1077
+ st.success(f"Saved {scholarship_name} to your list!")
1078
+ else:
1079
+ st.info("This scholarship is already in your saved list.")
1080
+
1081
+ # Show raw data for transparency
1082
+ with st.expander("📊 View Full Scholarship Database"):
1083
+ st.dataframe(df)
1084
+
1085
+ with tab2:
1086
+ st.markdown("### 📋 Your Saved Scholarships")
1087
+
1088
+ saved = get_saved_scholarships(username)
1089
+
1090
+ if not saved:
1091
+ st.info("You haven't saved any scholarships yet. Go to the Recommendations tab to find and save scholarships.")
1092
+ else:
1093
+ # Group by status
1094
+ saved_by_status = {}
1095
+ for s in saved:
1096
+ status = s.get("status", "Saved")
1097
+ if status not in saved_by_status:
1098
+ saved_by_status[status] = []
1099
+ saved_by_status[status].append(s)
1100
+
1101
+ # Create tabs for different statuses
1102
+ status_tabs = st.tabs(list(saved_by_status.keys()))
1103
+
1104
+ for i, (status, scholarships) in enumerate(saved_by_status.items()):
1105
+ with status_tabs[i]:
1106
+ for scholarship in scholarships:
1107
+ with st.expander(f"{scholarship['name']} (Deadline: {scholarship['deadline']})"):
1108
+ st.markdown(f"**{scholarship['name']}**")
1109
+ st.markdown(f"Deadline: {scholarship['deadline']}")
1110
+ st.markdown(f"Saved on: {datetime.datetime.fromisoformat(scholarship['saved_at']).strftime('%Y-%m-%d')}")
1111
+
1112
+ # Find full details in the dataframe
1113
+ scholarship_details = df[df['Scholarship Name'] == scholarship['name']]
1114
+ if not scholarship_details.empty:
1115
+ st.markdown(f"Eligibility: {scholarship_details.iloc[0]['Eligibility']}")
1116
+ st.markdown(f"Link: {scholarship_details.iloc[0]['Link']}")
1117
+
1118
+ col1, col2 = st.columns(2)
1119
+
1120
+ with col1:
1121
+ if st.button("Start Application", key=f"apply_{scholarship['name']}"):
1122
+ track_application(username, scholarship['name'])
1123
+ update_scholarship_status(username, scholarship['name'], "Started")
1124
+ st.session_state.current_application = scholarship['name']
1125
+ st.rerun()
1126
+
1127
+ with col2:
1128
+ if st.button("Set Reminder", key=f"remind_{scholarship['name']}"):
1129
+ # Get user email
1130
+ users = load_users()
1131
+ email = users[username]["email"]
1132
+
1133
+ # Send notification
1134
+ if send_deadline_notification(email, scholarship['name'], scholarship['deadline']):
1135
+ st.success("Reminder email sent!")
1136
+ else:
1137
+ st.error("Failed to send reminder email.")
1138
+
1139
+ with tab3:
1140
+ st.markdown("### 📝 Your Applications")
1141
+
1142
+ # Check if a specific application is being viewed
1143
+ if "current_application" in st.session_state:
1144
+ render_application_form(username, st.session_state.current_application, df)
1145
+
1146
+ if st.button("Back to All Applications"):
1147
+ del st.session_state.current_application
1148
+ st.rerun()
1149
+ else:
1150
+ # Get user's applications
1151
+ users = load_users()
1152
+ applications = users[username]["applications"] if username in users else {}
1153
+
1154
+ if not applications:
1155
+ st.info("You haven't started any applications yet. Save a scholarship and click 'Start Application' to begin.")
1156
+ else:
1157
+ # Group by status/progress
1158
+ in_progress = []
1159
+ completed = []
1160
+ drafts = []
1161
+
1162
+ for name, app in applications.items():
1163
+ if app["progress"] == 100:
1164
+ completed.append((name, app))
1165
+ elif app["status"] == "Draft":
1166
+ drafts.append((name, app))
1167
+ else:
1168
+ in_progress.append((name, app))
1169
+
1170
+ # Create tabs for different statuses
1171
+ app_tabs = st.tabs(["In Progress", "Drafts", "Completed"])
1172
+
1173
+ with app_tabs[0]:
1174
+ if not in_progress:
1175
+ st.info("No applications in progress.")
1176
+ else:
1177
+ for name, app in in_progress:
1178
+ col1, col2 = st.columns([3, 1])
1179
+
1180
+ with col1:
1181
+ st.markdown(f"**{name}**")
1182
+ st.progress(app["progress"] / 100)
1183
+ st.markdown(f"Progress: {app['progress']}% complete")
1184
+
1185
+ with col2:
1186
+ if st.button("Continue", key=f"continue_{name}"):
1187
+ st.session_state.current_application = name
1188
+ st.rerun()
1189
+
1190
+ with app_tabs[1]:
1191
+ if not drafts:
1192
+ st.info("No draft applications.")
1193
+ else:
1194
+ for name, app in drafts:
1195
+ col1, col2 = st.columns([3, 1])
1196
+
1197
+ with col1:
1198
+ st.markdown(f"**{name}**")
1199
+ st.markdown(f"Last updated: {datetime.datetime.fromisoformat(app.get('updated_at', app['started_at'])).strftime('%Y-%m-%d')}")
1200
+
1201
+ with col2:
1202
+ if st.button("Edit Draft", key=f"edit_{name}"):
1203
+ st.session_state.current_application = name
1204
+ st.rerun()
1205
+
1206
+ with app_tabs[2]:
1207
+ if not completed:
1208
+ st.info("No completed applications.")
1209
+ else:
1210
+ for name, app in completed:
1211
+ st.markdown(f"**{name}**")
1212
+ st.markdown(f"Submitted on: {datetime.datetime.fromisoformat(app.get('updated_at', app['started_at'])).strftime('%Y-%m-%d')}")
1213
+ st.success("Application completed and submitted!")
1214
+
1215
+ with tab4:
1216
+ render_forum(username)
1217
+
1218
+ with tab5:
1219
+ render_mentorship_preview()
1220
+
1221
+ with tab6:
1222
+ st.markdown("### Financial Planning Tools")
1223
+
1224
+ tab1, tab2 = st.tabs(["Education Financing", "Career Planning"])
1225
+
1226
+ with tab1:
1227
+ render_financial_planning_preview()
1228
+
1229
+ with tab2:
1230
+ render_career_alignment_preview()
1231
+
1232
+ # Logout button
1233
+ if st.sidebar.button("Logout"):
1234
+ st.session_state.authenticated = False
1235
+ st.session_state.username = None
1236
+ st.session_state.profile_complete = False
1237
+ if "current_application" in st.session_state:
1238
+ del st.session_state.current_application
1239
+ if "profile_step" in st.session_state:
1240
+ del st.session_state.profile_step
1241
+ st.rerun()
1242
 
1243
  if __name__ == "__main__":
1244
  main()