AdithyaSNair commited on
Commit
ad6ef2a
·
verified ·
1 Parent(s): edfd203

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +402 -111
app.py CHANGED
@@ -1,5 +1,3 @@
1
- # app.py
2
-
3
  import streamlit as st
4
  from streamlit_option_menu import option_menu
5
  from langchain_groq import ChatGroq
@@ -11,15 +9,16 @@ import uuid
11
  import plotly.express as px
12
  import re
13
  import pandas as pd
14
- import json
15
  import sqlite3
16
- import streamlit_authenticator as stauth
17
  from datetime import datetime, timedelta
18
 
19
- # Initialize the LLM with your Groq API key from Streamlit secrets
 
 
 
20
  llm = ChatGroq(
21
  temperature=0,
22
- groq_api_key="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", # Securely accessing the Groq API key
23
  model_name="llama-3.1-70b-versatile"
24
  )
25
 
@@ -193,36 +192,42 @@ def suggest_keywords(resume_text, job_description=None):
193
 
194
  def get_job_recommendations(resume_text, location="India"):
195
  """
196
- Fetches job recommendations using the Remotive.io API based on the user's skills.
197
  """
198
  # Extract skills from resume
199
  skills = extract_skills(resume_text)
200
  query = " ".join(skills) if skills else "Software Engineer"
201
 
202
- url = "https://remotive.io/api/remote-jobs"
203
- params = {
204
- "search": query,
205
- "limit": 20
 
 
 
 
 
 
206
  }
207
 
208
  try:
209
- response = requests.get(url, params=params)
210
  response.raise_for_status()
211
- data = response.json()
212
- jobs = data.get("jobs", [])
213
- job_list = []
214
- for job in jobs:
215
- job_info = {
216
- "title": job.get("title"),
217
- "company": job.get("company_name"),
218
- "link": job.get("url"),
219
- "job_description": job.get("description") # Including job description for Skill Matching
220
- }
221
- job_list.append(job_info)
222
- return job_list
223
  except Exception as e:
224
  st.error(f"Error fetching job recommendations: {e}")
225
- return []
226
 
227
  def create_skill_distribution_chart(skills):
228
  """
@@ -394,18 +399,171 @@ def generate_learning_path(career_goal, current_skills):
394
  learning_path = response.content.strip()
395
  return learning_path
396
 
397
- def setup_authentication():
398
- """
399
- Sets up user authentication using streamlit-authenticator.
400
- """
401
- # In a real application, retrieve user data from a secure database
402
- names = ["Adithya S Nair"] # Replace with dynamic user data
403
- usernames = ["adithya"]
404
- # Passwords should be hashed in a real application
405
- passwords = ["$2b$12$KIXvUq2YdZ19FWJGzTqFUeAewH1/gO7xmD2z77Qvxh3A1F1C9KdaW"] # "password" hashed
 
 
 
 
 
406
 
407
- authenticator = stauth.Authenticate(names, usernames, passwords, "job_app_assistant", "abcdef", cookie_expiry_days=30)
408
- return authenticator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
  def application_tracking_dashboard():
411
  st.header("Application Tracking Dashboard")
@@ -568,31 +726,50 @@ def salary_estimation_module():
568
  Understand the salary expectations for your desired roles and learn effective negotiation strategies.
569
  """)
570
 
 
571
  job_title = st.text_input("Enter the job title:")
572
- location = st.text_input("Enter the location (e.g., Bangalore, India):")
573
 
574
  if st.button("Get Salary Estimate"):
575
  if not job_title or not location:
576
  st.error("Please enter both job title and location.")
577
  return
578
  with st.spinner("Fetching salary data..."):
579
- # Example using a placeholder API or precompiled data
580
- # Replace with actual API integration if available
581
- # For demonstration, we'll use a mock response
582
- prompt = f"""
583
- Provide an estimated salary range for a {job_title} in {location}. Include the minimum, average, and maximum salaries.
584
- """
585
- salary_data = llm.invoke({"input": prompt}).content.strip()
586
- st.subheader("Salary Estimate:")
587
- st.write(salary_data)
588
-
589
- # Generate negotiation tips
590
- tips_prompt = f"""
591
- Provide a list of 5 effective tips for negotiating a salary for a {job_title} position in {location}.
592
- """
593
- tips = llm.invoke({"input": tips_prompt}).content.strip()
594
- st.subheader("Negotiation Tips:")
595
- st.write(tips)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
 
