"use client"; import { useState, FormEvent, ChangeEvent } from "react"; import { JobPosition, JobApplication, careerService } from "@/lib/api/careerService"; interface JobApplicationFormProps { job: JobPosition; onClose?: () => void; } const inputStyle = { padding: '10px 12px', borderRadius: '6px', border: '1px solid #e0e0e0', fontSize: '14px', transition: 'all 0.2s', width: '100%' }; const labelStyle = { fontWeight: '500', color: '#555', marginBottom: '6px', display: 'block', fontSize: '14px' }; const sectionStyle = { backgroundColor: '#ffffff', padding: 'clamp(16px, 3vw, 20px)', borderRadius: '8px', border: '1px solid #e8e8e8', marginBottom: '16px', boxShadow: '0 2px 8px rgba(0,0,0,0.04)' }; const sectionHeaderStyle = { display: 'flex', alignItems: 'center', marginBottom: '14px', paddingBottom: '10px', borderBottom: '1px solid #f0f0f0' }; const JobApplicationForm = ({ job, onClose }: JobApplicationFormProps) => { const [formData, setFormData] = useState({ first_name: "", last_name: "", email: "", phone: "", current_position: "", current_company: "", years_of_experience: "", cover_letter: "", portfolio_url: "", linkedin_url: "", github_url: "", website_url: "", available_from: "", notice_period: "", expected_salary: "", salary_currency: "USD", consent: false, }); const [resume, setResume] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [submitStatus, setSubmitStatus] = useState<{ type: "success" | "error" | null; message: string; }>({ type: null, message: "" }); const handleInputChange = ( e: ChangeEvent ) => { const { name, value, type } = e.target; if (type === "checkbox") { const checked = (e.target as HTMLInputElement).checked; setFormData((prev) => ({ ...prev, [name]: checked })); } else { setFormData((prev) => ({ ...prev, [name]: value })); } }; const handleFileChange = (e: ChangeEvent) => { const file = e.target.files?.[0]; if (file) { // Validate file type const allowedTypes = [ "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", ]; if (!allowedTypes.includes(file.type)) { setSubmitStatus({ type: "error", message: "Please upload a PDF, DOC, or DOCX file", }); return; } // Validate file size (5MB) if (file.size > 5 * 1024 * 1024) { setSubmitStatus({ type: "error", message: "Resume file size must be less than 5MB", }); return; } setResume(file); setSubmitStatus({ type: null, message: "" }); } }; const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setIsSubmitting(true); setSubmitStatus({ type: null, message: "" }); // Validation if (!resume) { setSubmitStatus({ type: "error", message: "Please upload your resume", }); setIsSubmitting(false); return; } if (!formData.consent) { setSubmitStatus({ type: "error", message: "You must consent to data processing to apply", }); setIsSubmitting(false); return; } try { const applicationData: JobApplication = { job: job.id, first_name: formData.first_name, last_name: formData.last_name, email: formData.email, phone: formData.phone || undefined, current_position: formData.current_position || undefined, current_company: formData.current_company || undefined, years_of_experience: formData.years_of_experience || undefined, cover_letter: formData.cover_letter || undefined, resume: resume, portfolio_url: formData.portfolio_url || undefined, linkedin_url: formData.linkedin_url || undefined, github_url: formData.github_url || undefined, website_url: formData.website_url || undefined, available_from: formData.available_from || undefined, notice_period: formData.notice_period || undefined, expected_salary: formData.expected_salary ? parseFloat(formData.expected_salary) : undefined, salary_currency: formData.salary_currency || undefined, consent: formData.consent, }; await careerService.submitApplication(applicationData); setSubmitStatus({ type: "success", message: "Application submitted successfully! We'll be in touch soon.", }); // Reset form setFormData({ first_name: "", last_name: "", email: "", phone: "", current_position: "", current_company: "", years_of_experience: "", cover_letter: "", portfolio_url: "", linkedin_url: "", github_url: "", website_url: "", available_from: "", notice_period: "", expected_salary: "", salary_currency: "USD", consent: false, }); setResume(null); // Reset file input const fileInput = document.getElementById('resume') as HTMLInputElement; if (fileInput) fileInput.value = ''; } catch (error) { setSubmitStatus({ type: "error", message: error instanceof Error ? error.message : "Failed to submit application. Please try again.", }); } finally { setIsSubmitting(false); } }; return (
{/* Header Section with Gradient */}
{/* Close Button */} {onClose && ( )}
work_outline

Apply for {job.title}

Join our team and make an impact

{/* Form Content - Scrollable Area */}
{submitStatus.type && (
{submitStatus.type === "success" ? "check_circle" : "error"} {submitStatus.message}
)} {/* Personal Information */}
person

Personal Information

{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} required />
{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} required />
{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} required />
{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} />
{/* Professional Information */}
work

Professional Info

{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} />
{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} />
{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} />
{/* Resume and Cover Letter */}
upload_file

Documents

{ e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.1)'; }} onBlur={(e) => { e.target.style.borderColor = '#e0e0e0'; e.target.style.boxShadow = 'none'; }} required /> {resume && ✓ Selected: {resume.name}}