ai-resume-builder / components /InitialInputForm.tsx
mgbam's picture
Upload 11 files
2e9c97f verified
/**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import React, { useState, ChangeEvent } from 'react';
import type { InitialInput } from '../lib/types';
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist';
import mammoth from 'mammoth';
// Set workerSrc for pdf.js. This is crucial for it to work.
GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.min.js';
interface InitialInputFormProps {
onSubmit: (formData: InitialInput) => void;
onClear: () => void;
disabled: boolean;
isLoading: boolean;
}
const initialFormState: InitialInput = {
fullName: '',
jobTitle: '',
careerGoal: '',
jobDescription: '',
uploadedResumeContent: '',
yearsOfExperience: '2-4 Years',
keySkills: '',
previousRoles: '',
education: '',
};
export default function InitialInputForm({ onSubmit, onClear, disabled, isLoading }: InitialInputFormProps) {
const [formData, setFormData] = useState<InitialInput>(initialFormState);
const [selectedFileName, setSelectedFileName] = useState<string>('');
const [fileError, setFileError] = useState<string | null>(null);
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
setFileError(null);
setSelectedFileName('');
setFormData(prev => ({ ...prev, uploadedResumeContent: '' }));
if (file) {
setSelectedFileName(file.name);
try {
let text = '';
if (file.name.toLowerCase().endsWith('.txt')) {
text = await file.text();
} else if (file.name.toLowerCase().endsWith('.pdf')) {
const arrayBuffer = await file.arrayBuffer();
const pdf = await getDocument({ data: arrayBuffer }).promise;
let pdfText = '';
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const textContent = await page.getTextContent();
pdfText += textContent.items.map((item: any) => item.str).join(' ') + '\n';
}
text = pdfText;
} else if (file.name.toLowerCase().endsWith('.docx')) {
const arrayBuffer = await file.arrayBuffer();
const result = await mammoth.extractRawText({ arrayBuffer });
text = result.value;
} else {
setFileError("Unsupported file type. Please use .txt, .pdf, or .docx.");
return;
}
setFormData(prev => ({ ...prev, uploadedResumeContent: text }));
} catch (error) {
setFileError(`Error processing file: ${error instanceof Error ? error.message : "Unknown error"}.`);
}
}
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (fileError) {
alert(`Cannot submit: Please resolve the file error first. ${fileError}`);
return;
}
onSubmit(formData);
};
const handleClear = () => {
setFormData(initialFormState);
setSelectedFileName('');
setFileError(null);
const fileInput = document.getElementById('resumeUpload') as HTMLInputElement;
if (fileInput) fileInput.value = '';
onClear();
};
return (
<form onSubmit={handleSubmit} className="initial-input-form">
<h2>Initial Setup</h2>
{/* Form groups for all inputs */}
<div className="form-group">
<label htmlFor="fullName">Full Name</label>
<input type="text" id="fullName" name="fullName" value={formData.fullName} onChange={handleChange} placeholder="e.g., Jane Doe" required disabled={disabled}/>
</div>
<div className="form-group">
<label htmlFor="jobTitle">Current or Target Job Title</label>
<input type="text" id="jobTitle" name="jobTitle" value={formData.jobTitle} onChange={handleChange} placeholder="e.g., Senior Software Engineer" required disabled={disabled}/>
</div>
<div className="form-group">
<label htmlFor="jobDescription">Target Job Description (Crucial for Scoring)</label>
<textarea id="jobDescription" name="jobDescription" value={formData.jobDescription} onChange={handleChange} placeholder="Paste the job description here..." rows={6} disabled={disabled}/>
</div>
<div className="form-group">
<label htmlFor="resumeUpload">Upload Existing Resume (Optional)</label>
<input type="file" id="resumeUpload" name="resumeUpload" accept=".txt,.pdf,.docx" onChange={handleFileChange} disabled={disabled}/>
<small className="form-text text-muted">{selectedFileName ? `Selected: ${selectedFileName}` : "Upload for richer context."}</small>
{fileError && <p role="alert" style={{color:'var(--color-error)',fontSize:'0.9em',marginTop:'0.5em'}}>{fileError}</p>}
</div>
<div className="form-group">
<label htmlFor="keySkills">Key Skills (to supplement resume)</label>
<textarea id="keySkills" name="keySkills" value={formData.keySkills} onChange={handleChange} placeholder="List skills not detailed in your resume..." rows={3} disabled={disabled}/>
</div>
{/* Additional fields like careerGoal, yearsOfExperience etc. can be added here if needed */}
<div className="form-actions" style={{marginTop: '1.5rem', display: 'flex', gap: '1rem'}}>
<button type="submit" className={`submit-button ${isLoading ? 'is-loading' : ''}`} disabled={disabled}>
<span>{isLoading ? 'Generating...' : 'Generate Resume'}</span>
</button>
<button type="button" className="clear-button" onClick={handleClear} disabled={disabled}>
Clear All
</button>
</div>
</form>
);
}