From ddf46674c438571badefc5bbc0ced5c442e4d72e Mon Sep 17 00:00:00 2001 From: Username * Date: Tue, 31 Dec 2024 01:03:01 +0100 Subject: [PATCH] subject management sheet --- assets/translations/en-US.json | 1 + assets/translations/fr-FR.json | 1 + .../subject_management/subject_screen.dart | 32 +-- .../subject_management_bottom_sheet.dart | 263 ++++++++++++++++++ .../grid_view/grid_view_subject_builder.dart | 23 +- .../grid_view_subject_container_builder.dart | 4 +- 6 files changed, 284 insertions(+), 40 deletions(-) create mode 100644 lib/components/widgets/bottom_sheets/subject_management_bottom_sheet.dart diff --git a/assets/translations/en-US.json b/assets/translations/en-US.json index 72be06a..2f17fb4 100644 --- a/assets/translations/en-US.json +++ b/assets/translations/en-US.json @@ -103,6 +103,7 @@ "ok": "OK", "create": "Create", + "add": "Add", "save": "Save", "proceed": "Proceed", "delete": "Delete", diff --git a/assets/translations/fr-FR.json b/assets/translations/fr-FR.json index bd72e52..5030516 100644 --- a/assets/translations/fr-FR.json +++ b/assets/translations/fr-FR.json @@ -103,6 +103,7 @@ "ok": "OK", "create": "Créer", + "add": "Ajouter", "save": "Sauvegarder", "proceed": "Continuer", "delete": "Supprimer", diff --git a/lib/components/subject_management/subject_screen.dart b/lib/components/subject_management/subject_screen.dart index 3601da5..876b1ae 100644 --- a/lib/components/subject_management/subject_screen.dart +++ b/lib/components/subject_management/subject_screen.dart @@ -153,34 +153,8 @@ class SubjectScreen extends HookConsumerWidget { return Scaffold( appBar: AppBar( actions: [ - if (!isSubjectNull) - ElevatedButton.icon( - style: ElevatedButton.styleFrom( - shadowColor: Colors.transparent, - backgroundColor: Theme.of(context).colorScheme.error, - foregroundColor: Theme.of(context).colorScheme.errorContainer, - iconColor: Theme.of(context).colorScheme.errorContainer, - ), - onPressed: () async { - final navigator = Navigator.of(context); - final messenger = ScaffoldMessenger.of(context); - - await subjectNotifier.deleteSubject(newSubject).then( - (_) { - navigator.pop(); - messenger.showSnackBar( - SnackBar( - content: const Text('subject_deleted_snackbar').tr(), - ), - ); - }, - ); - }, - icon: const Icon(Icons.delete_outline), - label: const Text("delete").tr(), - ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const EdgeInsets.symmetric(horizontal: 16), child: ElevatedButton.icon( style: ElevatedButton.styleFrom( shadowColor: Colors.transparent, @@ -208,12 +182,12 @@ class SubjectScreen extends HookConsumerWidget { if (isSubjectNull) { await subjectNotifier .addSubject(newSubject.toCompanion(true)) - .then((_) => navigator.pop(label.value)); + .then((_) => navigator.pop(newSubject)); } if (!isSubjectNull) { await subjectNotifier .updateSubject(newSubject) - .then((_) => navigator.pop(label.value)); + .then((_) => navigator.pop(newSubject)); } }, icon: Icon( diff --git a/lib/components/widgets/bottom_sheets/subject_management_bottom_sheet.dart b/lib/components/widgets/bottom_sheets/subject_management_bottom_sheet.dart new file mode 100644 index 0000000..11cb80d --- /dev/null +++ b/lib/components/widgets/bottom_sheets/subject_management_bottom_sheet.dart @@ -0,0 +1,263 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:timetable/components/subject_management/subject_screen.dart'; +import 'package:timetable/components/widgets/color_indicator.dart'; +import 'package:timetable/db/database.dart'; +import 'package:timetable/helpers/rotation_weeks.dart'; +import 'package:timetable/provider/overlapping_subjects.dart'; +import 'package:timetable/provider/settings.dart'; +import 'package:timetable/provider/subjects.dart'; +import 'package:timetable/provider/timetables.dart'; + +/// Bottom sheet widget to quickly see the full subject properties +class SubjectManagementBottomSheet extends ConsumerWidget { + final SubjectData subject; + + const SubjectManagementBottomSheet({ + super.key, + required this.subject, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final subjectNotifier = ref.watch(subjectProvider.notifier); + final overlappingSubjects = ref.watch(overlappingSubjectsProvider); + final timetables = ref.watch(timetableProvider); + final rotationWeeks = ref.watch(settingsProvider).rotationWeeks; + final customStartTime = ref.watch(settingsProvider).customStartTime; + + Color labelColor = + subject.color.computeLuminance() > .7 ? Colors.black : Colors.white; + Color subLabelsColor = subject.color.computeLuminance() > .7 + ? Colors.black.withValues(alpha: .6) + : Colors.white.withValues(alpha: .75); + + String label = subject.label; + String? location = subject.location; + Color color = subject.color; + String? note = subject.note; + + final bool locationCheck = location != null && location.isNotEmpty; + final bool noteCheck = note != null && note.isNotEmpty; + + final inOverlappingSubjectsCheck = () { + for (var couple in overlappingSubjects) { + if (couple.contains(subject)) return true; + } + return false; + }(); + + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(right: 10), + child: ColorIndicator(color: color), + ), + Expanded( + child: Text( + label, + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: labelColor, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.5), + ), + const Divider(), + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.5), + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10), + child: Icon( + Icons.schedule_outlined, + size: 19, + color: subLabelsColor, + ), + ), + Row( + children: [ + Text( + "${subject.startTime.hour.toString()}:00", + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: subLabelsColor, + ), + ), + Icon( + Icons.arrow_forward_rounded, + size: 20, + color: subLabelsColor, + ), + Text( + "${subject.endTime.hour.toString()}:00", + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: subLabelsColor, + ), + ), + ], + ), + ], + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.5), + ), + if (locationCheck) + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10), + child: Icon( + Icons.location_on_outlined, + size: 19, + color: subLabelsColor, + ), + ), + Expanded( + child: Text( + location.toString(), + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: subLabelsColor, + ), + ), + ), + ], + ), + if (locationCheck && noteCheck) + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.5), + ), + if (noteCheck) + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10), + child: Icon( + Icons.sticky_note_2_outlined, + size: 19, + color: subLabelsColor, + ), + ), + Expanded( + child: Text( + note.toString(), + maxLines: 4, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 17, + fontWeight: FontWeight.w500, + color: subLabelsColor, + ), + ), + ), + ], + ), + if (rotationWeeks && noteCheck) + const Padding( + padding: EdgeInsets.symmetric(vertical: 2.5), + ), + if (rotationWeeks) + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 10), + child: Icon( + Icons.screen_rotation_alt_outlined, + size: 19, + color: subLabelsColor, + ), + ), + Expanded( + child: Text( + getRotationWeekLabel(subject.rotationWeek), + style: TextStyle( + color: subLabelsColor, + fontSize: 17, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ], + ), + ), + if (!inOverlappingSubjectsCheck) + ListTile( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SubjectScreen( + rowIndex: subject.startTime.hour - customStartTime.hour, + columnIndex: subject.day.index, + currentTimetable: ValueNotifier( + timetables.firstWhere((e) => e.name == subject.timetable), + ), + ), + ), + ); + }, + leading: const Icon(Icons.add_outlined), + title: const Text("add").tr(), + ), + ListTile( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => SubjectScreen(subject: subject), + ), + ); + }, + leading: const Icon(Icons.edit_outlined), + title: const Text("edit").tr(), + ), + ListTile( + onTap: () async { + final navigator = Navigator.of(context); + final messenger = ScaffoldMessenger.of(context); + + await subjectNotifier.deleteSubject(subject).then( + (_) { + navigator.pop(); + messenger.showSnackBar( + SnackBar( + content: const Text('subject_deleted_snackbar').tr(), + ), + ); + }, + ); + }, + leading: const Icon(Icons.delete_outlined), + title: const Text("delete").tr(), + ) + ], + ); + } +} diff --git a/lib/components/widgets/views/grid_view/grid_view_subject_builder.dart b/lib/components/widgets/views/grid_view/grid_view_subject_builder.dart index 33fae41..2359f27 100644 --- a/lib/components/widgets/views/grid_view/grid_view_subject_builder.dart +++ b/lib/components/widgets/views/grid_view/grid_view_subject_builder.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:non_uniform_border/non_uniform_border.dart'; +import 'package:timetable/components/widgets/bottom_sheets/subject_management_bottom_sheet.dart'; import 'package:timetable/constants/custom_times.dart'; import 'package:timetable/helpers/rotation_weeks.dart'; import 'package:timetable/db/database.dart'; import 'package:timetable/provider/settings.dart'; -import 'package:timetable/components/subject_management/subject_screen.dart'; import 'package:timetable/constants/grid_properties.dart'; /// Subject builder for the grid view. @@ -119,13 +119,20 @@ class SubjectBuilder extends ConsumerWidget { ) { return InkWell( onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SubjectScreen( - subject: subject, - ), - ), + showModalBottomSheet( + showDragHandle: true, + enableDrag: true, + isDismissible: true, + context: context, + builder: (context) { + return Wrap( + children: [ + SubjectManagementBottomSheet( + subject: subject, + ), + ], + ); + }, ); }, borderRadius: BorderRadius.circular(5), diff --git a/lib/components/widgets/views/grid_view/grid_view_subject_container_builder.dart b/lib/components/widgets/views/grid_view/grid_view_subject_container_builder.dart index 42974eb..0fb3b94 100644 --- a/lib/components/widgets/views/grid_view/grid_view_subject_container_builder.dart +++ b/lib/components/widgets/views/grid_view/grid_view_subject_container_builder.dart @@ -44,9 +44,7 @@ class SubjectContainerBuilder extends ConsumerWidget { ); }, child: Container( - decoration: ShapeDecoration( - shape: shape, - ), + decoration: ShapeDecoration(shape: shape), child: Align( child: Container( height: 1,