4d4ea6d2ff
PropertyDetailView.tsx extracted into 5 focused components: - PropertyDetailHelpers: Field, FieldGrid, SectionTitle, floorLabel - UnitStructurePanel: floor structure with unit matching - PreMarketPanel: schattenmarkt release controls - PropertyDetailOverview: overview tab content - MatchabilityTabPanel: need matches tab MatchDetail.tsx extracted into 2 focused components: - MatchDetailHero: image/map, header, key facts strip - MatchDetailPropertySections: Preis/Hauptangaben/Eigenschaften/etc. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
42 lines
1.3 KiB
TypeScript
42 lines
1.3 KiB
TypeScript
import { Box, Typography } from '@mui/material'
|
|
import type { PropertyUnit } from '../../domain/property'
|
|
|
|
export function floorLabel(u: PropertyUnit): string {
|
|
if (u.floorLevel === 0) return 'EG'
|
|
if (u.floorLevel < 0) return `UG${Math.abs(u.floorLevel)}`
|
|
return `${u.floorLevel}.OG`
|
|
}
|
|
|
|
export function Field({ label, value }: { label: string; value?: string | number | boolean | null }) {
|
|
return (
|
|
<Box sx={{ mb: 1.5 }}>
|
|
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', lineHeight: 1 }}>
|
|
{label}
|
|
</Typography>
|
|
{value !== undefined && value !== null && value !== '' ? (
|
|
<Typography variant="body2" sx={{ fontWeight: 500, mt: 0.25 }}>
|
|
{typeof value === 'boolean' ? (value ? 'Ja' : 'Nein') : String(value)}
|
|
</Typography>
|
|
) : (
|
|
<Typography variant="body2" color="text.disabled" sx={{ mt: 0.25 }}>—</Typography>
|
|
)}
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
export function FieldGrid({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<Box sx={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 0.5 }}>
|
|
{children}
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
export function SectionTitle({ title }: { title: string }) {
|
|
return (
|
|
<Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 1.5, mt: 0.5 }}>
|
|
{title}
|
|
</Typography>
|
|
)
|
|
}
|