597
  def feedback_and_improvement_module():
598
  st.header("Feedback and Continuous Improvement")
@@ -612,74 +789,188 @@ def feedback_and_improvement_module():
612
  if not name or not email or not feedback:
613
  st.error("Please fill in all the fields.")
614
  else:
615
- # Here you can implement logic to store feedback, e.g., in a database or send via email
616
- # For demonstration, we'll print to the console
617
  print(f"Feedback from {name} ({email}): {feedback_type} - {feedback}")
618
  st.success("Thank you for your feedback!")
619
 
620
- # -------------------------------
621
- # Authentication Setup
622
- # -------------------------------
623
 
624
- def setup_authentication():
625
- """
626
- Sets up user authentication using streamlit-authenticator.
627
- """
628
- # In a real application, retrieve user data from a secure database
629
- names = ["Adithya S Nair"] # Replace with dynamic user data
630
- usernames = ["adithya"]
631
- # Passwords should be hashed in a real application
632
- passwords = ["$2b$12$KIXvUq2YdZ19FWJGzTqFUeAewH1/gO7xmD2z77Qvxh3A1F1C9KdaW"] # "password" hashed
633
 
634
- authenticator = stauth.Authenticate(names, usernames, passwords, "job_app_assistant", "abcdef", cookie_expiry_days=30)
635
- return authenticator
 
 
 
 
 
 
 
 
636
 
637
- # -------------------------------
638
- # Main App with Sidebar Navigation
639
- # -------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
 
641
  def main():
642
  st.set_page_config(page_title="Job Application Assistant", layout="wide")
643
 
644
- # Setup authentication
645
- authenticator = setup_authentication()
646
- name, authentication_status = authenticator.login("Login", "main")
647
-
648
- if authentication_status:
649
- with st.sidebar:
650
- selected = option_menu(
651
- "Main Menu",
652
- ["Email Generator", "Cover Letter Generator", "Resume Analysis", "Application Tracking",
653
- "Interview Preparation", "Personalized Learning Paths", "Networking Opportunities",
654
- "Salary Estimation", "Feedback"],
655
- icons=["envelope", "file-earmark-text", "file-person", "briefcase", "gear",
656
- "book", "people", "currency-dollar", "chat-left-text"],
657
- menu_icon="cast",
658
- default_index=0,
659
- )
660
 
661
- if selected == "Email Generator":
662
- email_generator_page()
663
- elif selected == "Cover Letter Generator":
664
- cover_letter_generator_page()
665
- elif selected == "Resume Analysis":
666
- resume_analysis_page()
667
- elif selected == "Application Tracking":
668
- application_tracking_dashboard()
669
- elif selected == "Interview Preparation":
670
- interview_preparation_module()
671
- elif selected == "Personalized Learning Paths":
672
- personalized_learning_paths_module()
673
- elif selected == "Networking Opportunities":
674
- networking_opportunities_module()
675
- elif selected == "Salary Estimation":
676
- salary_estimation_module()
677
- elif selected == "Feedback":
678
- feedback_and_improvement_module()
679
- elif authentication_status == False:
680
- st.error("Username/password is incorrect")
681
- elif authentication_status == None:
682
- st.warning("Please enter your username and password")
 
 
 
 
683
 
684
  if __name__ == "__main__":
685
  main()
 
 
 
1
  import streamlit as st
2
  from streamlit_option_menu import option_menu
3
  from langchain_groq import ChatGroq
 
9
  import plotly.express as px
10
  import re
11
  import pandas as pd
 
12
  import sqlite3
 
13
  from datetime import datetime, timedelta
14
 
15
+ GROQ_API_KEY = "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"
16
+ RAPIDAPI_KEY = "2a4a8a38a9msh97ce530a89589a6p1d0106jsn1acc0a5ea6bc"
17
+
18
+
19
  llm = ChatGroq(
20
  temperature=0,
21
+ groq_api_key=GROQ_API_KEY,
22
  model_name="llama-3.1-70b-versatile"
23
  )
24
 
 
192
 
193
  def get_job_recommendations(resume_text, location="India"):
194
  """
195
+ Fetches job recommendations using the JSearch API based on the user's skills.
196
  """
197
  # Extract skills from resume
