'use client' import { useState, useEffect } from 'react' import { subjectMinDayGapApi, subjectContiguousWhenRepeatedApi, subjectDoubleLessonApi, subjectsApi, } from '@/lib/stundenplan/api' import type { SubjectMinDayGap, SubjectContiguousWhenRepeated, SubjectDoubleLesson, TimetableSubject, } from '@/app/stundenplan/types' import { useConstraintCrud, ConstraintShell, useShellStyles } from './_shell' function useSubjects() { const [subjects, setSubjects] = useState([]) useEffect(() => { subjectsApi.list().then(setSubjects).catch(() => setSubjects([])) }, []) return subjects } function sLabel(subjects: TimetableSubject[], id: string): string { const s = subjects.find(x => x.id === id) return s ? `${s.name} (${s.short_code})` : id.slice(0, 8) + '…' } // ---------- Min Day Gap ---------- type GapForm = Omit const initialGap: GapForm = { subject_id: '', min_gap_days: 1, is_hard: false, weight: 70, active: true, note: '' } export function SubjectMinDayGapEditor() { const styles = useShellStyles() const subjects = useSubjects() const crud = useConstraintCrud(subjectMinDayGapApi, initialGap) return (
crud.setForm({ ...crud.form, min_gap_days: parseInt(e.target.value) || 1 })} className={`w-full px-3 py-2 rounded-lg border ${styles.inputClass}`} />
crud.setForm({ ...crud.form, weight: parseInt(e.target.value) || 0 })} className={`w-full px-3 py-2 rounded-lg border ${styles.inputClass}`} />
crud.setForm({ ...crud.form, is_hard: e.target.checked })} className="w-5 h-5" />
} renderRow={(item) => { const c = item as SubjectMinDayGap return ( {sLabel(subjects, c.subject_id)} {c.min_gap_days} {c.is_hard ? '✓' : '—'} {c.weight} ) }} /> ) } // ---------- Contiguous When Repeated ---------- type ContForm = Omit const initialCont: ContForm = { subject_id: '', is_hard: true, weight: 100, active: true, note: '' } export function SubjectContiguousWhenRepeatedEditor() { const styles = useShellStyles() const subjects = useSubjects() const crud = useConstraintCrud(subjectContiguousWhenRepeatedApi, initialCont) return (
crud.setForm({ ...crud.form, weight: parseInt(e.target.value) || 0 })} className={`w-full px-3 py-2 rounded-lg border ${styles.inputClass}`} />
crud.setForm({ ...crud.form, is_hard: e.target.checked })} className="w-5 h-5" />
} renderRow={(item) => { const c = item as SubjectContiguousWhenRepeated return ( {sLabel(subjects, c.subject_id)} {c.is_hard ? '✓' : '—'} {c.weight} ) }} /> ) } // ---------- Double Lesson ---------- type DoubleForm = Omit const initialDouble: DoubleForm = { subject_id: '', is_hard: false, weight: 60, active: true, note: '' } export function SubjectDoubleLessonEditor() { const styles = useShellStyles() const subjects = useSubjects() const crud = useConstraintCrud(subjectDoubleLessonApi, initialDouble) return (
crud.setForm({ ...crud.form, weight: parseInt(e.target.value) || 0 })} className={`w-full px-3 py-2 rounded-lg border ${styles.inputClass}`} />
crud.setForm({ ...crud.form, is_hard: e.target.checked })} className="w-5 h-5" />
} renderRow={(item) => { const c = item as SubjectDoubleLesson return ( {sLabel(subjects, c.subject_id)} {c.is_hard ? '✓' : '—'} {c.weight} ) }} /> ) }