Of course. Here is all the code for the project, organized by file, in a single chat message for easy copying. ✅ Backend Code (backend/ folder) 1. File Path: backend/package.json code JSON download content_copy expand_less { "name": "pdf-converter-backend", "version": "1.0.0", "description": "Backend for AI PDF Converter", "main": "app.js", "scripts": { "start": "node app.js", "dev": "nodemon app.js" }, "dependencies": { "@google/generative-ai": "^0.7.1", "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.19.2", "multer": "^1.4.5-lts.1", "pdf-lib": "^1.17.1", "sharp": "^0.33.3" }, "devDependencies": { "nodemon": "^3.1.0" } } 2. File Path: backend/.env code Code download content_copy expand_less # Replace YOUR_GEMINI_API_KEY_HERE with your actual key from Google AI Studio GEMINI_API_KEY=YOUR_GEMINI_API_KEY_HERE 3. File Path: backend/app.js code JavaScript download content_copy expand_less const express = require('express'); const cors = require('cors'); require('dotenv').config(); const apiRoutes = require('./routes/apiRoutes'); const app = express(); const PORT = process.env.PORT || 5001; // Middleware app.use(cors()); app.use(express.json()); // API Routes app.use('/api', apiRoutes); app.listen(PORT, () => { console.log(`✅ Backend server is running on http://localhost:${PORT}`); }); 4. File Path: backend/routes/apiRoutes.js code JavaScript download content_copy expand_less const express = require('express'); const multer = require('multer'); const { jpgToPdf, summarizeText } = require('../controllers/conversionController'); const router = express.Router(); const upload = multer({ dest: 'uploads/' }); // Route for converting JPG to PDF router.post('/jpg-to-pdf', upload.single('file'), jpgToPdf); // Route for summarizing text content with Gemini AI router.post('/summarize', upload.single('file'), summarizeText); module.exports = router; 5. File Path: backend/controllers/conversionController.js code JavaScript download content_copy expand_less const { PDFDocument } = require('pdf-lib'); const sharp = require('sharp'); const fs = require('fs').promises; const { getGeminiSummary } = require('../services/geminiService'); // 1. JPG to PDF Converter exports.jpgToPdf = async (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No file was uploaded.' }); } const imageBytes = await fs.readFile(req.file.path); const { width, height } = await sharp(imageBytes).metadata(); const pdfDoc = await PDFDocument.create(); const page = pdfDoc.addPage([width, height]); const jpgImage = await pdfDoc.embedJpg(imageBytes); page.drawImage(jpgImage, { x: 0, y: 0, width, height }); const pdfBytes = await pdfDoc.save(); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename=converted.pdf'); res.send(Buffer.from(pdfBytes)); } catch (error) { console.error('JPG to PDF conversion error:', error); res.status(500).json({ error: 'Server error during file conversion.' }); } finally { if (req.file) { await fs.unlink(req.file.path); } } }; // 2. AI Text Summarizer exports.summarizeText = async (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No file was uploaded.' }); } const fileContent = await fs.readFile(req.file.path, 'utf-8'); const summary = await getGeminiSummary(fileContent); res.json({ summary }); } catch (error) { console.error('Summarization error:', error); res.status(500).json({ error: 'Failed to generate summary.' }); } finally { if (req.file) { await fs.unlink(req.file.path); } } }; 6. File Path: backend/services/geminiService.js code JavaScript download content_copy expand_less const { GoogleGenerativeAI } = require('@google/generative-ai'); const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); async function getGeminiSummary(textContent) { try { const model = genAI.getGenerativeModel({ model: 'gemini-pro' }); const prompt = `Please provide a concise, easy-to-read summary of the following content:\n\n---\n\n${textContent}`; const result = await model.generateContent(prompt); const response = await result.response; const summary = response.text(); return summary; } catch (error) { console.error('Error communicating with Gemini API:', error); throw new Error('Failed to generate summary from Gemini.'); } } module.exports = { getGeminiSummary }; ✅ Frontend Code (frontend/ folder) 1. File Path: frontend/app/page.tsx code Tsx download content_copy expand_less import MainConverter from './components/MainConverter'; export default function Home() { return (

AI-Powered PDF Converter

Your one-stop solution for document management.

); } 2. File Path: frontend/app/components/MainConverter.tsx code Tsx download content_copy expand_less 'use client'; import React, { useState } from 'react'; import FileUpload from './FileUpload'; export default function MainConverter() { const [activeTab, setActiveTab] = useState('jpgToPdf'); const renderContent = () => { switch (activeTab) { case 'jpgToPdf': return ( ); case 'summarize': return ( ); default: return null; } }; return (
{renderContent()}
); } 3. File Path: frontend/app/components/FileUpload.tsx code Tsx download content_copy expand_less 'use client'; import { useState, useCallback } from 'react'; import { useDropzone } from 'react-dropzone'; import axios from 'axios'; import { UploadCloud, File as FileIcon, CheckCircle } from 'lucide-react'; interface FileUploadProps { endpoint: string; acceptedFiles: { [key: string]: string[] }; buttonText: string; isJsonResponse?: boolean; } export default function FileUpload({ endpoint, acceptedFiles, buttonText, isJsonResponse = false }: FileUploadProps) { const [file, setFile] = useState(null); const [isLoading, setIsLoading] = useState(false); const [aiSummary, setAiSummary] = useState(''); const onDrop = useCallback((acceptedFiles: File[]) => { if (acceptedFiles.length > 0) { setFile(acceptedFiles[0]); setAiSummary(''); // Reset previous results } }, []); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, accept: acceptedFiles, multiple: false }); const handleProcess = async () => { if (!file) return; const formData = new FormData(); formData.append('file', file); setIsLoading(true); setAiSummary(''); try { const response = await axios.post(endpoint, formData, { responseType: isJsonResponse ? 'json' : 'blob', }); if (isJsonResponse) { setAiSummary(response.data.summary); } else { const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', file.name.replace(/\.[^/.]+$/, "") + '.pdf'); document.body.appendChild(link); link.click(); link.remove(); alert('Success! Your download has started.'); } setFile(null); // Clear file on success } catch (error) { console.error('An error occurred:', error); alert('Processing failed. Please try again.'); } finally { setIsLoading(false); } }; return (

Drag & drop your file here, or click to select

{`Supported: ${Object.values(acceptedFiles).flat().join(', ')}`}

{file && (
{file.name}
)} {aiSummary && (

AI Summary:

{aiSummary}

)}
); }