198
  skills = extract_skills(resume_text)
199
  query = " ".join(skills) if skills else "Software Engineer"
200
 
201
+ url = "https://jsearch.p.rapidapi.com/estimated-salary"
202
+ querystring = {
203
+ "job_title": query,
204
+ "location": location,
205
+ "radius": "100" # Adjust radius as needed
206
+ }
207
+
208
+ headers = {
209
+ "x-rapidapi-key": RAPIDAPI_KEY, # Embedded API key
210
+ "x-rapidapi-host": "jsearch.p.rapidapi.com"
211
  }
212
 
213
  try:
214
+ response = requests.get(url, headers=headers, params=querystring)
215
  response.raise_for_status()
216
+ salary_data = response.json()
217
+
218
+ # Extract relevant data
219
+ min_salary = salary_data.get("min_salary")
220
+ avg_salary = salary_data.get("avg_salary")
221
+ max_salary = salary_data.get("max_salary")
222
+
223
+ return {
224
+ "min_salary": min_salary,
225
+ "avg_salary": avg_salary,
226
+ "max_salary": max_salary
227
+ }
228
  except Exception as e:
229
  st.error(f"Error fetching job recommendations: {e}")
230
+ return {}
231
 
232
  def create_skill_distribution_chart(skills):
233
  """
 
399
  learning_path = response.content.strip()
400
  return learning_path
401
 
402
+ # -------------------------------
403
+ # Page Functions
404
+ # -------------------------------
405
+
406
+ def email_generator_page():
407
+ st.header("Automated Email Generator")
408
+
409
+ st.write("""
410
+ Generate personalized cold emails based on job postings and your resume.
411
+ """)
412
+
413
+ # Input fields
414
+ job_link = st.text_input("Enter the job link:")
415
+ uploaded_file = st.file_uploader("Upload your resume (PDF format):", type="pdf")
416
 
417
+ if st.button("Generate Email"):
418
+ if not job_link:
419
+ st.error("Please enter a job link.")
420
+ return
421
+ if not uploaded_file:
422
+ st.error("Please upload your resume.")
423
+ return
424
+
425
+ with st.spinner("Processing..."):
426
+ # Extract job description
427
+ job_description = extract_job_description(job_link)
428
+ if not job_description:
429
+ st.error("Failed to extract job description.")
430
+ return
431
+
432
+ # Extract requirements
433
+ requirements = extract_requirements(job_description)
434
+ if not requirements:
435
+ st.error("Failed to extract requirements.")
436
+ return
437
+
438
+ # Extract resume text
439
+ resume_text = extract_text_from_pdf(uploaded_file)
440
+ if not resume_text:
441
+ st.error("Failed to extract text from resume.")
442
+ return
443
+
444
+ # Generate email
445
+ email_text = generate_email(job_description, requirements, resume_text)
446
+ if email_text:
447
+ st.subheader("Generated Email:")
448
+ st.write(email_text)
449
+ # Provide download option
450
+ st.download_button(
451
+ label="Download Email",
452
+ data=email_text,
453
+ file_name="generated_email.txt",
454
+ mime="text/plain"
455
+ )
456
+ else:
457
+ st.error("Failed to generate email.")
458
+
459
+ def cover_letter_generator_page():
460
+ st.header("Automated Cover Letter Generator")
461
+
462
+ st.write("""
463
+ Generate personalized cover letters based on job postings and your resume.
464
+ """)
465
+
466
+ # Input fields
467
+ job_link = st.text_input("Enter the job link:")
468
+ uploaded_file = st.file_uploader("Upload your resume (PDF format):", type="pdf")
469
+
470
+ if st.button("Generate Cover Letter"):
471
+ if not job_link:
472
+ st.error("Please enter a job link.")
473
+ return
474
+ if not uploaded_file:
475
+ st.error("Please upload your resume.")
476
+ return
477
+
478
+ with st.spinner("Processing..."):
479
+ # Extract job description
480
+ job_description = extract_job_description(job_link)
481
+ if not job_description:
482
+ st.error("Failed to extract job description.")
483
+ return
484
+
485
+ # Extract requirements
486
+ requirements = extract_requirements(job_description)
487
+ if not requirements:
488
+ st.error("Failed to extract requirements.")
489
+ return
490
+
491
+ # Extract resume text
492
+ resume_text = extract_text_from_pdf(uploaded_file)
493
+ if not resume_text:
494
+ st.error("Failed to extract text from resume.")
495
+ return
496
+
497
+ # Generate cover letter
498
+ cover_letter = generate_cover_letter(job_description, requirements, resume_text)
499
+ if cover_letter:
500
+ st.subheader("Generated Cover Letter:")
501
+ st.write(cover_letter)
502
+ # Provide download option
503
+ st.download_button(
504
+ label="Download Cover Letter",
505
+ data=cover_letter,
506
+ file_name="generated_cover_letter.txt",
507
+ mime="text/plain"
508
+ )
509
+ else:
510
+ st.error("Failed to generate cover letter.")
511
+
512
+ def resume_analysis_page():
513
+ st.header("Resume Analysis and Optimization")
514
+
515
+ uploaded_file = st.file_uploader("Upload your resume (PDF format):", type="pdf")
516
+
517
+ if uploaded_file:
518
+ resume_text = extract_text_from_pdf(uploaded_file)
519
+ if resume_text:
520
+ st.success("Resume uploaded successfully!")
521
+ # Perform analysis
522
+ st.subheader("Extracted Information")
523
+ # Extracted skills
524
+ skills = extract_skills(resume_text)
525
+ st.write("**Skills:**", ', '.join(skills))
526
+ # Extract keywords
527
+ keywords = suggest_keywords(resume_text)
528
+ st.write("**Suggested Keywords for ATS Optimization:**", ', '.join(keywords))
529
+ # Provide optimization suggestions
530
+ st.subheader("Optimization Suggestions")
531
+ st.write("- **Keyword Optimization:** Incorporate the suggested keywords to improve ATS compatibility.")
532
+ st.write("- **Formatting:** Ensure consistent formatting for headings and bullet points to enhance readability.")
533
+ st.write("- **Experience Details:** Provide specific achievements and quantify your accomplishments where possible.")
534
+
535
+ # Visual Resume Analytics
536
+ st.subheader("Visual Resume Analytics")
537
+ # Skill Distribution Chart
538
+ if skills:
539
+ st.write("**Skill Distribution:**")
540
+ fig_skills = create_skill_distribution_chart(skills)
541
+ st.plotly_chart(fig_skills)
542
+
543
+ # Experience Timeline (if applicable)
544
+ fig_experience = create_experience_timeline(resume_text)
545
+ if fig_experience:
546
+ st.write("**Experience Timeline:**")
547
+ st.plotly_chart(fig_experience)
548
+ else:
549
+ st.write("**Experience Timeline:** Not enough data to generate a timeline.")
550
+
551
+ # Save the resume and analysis to the database
552
+ if st.button("Save Resume Analysis"):
553
+ add_application(
554
+ job_title="N/A",
555
+ company="N/A",
556
+ application_date=datetime.now().strftime("%Y-%m-%d"),
557
+ status="N/A",
558
+ deadline="N/A",
559
+ notes="Resume Analysis",
560
+ job_description="N/A",
561
+ resume_text=resume_text,
562
+ skills=skills
563
+ )
564
+ st.success("Resume analysis saved successfully!")
565
+ else:
566
+ st.error("Failed to extract text from resume.")
567
 
568
  def application_tracking_dashboard():
569
  st.header("Application Tracking Dashboard")
 
726
  Understand the salary expectations for your desired roles and learn effective negotiation strategies.
727
  """)
