Spaces:
Sleeping
Sleeping
| """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']}") | |