import React, { useState, useEffect } from 'react'; import api from '../auth/apiClient.js'; function ResumeRewrite() { const [resumeFile, setResumeFile] = useState(null); const [jobTitle, setJobTitle] = useState(''); const [jobDescription, setJobDescription] = useState(''); const [optimizedResume, setOptimizedResume] = useState(''); const [error, setError] = useState(''); const [remainingOptimizations, setRemainingOptimizations] = useState(null); const [resetDate, setResetDate] = useState(null); const [loading, setLoading] = useState(false); const ALLOWED_TYPES = [ 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx ]; const MAX_MB = 5; const handleFileChange = (e) => { const f = e.target.files?.[0] || null; setOptimizedResume(''); setError(''); if (!f) { setResumeFile(null); return; } // Basic client-side validation if (!ALLOWED_TYPES.includes(f.type)) { setError('Please upload a PDF or DOCX file.'); setResumeFile(null); return; } if (f.size > MAX_MB * 1024 * 1024) { setError(`File is too large. Maximum ${MAX_MB}MB.`); setResumeFile(null); return; } setResumeFile(f); }; const fetchRemainingOptimizations = async () => { try { const res = await api.get('/api/premium/resume/remaining', { withCredentials: true }); setRemainingOptimizations(res.data.remainingOptimizations); setResetDate(res.data.resetDate ? new Date(res.data.resetDate).toLocaleDateString() : null); } catch (err) { console.error('Error fetching optimizations:', err); setError('Could not fetch optimization limits.'); } }; useEffect(() => { fetchRemainingOptimizations(); }, []); const handleSubmit = async (e) => { e.preventDefault(); setError(''); setOptimizedResume(''); if (!resumeFile || !jobTitle.trim() || !jobDescription.trim()) { setError('Please fill in all fields.'); return; } // If a previous error existed, reset the file input to prompt a fresh pick if (error) { // reset the native input if accessible const el = e.target?.querySelector('input[type="file"]'); if (el) el.value = ''; } setLoading(true); try { const formData = new FormData(); formData.append('resumeFile', resumeFile); formData.append('jobTitle', jobTitle.trim()); formData.append('jobDescription', jobDescription.trim()); // Let axios/browser set multipart boundary automatically; just include credentials. const res = await api.post('/api/premium/resume/optimize', formData, { withCredentials: true, }); setOptimizedResume(res.data.optimizedResume || ''); setError(''); fetchRemainingOptimizations(); } catch (err) { console.error('Resume optimization error:', err); const status = err?.response?.status; const code = err?.response?.data?.error; if (status === 413 || code === 'file_too_large') { setError(`File is too large. Maximum ${MAX_MB}MB.`); } else if (status === 415 || code === 'unsupported_type') { setError('Unsupported file type. Please upload a PDF or DOCX.'); } else if (status === 429) { setError('Too many requests. Please wait a moment and try again.'); } else if (status === 400) { setError('Bad upload. Please re-select your file and try again.'); } else { setError('Failed to optimize resume. Please try again.'); } } finally { setLoading(false); } }; return (
{optimizedResume}