fix(anfragencenter): match cards fixed width 240px, horizontal scroll rail

Replace flex-stretch layout (cards filling full width = distorted images)
with fixed 240px cards in a horizontal overflow-auto rail. Shows as many
cards as fit the screen naturally; image height increased to 90px for a
cleaner 240×90 (≈ 8:3) proportion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-06-10 23:46:04 +02:00
parent b0f675c319
commit cf9089b5a2
@@ -1,6 +1,5 @@
import { useState } from 'react'
import { Box, Button, CircularProgress, Divider, IconButton, Typography } from '@mui/material'
import { ArrowRight, Building2, Calendar, ChevronLeft, ChevronRight, MapPin, Ruler } from 'lucide-react'
import { Box, Button, CircularProgress, Divider, Typography } from '@mui/material'
import { ArrowRight, Building2, Calendar, MapPin, Ruler } from 'lucide-react'
import { useNavigate } from 'react-router'
import { usePropertyById } from '../../hooks/useProperties'
import { useAdditionalMatchesForInquiry } from '../../hooks/useMatches'
@@ -15,7 +14,6 @@ interface RelatedPropertyCardPanelProps {
export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: RelatedPropertyCardPanelProps) {
const { data: property, isLoading } = usePropertyById(propertyId)
const navigate = useNavigate()
const [sliderIndex, setSliderIndex] = useState(0)
const {
data: additionalMatches = [],
isLoading: loadingMatches,
@@ -30,40 +28,14 @@ export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: Rel
}
if (compact) {
const visibleMatches = additionalMatches.slice(sliderIndex, sliderIndex + 2)
const canGoBack = sliderIndex > 0
const canGoForward = sliderIndex + 2 < additionalMatches.length
return (
<Box sx={{ p: 1.5, bgcolor: 'white' }}>
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
<Typography
variant="caption"
sx={{ color: '#64748b', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, fontSize: '0.65rem' }}
>
Weitere passende Objekte
</Typography>
{additionalMatches.length > 2 && (
<Box sx={{ display: 'flex', gap: 0.25 }}>
<IconButton
size="small"
disabled={!canGoBack}
onClick={() => setSliderIndex(i => i - 1)}
sx={{ p: 0.25, color: canGoBack ? '#152642' : '#cbd5e1' }}
>
<ChevronLeft size={14} />
</IconButton>
<IconButton
size="small"
disabled={!canGoForward}
onClick={() => setSliderIndex(i => i + 1)}
sx={{ p: 0.25, color: canGoForward ? '#152642' : '#cbd5e1' }}
>
<ChevronRight size={14} />
</IconButton>
</Box>
)}
</Box>
<Box sx={{ px: 1.5, pt: 1.25, pb: 1.5, bgcolor: 'white' }}>
<Typography
variant="caption"
sx={{ color: '#64748b', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, fontSize: '0.65rem', display: 'block', mb: 1 }}
>
Weitere passende Objekte
</Typography>
{loadingMatches ? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 1.5 }}>
@@ -74,8 +46,17 @@ export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: Rel
Keine weiteren Matches
</Typography>
) : (
<Box sx={{ display: 'flex', gap: 1.5 }}>
{visibleMatches.map(m => (
<Box
sx={{
display: 'flex',
gap: 1.25,
overflowX: 'auto',
pb: 0.5,
'&::-webkit-scrollbar': { height: 3 },
'&::-webkit-scrollbar-thumb': { bgcolor: '#cbd5e1', borderRadius: 2 },
}}
>
{additionalMatches.map(m => (
<MatchSliderCard key={m.propertyId} match={m} />
))}
</Box>
@@ -198,8 +179,8 @@ function MatchSliderCard({ match }: { match: AdditionalPropertyMatch }) {
<Box
onClick={() => navigate('/supply/properties')}
sx={{
flex: '1 1 0',
minWidth: 0,
flexShrink: 0,
width: 240,
border: '1px solid #e8e7e4',
borderRadius: 2,
overflow: 'hidden',
@@ -213,7 +194,7 @@ function MatchSliderCard({ match }: { match: AdditionalPropertyMatch }) {
}}
>
{/* Image with consistent aspect ratio */}
<Box sx={{ position: 'relative', height: 72, overflow: 'hidden', bgcolor: '#f4f3f0' }}>
<Box sx={{ position: 'relative', height: 90, overflow: 'hidden', bgcolor: '#f4f3f0' }}>
{match.imageUrl ? (
<Box
component="img"