From a1f087758f0194445cb5b1f4b833c9c25bbe994d Mon Sep 17 00:00:00 2001 From: kima Date: Thu, 22 Jun 2023 19:15:02 +0200 Subject: [PATCH] started summary personality page --- filcnaplo/lib/models/personality.dart | 21 ++ .../personality_card/personality_card.dart | 192 ++++++++++++++++++ .../screens/summary/pages/allsum_page.dart | 1 + .../screens/summary/pages/lessons_page.dart | 2 +- .../summary/pages/personality_page.dart | 25 ++- 5 files changed, 238 insertions(+), 3 deletions(-) create mode 100644 filcnaplo/lib/models/personality.dart create mode 100644 filcnaplo_mobile_ui/lib/common/personality_card/personality_card.dart diff --git a/filcnaplo/lib/models/personality.dart b/filcnaplo/lib/models/personality.dart new file mode 100644 index 0000000..703917a --- /dev/null +++ b/filcnaplo/lib/models/personality.dart @@ -0,0 +1,21 @@ +class Personality { + PersonalityType type; + + Personality({ + this.type = PersonalityType.npc, + }); +} + +enum PersonalityType { + geek, + sick, + late, + quitter, + healthy, + acceptable, + fallible, + average, + diligent, + cheater, + npc +} diff --git a/filcnaplo_mobile_ui/lib/common/personality_card/personality_card.dart b/filcnaplo_mobile_ui/lib/common/personality_card/personality_card.dart new file mode 100644 index 0000000..e166414 --- /dev/null +++ b/filcnaplo_mobile_ui/lib/common/personality_card/personality_card.dart @@ -0,0 +1,192 @@ +import 'package:filcnaplo/api/providers/user_provider.dart'; +import 'package:filcnaplo/helpers/average_helper.dart'; +import 'package:filcnaplo/models/settings.dart'; +import 'package:filcnaplo/models/personality.dart'; +import 'package:filcnaplo_kreta_api/models/absence.dart'; +import 'package:filcnaplo_kreta_api/models/grade.dart'; +import 'package:filcnaplo_kreta_api/models/lesson.dart'; +import 'package:filcnaplo_kreta_api/models/subject.dart'; +import 'package:filcnaplo_kreta_api/models/week.dart'; +import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class PersonalityCard extends StatefulWidget { + const PersonalityCard({ + Key? key, + required this.user, + }) : super(key: key); + + final UserProvider user; + + @override + State createState() => _PersonalityCardState(); +} + +class _PersonalityCardState extends State { + late GradeProvider gradeProvider; + late AbsenceProvider absenceProvider; + late TimetableProvider timetableProvider; + late SettingsProvider settings; + + late List subjectAvgsList = []; + late Map subjectAvgs = {}; + late double subjectAvg; + late List classWorkGrades; + late int mostCommonGrade; + late int onesCount; + late List absences = []; + late List delays = []; + final Map _lessonCount = {}; + + late PersonalityType finalPersonality; + + List getSubjectGrades(Subject subject, {int days = 0}) => gradeProvider + .grades + .where((e) => + e.subject == subject && + e.type == GradeType.midYear && + (days == 0 || + e.date.isBefore(DateTime.now().subtract(Duration(days: days))))) + .toList(); + + @override + void initState() { + super.initState(); + + gradeProvider = Provider.of(context, listen: false); + absenceProvider = Provider.of(context, listen: false); + timetableProvider = Provider.of(context, listen: false); + settings = Provider.of(context, listen: false); + + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + for (final lesson in timetableProvider.getWeek(Week.current()) ?? []) { + if (!lesson.isEmpty && + lesson.subject.id != '' && + lesson.lessonYearIndex != null) { + _lessonCount.update( + lesson.subject, + (value) { + if (lesson.lessonYearIndex! > value.lessonYearIndex!) { + return lesson; + } else { + return value; + } + }, + ifAbsent: () => lesson, + ); + } + } + setState(() {}); + }); + } + + void getGrades() { + List subjects = gradeProvider.grades + .map((e) => e.subject) + .toSet() + .toList() + ..sort((a, b) => a.name.compareTo(b.name)); + + for (Subject subject in subjects) { + List subjectGrades = getSubjectGrades(subject); + + double avg = AverageHelper.averageEvals(subjectGrades); + if (avg != 0) subjectAvgs[subject] = avg; + + subjectAvgsList.add(avg.round()); + } + + subjectAvg = subjectAvgs.isNotEmpty + ? subjectAvgs.values.fold(0.0, (double a, double b) => a + b) / + subjectAvgs.length + : 0.0; + + classWorkGrades = + gradeProvider.grades.where((a) => a.value.weight <= 75).toList(); + } + + void getMostCommonGrade() { + Map counts = {}; + + subjectAvgsList.map((e) { + if (counts.containsKey(e)) { + counts.update(e, (value) => value++); + } else { + counts[e] = 1; + } + }); + + var maxValue = 0; + var maxKey = 0; + + counts.forEach((k, v) { + if (v > maxValue) { + maxValue = v; + maxKey = k; + } + }); + + mostCommonGrade = maxKey; + onesCount = counts.values.toList()[0]; + } + + void getAbsences() { + absences = absenceProvider.absences.where((a) => a.delay == 0).toList(); + } + + void getAndSortDelays() { + delays = absenceProvider.absences; + delays.sort((a, b) => -a.delay.compareTo(b.delay)); + } + + void doEverything() { + getGrades(); + getMostCommonGrade(); + getAbsences(); + getAndSortDelays(); + } + + void getPersonality() { + if (settings.goodStudent) { + finalPersonality = PersonalityType.cheater; + } else if (subjectAvg > 4.7) { + finalPersonality = PersonalityType.geek; + } else if (onesCount > 1) { + finalPersonality = PersonalityType.fallible; + } else if (absences.length < 10) { + finalPersonality = PersonalityType.healthy; + } else if ((absences.where( + (a) => a.state == Justification.unexcused && a.delay == 0)) + .length >= + 10) { + finalPersonality = PersonalityType.quitter; + } else if ((absences.where( + (a) => a.state == Justification.unexcused && a.delay > 0)) + .map((e) => e.delay) + .reduce((a, b) => a + b) > + 50) { + finalPersonality = PersonalityType.late; + } else if (absences.length >= 100) { + finalPersonality = PersonalityType.sick; + } else if (mostCommonGrade == 2) { + finalPersonality = PersonalityType.acceptable; + } else if (mostCommonGrade == 3) { + finalPersonality = PersonalityType.average; + } else if (classWorkGrades.length >= 5) { + finalPersonality = PersonalityType.diligent; + } else { + finalPersonality = PersonalityType.npc; + } + } + + @override + Widget build(BuildContext context) { + doEverything(); + getPersonality(); + + return Container(); + } +} diff --git a/filcnaplo_mobile_ui/lib/screens/summary/pages/allsum_page.dart b/filcnaplo_mobile_ui/lib/screens/summary/pages/allsum_page.dart index c56a6e6..d7d03b5 100644 --- a/filcnaplo_mobile_ui/lib/screens/summary/pages/allsum_page.dart +++ b/filcnaplo_mobile_ui/lib/screens/summary/pages/allsum_page.dart @@ -21,6 +21,7 @@ class _AllSumBodyState extends State { late HomeworkProvider homeworkProvider; late AbsenceProvider absenceProvider; //late TimetableProvider timetableProvider; + late Map> things = {}; late List firstSixTiles = []; late List lastSixTiles = []; diff --git a/filcnaplo_mobile_ui/lib/screens/summary/pages/lessons_page.dart b/filcnaplo_mobile_ui/lib/screens/summary/pages/lessons_page.dart index 5e6394a..f9eb459 100644 --- a/filcnaplo_mobile_ui/lib/screens/summary/pages/lessons_page.dart +++ b/filcnaplo_mobile_ui/lib/screens/summary/pages/lessons_page.dart @@ -32,10 +32,10 @@ class _LessonsBodyState extends State { late AbsenceProvider absenceProvider; late SettingsProvider settingsProvider; late TimetableProvider timetableProvider; + late List absences = []; late List lessons = []; late List delays = []; - final Map _lessonCount = {}; @override diff --git a/filcnaplo_mobile_ui/lib/screens/summary/pages/personality_page.dart b/filcnaplo_mobile_ui/lib/screens/summary/pages/personality_page.dart index 933dd38..d54b69b 100644 --- a/filcnaplo_mobile_ui/lib/screens/summary/pages/personality_page.dart +++ b/filcnaplo_mobile_ui/lib/screens/summary/pages/personality_page.dart @@ -1,10 +1,31 @@ +import 'package:filcnaplo/api/providers/user_provider.dart'; +import 'package:filcnaplo_mobile_ui/common/personality_card/personality_card.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -class PersonalityBody extends StatelessWidget { +class PersonalityBody extends StatefulWidget { const PersonalityBody({Key? key}) : super(key: key); + @override + _PersonalityBodyState createState() => _PersonalityBodyState(); +} + +class _PersonalityBodyState extends State { + late UserProvider user; + @override Widget build(BuildContext context) { - return const Column(); + user = Provider.of(context); + + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + const SizedBox(height: 40), + PersonalityCard( + user: user, + ), + const SizedBox(height: 40), + ]); } }