Spaces:
Running
Running
File size: 5,774 Bytes
2e9c97f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
/**
* @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>
);
}
|