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:
@@ -1,6 +1,5 @@
|
|||||||
import { useState } from 'react'
|
import { Box, Button, CircularProgress, Divider, Typography } from '@mui/material'
|
||||||
import { Box, Button, CircularProgress, Divider, IconButton, Typography } from '@mui/material'
|
import { ArrowRight, Building2, Calendar, MapPin, Ruler } from 'lucide-react'
|
||||||
import { ArrowRight, Building2, Calendar, ChevronLeft, ChevronRight, MapPin, Ruler } from 'lucide-react'
|
|
||||||
import { useNavigate } from 'react-router'
|
import { useNavigate } from 'react-router'
|
||||||
import { usePropertyById } from '../../hooks/useProperties'
|
import { usePropertyById } from '../../hooks/useProperties'
|
||||||
import { useAdditionalMatchesForInquiry } from '../../hooks/useMatches'
|
import { useAdditionalMatchesForInquiry } from '../../hooks/useMatches'
|
||||||
@@ -15,7 +14,6 @@ interface RelatedPropertyCardPanelProps {
|
|||||||
export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: RelatedPropertyCardPanelProps) {
|
export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: RelatedPropertyCardPanelProps) {
|
||||||
const { data: property, isLoading } = usePropertyById(propertyId)
|
const { data: property, isLoading } = usePropertyById(propertyId)
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [sliderIndex, setSliderIndex] = useState(0)
|
|
||||||
const {
|
const {
|
||||||
data: additionalMatches = [],
|
data: additionalMatches = [],
|
||||||
isLoading: loadingMatches,
|
isLoading: loadingMatches,
|
||||||
@@ -30,40 +28,14 @@ export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: Rel
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (compact) {
|
if (compact) {
|
||||||
const visibleMatches = additionalMatches.slice(sliderIndex, sliderIndex + 2)
|
|
||||||
const canGoBack = sliderIndex > 0
|
|
||||||
const canGoForward = sliderIndex + 2 < additionalMatches.length
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ p: 1.5, bgcolor: 'white' }}>
|
<Box sx={{ px: 1.5, pt: 1.25, pb: 1.5, bgcolor: 'white' }}>
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
|
|
||||||
<Typography
|
<Typography
|
||||||
variant="caption"
|
variant="caption"
|
||||||
sx={{ color: '#64748b', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, fontSize: '0.65rem' }}
|
sx={{ color: '#64748b', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5, fontSize: '0.65rem', display: 'block', mb: 1 }}
|
||||||
>
|
>
|
||||||
Weitere passende Objekte
|
Weitere passende Objekte
|
||||||
</Typography>
|
</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>
|
|
||||||
|
|
||||||
{loadingMatches ? (
|
{loadingMatches ? (
|
||||||
<Box sx={{ display: 'flex', justifyContent: 'center', py: 1.5 }}>
|
<Box sx={{ display: 'flex', justifyContent: 'center', py: 1.5 }}>
|
||||||
@@ -74,8 +46,17 @@ export function RelatedPropertyCardPanel({ propertyId, inquiryId, compact }: Rel
|
|||||||
Keine weiteren Matches
|
Keine weiteren Matches
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
) : (
|
||||||
<Box sx={{ display: 'flex', gap: 1.5 }}>
|
<Box
|
||||||
{visibleMatches.map(m => (
|
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} />
|
<MatchSliderCard key={m.propertyId} match={m} />
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
@@ -198,8 +179,8 @@ function MatchSliderCard({ match }: { match: AdditionalPropertyMatch }) {
|
|||||||
<Box
|
<Box
|
||||||
onClick={() => navigate('/supply/properties')}
|
onClick={() => navigate('/supply/properties')}
|
||||||
sx={{
|
sx={{
|
||||||
flex: '1 1 0',
|
flexShrink: 0,
|
||||||
minWidth: 0,
|
width: 240,
|
||||||
border: '1px solid #e8e7e4',
|
border: '1px solid #e8e7e4',
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
@@ -213,7 +194,7 @@ function MatchSliderCard({ match }: { match: AdditionalPropertyMatch }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Image with consistent aspect ratio */}
|
{/* 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 ? (
|
{match.imageUrl ? (
|
||||||
<Box
|
<Box
|
||||||
component="img"
|
component="img"
|
||||||
|
|||||||
Reference in New Issue
Block a user