Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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 |
-
|
|
|
|
|
|
|
20 |
llm = ChatGroq(
|
21 |
temperature=0,
|
22 |
-
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
|
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://
|
203 |
-
|
204 |
-
"
|
205 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
}
|
207 |
|
208 |
try:
|
209 |
-
response = requests.get(url, params=
|
210 |
response.raise_for_status()
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
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 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
|
|
|
|
|
|
|
|
|
|
406 |
|
407 |
-
|
408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.,
|
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 |
-
#
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
622 |
-
# -------------------------------
|
623 |
|
624 |
-
|
625 |
-
|
626 |
-
|
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 |
-
|
635 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
636 |
|
637 |
-
|
638 |
-
|
639 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
|
641 |
def main():
|
642 |
st.set_page_config(page_title="Job Application Assistant", layout="wide")
|
643 |
|
644 |
-
#
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
"book", "people", "currency-dollar", "chat-left-text"],
|
657 |
-
menu_icon="cast",
|
658 |
-
default_index=0,
|
659 |
-
)
|
660 |
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
elif
|
680 |
-
|
681 |
-
elif
|
682 |
-
|
|
|
|
|
|
|
|
|
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("")
|
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()
|