import React, { useState, useEffect, useRef } from 'react'; import { useConfigContext } from '../../contexts/ConfigContext'; import './UserForm.css'; const formatSuggestionAddress = (addr) => { const street = [addr.road, addr.house_number].filter(Boolean).join(' '); const place = addr.city || addr.town || addr.village || addr.municipality || addr.hamlet || ''; const postAndPlace = addr.postcode && place ? `${addr.postcode} ${place}` : (addr.postcode || place); return [street, postAndPlace].filter(Boolean).join(', '); }; const UserForm = ({ user, onSave, onCancel }) => { const { userTypes, userTypeLabels } = useConfigContext(); const typeOptions = Object.keys(userTypes); const [formData, setFormData] = useState({ name: '', address: '', phone: '', landline: '', email: '', type: typeOptions[0] || 'HS', available: true, gps: { lat: '', lng: '' } }); const [errors, setErrors] = useState({}); const [suggestions, setSuggestions] = useState([]); const [showSuggestions, setShowSuggestions] = useState(false); const [gpsAutoSet, setGpsAutoSet] = useState(false); const searchTimer = useRef(null); useEffect(() => { if (user) { setFormData({ name: user.name || '', address: user.address || '', phone: user.phone || '', landline: user.landline || '', email: user.email || '', type: user.type || (typeOptions[0] || 'HS'), available: user.available !== undefined ? user.available : true, gps: { lat: user.gps?.lat?.toString() || '', lng: user.gps?.lng?.toString() || '' } }); } else { setFormData({ name: '', address: '', phone: '', landline: '', email: '', type: typeOptions[0] || 'HS', available: true, gps: { lat: '', lng: '' } }); } setErrors({}); setGpsAutoSet(false); }, [user]); const validate = () => { const newErrors = {}; if (!formData.name.trim()) newErrors.name = 'Name ist erforderlich'; if (!formData.address.trim()) newErrors.address = 'Adresse ist erforderlich'; if (!formData.phone.trim()) newErrors.phone = 'Telefonnummer ist erforderlich'; if (formData.gps.lat && (isNaN(formData.gps.lat) || formData.gps.lat < -90 || formData.gps.lat > 90)) newErrors.gpsLat = 'Latitude muss zwischen -90 und 90 liegen'; if (formData.gps.lng && (isNaN(formData.gps.lng) || formData.gps.lng < -180 || formData.gps.lng > 180)) newErrors.gpsLng = 'Longitude muss zwischen -180 und 180 liegen'; setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSubmit = (e) => { e.preventDefault(); if (!validate()) return; const submitData = { name: formData.name.trim(), address: formData.address.trim(), phone: formData.phone.trim(), landline: formData.landline.trim() || null, email: formData.email.trim().toLowerCase() || null, type: formData.type, available: formData.available }; if (formData.gps.lat && formData.gps.lng) { submitData.gps = { lat: parseFloat(formData.gps.lat), lng: parseFloat(formData.gps.lng) }; } onSave(submitData); }; const handleChange = (e) => { const { name, value, type, checked } = e.target; if (name === 'lat' || name === 'lng') { setFormData(prev => ({ ...prev, gps: { ...prev.gps, [name]: value } })); setGpsAutoSet(false); } else { setFormData(prev => ({ ...prev, [name]: type === 'checkbox' ? checked : value })); } if (errors[name]) { setErrors(prev => { const n = { ...prev }; delete n[name]; return n; }); } }; const handleAddressChange = (e) => { const value = e.target.value; setFormData(prev => ({ ...prev, address: value })); setGpsAutoSet(false); if (errors.address) setErrors(prev => { const n = { ...prev }; delete n.address; return n; }); clearTimeout(searchTimer.current); if (value.trim().length < 4) { setSuggestions([]); setShowSuggestions(false); return; } searchTimer.current = setTimeout(async () => { try { const res = await fetch( `https://nominatim.openstreetmap.org/search?format=json&countrycodes=de&addressdetails=1&limit=5&q=${encodeURIComponent(value)}`, { headers: { 'User-Agent': 'stoeberhunde-app/1.0 (admin@kasimirat.de)' } } ); const data = await res.json(); setSuggestions(Array.isArray(data) ? data : []); setShowSuggestions(true); } catch { setSuggestions([]); } }, 400); }; const selectSuggestion = (s) => { const formatted = formatSuggestionAddress(s.address); setFormData(prev => ({ ...prev, address: formatted || s.display_name, gps: { lat: parseFloat(s.lat).toFixed(7), lng: parseFloat(s.lon).toFixed(7) } })); setGpsAutoSet(true); setSuggestions([]); setShowSuggestions(false); }; return (
); }; export default UserForm;