Skip to content

Commit

Permalink
Add teachers to the timetable (#1629)
Browse files Browse the repository at this point in the history
## Description

This pull request adds the Sharezone Plus feature to add teachers to the
timetable.

## Demo


https://github.com/SharezoneApp/sharezone-app/assets/24459435/51576d4d-c5ac-42be-bee9-04084cb228a5

Changed the lesson sheet to a dialog:


![image](https://github.com/SharezoneApp/sharezone-app/assets/24459435/a856afb7-9c76-4dd7-8ae0-f4af1466f6e3)

Reason: In the sheet you need to scroll to see the substitutions tiles
and it's not easy to adjust the size of the sheet (depending on the
screen size). A dialog is here the better option.

Users can also add the teacher when adding a lesson:


![image](https://github.com/SharezoneApp/sharezone-app/assets/24459435/cdbff9b2-2d99-4371-906a-414aba708264)

Sharezone Plus page:


![image](https://github.com/SharezoneApp/sharezone-app/assets/24459435/e737e6d5-5bbb-4638-ab2b-cd6d38d882d0)

## Related Tickets

Closes #1608
Opens #1628
  • Loading branch information
nilsreichardt authored May 16, 2024
1 parent 34c9cfa commit f1ae76d
Show file tree
Hide file tree
Showing 24 changed files with 620 additions and 158 deletions.
2 changes: 1 addition & 1 deletion app/lib/dashboard/dashboard_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import 'package:sharezone/sharezone_v2/sz_v2_announcement_dialog.dart';
import 'package:sharezone/timetable/src/widgets/events/calender_event_card.dart';
import 'package:sharezone/timetable/src/widgets/events/event_view.dart';
import 'package:sharezone/timetable/timetable_add_event/timetable_add_event_dialog.dart';
import 'package:sharezone/timetable/timetable_page/lesson/timetable_lesson_sheet.dart';
import 'package:sharezone/timetable/timetable_page/lesson/timetable_lesson_details.dart';
import 'package:sharezone/timetable/timetable_page/timetable_page.dart';
import 'package:sharezone/util/cache/key_value_store.dart';
import 'package:sharezone/util/cache/streaming_key_value_store.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ enum SharezonePlusFeature {
homeworkDueDateChips,
iCalLinks,
substitutions,
addTeachersToTimetable,
}

void trySetSharezonePlusAnalyticsUserProperties(Analytics analytics,
Expand Down
10 changes: 10 additions & 0 deletions app/lib/timetable/src/bloc/timetable_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:bloc_provider/bloc_provider.dart';
import 'package:common_domain_models/common_domain_models.dart';
import 'package:date/date.dart';
import 'package:date/weektype.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:flutter/widgets.dart';
import 'package:group_domain_models/group_domain_models.dart';
import 'package:rxdart/rxdart.dart';
Expand Down Expand Up @@ -45,6 +46,9 @@ class TimetableBloc extends BlocBase {
final CourseGateway courseGateway;
final SchoolClassFilterAnalytics schoolClassFilterAnalytics;

final _currentTeachersSubject = BehaviorSubject<ISet<String>>.seeded(ISet());
ISet<String> get currentTeachers => _currentTeachersSubject.value;

TimetableBloc(
this.schoolClassGateway,
this.userGateway,
Expand Down Expand Up @@ -103,6 +107,7 @@ class TimetableBloc extends BlocBase {
List<Lesson>, List<String>, SchoolClassFilter, List<Lesson>>(
lessonsStream, coursesOfSchoolClass, _selectedSchoolOptionSubject,
(lessons, coursesOfSchoolClass, schoolClassFilter) {
_setCurrentTeachers(lessons);
if (schoolClassFilter.shouldFilterForClass) {
lessons = _getLessonsOfASchoolClass(coursesOfSchoolClass, lessons);
}
Expand Down Expand Up @@ -209,6 +214,11 @@ class TimetableBloc extends BlocBase {
return streamGroup;
}

void _setCurrentTeachers(List<Lesson> lessons) {
final teachers = lessons.map((l) => l.teacher).nonNulls;
_currentTeachersSubject.add(_currentTeachersSubject.value.addAll(teachers));
}

@override
void dispose() {
_selectedSchoolOptionSubject.close();
Expand Down
5 changes: 3 additions & 2 deletions app/lib/timetable/src/models/lesson.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Lesson {
int? periodNumber,
WeekDay? weekday,
WeekType? weektype,
String? teacher,
String? Function()? teacher,
String? place,
Map<SubstitutionId, Substitution>? substitutions,
}) {
Expand All @@ -125,7 +125,8 @@ class Lesson {
periodNumber: periodNumber ?? this.periodNumber,
weekday: weekday ?? this.weekday,
weektype: weektype ?? this.weektype,
teacher: teacher ?? this.teacher,
// A function because otherwise one can't set the teacher null
teacher: teacher != null ? teacher() : this.teacher,
place: place ?? this.place,
substitutions: substitutions ?? this.substitutions,
);
Expand Down
8 changes: 7 additions & 1 deletion app/lib/timetable/timetable_add/bloc/timetable_add_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class TimetableAddBloc extends BlocBase {
final _weekTypeSubject = BehaviorSubject<WeekType>();
final _periodSubject = BehaviorSubject<Period?>();
final _timeTypeSubject = BehaviorSubject.seeded(TimeType.period);
final _teacherSubject = BehaviorSubject<String>();

final TimetableGateway gateway;
final LessonLengthCache cache;
Expand Down Expand Up @@ -75,6 +76,7 @@ class TimetableAddBloc extends BlocBase {
Function(WeekType) get changeWeekType => _weekTypeSubject.sink.add;
Function(Period) get changePeriod => _periodSubject.sink.add;
Function(TimeType) get changeTimeType => _timeTypeSubject.sink.add;
Function(String) get changeTeacher => _teacherSubject.sink.add;

Future<Time?> _calculateEndTime(Time startTime) async {
final lessonsLength = await cache.streamLessonLength().first;
Expand Down Expand Up @@ -124,6 +126,10 @@ class TimetableAddBloc extends BlocBase {
final weekType = _weekTypeSubject.valueOrNull ?? WeekType.always;
final period = _periodSubject.valueOrNull;
final timeType = _timeTypeSubject.valueOrNull!;
String? teacher = _teacherSubject.valueOrNull;
if (teacher?.isEmpty == true) {
teacher = null;
}
log("isValid: true; ${course.toString()}; $startTime; $endTime; $room $weekDay $period");

final lesson = Lesson(
Expand All @@ -134,7 +140,7 @@ class TimetableAddBloc extends BlocBase {
groupType: GroupType.course,
startDate: null,
endDate: null,
teacher: null,
teacher: teacher,
place: room,
weekday: weekDay,
weektype: weekType,
Expand Down
41 changes: 41 additions & 0 deletions app/lib/timetable/timetable_add/tabs/room_and_teacher_tab.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2022 Sharezone UG (haftungsbeschränkt)
// Licensed under the EUPL-1.2-or-later.
//
// You may obtain a copy of the Licence at:
// https://joinup.ec.europa.eu/software/page/eupl
//
// SPDX-License-Identifier: EUPL-1.2

part of '../timetable_add_page.dart';

class _RoomAndTeachersTab extends StatelessWidget {
const _RoomAndTeachersTab({
required this.index,
});

final int index;

@override
Widget build(BuildContext context) {
final bloc = BlocProvider.of<TimetableAddBloc>(context);
return _TimetableAddSection(
index: index,
title: 'Gib einen Raum & eine Lehrkraft an (optional)',
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
children: [
RoomField(
onChanged: bloc.changeRoom,
),
const SizedBox(height: 16),
TeacherField(
teachers: BlocProvider.of<TimetableBloc>(context).currentTeachers,
onTeacherChanged: bloc.changeTeacher,
),
],
),
),
);
}
}
43 changes: 0 additions & 43 deletions app/lib/timetable/timetable_add/tabs/room_tab.dart

This file was deleted.

5 changes: 3 additions & 2 deletions app/lib/timetable/timetable_add/timetable_add_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import 'package:sharezone/timetable/src/models/lesson.dart';
import 'package:sharezone/timetable/src/models/time_type.dart';
import 'package:sharezone/timetable/timetable_add/bloc/timetable_add_bloc.dart';
import 'package:sharezone/timetable/timetable_add/bloc/timetable_add_bloc_factory.dart';
import 'package:sharezone/timetable/timetable_edit/lesson/timetable_lesson_edit_page.dart';
import 'package:sharezone/timetable/timetable_page/timetable_page.dart';
import 'package:sharezone/widgets/fade_switch_between_index_with_tab_controller.dart';
import 'package:sharezone/widgets/tabs.dart';
Expand All @@ -35,7 +36,7 @@ import 'package:time/time.dart';
import 'package:user/user.dart';

part 'tabs/course_tab.dart';
part 'tabs/room_tab.dart';
part 'tabs/room_and_teacher_tab.dart';
part 'tabs/time_tab.dart';
part 'tabs/weekday_tab.dart';
part 'tabs/weektype_tab.dart';
Expand Down Expand Up @@ -100,7 +101,7 @@ class _TimetableAddPage extends StatelessWidget {
_WeekDayTab(),
if (abWeekEnabled) _WeekTypeTab(),
_TimeTab(index: abWeekEnabled ? 4 : 3),
_RoomTab(index: abWeekEnabled ? 5 : 4),
_RoomAndTeachersTab(index: abWeekEnabled ? 5 : 4),
],
abWeekEnabled: abWeekEnabled,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import 'package:sharezone/main/application_bloc.dart';
import 'package:sharezone/markdown/markdown_analytics.dart';
import 'package:sharezone/timetable/src/edit_date.dart';
import 'package:sharezone/timetable/src/edit_time.dart';
import 'package:sharezone/timetable/timetable_page/lesson/timetable_lesson_sheet.dart';
import 'package:sharezone/timetable/timetable_page/lesson/timetable_lesson_details.dart';
import 'package:sharezone/timetable/timetable_permissions.dart';
import 'package:sharezone/util/api/connections_gateway.dart';
import 'package:sharezone/util/api/timetable_gateway.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class TimetableEditBloc extends BlocBase {
final _weekDaySubject = BehaviorSubject<WeekDay>();
final _weekTypeSubject = BehaviorSubject<WeekType>();
final _periodSubject = BehaviorSubject<Period>();
final _teacherSubject = BehaviorSubject<String>();

final Lesson initialLesson;
final TimetableGateway gateway;
Expand Down Expand Up @@ -60,6 +61,9 @@ class TimetableEditBloc extends BlocBase {
_periodSubject.sink.add(period);
}
}
if (initialLesson.teacher != null) {
_teacherSubject.sink.add(initialLesson.teacher!);
}
}

Stream<Course> get course => _courseSegmentSubject;
Expand All @@ -69,13 +73,15 @@ class TimetableEditBloc extends BlocBase {
Stream<WeekDay> get weekDay => _weekDaySubject;
Stream<WeekType> get weekType => _weekTypeSubject;
Stream<Period> get period => _periodSubject;
Stream<String> get teacher => _teacherSubject;

Function(Course) get _changeCourse => _courseSegmentSubject.sink.add;
Function(Time) get changeStartTime => _startTimeSubject.sink.add;
Function(Time) get changeEndTime => _endTimeSubject.sink.add;
Function(String) get changeRoom => _roomSubject.sink.add;
Function(WeekDay) get changeWeekDay => _weekDaySubject.sink.add;
Function(WeekType) get changeWeekType => _weekTypeSubject.sink.add;
Function(String) get changeTeacher => _teacherSubject.sink.add;

void changePeriod(Period period) {
_periodSubject.sink.add(period);
Expand Down Expand Up @@ -104,12 +110,16 @@ class TimetableEditBloc extends BlocBase {
final weekDay = _weekDaySubject.valueOrNull;
final weekType = _weekTypeSubject.valueOrNull;
final period = _periodSubject.valueOrNull;
String? teacher = _teacherSubject.valueOrNull;
if (teacher?.isEmpty == true) {
teacher = null;
}

log("isValid: true; ${course.toString()}; $startTime; $endTime; $room $weekDay");

final lesson = initialLesson.copyWith(
groupID: course?.id,
teacher: null,
teacher: () => teacher,
place: room,
weekday: weekDay,
weektype: weekType,
Expand Down
Loading

0 comments on commit f1ae76d

Please sign in to comment.