Fixed .pdf resume upload, Logout button background

This commit is contained in:
Josh 2025-05-09 13:13:31 +00:00
parent f3125b2145
commit b0b5ff3aa8
9 changed files with 63 additions and 23 deletions

View File

@ -8,11 +8,12 @@ import sqlite3 from 'sqlite3';
import jwt from 'jsonwebtoken';
import { v4 as uuidv4 } from 'uuid';
import path from 'path';
import fs from 'fs';
import fs from 'fs/promises';
import multer from 'multer';
import mammoth from 'mammoth';
import { fileURLToPath } from 'url';
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.js';
import pkg from 'pdfjs-dist';
import OpenAI from 'openai';
// --- Basic file init ---
@ -28,6 +29,7 @@ dotenv.config({ path: envPath }); // Load .env file
const app = express();
const PORT = process.env.PREMIUM_PORT || 5002;
const { getDocument } = pkg;
let db;
const initDB = async () => {
@ -1655,6 +1657,22 @@ ${resumeText}
Precisely Tailored, ATS-Optimized Resume:
`;
async function extractTextFromPDF(filePath) {
const fileBuffer = await fs.readFile(filePath);
const uint8Array = new Uint8Array(fileBuffer); // Convert Buffer explicitly
const pdfDoc = await getDocument({ data: uint8Array }).promise;
let text = '';
for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {
const page = await pdfDoc.getPage(pageNum);
const pageText = await page.getTextContent();
text += pageText.items.map(item => item.str).join(' ');
}
return text;
}
// Your corrected endpoint with limits correctly returned:
app.post(
'/api/premium/resume/optimize',
upload.single('resumeFile'),
@ -1668,7 +1686,6 @@ app.post(
const userId = req.userId;
const now = new Date();
const currentWeek = getWeekNumber(now); // Function defined below
const userProfile = await db.get(
`SELECT is_premium, is_pro_premium, resume_optimizations_used, resume_limit_reset, resume_booster_count
@ -1702,16 +1719,20 @@ app.post(
}
const filePath = req.file.path;
const fileExt = req.file.originalname.split('.').pop().toLowerCase();
const mimeType = req.file.mimetype;
let resumeText = '';
if (fileExt === 'pdf') {
if (mimeType === 'application/pdf') {
resumeText = await extractTextFromPDF(filePath);
} else if (fileExt === 'docx') {
} else if (
mimeType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
mimeType === 'application/msword'
) {
const result = await mammoth.extractRawText({ path: filePath });
resumeText = result.value;
} else {
return res.status(400).json({ error: 'Unsupported file type.' });
await fs.unlink(filePath);
return res.status(400).json({ error: 'Unsupported or corrupted file upload.' });
}
const prompt = buildResumePrompt(resumeText, jobTitle, jobDescription);
@ -1729,11 +1750,15 @@ app.post(
[userId]
);
// Calculate remaining optimizations
const remainingOptimizations = totalLimit - (userProfile.resume_optimizations_used + 1);
fs.unlinkSync(filePath);
res.json({ optimizedResume, remainingOptimizations });
await fs.unlink(filePath);
res.json({
optimizedResume,
remainingOptimizations,
resetDate: resetDate.toISOString() // <-- explicitly returned here!
});
} catch (err) {
console.error('Error optimizing resume:', err);
res.status(500).json({ error: 'Failed to optimize resume.' });

View File

@ -236,12 +236,12 @@ function App() {
{/* Logout */}
<li>
<button
className="text-red-600 hover:text-red-800"
onClick={handleLogout}
>
Logout
</button>
<button
className="text-red-600 hover:text-red-800 bg-transparent border-none"
onClick={handleLogout}
>
Logout
</button>
</li>
</ul>
</nav>

View File

@ -9,6 +9,7 @@ function ResumeRewrite() {
const [error, setError] = useState('');
const [remainingOptimizations, setRemainingOptimizations] = useState(null);
const [resetDate, setResetDate] = useState(null);
const [loading, setLoading] = useState(false); // ADDED loading state
const handleFileChange = (e) => {
setResumeFile(e.target.files[0]);
@ -39,6 +40,8 @@ function ResumeRewrite() {
return;
}
setLoading(true); // ACTIVATE loading
try {
const token = localStorage.getItem('token');
const formData = new FormData();
@ -55,12 +58,12 @@ function ResumeRewrite() {
setOptimizedResume(res.data.optimizedResume || '');
setError('');
// Refresh remaining optimizations after optimizing
fetchRemainingOptimizations();
} catch (err) {
console.error('Resume optimization error:', err);
setError(err.response?.data?.error || 'Failed to optimize resume.');
} finally {
setLoading(false); // DEACTIVATE loading
}
};
@ -101,10 +104,22 @@ function ResumeRewrite() {
{error && <p className="text-red-600 font-semibold">{error}</p>}
<button type="submit"
className="inline-block bg-blue-600 text-white font-semibold px-5 py-2 rounded hover:bg-blue-700 transition-colors">
Optimize Resume
<button
type="submit"
disabled={loading}
className={`inline-block font-semibold px-5 py-2 rounded transition-colors ${
loading ? 'bg-gray-400 cursor-not-allowed' : 'bg-blue-600 hover:bg-blue-700'
} text-white`}
>
{loading ? 'Optimizing Resume...' : 'Optimize Resume'}
</button>
{loading && (
<div className="flex items-center justify-center mt-4">
<div className="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
<span className="ml-3 text-blue-700 font-semibold">Optimizing your resume...</span>
</div>
)}
</form>
{optimizedResume && (

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.