ResumeIQ / ui /email_composer.py
pranav8tripathi@gmail.com
init
9ba8b63
"""Email composer UI component"""
import streamlit as st
from utils.email_sender import EmailSender
def show_email_composer(shortlisted_candidates):
"""Show email composer with customization options"""
st.subheader("πŸ“§ Email Shortlisted Candidates")
email_sender = EmailSender()
if not email_sender.smtp_email or not email_sender.smtp_password:
st.error("❌ SMTP not configured. Please set SMTP_EMAIL and SMTP_PASSWORD in .env file")
return
_show_candidate_selection(shortlisted_candidates)
st.divider()
_show_email_customization()
st.divider()
_show_send_button(shortlisted_candidates, email_sender)
def _show_candidate_selection(shortlisted_candidates):
"""Show candidate selection checkboxes"""
st.write("**Select candidates to send emails:**")
if 'selected_candidates' not in st.session_state:
st.session_state.selected_candidates = {i: True for i in range(len(shortlisted_candidates))}
col1, col2 = st.columns([1, 5])
with col1:
select_all = st.checkbox("Select All", value=all(st.session_state.selected_candidates.values()))
if select_all != all(st.session_state.selected_candidates.values()):
for i in range(len(shortlisted_candidates)):
st.session_state.selected_candidates[i] = select_all
for idx, result in enumerate(shortlisted_candidates):
col1, col2, col3, col4 = st.columns([1, 3, 2, 2])
with col1:
st.session_state.selected_candidates[idx] = st.checkbox(
"βœ“",
value=st.session_state.selected_candidates.get(idx, True),
key=f"select_candidate_{idx}",
label_visibility="collapsed"
)
with col2:
st.write(f"**{result['candidate_name']}**")
with col3:
st.write(result['candidate_email'])
with col4:
st.write(f"{result['best_match']['match_score']:.1f}% match")
def _show_email_customization():
"""Show email customization options"""
with st.expander("✏️ Customize Email", expanded=True):
st.write("**Available placeholders:** `{name}`, `{job_title}`, `{match_score}`")
st.session_state.email_subject = st.text_input(
"Email Subject:",
value=st.session_state.email_subject,
key="email_subject_input"
)
st.session_state.email_body = st.text_area(
"Email Body (HTML supported):",
value=st.session_state.email_body,
height=300,
key="email_body_input"
)
if st.button("πŸ‘οΈ Preview Email"):
_show_email_preview()
def _show_email_preview():
"""Show email preview with sample data"""
st.write("**Preview (with sample data):**")
sample_subject = st.session_state.email_subject.format(
name="John Doe",
job_title="Software Engineer",
match_score="85.5"
)
sample_body = st.session_state.email_body.format(
name="John Doe",
job_title="Software Engineer",
match_score="85.5"
)
st.write(f"**Subject:** {sample_subject}")
st.markdown(sample_body, unsafe_allow_html=True)
def _show_send_button(shortlisted_candidates, email_sender):
"""Show send button and handle email sending"""
selected_count = sum(1 for v in st.session_state.selected_candidates.values() if v)
if selected_count == 0:
st.warning("⚠️ Please select at least one candidate to send emails.")
else:
col1, col2, col3 = st.columns([2, 2, 3])
with col1:
st.metric("Selected Candidates", selected_count)
with col2:
if st.button(f"πŸ“¨ Send Emails to {selected_count} Candidate(s)", type="primary"):
_send_customized_emails(shortlisted_candidates, email_sender)
def _send_customized_emails(shortlisted_candidates, email_sender):
"""Send customized emails to selected candidates"""
candidates_data = []
for idx, result in enumerate(shortlisted_candidates):
if st.session_state.selected_candidates.get(idx, False):
candidates_data.append({
'name': result['candidate_name'],
'email': result['candidate_email'],
'job_title': result['best_match']['job_title'],
'match_score': result['best_match']['match_score']
})
if not candidates_data:
st.warning("⚠️ No candidates selected.")
return
success_count = 0
failed_count = 0
with st.spinner(f"Sending emails to {len(candidates_data)} candidates..."):
for candidate in candidates_data:
subject = st.session_state.email_subject.format(
name=candidate['name'],
job_title=candidate['job_title'],
match_score=f"{candidate['match_score']:.1f}"
)
body = st.session_state.email_body.format(
name=candidate['name'],
job_title=candidate['job_title'],
match_score=f"{candidate['match_score']:.1f}"
)
if email_sender.send_email(candidate['email'], subject, body):
success_count += 1
else:
failed_count += 1
if success_count > 0:
st.success(f"βœ… Successfully sent {success_count} email(s)")
if failed_count > 0:
st.error(f"❌ Failed to send {failed_count} email(s)")
with st.expander("πŸ“‹ Email Details"):
for candidate in candidates_data:
st.write(f"β€’ {candidate['name']} ({candidate['email']}) - {candidate['job_title']}")