#24-PDF-Anzeigen #41
Binary file not shown.
|
|
@ -26,7 +26,7 @@ export default function UploadPage() {
|
|||
px={2}
|
||||
>
|
||||
<IconButton onClick={() => navigate({ to: '/config' })}>
|
||||
<SettingsIcon fontSize="large" />
|
||||
<SettingsIcon fontSize="large"/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Paper
|
||||
|
|
@ -91,7 +91,7 @@ export default function UploadPage() {
|
|||
backgroundColor: '#383838',
|
||||
}}
|
||||
disabled={files.length === 0}
|
||||
onClick={() => alert('Kein Backend, aber Button klickbar')}
|
||||
onClick={() => navigate({ to: '/extractedResult' })}
|
||||
>
|
||||
Kennzahlen extrahieren
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
import { Document, Page, pdfjs } from "react-pdf";
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
import { Box, IconButton } from '@mui/material';
|
||||
import ArrowCircleLeftIcon from '@mui/icons-material/ArrowCircleLeft';
|
||||
import ArrowCircleRightIcon from '@mui/icons-material/ArrowCircleRight';
|
||||
import testPDF from '/example.pdf';
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
"pdfjs-dist/build/pdf.worker.min.mjs",
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
export default function PDFViewer() {
|
||||
const [numPages, setNumPages] = useState<number | null>(null);
|
||||
const [pageNumber, setPageNumber] = useState(1);
|
||||
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
|
||||
setNumPages(numPages);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const updateWidth = () => {
|
||||
if (containerRef.current) {
|
||||
setContainerWidth(containerRef.current.offsetWidth);
|
||||
}
|
||||
};
|
||||
|
||||
updateWidth();
|
||||
window.addEventListener('resize', updateWidth);
|
||||
return () => window.removeEventListener('resize', updateWidth);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
width="100%"
|
||||
height="100%"
|
||||
p={2}
|
||||
>
|
||||
<Box
|
||||
ref={containerRef}
|
||||
sx={{
|
||||
width: '100%',
|
||||
maxHeight: '90vh',
|
||||
overflow: 'auto',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Document file={testPDF}
|
||||
onLoadSuccess={onDocumentLoadSuccess}
|
||||
onLoadError={(error) => console.error('Es gab ein Fehler beim Laden des PDFs:', error)}
|
||||
onSourceError={(error) => console.error('Ungültige PDF:', error)}>
|
||||
{containerWidth && (
|
||||
<Page
|
||||
pageNumber={pageNumber}
|
||||
width={containerWidth * 0.8}
|
||||
/>
|
||||
)}
|
||||
</Document>
|
||||
</Box>
|
||||
<Box
|
||||
mt={2}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap={1}
|
||||
>
|
||||
<IconButton disabled={pageNumber <= 1} onClick={() => setPageNumber(p => p - 1)}>
|
||||
<ArrowCircleLeftIcon fontSize="large" />
|
||||
</IconButton>
|
||||
<span>{pageNumber} / {numPages}</span>
|
||||
<IconButton
|
||||
disabled={pageNumber >= (numPages || 1)}
|
||||
onClick={() => setPageNumber(p => p + 1)}
|
||||
>
|
||||
<ArrowCircleRightIcon fontSize="large" />
|
||||
</IconButton>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
|
@ -11,11 +11,18 @@
|
|||
// Import Routes
|
||||
|
||||
import { Route as rootRoute } from './routes/__root'
|
||||
import { Route as ExtractedResultImport } from './routes/extractedResult'
|
||||
import { Route as ConfigImport } from './routes/config'
|
||||
import { Route as IndexImport } from './routes/index'
|
||||
|
||||
// Create/Update Routes
|
||||
|
||||
const ExtractedResultRoute = ExtractedResultImport.update({
|
||||
id: '/extractedResult',
|
||||
path: '/extractedResult',
|
||||
getParentRoute: () => rootRoute,
|
||||
} as any)
|
||||
|
||||
const ConfigRoute = ConfigImport.update({
|
||||
id: '/config',
|
||||
path: '/config',
|
||||
|
|
@ -46,6 +53,13 @@ declare module '@tanstack/react-router' {
|
|||
preLoaderRoute: typeof ConfigImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
'/extractedResult': {
|
||||
id: '/extractedResult'
|
||||
path: '/extractedResult'
|
||||
fullPath: '/extractedResult'
|
||||
preLoaderRoute: typeof ExtractedResultImport
|
||||
parentRoute: typeof rootRoute
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -54,36 +68,41 @@ declare module '@tanstack/react-router' {
|
|||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/config': typeof ConfigRoute
|
||||
'/extractedResult': typeof ExtractedResultRoute
|
||||
}
|
||||
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/config': typeof ConfigRoute
|
||||
'/extractedResult': typeof ExtractedResultRoute
|
||||
}
|
||||
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRoute
|
||||
'/': typeof IndexRoute
|
||||
'/config': typeof ConfigRoute
|
||||
'/extractedResult': typeof ExtractedResultRoute
|
||||
}
|
||||
|
||||
export interface FileRouteTypes {
|
||||
fileRoutesByFullPath: FileRoutesByFullPath
|
||||
fullPaths: '/' | '/config'
|
||||
fullPaths: '/' | '/config' | '/extractedResult'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to: '/' | '/config'
|
||||
id: '__root__' | '/' | '/config'
|
||||
to: '/' | '/config' | '/extractedResult'
|
||||
id: '__root__' | '/' | '/config' | '/extractedResult'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
ConfigRoute: typeof ConfigRoute
|
||||
ExtractedResultRoute: typeof ExtractedResultRoute
|
||||
}
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
ConfigRoute: ConfigRoute,
|
||||
ExtractedResultRoute: ExtractedResultRoute,
|
||||
}
|
||||
|
||||
export const routeTree = rootRoute
|
||||
|
|
@ -97,7 +116,8 @@ export const routeTree = rootRoute
|
|||
"filePath": "__root.tsx",
|
||||
"children": [
|
||||
"/",
|
||||
"/config"
|
||||
"/config",
|
||||
"/extractedResult"
|
||||
]
|
||||
},
|
||||
"/": {
|
||||
|
|
@ -105,6 +125,9 @@ export const routeTree = rootRoute
|
|||
},
|
||||
"/config": {
|
||||
"filePath": "config.tsx"
|
||||
},
|
||||
"/extractedResult": {
|
||||
"filePath": "extractedResult.tsx"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
import { Box, Paper, Typography, Button } from '@mui/material';
|
||||
import {createFileRoute, useNavigate} from '@tanstack/react-router';
|
||||
import PDFViewer from '../components/pdfViewer';
|
||||
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
|
||||
|
||||
export const Route = createFileRoute('/extractedResult')({
|
||||
component: ExtractedResultsPage,
|
||||
});
|
||||
|
||||
function ExtractedResultsPage() {
|
||||
const navigate = useNavigate();
|
||||
const status: 'green' | 'yellow' | 'red' = 'red';
|
||||
|
||||
const statusColor = {
|
||||
red: '#f43131',
|
||||
yellow: '#f6ed48',
|
||||
green: '#3fd942',
|
||||
}[status];
|
||||
|
||||
return (
|
||||
<Box p={4}>
|
||||
<Box display="flex" alignItems="center" gap={3}>
|
||||
<Box
|
||||
sx={{
|
||||
width: 45,
|
||||
height: 45,
|
||||
borderRadius: '50%',
|
||||
backgroundColor: statusColor,
|
||||
top: 32,
|
||||
left: 32,
|
||||
}}
|
||||
/>
|
||||
<Typography variant="h5" gutterBottom>
|
||||
Kennzahlen extrahiert aus: <br/><strong>FONDSNAME: TODO</strong>
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
display="flex"
|
||||
gap={4}
|
||||
sx={{
|
||||
width: '100vw',
|
||||
maxWidth: '100%',
|
||||
height: '80vh',
|
||||
mt: 4,
|
||||
}}
|
||||
>
|
||||
<Paper
|
||||
elevation={2}
|
||||
sx={{
|
||||
width: '45%',
|
||||
height: '100%',
|
||||
borderRadius: 2,
|
||||
backgroundColor: '#eeeeee',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Typography color="textSecondary">To-do: Table hierhin</Typography>
|
||||
</Paper>
|
||||
<Box
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
justifyContent="space-between"
|
||||
gap={5}
|
||||
sx={{ width: '55%', height: '95%' }}
|
||||
>
|
||||
<Paper
|
||||
elevation={2}
|
||||
sx={{
|
||||
height: '100%',
|
||||
borderRadius: 2,
|
||||
backgroundColor: '#eeeeee',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<PDFViewer/>
|
||||
</Paper>
|
||||
<Box mt={2} display="flex" justifyContent="flex-end" gap={2}>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ backgroundColor: '#383838' }}
|
||||
>
|
||||
<ContentPasteIcon sx={{ fontSize: 18, mr: 1 }} />
|
||||
Kennzahlenzeile kopieren
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ backgroundColor: '#383838' }}
|
||||
onClick={() => navigate({ to: '/' })}
|
||||
>
|
||||
Neu hochladen
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue