import React, { useState, useEffect, useMemo } from 'react'; import { X, Calendar } from 'lucide-react'; import { DomaApplication, DomaApplicationStatus } from '../../types'; import { backendApi } from '../../services/apiClient'; import { Building, Employee } from '../../types'; type ResidentOption = { key: string; fullName: string; apartment: string; phone?: string }; function residentsFromBuilding(building: Building | null): ResidentOption[] { if (!building?.accounts?.length) return []; const list: ResidentOption[] = []; for (const acc of building.accounts) { const apt = acc.apartmentNumber || ''; (acc.owners || []).forEach((o) => { if (o?.fullName) list.push({ key: `o:${acc.id}:${o.fullName}`, fullName: o.fullName, apartment: apt, phone: o.phone }); }); (acc.registered || []).forEach((r) => { if (r?.fullName) list.push({ key: `r:${acc.id}:${r.id}`, fullName: r.fullName, apartment: apt, phone: r.phone }); }); } const seen = new Set(); return list.filter((r) => { const k = `${r.apartment}::${r.fullName}`.toLowerCase(); if (seen.has(k)) return false; seen.add(k); return true; }); } const STATUS_OPTIONS: { value: DomaApplicationStatus; label: string }[] = [ { value: 'new', label: 'Новая' }, { value: 'in_progress', label: 'В работе' }, { value: 'deferred', label: 'Отложена' }, { value: 'done', label: 'Выполнена' }, { value: 'canceled', label: 'Отменена' }, ]; interface Props { isOpen: boolean; onClose: () => void; application: DomaApplication; onSuccess: () => void; } export const EditApplicationModal: React.FC = ({ isOpen, onClose, application, onSuccess }) => { const [status, setStatus] = useState(application.status || 'new'); const [deadlineAt, setDeadlineAt] = useState(''); const [buildingId, setBuildingId] = useState(''); const [address, setAddress] = useState(''); const [apartment, setApartment] = useState(''); const [description, setDescription] = useState(''); const [contactName, setContactName] = useState(''); const [contactPhone, setContactPhone] = useState(''); const [selectedResidentKey, setSelectedResidentKey] = useState(''); const [executorName, setExecutorName] = useState(''); const [responsibleName, setResponsibleName] = useState(''); const [observersText, setObserversText] = useState(''); const [buildings, setBuildings] = useState([]); const [selectedBuilding, setSelectedBuilding] = useState(null); const [employees, setEmployees] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const residents = useMemo(() => residentsFromBuilding(selectedBuilding), [selectedBuilding]); useEffect(() => { if (isOpen) { setStatus((application.status as DomaApplicationStatus) || 'new'); if (application.deadlineAt) { const d = new Date(application.deadlineAt); const pad = (n: number) => String(n).padStart(2, '0'); setDeadlineAt(`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`); } else { setDeadlineAt(''); } setAddress(application.address || ''); setApartment(application.apartment || ''); setDescription(application.description || ''); setContactName(application.contactName || application.clientName || ''); setContactPhone(application.contactPhone || ''); setExecutorName(application.executorName || application.performer?.name || ''); setResponsibleName(application.responsibleName || ''); setObserversText(application.observersText || ''); setError(null); backendApi.getEmployees().then(setEmployees).catch(() => setEmployees([])); backendApi.getBuildings().then(setBuildings).catch(() => setBuildings([])); } }, [isOpen, application]); useEffect(() => { if (!isOpen) return; const bid = application.buildingId || buildings.find(b => (b.passport as any)?.address === application.address)?.id || ''; setBuildingId(bid); }, [isOpen, application.buildingId, application.address, buildings]); useEffect(() => { if (!buildingId) { setSelectedBuilding(null); return; } if (buildingId !== application.buildingId) { setSelectedResidentKey(''); setContactName(''); setContactPhone(''); setApartment(''); } backendApi.getBuilding(buildingId).then((b) => { setSelectedBuilding(b); setAddress((b.passport as any)?.address || buildingId); }).catch(() => setSelectedBuilding(null)); }, [buildingId]); useEffect(() => { if (!residents.length || !contactName || selectedResidentKey) return; const match = residents.find(r => r.fullName === contactName && r.apartment === apartment); if (match) setSelectedResidentKey(match.key); }, [residents, contactName, apartment]); if (!isOpen) return null; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!buildingId || !address.trim()) { setError('Выберите адрес (дом)'); return; } if (!description.trim()) { setError('Опишите проблему'); return; } setLoading(true); try { await backendApi.updateApplication(application.id, { status, deadlineAt: deadlineAt ? new Date(deadlineAt).toISOString() : undefined, address: address.trim(), buildingId: buildingId || undefined, apartment: apartment.trim() || undefined, description: description.trim(), contactName: contactName.trim() || undefined, contactPhone: contactPhone.trim() || undefined, executorName: executorName.trim() || undefined, responsibleName: responsibleName.trim() || undefined, observersText: observersText.trim() || undefined, changedBy: 'Администратор', }); window.dispatchEvent(new CustomEvent('mkd-applications-changed')); onSuccess(); onClose(); } catch (err: any) { setError(err.message || 'Ошибка при сохранении'); } finally { setLoading(false); } }; const handleClose = () => { if (!loading) onClose(); }; return (
e.stopPropagation()}>

Редактировать заявку №{application.number}

{error && (
{error}
)}
setDeadlineAt(e.target.value)} className="flex-1 px-4 py-3 border border-slate-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500" />
{(selectedResidentKey || contactName) && (

{contactName}{contactPhone ? ` · ${contactPhone}` : ''}{apartment ? ` · кв. ${apartment}` : ''}

)}
setApartment(e.target.value)} placeholder="Номер квартиры" className="w-full px-4 py-3 border border-slate-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500" />
setContactPhone(e.target.value)} placeholder="+7 900 123-45-67" className="w-full px-4 py-3 border border-slate-200 rounded-xl text-sm outline-none focus:ring-2 focus:ring-primary-500 focus:border-primary-500" />