import React, { useState, useEffect } from 'react'; import { Building, BuildingTask, Employee } from '../../types'; import { Users, Wallet, Activity, TrendingDown, CheckCircle2, Calendar, User, Flag, Clock, MessageSquare, Camera, Image as ImageIcon } from 'lucide-react'; import { TaskModal } from './TaskModal'; import { OutagesJournal } from '../applications/OutagesJournal'; import { backendApi } from '../../services/apiClient'; import { storageService } from '../../services/storageService'; export const Overview: React.FC<{ building: Building, onNavigate: (tab: any) => void, setBuilding?: React.Dispatch> }> = ({ building, onNavigate, setBuilding }) => { const [isTaskModalOpen, setIsTaskModalOpen] = useState(false); const [selectedTask, setSelectedTask] = useState(null); const [employees, setEmployees] = useState([]); useEffect(() => { fetchEmployees(); }, []); const fetchEmployees = async () => { try { const fetchedEmployees = await backendApi.getEmployees(); setEmployees(fetchedEmployees); } catch (error) { console.error('Failed to fetch employees:', error); } }; const handleTaskClick = (task: BuildingTask) => { setSelectedTask(task); setIsTaskModalOpen(true); }; const handleNewTask = () => { setSelectedTask(null); setIsTaskModalOpen(true); }; const tasks = building.tasks ?? []; const handleSaveTask = (task: BuildingTask) => { const updatedTasks = task.id && tasks.find(t => t.id === task.id) ? tasks.map(t => t.id === task.id ? task : t) : [...tasks, task]; const updatedBuilding = { ...building, tasks: updatedTasks, isDirty: true }; if (setBuilding) { setBuilding(updatedBuilding); } // Сохраняем в localStorage storageService.saveBuildingData(updatedBuilding); // Пытаемся сохранить на сервер backendApi.updateBuilding(updatedBuilding).catch(err => { console.error('Failed to save task to backend:', err); }); }; const formatDate = (dateString: string) => { if (!dateString) return '—'; const date = new Date(dateString); if (Number.isNaN(date.getTime())) return '—'; return date.toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' }); }; const getPriorityColor = (priority: BuildingTask['priority']) => { switch (priority) { case 'urgent': return 'bg-red-50 text-red-600'; case 'high': return 'bg-amber-50 text-amber-600'; case 'medium': return 'bg-blue-50 text-blue-600'; case 'low': return 'bg-slate-100 text-slate-600'; default: return 'bg-slate-100 text-slate-600'; } }; const getPriorityLabel = (priority: BuildingTask['priority']) => { switch (priority) { case 'urgent': return 'Срочно'; case 'high': return 'Высокий'; case 'medium': return 'Средний'; case 'low': return 'Низкий'; default: return priority; } }; // Текущий месяц для блока «Статус работ» const MONTH_NAMES = ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']; const now = new Date(); const currentYear = now.getFullYear(); const currentMonthIndex = now.getMonth(); const currentMonthName = MONTH_NAMES[currentMonthIndex]; const currentMonthNameLower = currentMonthName.charAt(0).toLowerCase() + currentMonthName.slice(1); const annualPlan = building.annualPlan ?? []; const plansForCurrentMonth = annualPlan.filter( p => (p.month === currentMonthName || p.month?.toLowerCase() === currentMonthNameLower) && (p.year === currentYear || p.year == null) ); return (
Building

{building.passport?.address ?? 'Адрес не указан'}

{building.passport?.general?.constructionYear ?? '—'} г. • {building.passport?.general?.floors ?? '—'} эт. • {building.passport?.general?.totalArea ?? '—'} м²

onNavigate('accounts')}>

Жителей

{(building.accounts ?? []).reduce((sum, acc) => { const count = acc.registered?.length || acc.registeredCount || 0; return sum + (typeof count === 'number' ? count : 0); }, 0)}

onNavigate('finance')}>

Баланс

= 0 ? 'text-emerald-600' : 'text-red-600'}`}> {((building.financials?.balance ?? 0) / 1000).toFixed(0)}k

onNavigate('inspections')}>

Состояние

Удовл.

NPS

= 0 ? 'text-emerald-500' : 'text-red-500'}`}> {(building.nps ?? 0) > 0 ? '+' : ''}{building.nps ?? 0}

Оперативный план

{tasks.map(task => (
handleTaskClick(task)} className="flex-1 min-w-0 cursor-pointer" >

{task.title}

{formatDate(task.deadline)} {getPriorityLabel(task.priority)} {task.assignedToName && ( {task.assignedToName} )} {task.createdByName && ( {task.createdByName} )} {task.estimatedHours && ( {task.estimatedHours}ч )} {(task.comments?.length ?? 0) > 0 && ( {task.comments!.length} коммент. )} {task.requirePhotoReport !== false && ( {task.photoReportId ? ( ) : ( )} {task.photoReportId ? 'Фото приложен' : 'Нужен фото'} )}
))} {tasks.length === 0 && (

Нет задач

)}

Статус работ за {currentMonthNameLower}

{plansForCurrentMonth.map(plan => (
{plan.workName} {plan.progress}%
))} {plansForCurrentMonth.length === 0 &&

Работ на {currentMonthNameLower} не запланировано

}
{/* Журнал отключений по дому */}
{isTaskModalOpen && ( { setIsTaskModalOpen(false); setSelectedTask(null); }} onSave={handleSaveTask} task={selectedTask} buildingId={building.id} employees={employees} /> )}
); };