pse2_ff/project/frontend/src/components/UploadPage.tsx

215 lines
5.0 KiB
TypeScript

import SettingsIcon from "@mui/icons-material/Settings";
import { Backdrop, Box, Button, IconButton, Paper, Typography } from "@mui/material";
import { useNavigate, useRouter } from "@tanstack/react-router";
import { useCallback, useEffect, useState } from "react";
import FileUpload from "react-material-file-upload";
import { socket } from "../socket";
import { API_HOST } from "../util/api";
import { CircularProgressWithLabel } from "./CircularProgressWithLabel";
import DekaLogo from "../assets/Deka_logo.png";
export default function UploadPage() {
const [files, setFiles] = useState<File[]>([]);
const [pageId, setPageId] = useState<string | null>(null);
const [loadingState, setLoadingState] = useState<number | null>(null);
const fileTypes = ["pdf"];
const navigate = useNavigate();
const router = useRouter();
const uploadFile = useCallback(async () => {
const formData = new FormData();
formData.append("file", files[0]);
const response = await fetch(`${API_HOST}/api/pitch_book/`, {
method: "POST",
body: formData,
});
if (response.ok) {
console.log("File uploaded successfully");
const data = await response.json();
setPageId(data.id.toString());
setLoadingState(5);
} else {
console.error("Failed to upload file");
}
}, [files]);
const onConnection = useCallback(() => {
console.log("connected");
}, []);
const onProgress = useCallback(
(progress: { id: number; progress: number }) => {
if (pageId === progress.id.toString()) {
setLoadingState(progress.progress);
if (progress.progress === 100) {
setPageId(null);
setLoadingState(null);
navigate({
to: "/extractedResult/$pitchBook",
params: { pitchBook: progress.id.toString() },
});
}
}
},
[pageId, navigate],
);
useEffect(() => {
socket.on("connect", onConnection);
socket.on("progress", onProgress);
return () => {
socket.off("connect", onConnection);
socket.off("progress", onProgress);
};
}, [onConnection, onProgress]);
useEffect(() => {
return () => {
setPageId(null);
setLoadingState(null);
};
}, []);
return (
<>
<Backdrop
sx={(theme) => ({ color: "#fff", zIndex: theme.zIndex.drawer + 1 })}
open={pageId !== null && loadingState !== null && loadingState < 100}
>
<CircularProgressWithLabel
color="inherit"
value={loadingState || 0}
size={60}
/>
</Backdrop>
<Box
display="flex"
flexDirection="column"
alignItems="center"
justifyContent="flex-start"
height="100vh"
bgcolor="white"
pt={3}
>
<Box
width="100%"
display="flex"
justifyContent="space-between"
alignItems="center"
px={8}
py={5}
>
<Box sx={{ display: "flex", alignItems: "center" }}>
<img
src={DekaLogo}
alt="Company Logo"
style={{ height: "40px", width: "auto" }}
/>
</Box>
<IconButton onClick={() => navigate({ to: "/config" })}>
<SettingsIcon fontSize="large" />
</IconButton>
</Box>
<Typography
variant="h4"
component="h1"
sx={{
fontWeight: "bold",
color: "#383838",
marginBottom: 12,
marginTop: 3,
}}
>
Pitchbook Extractor
</Typography>
<Paper
elevation={3}
sx={{
width: 800,
height: 400,
backgroundColor: "#eeeeee",
borderRadius: 4,
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Box
sx={{
height: "100%",
width: "100%",
maxWidth: "100%",
margin: "0px",
padding: "0px",
"& .MuiBox-root": {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
border: "none",
textAlign: "center",
},
}}
>
<FileUpload
value={files}
onChange={setFiles}
accept={`.${fileTypes.join(", .")}`}
title="Hier Dokument hinziehen"
buttonText="Datei auswählen"
sx={{
height: "100%",
width: "100%",
padding: "0px",
"& svg": {
color: "#9e9e9e",
},
"& .MuiOutlinedInput-notchedOutline": {
border: "none",
},
"& .MuiButton-root": {
backgroundColor: "#9e9e9e",
},
"& .MuiTypography-root": {
fontSize: "1.25rem",
fontWeight: 500,
marginBottom: 1,
},
}}
/>
</Box>
</Paper>
<Button
variant="contained"
sx={{
mt: 4,
backgroundColor: "#383838",
}}
disabled={files.length === 0}
onClick={uploadFile}
>
Kennzahlen extrahieren
</Button>
<Button
variant="contained"
sx={{
position: "absolute",
bottom: 32,
left: 32,
backgroundColor: "#383838",
"&:hover": { backgroundColor: "#2e2e2e" },
}}
onMouseEnter={() => router.preloadRoute({ to: "/pitchbooks" })}
onClick={() => navigate({ to: "/pitchbooks" })}
>
Alle Pitchbooks anzeigen
</Button>
</Box>
</>
);
}