Merge branch 'main' into #16-progress

pull/48/head
Jaronim Pracht 2025-06-03 12:34:48 +02:00
commit 5fc226f4fc
2 changed files with 220 additions and 88 deletions

View File

@ -0,0 +1,132 @@
import {
Table, TableBody, TableCell, TableContainer,
TableHead, TableRow, Paper, Box,
Dialog, DialogActions, DialogContent, DialogTitle,
TextField, Button
} from '@mui/material';
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
import SearchIcon from '@mui/icons-material/Search';
import EditIcon from '@mui/icons-material/Edit';
import { useState } from 'react';
// Beispiel-Daten
const exampleData = [
{ label: 'Fondsname', value: 'Fund Real Estate Prime Europe', page: 1, status: 'ok' },
{ label: 'Fondsmanager', value: '', page: 1, status: 'error' },
{ label: 'Risikoprofil', value: 'Core/Core+', page: 10, status: 'warning' },
{ label: 'LTV', value: '30-35 %', page: 8, status: 'ok' }
];
// React-Komponente
export default function KennzahlenTable() {
// Zustand für bearbeitbare Daten
const [rows, setRows] = useState(exampleData);
// Zustände für Dialog-Funktion
const [open, setOpen] = useState(false); // Dialog anzeigen?
const [currentValue, setCurrentValue] = useState(''); // Eingabewert
const [currentIndex, setCurrentIndex] = useState<number | null>(null); // Zeilenindex
// Beim Klick auf das Stift-Icon: Dialog öffnen
const handleEditClick = (value: string, index: number) => {
setCurrentValue(value);
setCurrentIndex(index);
setOpen(true);
};
// Wert speichern und Dialog schließen
const handleSave = () => {
if (currentIndex !== null) {
const updated = [...rows];
updated[currentIndex].value = currentValue;
setRows(updated);
}
setOpen(false);
};
return (
<>
<TableContainer component={Paper}>
<Table>
{/* Tabellenkopf */}
<TableHead>
<TableRow>
<TableCell><strong>Kennzahl</strong></TableCell>
<TableCell><strong>Wert</strong></TableCell>
<TableCell><strong>Seite</strong></TableCell>
</TableRow>
</TableHead>
{/* Tabelleninhalt */}
<TableBody>
{rows.map((row, index) => {
// Rahmenfarbe anhand Status
let borderColor = 'transparent';
if (row.status === 'error') borderColor = 'red';
else if (row.status === 'warning') borderColor = '#f6ed48';
return (
<TableRow key={index}>
{/* Kennzahl */}
<TableCell>{row.label}</TableCell>
{/* Wert mit Status-Icons + Stift rechts */}
<TableCell>
<Box
sx={{
border: `2px solid ${borderColor}`,
borderRadius: 1,
padding: '4px 8px',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
{row.status === 'error' && <ErrorOutlineIcon fontSize="small" color="error" />}
{row.status === 'warning' && <SearchIcon fontSize="small" sx={{ color: '#f6ed48' }} />}
<span>{row.value || '—'}</span>
</Box>
{/* Stift-Icon */}
<EditIcon
fontSize="small"
sx={{ color: '#555', cursor: 'pointer' }}
onClick={() => handleEditClick(row.value, index)}
/>
</Box>
</TableCell>
{/* Seitenzahl */}
<TableCell>{row.page}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
{/* Dialog zum Bearbeiten */}
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>Kennzahl bearbeiten</DialogTitle>
<DialogContent>
<TextField
fullWidth
value={currentValue}
onChange={(e) => setCurrentValue(e.target.value)}
label="Neuer Wert"
variant="outlined"
margin="dense"
/>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)}>Abbrechen</Button>
<Button onClick={handleSave} variant="contained">Speichern</Button>
</DialogActions>
</Dialog>
</>
);
}

View File

@ -1,100 +1,100 @@
import ContentPasteIcon from "@mui/icons-material/ContentPaste"; import ContentPasteIcon from "@mui/icons-material/ContentPaste";
import { Box, Button, Paper, Typography } from "@mui/material"; import { Box, Button, Paper, Typography } from "@mui/material";
import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { createFileRoute, useNavigate } from "@tanstack/react-router";
import KennzahlenTable from "../components/KennzahlenTable";
import PDFViewer from "../components/pdfViewer"; import PDFViewer from "../components/pdfViewer";
export const Route = createFileRoute("/extractedResult/$pitchBook")({ export const Route = createFileRoute("/extractedResult/$pitchBook")({
component: ExtractedResultsPage, component: ExtractedResultsPage,
}); });
function ExtractedResultsPage() { function ExtractedResultsPage() {
const { pitchBook } = Route.useParams(); const { pitchBook } = Route.useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const status: "green" | "yellow" | "red" = "red"; const status: "green" | "yellow" | "red" = "red";
const statusColor = { const statusColor = {
red: "#f43131", red: "#f43131",
yellow: "#f6ed48", yellow: "#f6ed48",
green: "#3fd942", green: "#3fd942",
}[status]; }[status];
return ( return (
<Box p={4}> <Box p={4}>
<Box display="flex" alignItems="center" gap={3}> <Box display="flex" alignItems="center" gap={3}>
<Box <Box
sx={{ sx={{
width: 45, width: 45,
height: 45, height: 45,
borderRadius: "50%", borderRadius: "50%",
backgroundColor: statusColor, backgroundColor: statusColor,
top: 32, top: 32,
left: 32, left: 32,
}} }}
/> />
<Typography variant="h5" gutterBottom> <Typography variant="h5" gutterBottom>
Kennzahlen extrahiert aus: <br /> Kennzahlen extrahiert aus: <br />
<strong>FONDSNAME: TODO</strong> <strong>FONDSNAME: TODO</strong>
</Typography> </Typography>
</Box> </Box>
<Box <Box
display="flex" display="flex"
gap={4} gap={4}
sx={{ sx={{
width: "100vw", width: "100vw",
maxWidth: "100%", maxWidth: "100%",
height: "80vh", height: "80vh",
mt: 4, mt: 4,
}} }}
> >
<Paper <Paper
elevation={2} elevation={2}
sx={{ sx={{
width: "45%", width: "45%",
height: "100%", height: "100%",
borderRadius: 2, borderRadius: 2,
backgroundColor: "#eeeeee", backgroundColor: "#eeeeee",
display: "flex", padding: 2,
alignItems: "center", overflow: "auto",
justifyContent: "center", }}
}} >
> <KennzahlenTable />
<Typography color="textSecondary">To-do: Table hierhin</Typography> </Paper>
</Paper> <Box
<Box display="flex"
display="flex" flexDirection="column"
flexDirection="column" justifyContent="space-between"
justifyContent="space-between" gap={5}
gap={5} sx={{ width: "55%", height: "95%" }}
sx={{ width: "55%", height: "95%" }} >
> <Paper
<Paper elevation={2}
elevation={2} sx={{
sx={{ height: "100%",
height: "100%", borderRadius: 2,
borderRadius: 2, backgroundColor: "#eeeeee",
backgroundColor: "#eeeeee", display: "flex",
display: "flex", alignItems: "center",
alignItems: "center", justifyContent: "center",
justifyContent: "center", }}
}} >
> <PDFViewer pitchBookId={pitchBook} />
<PDFViewer pitchBookId={pitchBook} /> </Paper>
</Paper> <Box mt={2} display="flex" justifyContent="flex-end" gap={2}>
<Box mt={2} display="flex" justifyContent="flex-end" gap={2}> <Button variant="contained" sx={{ backgroundColor: "#383838" }}>
<Button variant="contained" sx={{ backgroundColor: "#383838" }}> <ContentPasteIcon sx={{ fontSize: 18, mr: 1 }} />
<ContentPasteIcon sx={{ fontSize: 18, mr: 1 }} /> Kennzahlenzeile kopieren
Kennzahlenzeile kopieren </Button>
</Button> <Button
<Button variant="contained"
variant="contained" sx={{ backgroundColor: "#383838" }}
sx={{ backgroundColor: "#383838" }} onClick={() => navigate({ to: "/" })}
onClick={() => navigate({ to: "/" })} >
> Neu hochladen
Neu hochladen </Button>
</Button> </Box>
</Box> </Box>
</Box> </Box>
</Box> </Box>
</Box> );
);
} }