diff --git a/filcnaplo/android/app/src/main/AndroidManifest.xml b/filcnaplo/android/app/src/main/AndroidManifest.xml
index f9291f4..78ffac3 100644
--- a/filcnaplo/android/app/src/main/AndroidManifest.xml
+++ b/filcnaplo/android/app/src/main/AndroidManifest.xml
@@ -14,7 +14,7 @@
android:resource="@style/NormalTheme" />
-
+
diff --git a/filcnaplo_mobile_ui/lib/pages/grades/calculator/grade_calculator.dart b/filcnaplo_mobile_ui/lib/pages/grades/calculator/grade_calculator.dart
index 5e531b5..b8eae92 100755
--- a/filcnaplo_mobile_ui/lib/pages/grades/calculator/grade_calculator.dart
+++ b/filcnaplo_mobile_ui/lib/pages/grades/calculator/grade_calculator.dart
@@ -16,7 +16,7 @@ import 'grade_calculator.i18n.dart';
class GradeCalculator extends StatefulWidget {
const GradeCalculator(this.subject, {Key? key}) : super(key: key);
- final GradeSubject subject;
+ final GradeSubject? subject;
@override
_GradeCalculatorState createState() => _GradeCalculatorState();
@@ -142,7 +142,8 @@ class _GradeCalculatorState extends State {
List grades = calculatorProvider.grades
.where((e) =>
e.type == GradeType.midYear &&
- e.subject == widget.subject)
+ (e.subject == widget.subject ||
+ widget.subject == null))
.toList();
grades.sort((a, b) => -a.writeDate.compareTo(b.writeDate));
date = grades.first.date;
@@ -158,7 +159,12 @@ class _GradeCalculatorState extends State {
teacher: Teacher.fromString("Ghost"),
type: GradeType.ghost,
form: "",
- subject: widget.subject,
+ subject: widget.subject ??
+ GradeSubject(
+ id: randomId(),
+ category: Category(id: randomId()),
+ name: 'All',
+ ),
mode: Category.fromJson({}),
seenDate: DateTime(0),
groupId: "",
diff --git a/filcnaplo_mobile_ui/lib/pages/grades/grades_page.dart b/filcnaplo_mobile_ui/lib/pages/grades/grades_page.dart
index 947b891..6398f68 100755
--- a/filcnaplo_mobile_ui/lib/pages/grades/grades_page.dart
+++ b/filcnaplo_mobile_ui/lib/pages/grades/grades_page.dart
@@ -11,6 +11,7 @@ import 'package:filcnaplo_kreta_api/models/grade.dart';
import 'package:filcnaplo_kreta_api/models/subject.dart';
import 'package:filcnaplo_kreta_api/models/group_average.dart';
import 'package:filcnaplo_mobile_ui/common/average_display.dart';
+import 'package:filcnaplo_mobile_ui/common/bottom_sheet_menu/rounded_bottom_sheet.dart';
import 'package:filcnaplo_mobile_ui/common/empty.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel.dart';
import 'package:filcnaplo_mobile_ui/common/profile_image/profile_button.dart';
@@ -24,10 +25,13 @@ import 'package:filcnaplo_mobile_ui/pages/grades/graph.dart';
import 'package:filcnaplo_mobile_ui/pages/grades/grade_subject_view.dart';
import 'package:filcnaplo_premium/providers/premium_provider.dart';
import 'package:flutter/material.dart';
+import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:provider/provider.dart';
import 'package:filcnaplo/helpers/average_helper.dart';
import 'average_selector.dart';
import 'package:filcnaplo_premium/ui/mobile/premium/premium_inline.dart';
+import 'calculator/grade_calculator.dart';
+import 'calculator/grade_calculator_provider.dart';
import 'grades_page.i18n.dart';
class GradesPage extends StatefulWidget {
@@ -38,9 +42,14 @@ class GradesPage extends StatefulWidget {
}
class _GradesPageState extends State {
+ final GlobalKey _scaffoldKey = GlobalKey();
+
+ PersistentBottomSheetController? _sheetController;
+
late UserProvider user;
late GradeProvider gradeProvider;
late UpdateProvider updateProvider;
+ late GradeCalculatorProvider calculatorProvider;
late String firstName;
late Widget yearlyGraph;
late Widget gradesCount;
@@ -48,15 +57,26 @@ class _GradesPageState extends State {
int avgDropValue = 0;
- List getSubjectGrades(GradeSubject 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();
+ bool gradeCalcMode = false;
+
+ List getSubjectGrades(GradeSubject subject,
+ {int days = 0}) =>
+ !gradeCalcMode
+ ? gradeProvider
+ .grades
+ .where((e) =>
+ e
+ .subject ==
+ subject &&
+ e.type == GradeType.midYear &&
+ (days ==
+ 0 ||
+ e.date.isBefore(
+ DateTime.now().subtract(Duration(days: days)))))
+ .toList()
+ : calculatorProvider.grades
+ .where((e) => e.subject == subject)
+ .toList();
void generateTiles() {
List subjects = gradeProvider.grades
@@ -200,6 +220,7 @@ class _GradesPageState extends State {
user = Provider.of(context);
gradeProvider = Provider.of(context);
updateProvider = Provider.of(context);
+ calculatorProvider = Provider.of(context);
context.watch();
List nameParts = user.displayName?.split(" ") ?? ["?"];
@@ -218,21 +239,31 @@ class _GradesPageState extends State {
.date
: DateTime.now();
- final currentStudentAvg = AverageHelper.averageEvals(gradeProvider.grades
- .where((e) => e.type == GradeType.midYear)
- .toList());
+ final currentStudentAvg = AverageHelper.averageEvals(!gradeCalcMode
+ ? gradeProvider.grades
+ .where((e) => e.type == GradeType.midYear)
+ .toList()
+ : calculatorProvider.grades.toList());
+
final prevStudentAvg = AverageHelper.averageEvals(gradeProvider.grades
.where((e) => e.type == GradeType.midYear)
.where((e) => e.date.isBefore(now.subtract(const Duration(days: 30))))
.toList());
- List graphGrades = gradeProvider.grades
- .where((e) =>
- e.type == GradeType.midYear &&
- (avgDropValue == 0 ||
+ List graphGrades = !gradeCalcMode
+ ? gradeProvider.grades
+ .where((e) =>
+ e.type == GradeType.midYear &&
+ (avgDropValue == 0 ||
+ e.date.isAfter(
+ DateTime.now().subtract(Duration(days: avgDropValue)))))
+ .toList()
+ : calculatorProvider.grades
+ .where(((e) =>
+ avgDropValue == 0 ||
e.date.isAfter(
DateTime.now().subtract(Duration(days: avgDropValue)))))
- .toList();
+ .toList();
yearlyGraph = Padding(
padding: const EdgeInsets.only(top: 12.0, bottom: 8.0),
@@ -278,6 +309,7 @@ class _GradesPageState extends State {
generateTiles();
return Scaffold(
+ key: _scaffoldKey,
body: Padding(
padding: const EdgeInsets.only(top: 9.0),
child: NestedScrollView(
@@ -291,7 +323,23 @@ class _GradesPageState extends State {
snap: false,
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
actions: [
- // Profile Icon
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 5.0, vertical: 0.0),
+ child: IconButton(
+ splashRadius: 24.0,
+ onPressed: () {
+ // SoonAlert.show(context: context);
+ gradeCalcTotal(context);
+ },
+ icon: Icon(
+ FeatherIcons.plus,
+ color: AppColors.of(context).text,
+ ),
+ ),
+ ),
+
+ // profile Icon
Padding(
padding: const EdgeInsets.only(right: 24.0),
child: ProfileButton(
@@ -355,4 +403,30 @@ class _GradesPageState extends State {
),
);
}
+
+ void gradeCalcTotal(BuildContext context) {
+ calculatorProvider.clear();
+ calculatorProvider.addAllGrades(gradeProvider.grades);
+
+ _sheetController = _scaffoldKey.currentState?.showBottomSheet(
+ (context) => const RoundedBottomSheet(
+ child: GradeCalculator(null), borderRadius: 14.0),
+ backgroundColor: const Color(0x00000000),
+ elevation: 12.0,
+ );
+
+ // Hide the fab and grades
+ setState(() {
+ gradeCalcMode = true;
+ });
+
+ _sheetController!.closed.then((value) {
+ // Show fab and grades
+ if (mounted) {
+ setState(() {
+ gradeCalcMode = false;
+ });
+ }
+ });
+ }
}