import { useEffect, useState } from 'react'; import { formatIsoDate, trimTime } from '../shared/dates.js'; import { buildChangeRequestPayload, candidateOptions, fetchChangeRequestCandidates } from './teacher-service.js'; export function RequestDialog({ lesson, onClose, onSubmitted }) { const [candidates, setCandidates] = useState(null); const [candidatesError, setCandidatesError] = useState(false); const [requestType, setRequestType] = useState('MOVE'); const [targetDate, setTargetDate] = useState(''); const [timeSlotId, setTimeSlotId] = useState(''); const [classroomId, setClassroomId] = useState(''); const [reason, setReason] = useState(''); const [message, setMessage] = useState({ text: 'Проверяем допустимые варианты...', isError: false }); const [submitting, setSubmitting] = useState(false); useEffect(() => { document.body.classList.add('dialog-open'); return () => { document.body.classList.remove('dialog-open'); }; }, []); useEffect(() => { let active = true; (async () => { try { const loaded = await fetchChangeRequestCandidates({ baseRuleSlotId: lesson.scheduleRuleSlotId, lessonDate: lesson.date }); if (!active) return; setCandidates(loaded); setCandidatesError(false); setTargetDate(loaded.checkedDate || (loaded.availableDates || [])[0] || ''); setMessage({ text: 'Доступны только варианты, прошедшие проверку конфликтов', isError: false }); } catch { if (!active) return; setCandidatesError(true); setMessage({ text: 'Не удалось проверить допустимые варианты', isError: true }); } })(); return () => { active = false; }; }, [lesson]); async function reloadCandidates(nextDate) { if (!nextDate) return; setMessage({ text: 'Проверяем выбранную дату...', isError: false }); try { const loaded = await fetchChangeRequestCandidates({ baseRuleSlotId: lesson.scheduleRuleSlotId, lessonDate: lesson.date, targetDate: nextDate }); setCandidates(loaded); setCandidatesError(false); setTimeSlotId(''); setClassroomId(''); setMessage({ text: 'Предварительная проверка завершена', isError: false }); } catch { setMessage({ text: 'Не удалось проверить допустимые варианты', isError: true }); } } async function submit(event) { event.preventDefault(); if (!reason.trim()) { setMessage({ text: 'Укажите обоснование заявки', isError: true }); return; } setSubmitting(true); try { await onSubmitted(buildChangeRequestPayload({ classroomId, lesson, reason, requestType, targetDate, timeSlotId })); } finally { setSubmitting(false); } } const timeOptions = candidateOptions(candidates?.timeSlots, 'Нет свободных временных слотов'); const classroomOptions = candidateOptions(candidates?.classrooms, 'Нет свободных аудиторий'); return (
{ if (event.target === event.currentTarget) onClose(); }}>
Предварительная проверка

Заявка на изменение

{lesson.subjectName} · {formatIsoDate(lesson.date)} · {trimTime(lesson.startTime)}–{trimTime(lesson.endTime)}

{requestType === 'MOVE' && ( )} {requestType === 'MOVE' && ( )} {requestType === 'CHANGE_CLASSROOM' && ( )}