Implementiere PDF-Highlighting für Kennzahlen (Ticket #31)

pull/47/head
Abdulrahman Dabbagh 2025-06-02 12:11:53 +02:00
parent 76a060a563
commit 0dd3785fdd
5 changed files with 106 additions and 14 deletions

View File

@ -0,0 +1,30 @@
import { Box } from '@mui/material';
type Props = {
x: number;
y: number;
width: number;
height: number;
type: 'all' | 'selected';
};
// Eine farbige Box, die über dem PDF angezeigt wird
export default function HighlightOverlay({ x, y, width, height, type }: Props) {
return (
<Box
sx={{
position: 'absolute',
top: y,
left: x,
width: width,
height: height,
backgroundColor: type === 'all' ? 'rgba(255, 255, 0, 0.4)' : 'rgba(255, 165, 0, 0.4)',
border: '1px solid',
borderColor: type === 'all' ? '#FFD700' : '#FF8C00',
borderRadius: '2px',
pointerEvents: 'none',
zIndex: 10,
}}
/>
);
}

View File

@ -8,6 +8,7 @@ import {
import SearchIcon from '@mui/icons-material/Search';
import EditIcon from '@mui/icons-material/Edit';
import { useState } from 'react';
import { Dispatch, SetStateAction } from 'react';
// Beispiel-Daten
@ -19,7 +20,12 @@ import {
];
// React-Komponente
export default function KennzahlenTable() {
type Props = {
setSelectedLabel: Dispatch<SetStateAction<string | null>>;
};
export default function KennzahlenTable({ setSelectedLabel }: Props) {
// Zustand für bearbeitbare Daten
const [rows, setRows] = useState(exampleData);
@ -67,7 +73,13 @@ import {
else if (row.status === 'warning') borderColor = '#f6ed48';
return (
<TableRow key={index}>
<TableRow
key={index}
onClick={() => setSelectedLabel(row.label)}
hover
sx={{ cursor: 'pointer' }}
>
{/* Kennzahl */}
<TableCell>{row.label}</TableCell>

View File

@ -0,0 +1,21 @@
// Beispielhafte Highlight-Daten mit Labels
export const highlightData = [
{
label: 'Risikoprofil',
page: 1,
x: 100,
y: 200,
width: 120,
height: 20,
type: 'all', // gelb
},
{
label: 'Risikoprofil',
page: 1,
x: 100,
y: 300,
width: 140,
height: 25,
type: 'selected', // orange (nur wenn ausgewählt)
}
];

View File

@ -6,13 +6,22 @@ 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';
import HighlightOverlay from './HighlightOverlay';
import { highlightData } from './highlightData';
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
"pdfjs-dist/build/pdf.worker.min.mjs",
import.meta.url,
).toString();
export default function PDFViewer() {
type Props = {
selectedLabel: string | null;
};
export default function PDFViewer({ selectedLabel }: Props) {
const [numPages, setNumPages] = useState<number | null>(null);
const [pageNumber, setPageNumber] = useState(1);
const [containerWidth, setContainerWidth] = useState<number | null>(null);
@ -56,17 +65,34 @@ export default function PDFViewer() {
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
file={testPDF}
onLoadSuccess={onDocumentLoadSuccess}
onLoadError={(error) => console.error('Fehler beim Laden:', error)}
onSourceError={(error) => console.error('Ungültige PDF:', error)}
>
{containerWidth && (
<Box position="relative">
<Page
pageNumber={pageNumber}
width={containerWidth * 0.8}
/>
{/* Highlights einfügen */}
{highlightData
.filter((h) => h.page === pageNumber)
.map((h, idx) => (
<HighlightOverlay
key={idx}
{...h}
type={selectedLabel && h.label === selectedLabel ? 'selected' : 'all'}
/>
)}
))}
</Box>
)}
</Document>
</Box>
<Box
mt={2}

View File

@ -3,6 +3,7 @@ import {createFileRoute, useNavigate} from '@tanstack/react-router';
import PDFViewer from '../components/pdfViewer';
import ContentPasteIcon from '@mui/icons-material/ContentPaste';
import KennzahlenTable from "../components/KennzahlenTable";
import { useState } from 'react';
export const Route = createFileRoute('/extractedResult')({
@ -10,6 +11,7 @@ export const Route = createFileRoute('/extractedResult')({
});
function ExtractedResultsPage() {
const [selectedLabel, setSelectedLabel] = useState<string | null>(null);
const navigate = useNavigate();
const status: 'green' | 'yellow' | 'red' = 'red';
@ -57,7 +59,8 @@ function ExtractedResultsPage() {
overflow: 'auto', // Scrollen falls Tabelle zu lang
}}
>
<KennzahlenTable />
<KennzahlenTable setSelectedLabel={setSelectedLabel} />
</Paper>
<Box
@ -78,7 +81,7 @@ function ExtractedResultsPage() {
justifyContent: 'center',
}}
>
<PDFViewer/>
<PDFViewer selectedLabel={selectedLabel} />
</Paper>
<Box mt={2} display="flex" justifyContent="flex-end" gap={2}>
<Button