728
 
729
+ # Input fields
730
  job_title = st.text_input("Enter the job title:")
731
+ location = st.text_input("Enter the location (e.g., New York, NY, USA):")
732
 
733
  if st.button("Get Salary Estimate"):
734
  if not job_title or not location:
735
  st.error("Please enter both job title and location.")
736
  return
737
  with st.spinner("Fetching salary data..."):
738
+ # JSearch API Integration
739
+ salary_data = get_job_recommendations(job_title, location)
740
+ if salary_data:
741
+ min_salary = salary_data.get("min_salary")
742
+ avg_salary = salary_data.get("avg_salary")
743
+ max_salary = salary_data.get("max_salary")
744
+
745
+ if min_salary and avg_salary and max_salary:
746
+ st.subheader("Salary Estimate:")
747
+ st.write(f"**Minimum Salary:** ${min_salary:,}")
748
+ st.write(f"**Average Salary:** ${avg_salary:,}")
749
+ st.write(f"**Maximum Salary:** ${max_salary:,}")
750
+
751
+ # Visualization
752
+ salary_df = pd.DataFrame({
753
+ "Salary Range": ["Minimum", "Average", "Maximum"],
754
+ "Amount": [min_salary, avg_salary, max_salary]
755
+ })
756
+
757
+ fig = px.bar(salary_df, x="Salary Range", y="Amount",
758
+ title=f"Salary Estimates for {job_title} in {location}",
759
+ labels={"Amount": "Salary (USD)"},
760
+ text_auto=True)
761
+ st.plotly_chart(fig)
762
+ else:
763
+ st.error("Salary data not available for the provided job title and location.")
764
+
765
+ tips_prompt = f"""
766
+ Provide a list of 5 effective tips for negotiating a salary for a {job_title} position in {location}.
767
+ """
768
+ tips = llm.invoke({"input": tips_prompt}).content.strip()
769
+ st.subheader("Negotiation Tips:")
770
+ st.write(tips)
771
+ else:
772
+ st.error("Failed to retrieve salary data.")
773
 
