import 'dart:collection'; import 'package:aitrainer_app/bloc/menu/menu_bloc.dart'; import 'package:flutter/cupertino.dart'; import 'package:intl/intl.dart'; import 'package:aitrainer_app/bloc/training_log/training_log_bloc.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/model/exercise.dart'; import 'package:aitrainer_app/model/exercise_type.dart'; import 'package:aitrainer_app/model/training_result.dart'; import 'package:aitrainer_app/repository/exercise_repository.dart'; import 'package:aitrainer_app/util/app_language.dart'; import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/trans.dart'; import 'package:aitrainer_app/widgets/app_bar.dart'; import 'package:aitrainer_app/widgets/bottom_nav.dart'; import 'package:aitrainer_app/widgets/dialog_premium.dart'; import 'package:aitrainer_app/widgets/menu_search_bar.dart'; import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; import 'package:syncfusion_flutter_calendar/calendar.dart'; import 'package:syncfusion_flutter_core/theme.dart'; // ignore: must_be_immutable class MyDevelopmentLog extends StatelessWidget with Trans, Common { MyDevelopmentLog({Key? key}) : super(key: key); @override Widget build(BuildContext context) { setContext(context); return BlocProvider( create: (context) => TrainingLogBloc()..add(TrainingLogLoad()), child: BlocConsumer(listener: (context, state) { if (state is TrainingLogError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white)))); } }, builder: (context, state) { final bloc = BlocProvider.of(context); return ModalProgressHUD( child: getTrainingLog(bloc), inAsyncCall: state is TrainingLogLoading, opacity: 0.5, color: Colors.black54, progressIndicator: CircularProgressIndicator(), ); })); } Widget getTrainingLog(TrainingLogBloc bloc) { return Scaffold( appBar: AppBarNav(depth: 1), body: Container( height: double.infinity, width: double.infinity, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('asset/image/WT_plainblack_background.jpg'), fit: BoxFit.cover, alignment: Alignment.center, ), ), child: Container( padding: EdgeInsets.only(left: 10, right: 10), child: Column(children: [ getHeader(bloc), getCalendar(bloc), ]), )), bottomNavigationBar: BottomNavigator(bottomNavIndex: 1), ); } Widget getSearchBar(TrainingLogBloc bloc) { final MenuBloc menuBloc = BlocProvider.of(context); return MenuSearchBar( listItems: menuBloc.menuTreeRepository.menuAsExercise, onFind: (value) { print("Found exercise $value"); if (value != null) { bloc.add(TrainingLogSearch(exerciseTypeId: value.exerciseTypeId)); } }, ); } Widget getCalendar(TrainingLogBloc bloc) { return Expanded( child: SfCalendarTheme( data: SfCalendarThemeData(brightness: Brightness.dark, backgroundColor: Colors.transparent), child: SfCalendar( dataSource: TrainingDataSource(bloc.results), allowedViews: [ CalendarView.month, CalendarView.day, ], view: CalendarView.month, monthViewSettings: MonthViewSettings( showAgenda: true, appointmentDisplayMode: MonthAppointmentDisplayMode.appointment, showTrailingAndLeadingDates: true, ), appointmentTimeTextFormat: 'HH:mm', headerDateFormat: "y MMMM", firstDayOfWeek: 1, // Monday selectionDecoration: BoxDecoration( color: Colors.transparent, border: Border.all(color: Color(0xffb4f500), width: 2), borderRadius: const BorderRadius.all(Radius.circular(4)), shape: BoxShape.rectangle, ), todayHighlightColor: Color(0xffb4f500), showNavigationArrow: true, showDatePickerButton: false, allowViewNavigation: true, appointmentBuilder: (BuildContext context, CalendarAppointmentDetails details) { final TrainingResult result = details.appointments.first; return ClipRRect( borderRadius: BorderRadius.circular(6.0), child: Badge( elevation: 0, padding: EdgeInsets.all(0), position: BadgePosition.topEnd(top: -15, end: -17), animationDuration: Duration(milliseconds: 1500), animationType: BadgeAnimationType.fade, badgeColor: Colors.transparent, showBadge: true, badgeContent: result.isExercise ? IconButton( padding: EdgeInsets.zero, iconSize: 20, icon: Icon(Icons.delete, color: Colors.black26), onPressed: () => deleteConfirmation(bloc, result.exercise!), ) : Offstage(), child: Container( padding: EdgeInsets.only(left: 8, top: 5, right: 5, bottom: 5), width: details.bounds.width, height: details.bounds.height * 1.5, color: result.background, child: Row(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ Flexible( fit: FlexFit.tight, flex: 30, child: Text(result.eventName, style: GoogleFonts.inter( fontSize: result.isExercise ? 14 : 16, color: Colors.white, fontWeight: FontWeight.bold)), ), Visibility( visible: result.isExercise, child: Flexible( fit: FlexFit.tight, flex: 25, child: Text( result.summary == null ? "" : result.summary!, style: TextStyle(fontSize: 12, color: Colors.white), ))), IconButton( padding: EdgeInsets.zero, icon: Icon(Icons.info_outline, color: Color(0xffb4f500)), onPressed: () => result.isExercise ? evaluation(bloc.exerciseRepository, result.exercise!) : trainingEvaluation(), ), /* */ ])), )); }), )); } void deleteConfirmation(TrainingLogBloc bloc, Exercise exercise) { ExerciseType? exerciseType = bloc.exerciseRepository.getExerciseTypeById(exercise.exerciseTypeId!); String exerciseName = AppLanguage().appLocal == Locale("en") ? exerciseType!.name : exerciseType!.nameTranslation; String strDate = AppLanguage().appLocal == Locale("en") ? "on the " + DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(exercise.dateAdd!.toUtc()) : DateFormat(DateFormat.YEAR_MONTH_DAY, AppLanguage().appLocal.toString()).format(exercise.dateAdd!.toUtc()) + "-n"; final String unitQuantity = exercise.unitQuantity == null ? "" : "x" + exercise.unitQuantity!.toStringAsFixed(0); showCupertinoDialog( useRootNavigator: true, context: context, //barrierDismissible: false, builder: (_) => CupertinoAlertDialog( title: Text(t("Are you sure to delete this exercise?")), content: Column(children: [ Divider(), Text( t("Exercise") + ": " + exerciseName, style: (TextStyle(color: Colors.blue)), ), Text( exercise.quantity!.toStringAsFixed(0) + unitQuantity + " ", style: (TextStyle(color: Colors.deepOrange)), ), Text( strDate, style: (TextStyle(color: Colors.deepOrange)), ), ]), actions: [ TextButton( child: Text(t("No")), onPressed: () => Navigator.pop(context), ), TextButton( child: Text(t("Yes")), onPressed: () { Navigator.pop(context); if (!Cache().hasPurchased) { showDialog( context: context, builder: (BuildContext context) { return DialogPremium( unlocked: Cache().hasPurchased, unlockRound: 1, unlockedText: t("Enjoy also this premium fetaure to delete mistyped old exercises."), function: "Delete Exercise", onTap: () => {Navigator.of(context).pop()}, onCancel: () => {Navigator.of(context).pop()}, ); }); } else { bloc.add(TrainingLogDelete(exercise: exercise)); } }, ) ], )); } void trainingEvaluation() {} void evaluation(ExerciseRepository exerciseRepository, Exercise exercise) { if (Cache().userLoggedIn != null) { if (!Cache().hasPurchased) { showDialog( context: context, builder: (BuildContext context) { return DialogPremium( unlocked: Cache().hasPurchased, unlockRound: 1, unlockedText: t("Enjoy also this premium feature to show all old evaluation data of your successful exercises."), function: "My Exercise Logs", onTap: () => {Navigator.of(context).pop()}, onCancel: () => {Navigator.of(context).pop()}, ); }); } else { LinkedHashMap args = LinkedHashMap(); args['exerciseRepository'] = exerciseRepository; args['exercise'] = exercise; args['past'] = true; Navigator.of(context).pushNamed('evaluationPage', arguments: args); } } } Widget getHeader(TrainingLogBloc bloc) { return Card( color: Colors.white60, child: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('asset/image/WT_plainblack_background.jpg'), fit: BoxFit.cover, alignment: Alignment.center, ), ), padding: EdgeInsets.only(left: 10, right: 5, top: 12, bottom: 8), child: Column(children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon( Icons.info, color: Colors.orangeAccent, ), Text(" "), Text( t("My Exercise Logs"), style: GoogleFonts.inter( fontSize: 16, color: Colors.white, fontWeight: FontWeight.bold, ), ), Divider(), Flexible( fit: FlexFit.tight, flex: 5, child: getSearchBar(bloc), ) ], ), bloc.search ? RichText( text: TextSpan( style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.normal, color: Colors.white, ), children: [ TextSpan(text: t("The found exercises are")), TextSpan(text: " "), TextSpan( text: t("in red"), style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.normal, color: Colors.redAccent, ), ), TextSpan(text: " "), TextSpan(text: t("in your calendar")), ]), ) : Offstage() ]))); } }