refactor: premium design polish — cards, results, grid view

- PropertyIntelligenceCard: aspect-ratio image, hover animation, compact
  data-completeness row, tighter body padding
- Results: replace verbose Card with compact active-search strip, remove
  DecisionContextPanel
- Properties: add 3/5/10 column toggle in grid view, persist to localStorage
- NeedInput, UnifiedResultCard/Feed, MatchCardViewModel: cleanup from
  earlier session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-06-11 00:06:23 +02:00
parent 6e67c698ce
commit beecf754d5
7 changed files with 94 additions and 177 deletions
+29 -5
View File
@@ -57,6 +57,9 @@ export default function Properties() {
const [view, setView] = useState<'list' | 'grid'>(() =>
(localStorage.getItem('view-properties') as 'list' | 'grid') ?? 'list'
)
const [columns, setColumns] = useState<3 | 5 | 10>(() =>
(Number(localStorage.getItem('view-properties-cols')) as 3 | 5 | 10) || 3
)
const [headerOpen, setHeaderOpen] = useState(() =>
localStorage.getItem('props-header-open') !== 'false'
)
@@ -109,10 +112,31 @@ export default function Properties() {
title="Objektverwaltung"
subtitle={`${filtered.length} von ${properties.length} Objekten`}
secondaryActions={
<ViewToggle
view={view}
onChange={v => { setView(v); localStorage.setItem('view-properties', v) }}
/>
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
{view === 'grid' && (
<Box sx={{ display: 'flex', border: '1px solid #e2e8f0', borderRadius: 1, overflow: 'hidden' }}>
{([3, 5, 10] as const).map(n => (
<Box
key={n}
onClick={() => { setColumns(n); localStorage.setItem('view-properties-cols', String(n)) }}
sx={{
width: 32, height: 32, display: 'flex', alignItems: 'center', justifyContent: 'center',
cursor: 'pointer', fontSize: '0.72rem', fontWeight: 600,
bgcolor: columns === n ? '#152642' : 'transparent',
color: columns === n ? 'white' : '#64748b',
'&:hover': { bgcolor: columns === n ? '#162d4a' : '#f1f5f9' },
}}
>
{n}
</Box>
))}
</Box>
)}
<ViewToggle
view={view}
onChange={v => { setView(v); localStorage.setItem('view-properties', v) }}
/>
</Box>
}
/>
@@ -201,7 +225,7 @@ export default function Properties() {
<Box sx={{ flex: 1, overflowY: 'auto' }}>
{view === 'grid' ? (
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(320px, 1fr))', gap: 2, p: 2.5 }}>
<Box sx={{ display: 'grid', gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 3, p: 3 }}>
{filtered.map(p => (
<PropertyIntelligenceCard key={p.id} property={p} onSelect={setSelectedId} inquiryCount={inquiryCountByProperty.get(p.id) ?? 0} />
))}