Merge branch 'develop' into develop-connectedDoubleLessons
This commit is contained in:
@ -53,7 +53,7 @@ class _AppointmentComponentState extends State<AppointmentComponent> {
|
||||
FittedBox(
|
||||
fit: BoxFit.fitWidth,
|
||||
child: Text(
|
||||
(meeting.location == null || meeting.location!.isEmpty ? " " : meeting.location!),
|
||||
(meeting.location == null || meeting.location!.isEmpty ? ' ' : meeting.location!),
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
|
@ -5,6 +5,7 @@ import 'package:bottom_sheet/bottom_sheet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rrule/rrule.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
@ -26,9 +27,9 @@ import 'customTimetableEventEditDialog.dart';
|
||||
|
||||
class AppointmentDetails {
|
||||
static String _getEventPrefix(String? code) {
|
||||
if(code == "cancelled") return "Entfällt: ";
|
||||
if(code == "irregular") return "Änderung: ";
|
||||
return code ?? "";
|
||||
if(code == 'cancelled') return 'Entfällt: ';
|
||||
if(code == 'irregular') return 'Änderung: ';
|
||||
return code ?? '';
|
||||
}
|
||||
|
||||
static void show(BuildContext context, TimetableProps webuntisData, Appointment appointment) {
|
||||
@ -64,13 +65,13 @@ class AppointmentDetails {
|
||||
try {
|
||||
subject = webuntisData.getSubjectsResponse.result.firstWhere((subject) => subject.id == timetableData.su[0].id);
|
||||
} catch(e) {
|
||||
subject = GetSubjectsResponseObject(0, "?", "Unbekannt", "?", true);
|
||||
subject = GetSubjectsResponseObject(0, '?', 'Unbekannt', '?', true);
|
||||
}
|
||||
|
||||
try {
|
||||
room = webuntisData.getRoomsResponse.result.firstWhere((room) => room.id == timetableData.ro[0].id);
|
||||
} catch(e) {
|
||||
room = GetRoomsResponseObject(0, "?", "Unbekannt", true, "?");
|
||||
room = GetRoomsResponseObject(0, '?', 'Unbekannt', true, '?');
|
||||
}
|
||||
|
||||
_bottomSheet(
|
||||
@ -98,11 +99,11 @@ class AppointmentDetails {
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.room),
|
||||
title: Text("Raum: ${room.name} (${room.longName})"),
|
||||
title: Text('Raum: ${room.name} (${room.longName})'),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.house_outlined),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const Roomplan()));
|
||||
pushScreen(context, withNavBar: false, screen: const Roomplan());
|
||||
},
|
||||
),
|
||||
),
|
||||
@ -110,7 +111,7 @@ class AppointmentDetails {
|
||||
leading: const Icon(Icons.person),
|
||||
title: timetableData.te.isNotEmpty
|
||||
? Text("Lehrkraft: ${timetableData.te[0].name} ${timetableData.te[0].longname.isNotEmpty ? "(${timetableData.te[0].longname})" : ""}")
|
||||
: const Text("?"),
|
||||
: const Text('?'),
|
||||
trailing: Visibility(
|
||||
visible: !kReleaseMode,
|
||||
child: IconButton(
|
||||
@ -123,7 +124,7 @@ class AppointmentDetails {
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.abc),
|
||||
title: Text("Typ: ${timetableData.activityType}"),
|
||||
title: Text('Typ: ${timetableData.activityType}'),
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.people),
|
||||
@ -139,9 +140,9 @@ class AppointmentDetails {
|
||||
static Completer deleteCustomEvent(BuildContext context, CustomTimetableEvent appointment) {
|
||||
Completer future = Completer();
|
||||
ConfirmDialog(
|
||||
title: "Termin löschen",
|
||||
title: 'Termin löschen',
|
||||
content: "Der ${appointment.rrule.isEmpty ? "Termin" : "Serientermin"} wird unwiederruflich gelöscht.",
|
||||
confirmButton: "Löschen",
|
||||
confirmButton: 'Löschen',
|
||||
onConfirm: () {
|
||||
RemoveCustomTimetableEvent(
|
||||
RemoveCustomTimetableEventParams(
|
||||
@ -185,14 +186,14 @@ class AppointmentDetails {
|
||||
builder: (context) => CustomTimetableEventEditDialog(existingEvent: appointment),
|
||||
);
|
||||
},
|
||||
label: const Text("Bearbeiten"),
|
||||
label: const Text('Bearbeiten'),
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: () {
|
||||
deleteCustomEvent(context, appointment).future.then((value) => Navigator.of(context).pop());
|
||||
},
|
||||
label: const Text("Löschen"),
|
||||
label: const Text('Löschen'),
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
),
|
||||
],
|
||||
@ -201,7 +202,7 @@ class AppointmentDetails {
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.info_outline),
|
||||
title: Text(appointment.description.isEmpty ? "Keine Beschreibung" : appointment.description),
|
||||
title: Text(appointment.description.isEmpty ? 'Keine Beschreibung' : appointment.description),
|
||||
),
|
||||
ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.repeat_outlined)),
|
||||
@ -209,10 +210,10 @@ class AppointmentDetails {
|
||||
subtitle: FutureBuilder(
|
||||
future: RruleL10nEn.create(),
|
||||
builder: (context, snapshot) {
|
||||
if(appointment.rrule.isEmpty) return const Text("Keine weiteren vorkomnisse");
|
||||
if(snapshot.data == null) return const Text("...");
|
||||
if(appointment.rrule.isEmpty) return const Text('Keine weiteren vorkomnisse');
|
||||
if(snapshot.data == null) return const Text('...');
|
||||
RecurrenceRule rrule = RecurrenceRule.fromString(appointment.rrule);
|
||||
if(!rrule.canFullyConvertToText) return const Text("Keine genauere Angabe möglich.");
|
||||
if(!rrule.canFullyConvertToText) return const Text('Keine genauere Angabe möglich.');
|
||||
return Text(rrule.toText(l10n: snapshot.data!));
|
||||
},
|
||||
)
|
||||
@ -220,8 +221,8 @@ class AppointmentDetails {
|
||||
DebugTile(context).child(
|
||||
ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.rule)),
|
||||
title: const Text("RRule"),
|
||||
subtitle: Text(appointment.rrule.isEmpty ? "Keine" : appointment.rrule),
|
||||
title: const Text('RRule'),
|
||||
subtitle: Text(appointment.rrule.isEmpty ? 'Keine' : appointment.rrule),
|
||||
)
|
||||
),
|
||||
DebugTile(context).jsonData(appointment.toJson()),
|
||||
|
42
lib/view/pages/timetable/customTimetableColors.dart
Normal file
42
lib/view/pages/timetable/customTimetableColors.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../theming/darkAppTheme.dart';
|
||||
|
||||
enum CustomTimetableColors {
|
||||
orange,
|
||||
red,
|
||||
green,
|
||||
blue
|
||||
}
|
||||
|
||||
class TimetableColors {
|
||||
static const CustomTimetableColors defaultColor = CustomTimetableColors.orange;
|
||||
|
||||
static ColorModeDisplay getDisplayOptions(CustomTimetableColors color) {
|
||||
switch(color) {
|
||||
case CustomTimetableColors.green:
|
||||
return ColorModeDisplay(color: Colors.green, displayName: 'Grün');
|
||||
|
||||
case CustomTimetableColors.blue:
|
||||
return ColorModeDisplay(color: Colors.blue, displayName: 'Blau');
|
||||
|
||||
case CustomTimetableColors.orange:
|
||||
return ColorModeDisplay(color: Colors.orange.shade800, displayName: 'Orange');
|
||||
|
||||
case CustomTimetableColors.red:
|
||||
return ColorModeDisplay(color: DarkAppTheme.marianumRed, displayName: 'Rot');
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static Color getColorFromString(String color) {
|
||||
return getDisplayOptions(CustomTimetableColors.values.firstWhere((element) => element.name == color, orElse: () => TimetableColors.defaultColor)).color;
|
||||
}
|
||||
}
|
||||
|
||||
class ColorModeDisplay {
|
||||
final Color color;
|
||||
final String displayName;
|
||||
|
||||
ColorModeDisplay({required this.color, required this.displayName});
|
||||
}
|
@ -3,7 +3,7 @@ import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:jiffy/jiffy.dart';
|
||||
import 'package:marianum_mobile/extensions/dateTime.dart';
|
||||
import '../../../extensions/dateTime.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:rrule_generator/rrule_generator.dart';
|
||||
import 'package:time_range_picker/time_range_picker.dart';
|
||||
@ -16,6 +16,7 @@ import '../../../api/mhsl/customTimetableEvent/update/updateCustomTimetableEvent
|
||||
import '../../../model/accountData.dart';
|
||||
import '../../../model/timetable/timetableProps.dart';
|
||||
import '../../../widget/infoDialog.dart';
|
||||
import 'customTimetableColors.dart';
|
||||
|
||||
class CustomTimetableEventEditDialog extends StatefulWidget {
|
||||
final CustomTimetableEvent? existingEvent;
|
||||
@ -31,7 +32,11 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
late TimeOfDay _endTime = widget.existingEvent?.endDate.toTimeOfDay() ?? const TimeOfDay(hour: 09, minute: 30);
|
||||
late final TextEditingController _eventName = TextEditingController(text: widget.existingEvent?.title);
|
||||
late final TextEditingController _eventDescription = TextEditingController(text: widget.existingEvent?.description);
|
||||
late String _recurringRule = widget.existingEvent?.rrule ?? "";
|
||||
late String _recurringRule = widget.existingEvent?.rrule ?? '';
|
||||
late CustomTimetableColors _customTimetableColor = CustomTimetableColors.values.firstWhere(
|
||||
(element) => element.name == widget.existingEvent?.color,
|
||||
orElse: () => TimetableColors.defaultColor
|
||||
);
|
||||
|
||||
late bool isEditingExisting = widget.existingEvent != null;
|
||||
|
||||
@ -59,7 +64,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
controller: _eventName,
|
||||
autofocus: true,
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Terminname",
|
||||
labelText: 'Terminname',
|
||||
border: OutlineInputBorder()
|
||||
),
|
||||
),
|
||||
@ -70,15 +75,16 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
maxLines: 2,
|
||||
minLines: 2,
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Beschreibung",
|
||||
labelText: 'Beschreibung',
|
||||
border: OutlineInputBorder()
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.date_range_outlined),
|
||||
title: Text(Jiffy.parseFromDateTime(_date).yMMMd),
|
||||
subtitle: const Text("Datum"),
|
||||
subtitle: const Text('Datum'),
|
||||
onTap: () async {
|
||||
final DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
@ -94,8 +100,9 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: Text("${_startTime.format(context).toString()} - ${_endTime.format(context).toString()}"),
|
||||
subtitle: const Text("Zeitraum"),
|
||||
leading: const Icon(Icons.access_time_outlined),
|
||||
title: Text('${_startTime.format(context).toString()} - ${_endTime.format(context).toString()}'),
|
||||
subtitle: const Text('Zeitraum'),
|
||||
onTap: () async {
|
||||
TimeRange timeRange = await showTimeRangePicker(
|
||||
context: context,
|
||||
@ -105,8 +112,8 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
disabledColor: Colors.grey,
|
||||
paintingStyle: PaintingStyle.fill,
|
||||
interval: const Duration(minutes: 5),
|
||||
fromText: "Beginnend",
|
||||
toText: "Endend",
|
||||
fromText: 'Beginnend',
|
||||
toText: 'Endend',
|
||||
strokeColor: Theme.of(context).colorScheme.secondary,
|
||||
minDuration: const Duration(minutes: 15),
|
||||
selectedColor: Theme.of(context).primaryColor,
|
||||
@ -120,6 +127,31 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
},
|
||||
),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.color_lens_outlined),
|
||||
title: const Text('Farbgebung'),
|
||||
trailing: DropdownButton<CustomTimetableColors>(
|
||||
value: _customTimetableColor,
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
items: CustomTimetableColors.values.map((e) => DropdownMenuItem<CustomTimetableColors>(
|
||||
value: e,
|
||||
enabled: e != _customTimetableColor,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.circle, color: TimetableColors.getDisplayOptions(e).color),
|
||||
const SizedBox(width: 10),
|
||||
Text(TimetableColors.getDisplayOptions(e).displayName),
|
||||
],
|
||||
),
|
||||
)).toList(),
|
||||
onChanged: (e) {
|
||||
setState(() {
|
||||
_customTimetableColor = e!;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
RRuleGenerator(
|
||||
config: RRuleGeneratorConfig(
|
||||
headerEnabled: true,
|
||||
@ -130,7 +162,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
initialRRule: _recurringRule,
|
||||
textDelegate: const GermanRRuleTextDelegate(),
|
||||
onChange: (String newValue) {
|
||||
log("Rule: $newValue");
|
||||
log('Rule: $newValue');
|
||||
setState(() {
|
||||
_recurringRule = newValue;
|
||||
});
|
||||
@ -151,11 +183,12 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
if(!validate()) return;
|
||||
|
||||
CustomTimetableEvent editedEvent = CustomTimetableEvent(
|
||||
id: "",
|
||||
id: '',
|
||||
title: _eventName.text,
|
||||
description: _eventDescription.text,
|
||||
startDate: _date.withTime(_startTime),
|
||||
endDate: _date.withTime(_endTime),
|
||||
color: _customTimetableColor.name,
|
||||
rrule: _recurringRule,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
@ -177,7 +210,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
} else {
|
||||
UpdateCustomTimetableEvent(
|
||||
UpdateCustomTimetableEventParams(
|
||||
widget.existingEvent?.id ?? "",
|
||||
widget.existingEvent?.id ?? '',
|
||||
editedEvent
|
||||
)
|
||||
).run().then((value) {
|
||||
@ -191,7 +224,7 @@ class _AddCustomTimetableEventDialogState extends State<CustomTimetableEventEdit
|
||||
|
||||
|
||||
},
|
||||
child: Text(isEditingExisting ? "Speichern" : "Erstellen"),
|
||||
child: Text(isEditingExisting ? 'Speichern' : 'Erstellen'),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -33,12 +33,12 @@ class _TimeRegionComponentState extends State<TimeRegionComponent> {
|
||||
children: [
|
||||
const SizedBox(height: 15),
|
||||
const Icon(Icons.cake),
|
||||
const Text("FREI"),
|
||||
const Text('FREI'),
|
||||
const SizedBox(height: 10),
|
||||
RotatedBox(
|
||||
quarterTurns: 1,
|
||||
child: Text(
|
||||
text.split(":").last,
|
||||
text.split(':').last,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
|
@ -2,7 +2,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:marianum_mobile/extensions/dateTime.dart';
|
||||
import '../../../extensions/dateTime.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
@ -17,6 +17,7 @@ import '../../../widget/placeholderView.dart';
|
||||
import 'appointmenetComponent.dart';
|
||||
import 'appointmentDetails.dart';
|
||||
import 'arbitraryAppointment.dart';
|
||||
import 'customTimetableColors.dart';
|
||||
import 'customTimetableEventEditDialog.dart';
|
||||
import 'timeRegionComponent.dart';
|
||||
import 'timetableEvents.dart';
|
||||
@ -56,7 +57,7 @@ class _TimetableState extends State<Timetable> {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Stunden & Vertretungsplan"),
|
||||
title: const Text('Stunden & Vertretungsplan'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.home_outlined),
|
||||
@ -73,11 +74,11 @@ class _TimetableState extends State<Timetable> {
|
||||
Icon icon;
|
||||
switch(e) {
|
||||
case CalendarActions.addEvent:
|
||||
title = "Kalendereintrag hinzufügen";
|
||||
title = 'Kalendereintrag hinzufügen';
|
||||
icon = const Icon(Icons.add);
|
||||
case CalendarActions.viewEvents:
|
||||
default:
|
||||
title = "Kalendereinträge anzeigen";
|
||||
title = 'Kalendereinträge anzeigen';
|
||||
icon = const Icon(Icons.perm_contact_calendar_outlined);
|
||||
}
|
||||
return PopupMenuItem<CalendarActions>(
|
||||
@ -111,9 +112,9 @@ class _TimetableState extends State<Timetable> {
|
||||
if(value.hasError) {
|
||||
return PlaceholderView(
|
||||
icon: Icons.calendar_month,
|
||||
text: "Webuntis error: ${value.error.toString()}",
|
||||
text: 'Webuntis error: ${value.error.toString()}',
|
||||
button: TextButton(
|
||||
child: const Text("Neu laden"),
|
||||
child: const Text('Neu laden'),
|
||||
onPressed: () {
|
||||
controller.displayDate = DateTime.now().add(const Duration(days: 2));
|
||||
Provider.of<TimetableProps>(context, listen: false).resetWeek();
|
||||
@ -154,8 +155,8 @@ class _TimetableState extends State<Timetable> {
|
||||
startHour: 07.5,
|
||||
endHour: 16.5,
|
||||
timeInterval: Duration(minutes: 30),
|
||||
timeFormat: "HH:mm",
|
||||
dayFormat: "EE",
|
||||
timeFormat: 'HH:mm',
|
||||
dayFormat: 'EE',
|
||||
timeIntervalHeight: 40,
|
||||
),
|
||||
|
||||
@ -292,10 +293,10 @@ class _TimetableState extends State<Timetable> {
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
subject: subjects.result.firstWhere((subject) => subject.id == element.su[0].id).name,
|
||||
location: ""
|
||||
"${rooms.result.firstWhere((room) => room.id == element.ro[0].id).name}"
|
||||
"\n"
|
||||
"${element.te.first.longname}",
|
||||
location: ''
|
||||
'${rooms.result.firstWhere((room) => room.id == element.ro[0].id).name}'
|
||||
'\n'
|
||||
'${element.te.first.longname}',
|
||||
notes: element.activityType,
|
||||
color: _getEventColor(element, startTime, endTime),
|
||||
);
|
||||
@ -305,7 +306,7 @@ class _TimetableState extends State<Timetable> {
|
||||
id: ArbitraryAppointment(webuntis: element),
|
||||
startTime: _parseWebuntisTimestamp(element.date, element.startTime),
|
||||
endTime: endTime,
|
||||
subject: "Änderung",
|
||||
subject: 'Änderung',
|
||||
notes: element.info,
|
||||
location: 'Unbekannt',
|
||||
color: endTime.isBefore(DateTime.now()) ? Theme.of(context).primaryColor.withAlpha(100) : Theme.of(context).primaryColor,
|
||||
@ -323,7 +324,7 @@ class _TimetableState extends State<Timetable> {
|
||||
location: customEvent.description,
|
||||
subject: customEvent.title,
|
||||
recurrenceRule: customEvent.rrule,
|
||||
color: Colors.deepOrange.shade800,
|
||||
color: TimetableColors.getColorFromString(customEvent.color ?? TimetableColors.defaultColor.name),
|
||||
startTimeZone: '',
|
||||
endTimeZone: '',
|
||||
);
|
||||
@ -342,10 +343,10 @@ class _TimetableState extends State<Timetable> {
|
||||
int alpha = endTime.isBefore(DateTime.now()) ? 100 : 255;
|
||||
|
||||
// Cancelled
|
||||
if(webuntisElement.code == "cancelled") return const Color(0xff000000).withAlpha(alpha);
|
||||
if(webuntisElement.code == 'cancelled') return const Color(0xff000000).withAlpha(alpha);
|
||||
|
||||
// Any changes or no teacher at this element
|
||||
if(webuntisElement.code == "irregular" || webuntisElement.te.first.id == 0) return const Color(0xff8F19B3).withAlpha(alpha);
|
||||
if(webuntisElement.code == 'irregular' || webuntisElement.te.first.id == 0) return const Color(0xff8F19B3).withAlpha(alpha);
|
||||
|
||||
// Event was in the past
|
||||
if(endTime.isBefore(DateTime.now())) return Theme.of(context).primaryColor.withAlpha(alpha);
|
||||
@ -360,7 +361,7 @@ class _TimetableState extends State<Timetable> {
|
||||
bool _isCrossedOut(CalendarAppointmentDetails calendarEntry) {
|
||||
ArbitraryAppointment appointment = calendarEntry.appointments.first.id as ArbitraryAppointment;
|
||||
if(appointment.hasWebuntis()) {
|
||||
return appointment.webuntis!.code == "cancelled";
|
||||
return appointment.webuntis!.code == 'cancelled';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text("Eigene Termine"),
|
||||
title: const Text('Eigene Termine'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add),
|
||||
@ -77,10 +77,10 @@ class _ViewCustomTimetableEventsState extends State<ViewCustomTimetableEvents> {
|
||||
|
||||
var placeholder = PlaceholderView(
|
||||
icon: Icons.calendar_today_outlined,
|
||||
text: "Keine Einträge vorhanden",
|
||||
text: 'Keine Einträge vorhanden',
|
||||
button: TextButton(
|
||||
onPressed: _openCreateDialog,
|
||||
child: const Text("Termin erstellen"),
|
||||
child: const Text('Termin erstellen'),
|
||||
),
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user