Skip to content

Commit

Permalink
Feat: Add PDF frontend rendering functionality and related components
Browse files Browse the repository at this point in the history
  • Loading branch information
SverreNystad committed Jan 5, 2024
1 parent 011ebef commit 7c0f212
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 8 deletions.
7 changes: 5 additions & 2 deletions backend/documents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

@api_view(["POST"])
def upload_pdf(request):
print(request.data, flush=True)

if "pdf" in request.FILES:
pdf_file = request.FILES.get("pdf")

print(request.FILES.get("pdf"), flush=True)
print(pdf_file.content_type, flush=True)
# Check if the uploaded file is a PDF
if pdf_file.content_type != "application/pdf":
if pdf_file.content_type != "multipart/form-data":
return Response(
{"message": "The uploaded file is not a PDF"},
status=status.HTTP_400_BAD_REQUEST,
Expand Down
3 changes: 3 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
"axios": "^1.6.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-pdf": "^7.6.0",
"react-router-dom": "^6.21.1"
},
"devDependencies": {
"@types/node": "^20.10.6",
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@typescript-eslint/eslint-plugin": "^6.14.0",
Expand All @@ -31,6 +33,7 @@
"tailwindcss": "^3.4.0",
"typescript": "^5.2.2",
"vite": "^5.0.8",
"vite-plugin-static-copy": "^1.0.0",
"vitest": "^1.1.1"
}
}
68 changes: 68 additions & 0 deletions frontend/src/pages/Upload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// UploadComponent.tsx

import React, { useState } from 'react';
import uploadPDF from '../services/uploadService';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css';

// Configure PDF.js worker
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;


const UploadComponent: React.FC = () => {
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const [pdfData, setPdfData] = useState<any>(null);
const [numPages, setNumPages] = useState<number | null>(null);
const [pageNumber, setPageNumber] = useState<number>(1);

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files && event.target.files[0]) {
const file = event.target.files[0];
setSelectedFile(file);
setPdfData(file);

// Convert file to a data URL for react-pdf
const reader = new FileReader();
reader.onload = (e) => setPdfData(e.target?.result);
reader.readAsDataURL(file);
}
};

const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
setNumPages(numPages);
};

const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
if (selectedFile) {
try {
const response = await uploadPDF(selectedFile);
console.log(response);
// Handle the response data
} catch (error) {
console.error('Error uploading file:', error);
}
}
};

return (
<>
<form onSubmit={handleSubmit}>
<input type="file" accept=".pdf" onChange={handleFileChange} />
<button type="submit">Upload PDF</button>
</form>

{pdfData && (
<Document file={pdfData} onLoadSuccess={onDocumentLoadSuccess}>
<Page pageNumber={pageNumber} />
</Document>
)}

{pdfData && numPages && (
<p>Page {pageNumber} of {numPages}</p>
)}
</>
);
};

export default UploadComponent;
5 changes: 3 additions & 2 deletions frontend/src/routes/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { Route, Routes } from "react-router-dom";
import Login from "../pages/Login.tsx";
import Signup from "../pages/Signup.tsx";
import Page404 from "../pages/Page404.tsx";

import Upload from "../pages/Upload.tsx";

const AppRoutes = () => {
return (
<Routes>
<Route path="/" element={<h1>Home</h1>} />
<Route path="/" element={<Login/>} />
<Route path="/upload" element={<Upload/>} />
<Route path="/login" element={<Login/>} />
<Route path="/signup" element={<Signup/>} />
<Route path="*" element={<Page404 />} />
Expand Down
29 changes: 29 additions & 0 deletions frontend/src/services/uploadService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import axios from "axios";
import apiRoutes from "../routes/routesDefinitions";

const uploadPDF = async (file: File): Promise<Response> => {
let formData = new FormData();
formData.append("pdf", file);
console.log(formData);

for (let [key, value] of formData.entries()) {
console.log(key, value);
}

const response = await axios
.post(apiRoutes.upload, {
method: "POST",
body: formData,
// Add headers if necessary (e.g., for authentication)
})
.then((res) => {
return res;
})
.catch((err) => {
return err;
});

return response;
};

export default uploadPDF;
28 changes: 24 additions & 4 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";

import path from "path";
import { createRequire } from "node:module";
import { viteStaticCopy } from "vite-plugin-static-copy";

const require = createRequire(import.meta.url);
const cMapsDir = path.join(
path.dirname(require.resolve("pdfjs-dist/package.json")),
"cmaps"
);

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})
plugins: [
react(),
viteStaticCopy({
targets: [
{
src: cMapsDir,
dest: "",
},
],
}),
],
});

0 comments on commit 7c0f212

Please sign in to comment.