From fef085705014e57612759ba358263e282b8cf8da Mon Sep 17 00:00:00 2001 From: Kima Date: Sat, 2 Sep 2023 14:48:05 +0200 Subject: [PATCH] worked on goal planner finish modal --- .../lib/providers/goal_provider.dart | 45 +++ .../goal_planner/goal_complete_modal.dart | 307 +++++++++++++----- .../goal_planner/goal_planner_screen.dart | 17 +- .../goal_planner/goal_state_screen.dart | 13 +- .../goal_planner/goal_state_screen.i18n.dart | 24 ++ 5 files changed, 312 insertions(+), 94 deletions(-) create mode 100644 filcnaplo_premium/lib/providers/goal_provider.dart diff --git a/filcnaplo_premium/lib/providers/goal_provider.dart b/filcnaplo_premium/lib/providers/goal_provider.dart new file mode 100644 index 0000000..ce73a96 --- /dev/null +++ b/filcnaplo_premium/lib/providers/goal_provider.dart @@ -0,0 +1,45 @@ +import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/api/providers/user_provider.dart'; +import 'package:filcnaplo_kreta_api/models/subject.dart'; +import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; +import 'package:flutter/widgets.dart'; + +class GoalProvider extends ChangeNotifier { + final DatabaseProvider _db; + final UserProvider _user; + final GradeProvider _gradeProvider; + + late bool _done = false; + late Subject _doneSubject; + + bool get hasDoneGoals => _done; + Subject get doneSubject => _doneSubject; + + GoalProvider({ + required DatabaseProvider database, + required UserProvider user, + required GradeProvider gradeProvider, + }) : _db = database, + _user = user, + _gradeProvider = gradeProvider; + + Future fetchDone() async { + var goalAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!); + var beforeAvgs = await _db.userQuery.subjectGoalAverages(userId: _user.id!); + + List subjects = _gradeProvider.grades + .map((e) => e.subject) + .toSet() + .toList() + ..sort((a, b) => a.name.compareTo(b.name)); + + goalAvgs.forEach((k, v) { + if (beforeAvgs[k] == v) { + _done = true; + _doneSubject = subjects.where((e) => e.id == k).toList()[0]; + + notifyListeners(); + } + }); + } +} diff --git a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_complete_modal.dart b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_complete_modal.dart index c4f2c65..289b6fc 100644 --- a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_complete_modal.dart +++ b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_complete_modal.dart @@ -1,92 +1,235 @@ -// import 'package:filcnaplo/api/providers/database_provider.dart'; -// import 'package:filcnaplo/api/providers/user_provider.dart'; -// import 'package:filcnaplo_kreta_api/models/subject.dart'; -// import 'package:flutter/material.dart'; -// import 'package:provider/provider.dart'; +import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/api/providers/user_provider.dart'; +import 'package:filcnaplo_kreta_api/models/subject.dart'; +import 'package:filcnaplo_mobile_ui/common/average_display.dart'; +import 'package:filcnaplo_premium/ui/mobile/goal_planner/goal_state_screen.i18n.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -// class GoalCompleteModal extends StatelessWidget { -// const GoalCompleteModal( -// this.subject, { -// Key? key, -// required this.user, -// required this.database, -// required this.goalAverage, -// required this.beforeAverage, -// required this.averageDifference, -// }) : super(key: key); +class GoalCompleteModal extends StatelessWidget { + const GoalCompleteModal( + this.subject, { + Key? key, + required this.user, + required this.database, + required this.goalAverage, + required this.beforeAverage, + required this.averageDifference, + }) : super(key: key); -// final UserProvider user; -// final DatabaseProvider database; -// final Subject subject; + final UserProvider user; + final DatabaseProvider database; + final Subject subject; -// final double goalAverage; -// final double beforeAverage; -// final double averageDifference; + final double goalAverage; + final double beforeAverage; + final double averageDifference; -// @override -// Widget build(BuildContext context) { -// return Padding( -// padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0), -// child: Material( -// borderRadius: BorderRadius.circular(12.0), -// child: Padding( -// padding: const EdgeInsets.all(12.0), -// child: Column( -// children: [ -// // content or idk -// Container( -// decoration: const BoxDecoration( -// image: DecorationImage( -// image: AssetImage('assets/images/static_confetti.png'), -// fit: BoxFit.fill, -// alignment: Alignment.topCenter, -// ), -// ), -// child: Text( -// goalAverage.toStringAsFixed(1), -// style: const TextStyle( -// color: Colors.white, -// fontSize: 40.0, -// ), -// ), -// ), -// ], -// ), -// ), -// ), -// ); -// } + @override + Widget build(BuildContext context) { + return Dialog( + elevation: 0, + backgroundColor: Colors.transparent, + child: Container( + padding: const EdgeInsets.all(16.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(14.0), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: double.infinity, + decoration: BoxDecoration( + image: const DecorationImage( + image: AssetImage('assets/images/static_confetti.png'), + fit: BoxFit.fitWidth, + alignment: Alignment.topCenter, + ), + color: Colors.white, + borderRadius: BorderRadius.circular(8.0), + ), + padding: const EdgeInsets.all(6.0), + child: Text( + goalAverage.toStringAsFixed(1), + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.white, + fontSize: 64.0, + fontWeight: FontWeight.w800, + ), + ), + ), + const SizedBox(height: 10.0), + Text( + 'congrats_title'.i18n, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 27.0, + fontWeight: FontWeight.w700, + height: 1.1, + ), + ), + Text( + 'goal_reached'.i18n.fill(['20']), + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.w500, + height: 1.1, + ), + ), + const SizedBox(height: 18.0), + Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'started_at'.i18n, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 17.0, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox(width: 5.0), + AverageDisplay( + average: beforeAverage, + ), + ], + ), + Text( + 'improved_by'.i18n.fill([ + averageDifference.toStringAsFixed(2) + '%', + ]), + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 17.0, + fontWeight: FontWeight.w500, + ), + ), + ], + ), + const SizedBox(height: 20.0), + Column( + children: [ + GestureDetector( + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text("Hamarosan...")), + ); + }, + child: Container( + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + gradient: const LinearGradient( + colors: [ + Color(0xFFCAECFA), + Color(0xFFF4D9EE), + Color(0xFFF3EFDA), + ], + stops: [0.0, 0.53, 1.0], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Text( + 'detailed_stats'.i18n, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.w700, + color: Color(0xFF691A9B), + ), + ), + ), + ), + ), + const SizedBox(height: 10.0), + GestureDetector( + onTap: () { + Navigator.of(context).pop(); + }, + child: Container( + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.0), + color: const Color(0xFFF5FAF9), + ), + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Text( + 'later'.i18n, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.w700, + color: Color(0xFF01342D), + ), + ), + ), + ), + ), + ], + ), + ], + ), + ), + ); -// static Future show( -// Subject subject, { -// required BuildContext context, -// }) async { -// UserProvider user = Provider.of(context, listen: false); -// DatabaseProvider db = Provider.of(context, listen: false); + // return Padding( + // padding: const EdgeInsets.symmetric(vertical: 100.0, horizontal: 32.0), + // child: Material( + // borderRadius: BorderRadius.circular(12.0), + // child: Padding( + // padding: const EdgeInsets.all(12.0), + // child: Column( + // children: [ + // // content or idk + // ], + // ), + // ), + // ), + // ); + } -// var goalAvgRes = await db.userQuery.subjectGoalAverages(userId: user.id!); -// var beforeAvgRes = await db.userQuery.subjectGoalBefores(userId: user.id!); + static Future show( + Subject subject, { + required BuildContext context, + }) async { + UserProvider user = Provider.of(context, listen: false); + DatabaseProvider db = Provider.of(context, listen: false); -// //DateTime goalPinDate = DateTime.parse((await db.userQuery.subjectGoalPinDates(userId: user.id!))[widget.subject.id]!); + var goalAvgRes = await db.userQuery.subjectGoalAverages(userId: user.id!); + var beforeAvgRes = await db.userQuery.subjectGoalBefores(userId: user.id!); -// String? goalAvgStr = goalAvgRes[subject.id]; -// String? beforeAvgStr = beforeAvgRes[subject.id]; -// double goalAvg = double.parse(goalAvgStr ?? '0.0'); -// double beforeAvg = double.parse(beforeAvgStr ?? '0.0'); + //DateTime goalPinDate = DateTime.parse((await db.userQuery.subjectGoalPinDates(userId: user.id!))[widget.subject.id]!); -// double avgDifference = ((goalAvg - beforeAvg) / beforeAvg.abs()) * 100; + String? goalAvgStr = goalAvgRes[subject.id]; + String? beforeAvgStr = beforeAvgRes[subject.id]; + double goalAvg = double.parse(goalAvgStr ?? '0.0'); + double beforeAvg = double.parse(beforeAvgStr ?? '0.0'); -// return showDialog( -// context: context, -// builder: (context) => GoalCompleteModal( -// subject, -// user: user, -// database: db, -// goalAverage: goalAvg, -// beforeAverage: beforeAvg, -// averageDifference: avgDifference, -// ), -// barrierDismissible: false, -// ); -// } -// } + double avgDifference = ((goalAvg - beforeAvg) / beforeAvg.abs()) * 100; + + return showDialog( + context: context, + builder: (context) => GoalCompleteModal( + subject, + user: user, + database: db, + goalAverage: goalAvg, + beforeAverage: beforeAvg, + averageDifference: avgDifference, + ), + barrierDismissible: false, + ); + } +} diff --git a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_planner_screen.dart b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_planner_screen.dart index f3dfb08..bca524f 100644 --- a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_planner_screen.dart +++ b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_planner_screen.dart @@ -375,12 +375,17 @@ class _GoalPlannerScreenState extends State { final goalBeforeGrades = await fetchGoalBees(); final goalPinDates = await fetchGoalPinDates(); - goalPlans[widget.subject.id] = - selectedRoute!.dbString; - goalAvgs[widget.subject.id] = - goalValue.toStringAsFixed(1); - goalBeforeGrades[widget.subject.id] = - avg.toStringAsFixed(1); + // goalPlans[widget.subject.id] = + // selectedRoute!.dbString; + // goalAvgs[widget.subject.id] = + // goalValue.toStringAsFixed(2); + // goalBeforeGrades[widget.subject.id] = + // avg.toStringAsFixed(2); + // goalPinDates[widget.subject.id] = + // DateTime.now().toIso8601String(); + goalPlans[widget.subject.id] = '1,2,3,4,5,'; + goalAvgs[widget.subject.id] = '3.69'; + goalBeforeGrades[widget.subject.id] = '3.69'; goalPinDates[widget.subject.id] = DateTime.now().toIso8601String(); diff --git a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.dart b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.dart index 5e6e35f..c056309 100644 --- a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.dart +++ b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.dart @@ -18,6 +18,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; +import 'goal_complete_modal.dart'; import 'goal_planner_screen.dart'; import 'graph.dart'; @@ -423,12 +424,12 @@ class _GoalStateScreenState extends State { plan: plan!, ) : const Text(''), - // TextButton( - // onPressed: () async { - // GoalCompleteModal.show(widget.subject, - // context: context); - // }, - // child: const Text('faszteszt')) + TextButton( + onPressed: () async { + GoalCompleteModal.show(widget.subject, + context: context); + }, + child: const Text('faszteszt')) ], ), ), diff --git a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.i18n.dart b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.i18n.dart index 6abe77c..6999dc8 100644 --- a/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.i18n.dart +++ b/filcnaplo_premium/lib/ui/mobile/goal_planner/goal_state_screen.i18n.dart @@ -4,6 +4,7 @@ extension Localization on String { static final _t = Translations.byLocale("hu_hu") + { "en_en": { + // base page "goal_planner_title": "Goal Planning", "almost_there": "Almost there! Keep going!", "started_with": "Started with:", @@ -14,8 +15,16 @@ extension Localization on String { "thats_progress": "Now that's what I call progress! Push a little more, you're almost there..", "you_need": "You need:", + // done modal + "congrats_title": "🎉 Congratulations!", + "goal_reached": "You reached your goal after %s days!", + "started_at": "You started at", + "improved_by": "and improved your grade by %s", + "detailed_stats": "See my detailed stats", + "later": "Yay! I'll see my stats later.", }, "hu_hu": { + // base page "goal_planner_title": "CĂ©l követĂ©s", "almost_there": "Majdnem megvan! Így tovĂĄbb!", "started_with": "Így kezdƑdött:", @@ -26,8 +35,16 @@ extension Localization on String { "thats_progress": "Ezt nevezem haladĂĄsnak! Hajts mĂ©g egy kicsit, mĂĄr majdnem kĂ©sz..", "you_need": "SzĂŒksĂ©ges:", + // done modal + "congrats_title": "🎉 GratulĂĄlunk!", + "goal_reached": "%s nap utĂĄn Ă©rted el a cĂ©lod!", + "started_at": "Átlagod kezdĂ©skor:", + "improved_by": "%s-os javulĂĄst Ă©rtĂ©l el!", + "detailed_stats": "RĂ©szletes statisztikĂĄm", + "later": "HurrĂĄ! MegnĂ©zem mĂĄskor.", }, "de_de": { + // base page "goal_planner_title": "Zielplanung", "almost_there": "Fast dort! Weitermachen!", "started_with": "Begann mit:", @@ -38,6 +55,13 @@ extension Localization on String { "thats_progress": "Das nenne ich Fortschritt! DrĂŒcken Sie noch ein wenig, Sie haben es fast geschafft..", "you_need": "Du brauchst:", + // done modal + "congrats_title": "🎉 GlĂŒckwunsch!", + "goal_reached": "Du hast dein Ziel nach %s Tagen erreicht!", + "started_at": "Gesamtbewertung:", + "improved_by": "Sie haben %s Verbesserung erreicht!", + "detailed_stats": "Detaillierte Statistiken", + "later": "Hurra! Ich schaue spĂ€ter nach.", }, };