774
  def feedback_and_improvement_module():
775
  st.header("Feedback and Continuous Improvement")
 
789
  if not name or not email or not feedback:
790
  st.error("Please fill in all the fields.")
791
  else:
 
 
792
  print(f"Feedback from {name} ({email}): {feedback_type} - {feedback}")
793
  st.success("Thank you for your feedback!")
794
 
795
+ def gamification_module():
796
+ st.header("Gamification and Achievements")
 
797
 
798
+ st.write("""
799
+ Stay motivated by earning badges and tracking your progress!
800
+ """)
 
 
 
 
 
 
801
 
802
+ # Example achievements
803
+ applications = fetch_applications()
804
+ num_apps = len(applications)
805
+ achievements = {
806
+ "First Application": num_apps >= 1,
807
+ "5 Applications": num_apps >= 5,
808
+ "10 Applications": num_apps >= 10,
809
+ "Resume Optimized": any(app['Skills'] for app in applications),
810
+ "Interview Scheduled": any(app['Status'] == 'Interviewing' for app in applications)
811
+ }
812
 
813
+ for achievement, earned in achievements.items():
814
+ if earned:
815
+ st.success(f"🎉 {achievement}")
816
+ else:
817
+ st.info(f"🔜 {achievement}")
818
+
819
+ # Progress Bar
820
+ progress = min(num_apps / 10 * 100, 100) # Assuming 10 applications for full progress
821
+ st.write("**Overall Progress:**")
822
+ st.progress(progress)
823
+ st.write(f"{progress:.0f}% complete")
824
+
825
+ def resource_library_page():
826
+ st.header("Resource Library")
827
+
828
+ st.write("""
829
+ Access a collection of templates and guides to enhance your job search.
830
+ """)
831
+
832
+ resources = [
833
+ {
834
+ "title": "Resume Template",
835
+ "description": "A professional resume template in DOCX format.",
836
+ "file": "resume_template.docx"
837
+ },
838
+ {
839
+ "title": "Cover Letter Template",
840
+ "description": "A customizable cover letter template.",
841
+ "file": "cover_letter_template.docx"
842
+ },
843
+ {
844
+ "title": "Job Application Checklist",
845
+ "description": "Ensure you have all the necessary steps covered during your job search.",
846
+ "file": "application_checklist.pdf"
847
+ }
848
+ ]
849
+
850
+ for resource in resources:
851
+ st.markdown(f"### {resource['title']}")
852
+ st.write(resource['description'])
853
+ try:
854
+ with open(resource['file'], "rb") as file:
855
+ btn = st.download_button(
856
+ label="Download",
857
+ data=file,
858
+ file_name=resource['file'],
859
+ mime="application/octet-stream"
860
+ )
861
+ except FileNotFoundError:
862
+ st.error(f"File {resource['file']} not found.")
863
+ st.write("---")
864
+
865
+ def success_stories_page():
866
+ st.header("Success Stories")
867
+
868
+ st.write("""
869
+ Hear from our users who have successfully landed their dream jobs with our assistance!
870
+ """)
871
+
872
+ # Example testimonials
873
+ testimonials = [
874
+ {
875
+ "name": "Rahul Sharma",
876
+ "position": "Data Scientist at TechCorp",
877
+ "testimonial": "This app transformed my job search process. The resume analysis and personalized emails were game-changers!",
878
+ "image": "images/user1.jpg" # Replace with actual image paths
879
+ },
880
+ {
881
+ "name": "Priya Mehta",
882
+ "position": "Machine Learning Engineer at InnovateX",
883
+ "testimonial": "The interview preparation module helped me ace my interviews with confidence. Highly recommended!",
884
+ "image": "images/user2.jpg"
885
+ }
886
+ ]
887
+
888
+ for user in testimonials:
889
+ col1, col2 = st.columns([1, 3])
890
+ with col1:
891
+ try:
892
+ st.image(user["image"], width=100)
893
+ except:
894
+ st.write("![User Image](https://via.placeholder.com/100)")
895
+ with col2:
896
+ st.write(f"**{user['name']}**")
897
+ st.write(f"*{user['position']}*")
898
+ st.write(f"\"{user['testimonial']}\"")
899
+ st.write("---")
900
+
901
+ def chatbot_support_page():
902
+ st.header("AI-Powered Chatbot Support")
903
+
904
+ st.write("""
905
+ Have questions or need assistance? Chat with our AI-powered assistant!
906
+ """)
907
+
908
+ # Initialize session state for chatbot
909
+ if 'chat_history' not in st.session_state:
910
+ st.session_state['chat_history'] = []
911
+
912
+ user_input = st.text_input("You:", key="user_input")
913
+
914
+ if st.button("Send"):
915
+ if user_input:
916
+ st.session_state['chat_history'].append(f"You: {user_input}")
917
+ prompt = f"""
918
+ You are a helpful assistant for a Job Application Assistant app. Answer the user's query based on the following context:
919
+
920
+ {user_input}
921
+ """
922
+ response = llm.invoke({"input": prompt}).content.strip()
923
+ st.session_state['chat_history'].append(f"Assistant: {response}")
924
+
925
+ # Display chat history
926
+ for message in st.session_state['chat_history']:
927
+ if message.startswith("You:"):
928
+ st.markdown(f"<p style='color:blue;'>{message}</p>", unsafe_allow_html=True)
929
+ else:
930
+ st.markdown(f"<p style='color:green;'>{message}</p>", unsafe_allow_html=True)
931
 
