da50f3b5ea
- Design tokens (ds.ts, theme.ts, scoreTheme.ts): new warm palette (#152642 navy, #f9f8f6 warm white, #e8e7e4 borders, #b8975a gold accent), flat score tier badges replacing CSS gradients, Inter + DM Serif Display typography - Card components: white-background cards, DM Serif score numbers, max-2 badge chips with +N overflow tooltip, editorial score badge positioning - Layout shell: gold left-accent nav active state, 64px top bar, outlined workspace chip, DM Serif page titles - Shared atoms: GenericBadge (outlined/solid variants), ResultFilterBar (simplified chip styles), DecisionContextPanel (dot metrics, no left accent) - Global replacement (118 files): #1e3a5f→#152642, #e2e8f0→#e8e7e4, #f4f6f9→#f9f8f6 — all handled via Node.js for proper UTF-8 safety Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
92 lines
3.8 KiB
TypeScript
92 lines
3.8 KiB
TypeScript
import { Box, Button, Divider, Paper, Typography } from '@mui/material'
|
|
import { DataQualityProgress } from './DataQualityProgress'
|
|
import { CriticalFieldWarning } from './CriticalFieldWarning'
|
|
import { MissingDataList } from './MissingDataList'
|
|
import { ProvenancePanel } from './ProvenancePanel'
|
|
import { DataQualityBadge } from './DataQualityBadge'
|
|
import { getRecommendedActions } from '../../services/dataQualityService'
|
|
import type { Property } from '../../domain/property'
|
|
|
|
interface DataQualityPanelProps {
|
|
property: Property
|
|
}
|
|
|
|
function SectionLabel({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<Typography variant="caption" sx={{
|
|
fontWeight: 700,
|
|
textTransform: 'uppercase',
|
|
letterSpacing: 0.5,
|
|
color: '#64748b',
|
|
display: 'block',
|
|
mb: 1,
|
|
}}>
|
|
{children}
|
|
</Typography>
|
|
)
|
|
}
|
|
|
|
export function DataQualityPanel({ property }: DataQualityPanelProps) {
|
|
const q = property.dataQuality
|
|
const actions = getRecommendedActions(q, q.freshness)
|
|
|
|
return (
|
|
<Box>
|
|
{/* ── Score & Dimensions ─────────────────────────────────────────── */}
|
|
<Paper variant="outlined" sx={{ p: 2, mb: 2, bgcolor: '#fafafa' }}>
|
|
<Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', mb: 1.5 }}>
|
|
<Box>
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 700, mb: 0.5 }}>Datenqualität</Typography>
|
|
<DataQualityBadge quality={q} showLabel size="medium" />
|
|
</Box>
|
|
<Box sx={{ textAlign: 'right' }}>
|
|
<Typography variant="caption" color="text.secondary" sx={{ display: 'block' }}>
|
|
{q.missingCriticalFields.length === 0 ? 'Alle Pflichtfelder vorhanden' : `${q.missingCriticalFields.length} Pflichtfeld(er) fehlen`}
|
|
</Typography>
|
|
<Typography variant="caption" color="text.secondary">
|
|
{q.missingOptionalFields.length} optionale Felder fehlen
|
|
</Typography>
|
|
</Box>
|
|
</Box>
|
|
<DataQualityProgress property={property} />
|
|
</Paper>
|
|
|
|
{/* ── Critical warnings ──────────────────────────────────────────── */}
|
|
<CriticalFieldWarning
|
|
fields={q.missingCriticalFields}
|
|
warnings={q.warnings}
|
|
/>
|
|
|
|
{/* ── Missing data with actions ──────────────────────────────────── */}
|
|
<Box sx={{ mb: 2 }}>
|
|
<SectionLabel>Fehlende Daten & Massnahmen</SectionLabel>
|
|
<MissingDataList
|
|
criticalFields={q.missingCriticalFields}
|
|
optionalFields={q.missingOptionalFields}
|
|
recommendedActions={actions}
|
|
/>
|
|
</Box>
|
|
|
|
<Divider sx={{ mb: 2 }} />
|
|
|
|
{/* ── Provenance ─────────────────────────────────────────────────── */}
|
|
<Box sx={{ mb: 2 }}>
|
|
<SectionLabel>Datenherkunft & Verifikation</SectionLabel>
|
|
<ProvenancePanel property={property} />
|
|
</Box>
|
|
|
|
{/* ── Action button ──────────────────────────────────────────────── */}
|
|
<Box sx={{ pt: 1 }}>
|
|
<Button variant="outlined" size="small" sx={{ textTransform: 'none', mr: 1 }}>
|
|
Datenaktualisierung anfragen
|
|
</Button>
|
|
{q.missingCriticalFields.length > 0 && (
|
|
<Button variant="contained" size="small" sx={{ textTransform: 'none', bgcolor: '#152642' }}>
|
|
Fehlende Felder ergänzen
|
|
</Button>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
)
|
|
}
|