refactor: split PropertyDetail, Anfragen, AISearch god components
PropertyDetail.tsx: 565→118 lines - Removed duplicate constants (import from MatchDetailPropertyDetails) - PropertyDetailPublicSections: Preis/Hauptangaben/Eigenschaften/Wegzeit/Einheiten/Beschreibung/Quelle sections - PropertyContactForm: Verwaltung kontaktieren form Anfragen.tsx: 481→320 lines - anfragenKiDetection.ts: STAGE_ORDER, STAGE_LABELS, KI_RULES, detectKiStage - AnfragenMessageBubble: chat message bubble component - AnfragenInquiryItem: inquiry list row component AISearch.tsx: 398→342 lines - needSearchMapper.ts: generateSummary + buildNeedInput pure functions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
Alert,
|
||||
Box,
|
||||
Button,
|
||||
Paper,
|
||||
TextField,
|
||||
Typography,
|
||||
} from '@mui/material'
|
||||
import { Calendar, CheckCircle2, Mail } from 'lucide-react'
|
||||
import type { PropertyUnit } from '../../domain/property'
|
||||
|
||||
interface PropertyContactFormProps {
|
||||
propertyTitle: string
|
||||
highlightUnitId?: string | null
|
||||
units?: PropertyUnit[]
|
||||
}
|
||||
|
||||
export function PropertyContactForm({ propertyTitle, highlightUnitId, units }: PropertyContactFormProps) {
|
||||
const [inquiryName, setInquiryName] = useState('')
|
||||
const [inquiryText, setInquiryText] = useState('')
|
||||
const [sent, setSent] = useState(false)
|
||||
|
||||
function handleSendInquiry() {
|
||||
if (!inquiryName.trim() || !inquiryText.trim()) return
|
||||
setSent(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper sx={{ p: 2.5 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 2 }}>
|
||||
<Mail size={15} color="#374151" />
|
||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>Verwaltung kontaktieren</Typography>
|
||||
</Box>
|
||||
|
||||
{sent ? (
|
||||
<Alert
|
||||
icon={<CheckCircle2 size={18} />}
|
||||
severity="success"
|
||||
sx={{ borderRadius: 1 }}
|
||||
>
|
||||
Ihre Anfrage wurde übermittelt. Die Verwaltung meldet sich in Kürze.
|
||||
</Alert>
|
||||
) : (
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', gap: 1.5 }}>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5 }}>Ihr Name</Typography>
|
||||
<TextField
|
||||
size="small"
|
||||
fullWidth
|
||||
placeholder="Max Muster"
|
||||
value={inquiryName}
|
||||
onChange={e => setInquiryName(e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ flex: 1 }}>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5 }}>Bezug</Typography>
|
||||
<TextField
|
||||
size="small"
|
||||
fullWidth
|
||||
value={
|
||||
highlightUnitId
|
||||
? (units?.find(u => u.id === highlightUnitId)?.unitLabel ?? 'Einheit')
|
||||
: propertyTitle
|
||||
}
|
||||
slotProps={{ input: { readOnly: true } }}
|
||||
sx={{ '& .MuiInputBase-input': { color: 'text.secondary', fontSize: '0.85rem' } }}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 0.5 }}>Ihre Nachricht</Typography>
|
||||
<TextField
|
||||
size="small"
|
||||
fullWidth
|
||||
multiline
|
||||
rows={4}
|
||||
placeholder="Wir interessieren uns für die Fläche und möchten gerne einen Besichtigungstermin vereinbaren..."
|
||||
value={inquiryText}
|
||||
onChange={e => setInquiryText(e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
|
||||
<Calendar size={12} color="#64748b" />
|
||||
<Typography variant="caption" color="text.secondary">Antwortzeit: typisch 1–2 Werktage</Typography>
|
||||
</Box>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="small"
|
||||
disabled={!inquiryName.trim() || !inquiryText.trim()}
|
||||
onClick={handleSendInquiry}
|
||||
startIcon={<Mail size={14} />}
|
||||
sx={{ bgcolor: '#7c3aed', '&:hover': { bgcolor: '#6d28d9' }, textTransform: 'none' }}
|
||||
>
|
||||
Anfrage senden
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user