Klausurtermine im Kalender (4.4.3) + Stundenplan: Ausnahme eintragen, Zahnrad-Settings-Link
- 4.4.3: Box "ANSTEHENDE KLAUSUREN" im Heute-Tab, gruppenübergreifend, nächste 21 Tage. IExamRepository um GetAll() erweitert. - Nutzer-Feedback: "Vertretung eintragen" deckt auch Ausfall/Sondereinsatz ab, daher umbenannt in "Ausnahme eintragen". "Stundenplan bearbeiten" (redundant zum Bearbeiten-Tab) ersetzt durch Zahnrad-Button, der direkt in die Einstellungen springt.
This commit is contained in:
@@ -29,6 +29,7 @@ public interface IGroupMembershipRepository
|
||||
public interface IExamRepository
|
||||
{
|
||||
Exam? GetById(Guid id);
|
||||
List<Exam> GetAll();
|
||||
List<Exam> GetByGroup(Guid groupId);
|
||||
void Save(Exam exam);
|
||||
void Delete(Guid id);
|
||||
|
||||
@@ -224,6 +224,20 @@ public sealed class RepositoryTests
|
||||
Assert.Equal("Früh", result[1].Title);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExamRepository_GetAll_UeberAlleGruppenHinwegSortiertAufsteigendNachDatum()
|
||||
{
|
||||
using var db = NewInMemoryContext();
|
||||
var repo = new ExamRepository(db);
|
||||
repo.Save(new Exam { GroupId = Guid.NewGuid(), Title = "Spät", Date = new DateOnly(2025, 11, 1) });
|
||||
repo.Save(new Exam { GroupId = Guid.NewGuid(), Title = "Früh", Date = new DateOnly(2025, 9, 1) });
|
||||
|
||||
var result = repo.GetAll();
|
||||
|
||||
Assert.Equal("Früh", result[0].Title);
|
||||
Assert.Equal("Spät", result[1].Title);
|
||||
}
|
||||
|
||||
// ── SubjectRepository ─────────────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -132,6 +132,7 @@ public class GroupMembershipRepository(LiteDbContext db) : IGroupMembershipRepos
|
||||
public class ExamRepository(LiteDbContext db) : IExamRepository
|
||||
{
|
||||
public Exam? GetById(Guid id) => db.Exams.FindById(id);
|
||||
public List<Exam> GetAll() => db.Exams.FindAll().OrderBy(e => e.Date).ToList();
|
||||
public List<Exam> GetByGroup(Guid groupId) =>
|
||||
db.Exams.Find(e => e.GroupId == groupId).OrderByDescending(e => e.Date).ToList();
|
||||
public void Save(Exam e) { e.UpdatedAt = DateTime.UtcNow; db.Exams.Upsert(e); }
|
||||
|
||||
@@ -76,6 +76,7 @@ public class FakeGrades : IGradeRepository
|
||||
public class FakeExams(List<Exam> all) : IExamRepository
|
||||
{
|
||||
public Exam? GetById(Guid id) => all.FirstOrDefault(e => e.Id == id);
|
||||
public List<Exam> GetAll() => all;
|
||||
public List<Exam> GetByGroup(Guid groupId) => all.Where(e => e.GroupId == groupId).ToList();
|
||||
public void Save(Exam exam) { }
|
||||
public void Delete(Guid id) { }
|
||||
|
||||
@@ -148,13 +148,15 @@ public sealed class TimetableViewModelTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ShowEditor_SchaltetAufBearbeiten_Tab()
|
||||
public void OpenSettings_RuftOnNavigateToSettingsAuf()
|
||||
{
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([]));
|
||||
var called = false;
|
||||
vm.OnNavigateToSettings = () => called = true;
|
||||
|
||||
vm.ShowEditorCommand.Execute(null);
|
||||
vm.OpenSettingsCommand.Execute(null);
|
||||
|
||||
Assert.Equal(1, vm.ActiveTabIndex);
|
||||
Assert.True(called);
|
||||
}
|
||||
|
||||
// ── "Heute"-Ansicht: Wochenraster (Nutzer-Feedback, zweite Iteration) ────────────────────
|
||||
@@ -742,4 +744,68 @@ public sealed class TimetableViewModelTests
|
||||
var item = Assert.Single(vm.TodayItems);
|
||||
Assert.False(item.HasLessonTopic);
|
||||
}
|
||||
|
||||
// ── Anstehende Klausurtermine (4.4.3) ────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void Load_ZeigtKlausurInnerhalbDesVorausblicks()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
||||
var exams = new FakeExams([new Exam { GroupId = group.Id, Date = today.AddDays(10), Title = "Klausur Nr. 2" }]);
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([group]), exams: exams);
|
||||
|
||||
var item = Assert.Single(vm.UpcomingExams);
|
||||
Assert.Equal("Q1 Chemie", item.GroupName);
|
||||
Assert.Equal("Klausur Nr. 2", item.Title);
|
||||
Assert.Equal(today.AddDays(10), item.Date);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_KlausurAusserhalbDesVorausblicks_WirdNichtGezeigt()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
||||
var exams = new FakeExams([new Exam { GroupId = group.Id, Date = today.AddDays(30), Title = "Klausur Nr. 3" }]);
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([group]), exams: exams);
|
||||
|
||||
Assert.Empty(vm.UpcomingExams);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_VergangeneKlausur_WirdNichtGezeigt()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
||||
var exams = new FakeExams([new Exam { GroupId = group.Id, Date = today.AddDays(-1), Title = "Alte Klausur" }]);
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([group]), exams: exams);
|
||||
|
||||
Assert.Empty(vm.UpcomingExams);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_MehrereKlausuren_SindNachDatumSortiert()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
||||
var exams = new FakeExams(
|
||||
[
|
||||
new Exam { GroupId = group.Id, Date = today.AddDays(15), Title = "Später" },
|
||||
new Exam { GroupId = group.Id, Date = today.AddDays(3), Title = "Früher" },
|
||||
]);
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([group]), exams: exams);
|
||||
|
||||
Assert.Equal(["Früher", "Später"], vm.UpcomingExams.Select(e => e.Title));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Load_HeutigeKlausur_IstImVorausblickEnthalten()
|
||||
{
|
||||
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
||||
var exams = new FakeExams([new Exam { GroupId = group.Id, Date = today, Title = "Heute" }]);
|
||||
var vm = BuildViewModel(new FakeTimetableSlots(), new FakeGroups([group]), exams: exams);
|
||||
|
||||
Assert.Single(vm.UpcomingExams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,8 +105,9 @@ public class App : Application
|
||||
sl.OnNavigateToDetail = id => main.NavigateToStudent(id);
|
||||
sl.OnAddStudent = () => ShowAddStudentDialog();
|
||||
|
||||
// Stundenplan "Heute" → GroupDetail (Tab "Planung")
|
||||
// Stundenplan "Heute" → GroupDetail (Tab "Planung") / Einstellungen (Zahnrad, Tab "Ferien & Feiertage")
|
||||
var timetable = Services.GetRequiredService<TimetableViewModel>();
|
||||
timetable.OnNavigateToSettings = () => main.NavigateToSettings(7);
|
||||
timetable.OnNavigateToGroup = id => main.NavigateToGroupDetail(id, 5);
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,14 @@ public partial class MainWindowViewModel : ObservableObject
|
||||
vm.LoadGroup(groupId); // dann Daten laden
|
||||
}
|
||||
|
||||
public void NavigateToSettings(int initialTab = 0)
|
||||
{
|
||||
ActiveNavItem = NavItem.Settings;
|
||||
var vm = _services.GetRequiredService<SettingsViewModel>();
|
||||
vm.ActiveTabIndex = initialTab;
|
||||
CurrentPage = vm;
|
||||
}
|
||||
|
||||
public void NavigateToStudent(Guid studentId)
|
||||
{
|
||||
ActiveNavItem = NavItem.Students;
|
||||
|
||||
@@ -67,6 +67,7 @@ public partial class TimetableViewModel : ObservableObject
|
||||
public ObservableCollection<TodayLessonItem> TodayItems { get; } = [];
|
||||
public ObservableCollection<TodaySupervisionItem> TodaySupervisions { get; } = [];
|
||||
public ObservableCollection<TodaySpecialAssignmentItem> TodaySpecialAssignments { get; } = [];
|
||||
public ObservableCollection<UpcomingExamItem> UpcomingExams { get; } = [];
|
||||
|
||||
[ObservableProperty] private int _activeTabIndex;
|
||||
[ObservableProperty] private string _todayLabel = "";
|
||||
@@ -77,6 +78,7 @@ public partial class TimetableViewModel : ObservableObject
|
||||
public Func<TimetableCellItem, Task>? OnEditSlot { get; set; }
|
||||
public Action<Guid>? OnNavigateToGroup { get; set; }
|
||||
public Func<Task>? OnAddSubstitution { get; set; }
|
||||
public Action? OnNavigateToSettings { get; set; }
|
||||
|
||||
public TimetableViewModel(ITimetableSlotRepository slots, IGroupRepository groups,
|
||||
ISubjectRepository subjects, ILessonRepository lessons, IExamRepository exams,
|
||||
@@ -127,6 +129,31 @@ public partial class TimetableViewModel : ObservableObject
|
||||
BuildWeekOverview(today, publicHolidayDates, duties);
|
||||
BuildToday(today);
|
||||
BuildHoursWarnings();
|
||||
BuildUpcomingExams(today);
|
||||
}
|
||||
|
||||
// ── Anstehende Klausurtermine (4.4.3) ────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Mehrtägiger Vorausblick über alle Gruppen hinweg (nicht nur "heute", wie die Tagesliste,
|
||||
/// und unabhängig von <see cref="WeekOffset"/>, anders als das Wochenraster) — Abgabefristen
|
||||
/// sind bewusst nicht enthalten, dafür gibt es noch kein eigenes Datenmodell (siehe TODO.md).
|
||||
/// </summary>
|
||||
private const int UpcomingExamsHorizonDays = 21;
|
||||
|
||||
private void BuildUpcomingExams(DateOnly today)
|
||||
{
|
||||
UpcomingExams.Clear();
|
||||
var groupNames = _groups.GetAll(includeInactive: true).ToDictionary(g => g.Id, g => g.Name);
|
||||
var horizon = today.AddDays(UpcomingExamsHorizonDays);
|
||||
|
||||
var upcoming = _exams.GetAll()
|
||||
.Where(e => e.Date >= today && e.Date <= horizon)
|
||||
.OrderBy(e => e.Date)
|
||||
.Take(10);
|
||||
|
||||
foreach (var exam in upcoming)
|
||||
UpcomingExams.Add(new UpcomingExamItem(exam.Date, groupNames.GetValueOrDefault(exam.GroupId, "?"), exam.Title));
|
||||
}
|
||||
|
||||
// ── "Heute": Tagesliste ──────────────────────────────────────────────────
|
||||
@@ -207,7 +234,7 @@ public partial class TimetableViewModel : ObservableObject
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void ShowEditor() => ActiveTabIndex = 1;
|
||||
private void OpenSettings() => OnNavigateToSettings?.Invoke();
|
||||
|
||||
// ── "Heute": Wochenraster (Nutzer-Feedback) — wie das Bearbeiten-Raster, aber nur Anzeige ──
|
||||
|
||||
@@ -649,6 +676,14 @@ public class HoursWarningItem(string groupName, int assigned, int expected)
|
||||
public string Text { get; } = $"{groupName}: {assigned} von {expected} Wochenstunden eingetragen";
|
||||
}
|
||||
|
||||
public class UpcomingExamItem(DateOnly date, string groupName, string title)
|
||||
{
|
||||
public DateOnly Date { get; } = date;
|
||||
public string DateDisplay { get; } = date.ToString("dd.MM.yyyy");
|
||||
public string GroupName { get; } = groupName;
|
||||
public string Title { get; } = title;
|
||||
}
|
||||
|
||||
public class TodayLessonItem
|
||||
{
|
||||
public Guid GroupId { get; private init; }
|
||||
|
||||
@@ -30,6 +30,8 @@ public partial class SettingsViewModel : ObservableObject
|
||||
private readonly IStudentRepository _students;
|
||||
private readonly IShorthandCodeRepository _shorthandCodes;
|
||||
|
||||
[ObservableProperty] private int _activeTabIndex;
|
||||
|
||||
// ── Fächer ────────────────────────────────────────────────────────────────
|
||||
|
||||
[ObservableProperty] private string _newName = "";
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
xmlns:models="clr-namespace:LehrerApp.Core.Models;assembly=LehrerApp.Core"
|
||||
x:Class="LehrerApp.Desktop.Views.Planning.SubstitutionEntryDialog"
|
||||
x:DataType="vm:SubstitutionEntryDialogViewModel"
|
||||
Title="Vertretung eintragen"
|
||||
Title="Ausnahme eintragen"
|
||||
Width="440" Height="560" MinWidth="400" MinHeight="480"
|
||||
CanResize="True" WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Grid RowDefinitions="*,Auto" Margin="24">
|
||||
<ScrollViewer Grid.Row="0">
|
||||
<StackPanel Spacing="14" Margin="0,0,12,0">
|
||||
<TextBlock Text="Vertretung eintragen" Classes="dialogtitle"/>
|
||||
<TextBlock Text="Ausnahme eintragen" Classes="dialogtitle"/>
|
||||
<TextBlock FontSize="12" Opacity="0.6" TextWrapping="Wrap"
|
||||
Text="Für einmalige Ausnahmen — Vertretungsaufsicht, Vertretungsstunde, Sondereinsatz (Ausflug, Berufsmesse, ...) oder schlichter Ausfall an einem konkreten Tag. Wiederkehrende Aufsicht wird in den Einstellungen gepflegt."/>
|
||||
|
||||
|
||||
@@ -127,9 +127,10 @@
|
||||
</TextBlock>
|
||||
<Button Grid.Column="3" Content="Diese Woche" Margin="0,0,8,0"
|
||||
Command="{Binding CurrentWeekCommand}" IsVisible="{Binding !IsCurrentWeek}"/>
|
||||
<Button Grid.Column="4" Content="Vertretung eintragen" Margin="0,0,8,0"
|
||||
<Button Grid.Column="4" Content="Ausnahme eintragen" Margin="0,0,8,0"
|
||||
Command="{Binding AddSubstitutionCommand}"/>
|
||||
<Button Grid.Column="5" Content="Stundenplan bearbeiten" Command="{Binding ShowEditorCommand}"/>
|
||||
<Button Grid.Column="5" Content="⚙️" Command="{Binding OpenSettingsCommand}"
|
||||
ToolTip.Tip="Einstellungen (Ferien, Aufsichten, Stundenraster)"/>
|
||||
</Grid>
|
||||
|
||||
<ItemsControl ItemsSource="{Binding WeekItems}">
|
||||
@@ -208,6 +209,25 @@
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
|
||||
CornerRadius="8" Padding="16" IsVisible="{Binding UpcomingExams.Count}">
|
||||
<StackPanel Spacing="8">
|
||||
<TextBlock Text="ANSTEHENDE KLAUSUREN" FontSize="11" FontWeight="Bold" Opacity="0.5"/>
|
||||
<ItemsControl ItemsSource="{Binding UpcomingExams}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:UpcomingExamItem">
|
||||
<Grid ColumnDefinitions="90,*" Margin="0,3">
|
||||
<TextBlock Grid.Column="0" Text="{Binding DateDisplay}" FontSize="12" Opacity="0.6"/>
|
||||
<TextBlock Grid.Column="1" FontSize="12">
|
||||
<Run Text="{Binding GroupName}"/><Run Text=" — "/><Run Text="{Binding Title}"/>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</DockPanel>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<shared:PageHeader Grid.Row="0" Title="Einstellungen" Margin="32,28,32,0"/>
|
||||
|
||||
<TabbedPage Grid.Row="1" TabPlacement="Top">
|
||||
<TabbedPage Grid.Row="1" TabPlacement="Top" SelectedIndex="{Binding ActiveTabIndex}">
|
||||
|
||||
<!-- Tab: Fächer -->
|
||||
<ContentPage Header="Fächer">
|
||||
|
||||
@@ -572,6 +572,20 @@ NAT-Unterricht der 6a aus, weil die 6a selbst auf Klassenfahrt ist. Kein Vertret
|
||||
die betroffene Stunde (Grau `#757575`, Aufschrift "Ausfall") — dieselbe Überschreiben-Logik wie
|
||||
bei Vertretungsstunden und Sondereinsätzen, nur dass hier nichts an die Stelle tritt.
|
||||
|
||||
**Nachtrag zu 4.3, achte Iteration (Button-Umbenennung + Zahnrad statt "bearbeiten"):**
|
||||
Nutzer-Feedback: Der Button "Vertretung eintragen" deckt nach der fünften bis siebten Iteration
|
||||
auch Sondereinsatz und Ausfall ab, der Name passt nicht mehr. Der Button "Stundenplan bearbeiten"
|
||||
war zudem redundant (das Bearbeiten-Tab ist direkt anklickbar) und fühlte sich unzuverlässig an.
|
||||
- "Vertretung eintragen" → "Ausnahme eintragen" (Button und Dialogtitel in
|
||||
`SubstitutionEntryDialog.axaml`) als neutraler Oberbegriff für alle vier `SubstitutionKind`-Fälle.
|
||||
- "Stundenplan bearbeiten" ersetzt durch einen kleinen Zahnrad-Button ("⚙️"), der in die
|
||||
Einstellungen springt, direkt auf den Tab "Ferien & Feiertage" (Nachbar-Tabs "Stundenraster" und
|
||||
"Aufsichten" sind von dort ein Klick entfernt) — dieselbe Navigate-mit-Zieltab-Konvention wie
|
||||
`NavigateToGroupDetail`. Dafür `SettingsViewModel.ActiveTabIndex` (an `TabbedPage.SelectedIndex`
|
||||
gebunden) sowie `MainWindowViewModel.NavigateToSettings(int initialTab = 0)` neu eingeführt.
|
||||
- `TimetableViewModel.ShowEditorCommand` entfernt (kein Aufrufer mehr) statt umbenannt — es tat
|
||||
ohnehin nur `ActiveTabIndex = 1`, was jetzt nirgends mehr gebraucht wird.
|
||||
|
||||
### 4.4 Wochen-/Tagesansicht
|
||||
- [x] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag — siehe Nachtrag zu 4.3
|
||||
("Heute"-Tab: Tagesliste unten angedockt, gruppenübergreifendes Wochenraster darüber, inkl.
|
||||
@@ -581,8 +595,13 @@ NAT-Unterricht der 6a aus, weil die 6a selbst auf Klassenfahrt ist. Kein Vertret
|
||||
- [x] **4.4.2** Sprung von einer Stunde direkt in die Lerngruppe — siehe Nachtrag zu 4.3
|
||||
("Heute"-Tab, Klick navigiert zur Planung der Gruppe statt direkt in die
|
||||
Mitarbeitserfassung, da das für den Vorbereitungs-Kontext des Tages passender ist).
|
||||
- [ ] **4.4.3** Anzeige anstehender Klausurtermine und Abgabefristen im Kalender. *(Heutige
|
||||
Klausuren bereits im "Heute"-Tab sichtbar — mehrtägiger Vorausblick fehlt noch.)*
|
||||
- [x] **4.4.3** Anzeige anstehender Klausurtermine im Kalender — neue Box "ANSTEHENDE KLAUSUREN"
|
||||
im "Heute"-Tab, gruppenübergreifend, nächste 21 Tage (max. 10 Einträge), unabhängig vom
|
||||
`WeekOffset` des Wochenrasters. `IExamRepository` brauchte dafür ein `GetAll()` (bisher nur
|
||||
`GetByGroup`). **Abgabefristen bewusst nicht enthalten:** es gibt im Datenmodell noch kein
|
||||
Frist-/Deadline-Konzept (nur `Exam.Date`) — das bräuchte ein neues Modell, siehe auch 9.8
|
||||
("ggf. einem neuen Termine-Modell"). Kein Aufschub aus Unklarheit, sondern weil das über den
|
||||
angefragten Umfang hinausginge.
|
||||
|
||||
### 4.5 Vernetzung Stundenplan ↔ Unterrichtsplanung (zurückgestellt)
|
||||
|
||||
@@ -1156,13 +1175,13 @@ Die Abschnitte sind thematisch, nicht chronologisch nummeriert. Sinnvolle Bearbe
|
||||
erledigt (13.1–13.4 vollständig; 13.4.2 bewusst zurückgestellt, siehe dort).
|
||||
5. ~~**Kapitel 5** (Schülerdokumentation)~~ — erledigt (5.2 als Auswertung des bestehenden
|
||||
Anwesenheits-Trackings statt zweiter Erfassung, siehe dort).
|
||||
6. ~~**Kapitel 4.1 + 4.2 + 4.3** (Unterrichtsplanung: Einheiten, Einzelstunden, Stundenplan)~~ —
|
||||
erledigt, inkl. mehrerer Nachtrag-Iterationen aus Nutzer-Feedback (Ferien-Pflege in den
|
||||
Einstellungen, Wochenraster mit Wochennavigation, Ferientage ausgegraut). ~~**Kapitel 4.4.1/
|
||||
4.4.2**~~ — erledigt (im Zuge der 4.3-Nachträge miterledigt). ~~**4.2.5**~~ (Serienerzeugung
|
||||
von Stunden aus dem Stundenplan) — erledigt. Offen bleiben **4.4.3** (Abgabefristen im
|
||||
Kalender) und **4.5** (engere Vernetzung Stundenplan ↔ Lesson-Planung — ausdrücklich vom
|
||||
Nutzer zurückgestellt, nicht aus Unklarheit; Desktop bekommt dort perspektivisch Graph/
|
||||
Kompetenz-Verknüpfung/KI-Planung, ein möglicher Companion-Client bleibt bewusst minimal).
|
||||
**→ nächster sinnvoller Schritt: 4.4.3, sonst weiter mit Kapitel 6/10/11.**
|
||||
6. ~~**Kapitel 4.1 + 4.2 + 4.3 + 4.4** (Unterrichtsplanung: Einheiten, Einzelstunden, Stundenplan,
|
||||
Wochen-/Tagesansicht)~~ — vollständig erledigt, inkl. mehrerer Nachtrag-Iterationen aus
|
||||
Nutzer-Feedback (Ferien-Pflege in den Einstellungen, Wochenraster mit Wochennavigation,
|
||||
Ferientage ausgegraut, Serienerzeugung, Stundenraster mit Zeitbedarf-Rückmeldung, Aufsichten,
|
||||
Vertretung/Sondereinsatz/Ausfall, anstehende Klausuren). Offen bleibt nur **4.5** (engere
|
||||
Vernetzung Stundenplan ↔ Lesson-Planung — ausdrücklich vom Nutzer zurückgestellt, nicht aus
|
||||
Unklarheit; Desktop bekommt dort perspektivisch Graph/Kompetenz-Verknüpfung/KI-Planung, ein
|
||||
möglicher Companion-Client bleibt bewusst minimal).
|
||||
**→ nächster sinnvoller Schritt: Kapitel 6, 10 oder 11.**
|
||||
7. **Kapitel 6** (Arbeitszeit), **11** (Export), **10** (Sync) — danach.
|
||||
|
||||
Reference in New Issue
Block a user