ResumeIQ / ui /interview_scheduling.py
pranav8tripathi's picture
Update ui/interview_scheduling.py (#9)
f2a0e05 verified
"""Interview scheduling UI components"""
import streamlit as st
import datetime
from agents.interview_scheduler import InterviewScheduler
from db.database import ResumeMatchDB
def handle_interview_scheduling(result, match):
"""Handle interview scheduling for a candidate"""
st.subheader("πŸ“… Schedule Interview")
interview_key = f"interview_{result['candidate_id']}"
if interview_key not in st.session_state.interview_data:
st.session_state.interview_data[interview_key] = {
"interviewer": "",
"meeting_link": "",
"notes": "",
"selected_slot": None
}
data = st.session_state.interview_data[interview_key]
data["interviewer"] = st.text_input(
"Interviewer Name",
value=data["interviewer"],
key=f"interviewer_{result['candidate_id']}"
)
data["meeting_link"] = st.text_input(
"Meeting Link (optional)",
value=data["meeting_link"],
key=f"meeting_{result['candidate_id']}"
)
data["notes"] = st.text_area(
"Additional Notes",
value=data["notes"],
key=f"notes_{result['candidate_id']}"
)
scheduler = InterviewScheduler(result['candidate_name'])
start_date = datetime.datetime.now() + datetime.timedelta(days=1)
slots = scheduler.generate_interview_slots(start_date)
data["selected_slot"] = st.selectbox(
"Select Interview Slot",
options=slots,
format_func=lambda x: x.strftime("%A, %B %d, %Y at %I:%M %p"),
key=f"slot_{result['candidate_id']}",
index=slots.index(data["selected_slot"]) if data["selected_slot"] in slots else 0
)
if st.button("Schedule Interview", key=f"schedule_{result['candidate_id']}"):
if data["selected_slot"] and data["interviewer"]:
schedule_interview(result, match, data)
else:
st.error("Please provide interviewer name and select a time slot")
def schedule_interview(result, match, data):
"""Schedule an interview, update session state, and send email notification"""
db = ResumeMatchDB()
scheduler = InterviewScheduler(result['candidate_name'])
# Format date and time for email
interview_date = data["selected_slot"].strftime("%A, %B %d, %Y")
interview_time = data["selected_slot"].strftime("%I:%M %p %Z")
# Generate meeting link HTML if available
meeting_link_html = f"<p><strong>Meeting Link:</strong> <a href='{data['meeting_link']}'>{data['meeting_link']}</a></p>" if data['meeting_link'] else ""
# Prepare email content
email_subject = f"Interview Scheduled: {match['job_title']} on {interview_date}"
email_body = f"""
<p>Dear {result['candidate_name']},</p>
<p>Your interview has been successfully scheduled for the position of <strong>{match['job_title']}</strong>.</p>
<div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
<h3 style="color: #2c3e50; margin-top: 0;">Interview Details</h3>
<p><strong>Date:</strong> {interview_date}</p>
<p><strong>Time:</strong> {interview_time}</p>
<p><strong>Interviewer:</strong> {data['interviewer']}</p>
{meeting_link_html}
{f"<p><strong>Notes:</strong> {data['notes']}</p>" if data['notes'] else ""}
</div>
<p>Please ensure you have the following ready for the interview:</p>
<ul>
<li>A copy of your resume</li>
<li>Any relevant work samples or portfolio items</li>
<li>Questions you may have about the role</li>
</ul>
<p>If you need to reschedule or have any questions, please reply to this email.</p>
<p style="margin-top: 30px;">
Best regards,<br>
<strong>ResumeIQ Hiring Team</strong>
</p>
"""
# Save to database
db.schedule_interview(
candidate_id=result['candidate_id'],
job_id=match['job_id'],
scheduled_date=data["selected_slot"],
interviewer=data["interviewer"],
meeting_link=data["meeting_link"],
notes=data["notes"]
)
# Update session state
st.session_state.scheduled_interviews.append({
"candidate_id": result['candidate_id'],
"candidate_name": result['candidate_name'],
"job_title": match['job_title'],
"interview_date": data["selected_slot"],
"interviewer": data["interviewer"]
})
# Send email notification
from utils.email_sender import EmailSender
email_sender = EmailSender()
if email_sender.smtp_email and email_sender.smtp_password:
try:
email_sender.send_email(
to_email=result['candidate_email'],
subject=email_subject,
body=email_body
)
st.success("βœ… Interview Scheduled & Email Sent!")
except Exception as e:
st.success("βœ… Interview Scheduled!")
st.warning(f"⚠️ Could not send email: {str(e)}")
else:
st.success("βœ… Interview Scheduled!")
st.warning("⚠️ Email not sent: SMTP not configured")
# Show interview details
st.write("### Interview Details")
st.write(f"**Candidate:** {result['candidate_name']}")
st.write(f"**Position:** {match['job_title']}")
st.write(f"**Date & Time:** {interview_date} at {interview_time}")
st.write(f"**Interviewer:** {data['interviewer']}")
if data['meeting_link']:
st.markdown(f"**Meeting Link:** [{data['meeting_link']}]({data['meeting_link']})")
if data['notes']:
st.write("**Notes:**", data['notes'])
def display_scheduled_interviews():
"""Display scheduled interviews and handle feedback"""
st.subheader("πŸ“… Upcoming Interviews")
db = ResumeMatchDB()
interviews = db.get_scheduled_interviews(status='pending')
if interviews:
with st.container():
for interview in interviews:
col1, col2 = st.columns([3, 1])
with col1:
st.markdown(f"""
**πŸ‘€ {interview['candidate_name']}**
**πŸ’Ό {interview['job_title']}**
**πŸ“… {_format_date(interview['scheduled_date'])}**
**πŸ‘” {interview['interviewer'] or 'Interviewer not specified'}**
""")
if interview['meeting_link']:
st.markdown(f"**πŸ”— [Join Meeting]({interview['meeting_link']})**")
if interview['notes']:
st.write(interview['notes'])
with col2:
if st.button("βœ… Complete", key=f"complete_{interview['id']}"):
db.update_interview_status(interview['id'], 'completed')
st.rerun()
st.markdown("---")
else:
st.info("No upcoming interviews scheduled.")
def _format_date(date_str):
"""Format date string for better readability"""
if date_str is None:
return "Not scheduled"
if isinstance(date_str, str):
try:
date_obj = datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
except ValueError:
return date_str
else:
date_obj = date_str
return date_obj.strftime('%a, %b %d, %I:%M %p')