Files
Client/lib/view/pages/timetable/details/webuntis_lesson_sheet.dart
T
2026-05-05 21:44:23 +02:00

110 lines
4.0 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:syncfusion_flutter_calendar/calendar.dart';
import '../../../../api/webuntis/queries/getRooms/getRoomsResponse.dart';
import '../../../../api/webuntis/queries/getSubjects/getSubjectsResponse.dart';
import '../../../../api/webuntis/queries/getTimetable/getTimetableResponse.dart';
import '../../../../routing/app_routes.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_bloc.dart';
import '../../../../state/app/modules/timetable/bloc/timetable_state.dart';
import '../../../../widget/debug/debug_tile.dart';
import '../../../../widget/unimplemented_dialog.dart';
import '_bottom_sheet.dart';
class WebuntisLessonSheet {
static void show(BuildContext context, TimetableBloc bloc, Appointment appointment, GetTimetableResponseObject lesson) {
final state = bloc.state.data;
if (state == null) return;
final subject = _resolveSubject(state, lesson);
final room = _resolveRoom(state, lesson);
showAppointmentBottomSheet(
context,
header: (_) => Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${_codePrefix(lesson.code)}${subject.alternateName}',
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 25),
overflow: TextOverflow.ellipsis,
),
Text(subject.longName),
Text(
'${Jiffy.parseFromDateTime(appointment.startTime).format(pattern: 'HH:mm')} - '
'${Jiffy.parseFromDateTime(appointment.endTime).format(pattern: 'HH:mm')}',
style: const TextStyle(fontSize: 15),
),
],
),
),
body: (_) => SliverChildListDelegate([
const Divider(),
ListTile(
leading: const Icon(Icons.notifications_active),
title: Text('Status: ${lesson.code != null ? "Geändert" : "Regulär"}'),
),
ListTile(
leading: const Icon(Icons.room),
title: Text('Raum: ${room.name} (${room.longName})'),
trailing: IconButton(
icon: const Icon(Icons.house_outlined),
onPressed: () => AppRoutes.openRoomplan(context),
),
),
ListTile(
leading: const Icon(Icons.person),
title: lesson.te.isNotEmpty
? Text(
'Lehrkraft: ${lesson.te[0].name}'
'${lesson.te[0].longname.isNotEmpty ? " (${lesson.te[0].longname})" : ""}',
)
: const Text('?'),
trailing: Visibility(
visible: !kReleaseMode,
child: IconButton(
icon: const Icon(Icons.textsms_outlined),
onPressed: () => UnimplementedDialog.show(context),
),
),
),
ListTile(
leading: const Icon(Icons.abc),
title: Text('Typ: ${lesson.activityType}'),
),
ListTile(
leading: const Icon(Icons.people),
title: Text('Klasse(n): ${lesson.kl.map((e) => e.name).join(", ")}'),
),
DebugTile(context).jsonData(lesson.toJson()),
]),
);
}
static String _codePrefix(String? code) {
if (code == 'cancelled') return 'Entfällt: ';
if (code == 'irregular') return 'Änderung: ';
return code ?? '';
}
static GetSubjectsResponseObject _resolveSubject(TimetableState state, GetTimetableResponseObject lesson) {
try {
return state.subjects!.result.firstWhere((s) => s.id == lesson.su[0].id);
} catch (_) {
return GetSubjectsResponseObject(0, '?', 'Unbekannt', '?', true);
}
}
static GetRoomsResponseObject _resolveRoom(TimetableState state, GetTimetableResponseObject lesson) {
try {
return state.rooms!.result.firstWhere((r) => r.id == lesson.ro[0].id);
} catch (_) {
return GetRoomsResponseObject(0, '?', 'Unbekannt', true, '?');
}
}
}