diff --git a/backend/documents/views.py b/backend/documents/views.py index 5ff15c6..fa36bea 100644 --- a/backend/documents/views.py +++ b/backend/documents/views.py @@ -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, diff --git a/frontend/package.json b/frontend/package.json index 7df51dc..acd8f5b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -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", @@ -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" } } diff --git a/frontend/src/pages/Upload.tsx b/frontend/src/pages/Upload.tsx new file mode 100644 index 0000000..8925afd --- /dev/null +++ b/frontend/src/pages/Upload.tsx @@ -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(null); + const [pdfData, setPdfData] = useState(null); + const [numPages, setNumPages] = useState(null); + const [pageNumber, setPageNumber] = useState(1); + + const handleFileChange = (event: React.ChangeEvent) => { + 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 ( + <> +
+ + +
+ + {pdfData && ( + + + + )} + + {pdfData && numPages && ( +

Page {pageNumber} of {numPages}

+ )} + + ); +}; + +export default UploadComponent; diff --git a/frontend/src/routes/Routes.tsx b/frontend/src/routes/Routes.tsx index a07d801..44bd221 100644 --- a/frontend/src/routes/Routes.tsx +++ b/frontend/src/routes/Routes.tsx @@ -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 ( - Home} /> + } /> + } /> } /> } /> } /> diff --git a/frontend/src/services/uploadService.ts b/frontend/src/services/uploadService.ts new file mode 100644 index 0000000..a103286 --- /dev/null +++ b/frontend/src/services/uploadService.ts @@ -0,0 +1,29 @@ +import axios from "axios"; +import apiRoutes from "../routes/routesDefinitions"; + +const uploadPDF = async (file: File): Promise => { + 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; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 861b04b..a9dee4e 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -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: "", + }, + ], + }), + ], +});