import React, { useState, useEffect, useMemo } from 'react'; import { X, Users, Check, Search } from 'lucide-react'; import { TrainingProgram, TrainingType, TrainingCategory, Employee } from '../../types'; interface ProgramModalProps { program?: TrainingProgram | null; employees?: Employee[]; onClose: () => void; onSave: (program: TrainingProgram, selectedEmployeeIds?: string[]) => void; } export const ProgramModal: React.FC = ({ program, employees = [], onClose, onSave }) => { const [formData, setFormData] = useState({ title: '', description: '', type: 'instruction' as TrainingType, category: 'safety' as TrainingCategory, durationHours: '', validityMonths: '', isRequired: false, requiredForPositions: '', instructorName: '', materialsUrl: '' }); const [selectedEmployees, setSelectedEmployees] = useState([]); const [showEmployeeSelection, setShowEmployeeSelection] = useState(false); const [employeeSearchQuery, setEmployeeSearchQuery] = useState(''); useEffect(() => { if (program) { setFormData({ title: program.title || '', description: program.description || '', type: program.type || 'instruction', category: program.category || 'safety', durationHours: program.durationHours?.toString() || '', validityMonths: program.validityMonths?.toString() || '', isRequired: program.isRequired || false, requiredForPositions: program.requiredForPositions?.join(', ') || '', instructorName: program.instructorName || '', materialsUrl: program.materialsUrl || '' }); // При редактировании существующей программы показываем выбор сотрудников setShowEmployeeSelection(true); } else { // При создании новой программы выбор сотрудников скрыт по умолчанию setShowEmployeeSelection(false); setSelectedEmployees([]); setEmployeeSearchQuery(''); } }, [program]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!formData.title.trim()) { alert('Название программы обязательно'); return; } const programData: TrainingProgram = { // ID только для существующих программ, для новых - undefined (backend сгенерирует) id: program?.id || undefined, title: formData.title.trim(), description: formData.description.trim() || undefined, type: formData.type, category: formData.category, durationHours: formData.durationHours ? parseFloat(formData.durationHours) : undefined, validityMonths: formData.validityMonths ? parseInt(formData.validityMonths) : undefined, isRequired: formData.isRequired, requiredForPositions: formData.requiredForPositions ? formData.requiredForPositions.split(',').map(p => p.trim()).filter(p => p) : undefined, instructorName: formData.instructorName.trim() || undefined, materialsUrl: formData.materialsUrl.trim() || undefined }; // Передаем выбранных сотрудников для массового назначения onSave(programData, selectedEmployees.length > 0 ? selectedEmployees : undefined); }; const toggleEmployee = (employeeId: string) => { setSelectedEmployees(prev => prev.includes(employeeId) ? prev.filter(id => id !== employeeId) : [...prev, employeeId] ); }; // Фильтрация сотрудников по поисковому запросу const filteredEmployees = useMemo(() => { if (!employeeSearchQuery.trim()) { return employees; } const query = employeeSearchQuery.toLowerCase().trim(); return employees.filter(emp => emp.name?.toLowerCase().includes(query) || emp.position?.toLowerCase().includes(query) ); }, [employees, employeeSearchQuery]); const selectAll = () => { if (selectedEmployees.length === filteredEmployees.length) { // Снимаем только выбранных из отфильтрованного списка setSelectedEmployees(prev => prev.filter(id => !filteredEmployees.some(emp => emp.id === id)) ); } else { // Добавляем всех из отфильтрованного списка const filteredIds = filteredEmployees.map(emp => emp.id); setSelectedEmployees(prev => { const newIds = [...new Set([...prev, ...filteredIds])]; return newIds; }); } }; return (
e.stopPropagation()} >

{program ? `Редактировать программу: ${program.title}` : 'Создать программу обучения'}

setFormData({ ...formData, title: e.target.value })} className="w-full px-4 py-3 border border-slate-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-primary-500" required />