ae82d0e6a0
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>
105 lines
3.7 KiB
TypeScript
105 lines
3.7 KiB
TypeScript
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>
|
||
)
|
||
}
|