import { useEffect, useState } from 'react'; import { dayName, formatDate, toIsoDate, weekDates } from '../shared/dates.js'; import { buildDesktopWeekModel, buildTeacherLessonChips, canRequestChange, lessonsByDate } from './teacher-service.js'; const MOBILE_BREAKPOINT = '(max-width: 980px)'; export function TeacherWeekGrid({ emptyMessage = 'Загрузка...', lessons = [], onRequestLesson, weekStart }) { const mobile = useMobileLayout(); if (mobile) { return ; } return ; } function DesktopWeek({ emptyMessage, lessons, onRequestLesson, weekStart }) { const { days, slots, lessonsByKey } = buildDesktopWeekModel(weekStart, lessons); const hasLessons = lessons.length > 0; return (
{days.map(day => )} {hasLessons ? ( slots.map(slot => ( )) ) : ( <>
Неделя
{days.map(day => (
{emptyMessage}
))} )}
); } function SlotRow({ days, lessonsByKey, onRequestLesson, slot }) { return ( <>
{slot.label}
{days.map(day => { const lesson = lessonsByKey.get(`${day.isoDate}:${slot.order}`); return (
{lesson ? :
Нет занятия
}
); })} ); } function MobileWeek({ emptyMessage, lessons, onRequestLesson, weekStart }) { const byDate = lessonsByDate(lessons); return (
{weekDates(weekStart).map(date => { const isoDate = toIsoDate(date); const dayLessons = byDate.get(isoDate) || []; return (
{dayLessons.length > 0 ? dayLessons.map((lesson, index) => ( )) :
{emptyMessage}
}
); })}
); } function DayHead({ date }) { return (
{dayName(date)} {formatDate(date)}
); } function LessonCard({ lesson, onRequestLesson }) { return (
{lesson.subjectName}
{buildTeacherLessonChips(lesson).map((chip, index) => ( {chip} ))}
{canRequestChange(lesson) ? ( ) : ( Занятие уже изменено учебным отделом )}
); } function trimKey(lesson) { return String(lesson.startTime || '').slice(0, 5); } function useMobileLayout() { const [mobile, setMobile] = useState(() => matchesMobile()); useEffect(() => { if (typeof window === 'undefined' || !window.matchMedia) return undefined; const query = window.matchMedia(MOBILE_BREAKPOINT); const update = () => setMobile(query.matches); update(); query.addEventListener('change', update); return () => query.removeEventListener('change', update); }, []); return mobile; } function matchesMobile() { return typeof window !== 'undefined' && Boolean(window.matchMedia) && window.matchMedia(MOBILE_BREAKPOINT).matches; }