From a9d892351837afcf559a24d2ba7b892d61692a36 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Wed, 8 May 2024 16:32:10 +0200 Subject: [PATCH] refactor: final touches --- README.md | 16 +++--- components/Dashboard.tsx | 109 +++---------------------------------- components/Form.tsx | 112 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 108 deletions(-) create mode 100644 components/Form.tsx diff --git a/README.md b/README.md index a8fd0e1..805ffb9 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,16 @@ +## PDF to text + +The goal of this project is to create a small web interface that allows the user to upload a PDF file and get the text content of the PDF. + +Features: + +- A small web interface allowing to upload a PDF file +- An output containing the text content of the PDF + ## Getting Started -To ruun the development server: +To run the development server: ```bash yarn dev ``` - -## TODO - -- edge cases -- tests diff --git a/components/Dashboard.tsx b/components/Dashboard.tsx index ac648b1..f79f3c0 100644 --- a/components/Dashboard.tsx +++ b/components/Dashboard.tsx @@ -1,115 +1,20 @@ -import { responseSchema } from '@/utils/data'; -import axios from 'axios'; -import { useCallback, useState } from 'react'; -import { Button } from './Button'; +import { useState } from 'react'; import { Content } from './Content'; +import { Form } from './Form'; export default function Dashboard() { - const [clearing, setClearing] = useState(false); - const [file, setFile] = useState(); const [loading, setLoading] = useState(false); const [error, setError] = useState(); const [parsedText, setParsedText] = useState(''); - const handleFileChange = useCallback( - (e: React.ChangeEvent) => { - if (e.target.files) { - setFile(e.target.files[0]); - } else { - setFile(undefined); - } - }, - [] - ); - - const handleClear = useCallback(() => { - setClearing(false); - setFile(undefined); - setParsedText(''); - }, []); - - const validateFile = useCallback((file: File) => { - if (file.type !== 'application/pdf') { - setError( - "The file you've selected is not a PDF file. Please select a PDF file." - ); - setLoading(false); - - return false; - } - - // This limit is caused by the project being deployed on Vercel using a free tier, with limited resources - if (file.size > 1024 * 1024) { - setError('The file must be smaller than 1MB.'); - setLoading(false); - - return false; - } - - return true; - }, []); - - const uploadFile = useCallback(async () => { - if (!file) return; - - if (!validateFile(file)) return; - - const formData = new FormData(); - - formData.append('File', file); - - try { - const response = await axios.post('/api/parse', formData); - const validatedData = responseSchema.safeParse(response.data); - - if (!validatedData.success) { - setError('There was an error parsing the file. Please try again.'); - return; - } - - setParsedText(validatedData.data.text); - setClearing(true); - } catch { - setError('Internal server error. Please try again later.'); - } finally { - setLoading(false); - } - }, [file, validateFile]); - - const handleUpload = useCallback(() => { - setLoading(true); - setError(undefined); - setParsedText(''); - - uploadFile(); - }, [uploadFile]); - - function renderForm() { - if (clearing) { - return ( - <> -

File: {file?.name}

-