932
  def main():
933
  st.set_page_config(page_title="Job Application Assistant", layout="wide")
934
 
935
+ # Sidebar Navigation
936
+ with st.sidebar:
937
+ selected = option_menu(
938
+ "Main Menu",
939
+ ["Email Generator", "Cover Letter Generator", "Resume Analysis", "Application Tracking",
940
+ "Interview Preparation", "Personalized Learning Paths", "Networking Opportunities",
941
+ "Salary Estimation", "Feedback", "Gamification", "Resource Library", "Success Stories", "Chatbot Support"],
942
+ icons=["envelope", "file-earmark-text", "file-person", "briefcase", "gear",
943
+ "book", "people", "currency-dollar", "chat-left-text", "trophy", "collection", "star", "chat"],
944
+ menu_icon="cast",
945
+ default_index=0,
946
+ )
 
 
 
 
947
 
948
+ if selected == "Email Generator":
949
+ email_generator_page()
950
+ elif selected == "Cover Letter Generator":
951
+ cover_letter_generator_page()
952
+ elif selected == "Resume Analysis":
953
+ resume_analysis_page()
954
+ elif selected == "Application Tracking":
955
+ application_tracking_dashboard()
956
+ elif selected == "Interview Preparation":
957
+ interview_preparation_module()
958
+ elif selected == "Personalized Learning Paths":
959
+ personalized_learning_paths_module()
960
+ elif selected == "Networking Opportunities":
961
+ networking_opportunities_module()
962
+ elif selected == "Salary Estimation":
963
+ salary_estimation_module()
964
+ elif selected == "Feedback":
965
+ feedback_and_improvement_module()
966
+ elif selected == "Gamification":
967
+ gamification_module()
968
+ elif selected == "Resource Library":
969
+ resource_library_page()
970
+ elif selected == "Success Stories":
971
+ success_stories_page()
972
+ elif selected == "Chatbot Support":
973
+ chatbot_support_page()
974
 
975
  if __name__ == "__main__":
976
  main()