forked from firka/student-legacy
705 lines
28 KiB
Dart
705 lines
28 KiB
Dart
// ignore_for_file: no_leading_underscores_for_local_identifiers
|
|
|
|
import 'dart:math';
|
|
|
|
import 'package:animations/animations.dart';
|
|
import 'package:collection/collection.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:refilc/api/providers/update_provider.dart';
|
|
import 'package:refilc/models/settings.dart';
|
|
import 'package:refilc/theme/colors/utils.dart';
|
|
import 'package:refilc/ui/date_widget.dart';
|
|
import 'package:refilc_kreta_api/models/absence.dart';
|
|
import 'package:refilc_kreta_api/models/lesson.dart';
|
|
import 'package:refilc_kreta_api/models/subject.dart';
|
|
import 'package:refilc_kreta_api/models/week.dart';
|
|
import 'package:refilc_kreta_api/providers/absence_provider.dart';
|
|
import 'package:refilc_kreta_api/providers/note_provider.dart';
|
|
import 'package:refilc/api/providers/user_provider.dart';
|
|
import 'package:refilc/theme/colors/colors.dart';
|
|
import 'package:refilc_kreta_api/providers/timetable_provider.dart';
|
|
import 'package:refilc_mobile_ui/common/action_button.dart';
|
|
import 'package:refilc_mobile_ui/common/empty.dart';
|
|
import 'package:refilc_mobile_ui/common/filter_bar.dart';
|
|
import 'package:refilc_mobile_ui/common/panel/panel.dart';
|
|
import 'package:refilc_mobile_ui/common/profile_image/profile_button.dart';
|
|
import 'package:refilc_mobile_ui/common/profile_image/profile_image.dart';
|
|
import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
|
|
import 'package:refilc_mobile_ui/common/widgets/absence/absence_subject_tile.dart';
|
|
import 'package:refilc_mobile_ui/common/widgets/absence/absence_viewable.dart';
|
|
import 'package:refilc_mobile_ui/common/widgets/miss_tile.dart';
|
|
import 'package:refilc_mobile_ui/pages/absences/absence_subject_view.dart';
|
|
import 'package:refilc/ui/filter/sort.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'absences_page.i18n.dart';
|
|
|
|
enum AbsenceFilter { absences, delays, misses }
|
|
|
|
class SubjectAbsence {
|
|
GradeSubject subject;
|
|
List<Absence> absences;
|
|
double percentage;
|
|
|
|
SubjectAbsence(
|
|
{required this.subject, this.absences = const [], this.percentage = 0.0});
|
|
}
|
|
|
|
class AbsencesPage extends StatefulWidget {
|
|
const AbsencesPage({super.key});
|
|
|
|
@override
|
|
AbsencesPageState createState() => AbsencesPageState();
|
|
}
|
|
|
|
class AbsencesPageState extends State<AbsencesPage>
|
|
with TickerProviderStateMixin {
|
|
late UserProvider user;
|
|
late AbsenceProvider absenceProvider;
|
|
late TimetableProvider timetableProvider;
|
|
late NoteProvider noteProvider;
|
|
late UpdateProvider updateProvider;
|
|
late String firstName;
|
|
late TabController _tabController;
|
|
late List<SubjectAbsence> absences = [];
|
|
final Map<GradeSubject, Lesson> _lessonCount = {};
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
_tabController = TabController(length: 3, vsync: this);
|
|
timetableProvider = Provider.of<TimetableProvider>(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 buildSubjectAbsences() {
|
|
Map<GradeSubject, SubjectAbsence> _absences = {};
|
|
|
|
for (final absence in absenceProvider.absences) {
|
|
if (absence.delay != 0) continue;
|
|
|
|
if (!_absences.containsKey(absence.subject)) {
|
|
_absences[absence.subject] =
|
|
SubjectAbsence(subject: absence.subject, absences: [absence]);
|
|
} else {
|
|
_absences[absence.subject]?.absences.add(absence);
|
|
}
|
|
}
|
|
|
|
_absences.forEach((subject, absence) {
|
|
final absentLessonsOfSubject = absenceProvider.absences
|
|
.where((e) => e.subject == subject && e.delay == 0)
|
|
.length;
|
|
final totalLessonsOfSubject = _lessonCount[subject]?.lessonYearIndex ?? 0;
|
|
|
|
double absentLessonsOfSubjectPercentage;
|
|
|
|
if (absentLessonsOfSubject <= totalLessonsOfSubject) {
|
|
absentLessonsOfSubjectPercentage =
|
|
absentLessonsOfSubject / totalLessonsOfSubject * 100;
|
|
} else {
|
|
absentLessonsOfSubjectPercentage = -1;
|
|
}
|
|
|
|
_absences[subject]?.percentage =
|
|
absentLessonsOfSubjectPercentage.clamp(-1, 100.0);
|
|
});
|
|
|
|
absences = _absences.values.toList();
|
|
absences.sort((a, b) => -a.percentage.compareTo(b.percentage));
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
user = Provider.of<UserProvider>(context);
|
|
absenceProvider = Provider.of<AbsenceProvider>(context);
|
|
noteProvider = Provider.of<NoteProvider>(context);
|
|
updateProvider = Provider.of<UpdateProvider>(context);
|
|
timetableProvider = Provider.of<TimetableProvider>(context);
|
|
|
|
List<String> nameParts = user.displayName?.split(" ") ?? ["?"];
|
|
firstName = nameParts.length > 1 ? nameParts[1] : nameParts[0];
|
|
|
|
buildSubjectAbsences();
|
|
|
|
return Scaffold(
|
|
body: Padding(
|
|
padding: const EdgeInsets.only(top: 12.0),
|
|
child: NestedScrollView(
|
|
physics: const BouncingScrollPhysics(
|
|
parent: AlwaysScrollableScrollPhysics()),
|
|
headerSliverBuilder: (context, _) => [
|
|
SliverAppBar(
|
|
pinned: true,
|
|
floating: false,
|
|
snap: false,
|
|
centerTitle: false,
|
|
surfaceTintColor: Theme.of(context).scaffoldBackgroundColor,
|
|
actions: [
|
|
// Profile Icon
|
|
Padding(
|
|
padding: const EdgeInsets.only(right: 24.0),
|
|
child: ProfileButton(
|
|
child: ProfileImage(
|
|
heroTag: "profile",
|
|
name: firstName,
|
|
backgroundColor: Theme.of(context)
|
|
.colorScheme
|
|
.tertiary, //ColorUtils.stringToColor(user.displayName ?? "?"),
|
|
badge: updateProvider.available,
|
|
role: user.role,
|
|
profilePictureString: user.picture,
|
|
gradeStreak: (user.gradeStreak ?? 0) > 1,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
automaticallyImplyLeading: false,
|
|
shadowColor: Theme.of(context).shadowColor,
|
|
title: Padding(
|
|
padding: const EdgeInsets.only(left: 8.0),
|
|
child: Text(
|
|
"Absences".i18n,
|
|
style: Provider.of<SettingsProvider>(context).fontFamily !=
|
|
'' &&
|
|
Provider.of<SettingsProvider>(context).titleOnlyFont
|
|
? GoogleFonts.getFont(
|
|
Provider.of<SettingsProvider>(context).fontFamily,
|
|
textStyle: TextStyle(
|
|
color: AppColors.of(context).text,
|
|
fontSize: 32.0,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
)
|
|
: TextStyle(
|
|
color: AppColors.of(context).text,
|
|
fontSize: 32.0,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
bottom: FilterBar(
|
|
items: [
|
|
Tab(text: "Absences".i18n),
|
|
Tab(text: "Delays".i18n),
|
|
Tab(text: "Misses".i18n),
|
|
],
|
|
controller: _tabController,
|
|
disableFading: true,
|
|
),
|
|
),
|
|
],
|
|
body: TabBarView(
|
|
physics: const BouncingScrollPhysics(),
|
|
controller: _tabController,
|
|
children: List.generate(
|
|
3, (index) => filterViewBuilder(context, index))),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
List<DateWidget> getFilterWidgets(AbsenceFilter activeData) {
|
|
List<DateWidget> items = [];
|
|
switch (activeData) {
|
|
case AbsenceFilter.absences:
|
|
for (var a in absences) {
|
|
items.add(DateWidget(
|
|
date: DateTime.fromMillisecondsSinceEpoch(0),
|
|
widget: AbsenceSubjectTile(
|
|
a.subject,
|
|
percentage: a.percentage,
|
|
excused: a.absences
|
|
.where((a) => a.state == Justification.excused)
|
|
.length,
|
|
unexcused: a.absences
|
|
.where((a) => a.state == Justification.unexcused)
|
|
.length,
|
|
pending: a.absences
|
|
.where((a) => a.state == Justification.pending)
|
|
.length,
|
|
onTap: () => AbsenceSubjectView.show(a.subject, a.absences,
|
|
context: context),
|
|
),
|
|
));
|
|
}
|
|
break;
|
|
case AbsenceFilter.delays:
|
|
for (var absence in absenceProvider.absences) {
|
|
if (absence.delay != 0) {
|
|
items.add(DateWidget(
|
|
date: absence.date,
|
|
widget: AbsenceViewable(absence, padding: EdgeInsets.zero),
|
|
));
|
|
}
|
|
}
|
|
break;
|
|
case AbsenceFilter.misses:
|
|
for (var note in noteProvider.notes) {
|
|
if (note.type?.name == "HaziFeladatHiany" ||
|
|
note.type?.name == "Felszereleshiany") {
|
|
items.add(DateWidget(
|
|
date: note.date,
|
|
widget: MissTile(note),
|
|
));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return items;
|
|
}
|
|
|
|
Widget filterViewBuilder(context, int activeData) {
|
|
List<Widget> filterWidgets = [];
|
|
|
|
var absWidgets = getFilterWidgets(AbsenceFilter.values[activeData])
|
|
.map((e) => e.widget)
|
|
.cast<Widget>()
|
|
.toList();
|
|
|
|
if (activeData > 0) {
|
|
filterWidgets = sortDateWidgets(
|
|
context,
|
|
dateWidgets: getFilterWidgets(AbsenceFilter.values[activeData]),
|
|
padding: EdgeInsets.zero,
|
|
hasShadow: true,
|
|
);
|
|
} else if (absWidgets.isNotEmpty) {
|
|
filterWidgets = [
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 24.0),
|
|
child: Panel(
|
|
padding: EdgeInsets.zero,
|
|
isTransparent: true,
|
|
hasShadow: false,
|
|
title: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text("Subjects".i18n),
|
|
Padding(
|
|
padding: const EdgeInsets.only(right: 4.0),
|
|
child: IconButton(
|
|
onPressed: () {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12.0)),
|
|
title: Text("attention".i18n),
|
|
content: Text("attention_body".i18n),
|
|
actions: [
|
|
ActionButton(
|
|
label: "Ok",
|
|
onTap: () => Navigator.of(context).pop(),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
padding: EdgeInsets.zero,
|
|
splashRadius: 24.0,
|
|
visualDensity: VisualDensity.compact,
|
|
constraints: BoxConstraints.tight(const Size(42.0, 42.0)),
|
|
icon: const Icon(FeatherIcons.info),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
child: PageTransitionSwitcher(
|
|
transitionBuilder: (
|
|
Widget child,
|
|
Animation<double> primaryAnimation,
|
|
Animation<double> secondaryAnimation,
|
|
) {
|
|
return FadeThroughTransition(
|
|
animation: primaryAnimation,
|
|
secondaryAnimation: secondaryAnimation,
|
|
fillColor: Colors.transparent,
|
|
child: child,
|
|
);
|
|
},
|
|
child: SplittedPanel(
|
|
padding: EdgeInsets.zero,
|
|
isSeparated: true,
|
|
isTransparent: true,
|
|
children: absWidgets,
|
|
),
|
|
),
|
|
),
|
|
)
|
|
];
|
|
}
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(top: 12.0),
|
|
child: RefreshIndicator(
|
|
color: Theme.of(context).colorScheme.secondary,
|
|
onRefresh: () async {
|
|
await absenceProvider.fetch();
|
|
await noteProvider.fetch();
|
|
},
|
|
child: ListView.builder(
|
|
padding: EdgeInsets.zero,
|
|
physics: const BouncingScrollPhysics(),
|
|
itemCount: max(filterWidgets.length + (activeData <= 1 ? 1 : 0), 1),
|
|
itemBuilder: (context, index) {
|
|
if (filterWidgets.isNotEmpty) {
|
|
if ((index == 0 && activeData == 1) ||
|
|
(index == 0 && activeData == 0)) {
|
|
int value1 = 0;
|
|
int value2 = 0;
|
|
int value3 = 0;
|
|
String title1 = "";
|
|
String title2 = "";
|
|
String suffix = "";
|
|
|
|
List<Absence> unexcused = [];
|
|
List<Absence> excused = [];
|
|
List<Absence> pending = [];
|
|
|
|
List<double> absencePositions = [];
|
|
List<Color> finalChartColors = [];
|
|
|
|
if (activeData == AbsenceFilter.absences.index) {
|
|
unexcused = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay == 0 && e.state == Justification.unexcused)
|
|
.toList();
|
|
excused = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay == 0 && e.state == Justification.excused)
|
|
.toList();
|
|
pending = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay == 0 && e.state == Justification.pending)
|
|
.toList();
|
|
|
|
value1 = excused.length;
|
|
value2 = unexcused.length;
|
|
value3 = pending.length;
|
|
title1 = "stat_1".i18n;
|
|
title2 = "stat_2".i18n;
|
|
suffix = " ${"hr".i18n}";
|
|
} else if (activeData == AbsenceFilter.delays.index) {
|
|
unexcused = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay != 0 && e.state == Justification.unexcused)
|
|
.toList();
|
|
excused = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay != 0 && e.state == Justification.excused)
|
|
.toList();
|
|
pending = absenceProvider.absences
|
|
.where((e) =>
|
|
e.delay != 0 && e.state == Justification.pending)
|
|
.toList();
|
|
|
|
value1 = excused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
|
value2 =
|
|
unexcused.map((e) => e.delay).fold(0, (a, b) => a + b);
|
|
value3 = pending.map((e) => e.delay).fold(0, (a, b) => a + b);
|
|
title1 = "stat_3".i18n;
|
|
title2 = "stat_4".i18n;
|
|
suffix = " ${"min".i18n}";
|
|
}
|
|
|
|
// bar chart magic
|
|
List<AbsenceChartData> absenceChartData = [];
|
|
|
|
int yr = DateTime.now().month < 9
|
|
? DateTime.now().year - 1
|
|
: DateTime.now().year;
|
|
int barTotal =
|
|
DateTime.now().difference(DateTime(yr, 09, 01)).inDays;
|
|
|
|
[...unexcused, ...excused, ...pending].forEachIndexed((i, a) {
|
|
int abs = DateTime.now().difference(a.date).inDays;
|
|
|
|
double startPos = (barTotal - abs) / barTotal;
|
|
double endPos = startPos + (barTotal / 100 / barTotal);
|
|
|
|
if (absenceChartData.isEmpty) {
|
|
absenceChartData.add(AbsenceChartData(
|
|
start: 0.0,
|
|
end: startPos,
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
));
|
|
}
|
|
absenceChartData.add(AbsenceChartData(
|
|
start: startPos,
|
|
end: endPos,
|
|
color: a.state == Justification.excused
|
|
? Colors.green
|
|
: a.state == Justification.unexcused
|
|
? Colors.red
|
|
: Colors.orange,
|
|
));
|
|
if ([...unexcused, ...excused, ...pending].length > i + 1) {
|
|
int nextAbs = DateTime.now()
|
|
.difference(
|
|
[...unexcused, ...excused, ...pending][i + 1].date)
|
|
.inDays;
|
|
|
|
double nextStartPos = (barTotal - nextAbs) / barTotal;
|
|
// double nextEndPos = startPos + (barTotal / 100 / barTotal);
|
|
|
|
absenceChartData.add(AbsenceChartData(
|
|
start: endPos,
|
|
end: nextStartPos < 0.999 ? nextStartPos : 1.0,
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
));
|
|
}
|
|
|
|
// print(value2.toString() + '-total');
|
|
// print(absenceChartData.length.toString() + '-chartdata');
|
|
if ((i + 1 ==
|
|
[...unexcused, ...excused, ...pending].length) &&
|
|
endPos < 0.999) {
|
|
absenceChartData.add(AbsenceChartData(
|
|
start: endPos,
|
|
end: 1.0,
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
));
|
|
}
|
|
});
|
|
|
|
for (var aP in absenceChartData) {
|
|
absencePositions.addAll([aP.start, aP.end]);
|
|
}
|
|
|
|
for (var aC in absenceChartData) {
|
|
finalChartColors.addAll([aC.color, aC.color]);
|
|
}
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(
|
|
bottom: 20.0, left: 24.0, right: 24.0),
|
|
child: Row(children: [
|
|
Expanded(
|
|
child: SplittedPanel(
|
|
padding: EdgeInsets.zero,
|
|
cardPadding: const EdgeInsets.symmetric(
|
|
vertical: 16.0,
|
|
horizontal: 18.0,
|
|
),
|
|
spacing: 8.0,
|
|
children: [
|
|
Column(
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
value1.toString() + suffix,
|
|
style: TextStyle(
|
|
fontSize: 18.0,
|
|
fontWeight: FontWeight.w700,
|
|
color: value1 > 0
|
|
? AppColors.of(context).green
|
|
: AppColors.of(context).text,
|
|
),
|
|
),
|
|
Text(
|
|
title1,
|
|
style: TextStyle(
|
|
fontSize: 16.0,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1.1,
|
|
color: value1 > 0
|
|
? ColorsUtils().fade(
|
|
context,
|
|
AppColors.of(context).green,
|
|
darkenAmount: 0.5,
|
|
lightenAmount: 0.4,
|
|
)
|
|
: AppColors.of(context).text,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
width: 18.0,
|
|
),
|
|
Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
value2.toString() + suffix,
|
|
style: TextStyle(
|
|
fontSize: 18.0,
|
|
fontWeight: FontWeight.w700,
|
|
color: value2 > 0
|
|
? AppColors.of(context).red
|
|
: AppColors.of(context).text,
|
|
),
|
|
),
|
|
Text(
|
|
title2,
|
|
style: TextStyle(
|
|
fontSize: 16.0,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1.1,
|
|
color: value2 > 0
|
|
? ColorsUtils().fade(
|
|
context,
|
|
AppColors.of(context).red,
|
|
darkenAmount: 0.4,
|
|
lightenAmount: 0.2,
|
|
)
|
|
: AppColors.of(context).text,
|
|
),
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 18.0,
|
|
),
|
|
Column(
|
|
children: [
|
|
Container(
|
|
height: 9.11,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(20.0),
|
|
color: Theme.of(context)
|
|
.scaffoldBackgroundColor,
|
|
gradient: LinearGradient(
|
|
colors: finalChartColors,
|
|
stops: absencePositions,
|
|
begin: Alignment.centerLeft,
|
|
end: Alignment.centerRight,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 3.0,
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
"sept".i18n,
|
|
),
|
|
Text("now".i18n),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(
|
|
Icons.av_timer_rounded,
|
|
color: value3 > 0 ? Colors.orange : null,
|
|
),
|
|
const SizedBox(
|
|
width: 10.0,
|
|
),
|
|
Text(
|
|
"pending".i18n,
|
|
style: const TextStyle(
|
|
fontSize: 16.0,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Text(
|
|
value3.toString() + suffix,
|
|
style: TextStyle(
|
|
fontSize: 16.0,
|
|
fontWeight: FontWeight.w500,
|
|
color: AppColors.of(context)
|
|
.text
|
|
.withValues(alpha: 0.8),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// Expanded(
|
|
// child: StatisticsTile(
|
|
// title: AutoSizeText(
|
|
// title1,
|
|
// textAlign: TextAlign.center,
|
|
// maxLines: 2,
|
|
// overflow: TextOverflow.ellipsis,
|
|
// ),
|
|
// valueSuffix: suffix,
|
|
// value: value1.toDouble(),
|
|
// decimal: false,
|
|
// showZero: true,
|
|
// color: AppColors.of(context).green,
|
|
// ),
|
|
// ),
|
|
// const SizedBox(width: 24.0),
|
|
// Expanded(
|
|
// child: StatisticsTile(
|
|
// title: AutoSizeText(
|
|
// title2,
|
|
// textAlign: TextAlign.center,
|
|
// maxLines: 2,
|
|
// overflow: TextOverflow.ellipsis,
|
|
// ),
|
|
// valueSuffix: suffix,
|
|
// value: value2.toDouble(),
|
|
// decimal: false,
|
|
// showZero: true,
|
|
// color: AppColors.of(context).red,
|
|
// ),
|
|
// ),
|
|
]),
|
|
);
|
|
}
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(
|
|
left: 24.0, right: 24.0, bottom: 12.0),
|
|
child: filterWidgets[index - (activeData <= 1 ? 1 : 0)],
|
|
);
|
|
} else {
|
|
return activeData == 1
|
|
? Empty(subtitle: "emptyDelays".i18n)
|
|
: Empty(subtitle: "emptyMisses".i18n);
|
|
}
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|