forked from firka/firka
feat: show class grades
This commit is contained in:
@@ -495,6 +495,51 @@ class KretaClient {
|
||||
return (resp, statusCode, null, false);
|
||||
}
|
||||
|
||||
ApiResponse<List<ClassGroupSubjectAverage>>? classGroupAveragesCache;
|
||||
|
||||
Future<ApiResponse<List<ClassGroupSubjectAverage>>> getClassGroupAverages(
|
||||
ClassGroup classGroup, {
|
||||
bool forceCache = true,
|
||||
}) async {
|
||||
String? err;
|
||||
if (classGroup.studyTask == null) {
|
||||
err = "classGroup.studyTask is null";
|
||||
logger.warning(err);
|
||||
return ApiResponse([], 0, err, false);
|
||||
}
|
||||
if (!forceCache) {
|
||||
classGroupAveragesCache = null;
|
||||
} else if (classGroupAveragesCache != null) {
|
||||
return classGroupAveragesCache!;
|
||||
}
|
||||
var studyTaskUid = classGroup.studyTask!.uid.toString().split(",").first;
|
||||
var (resp, status, ex, cached) = await _cachingGet(
|
||||
CacheId.getClassGroupAvg,
|
||||
KretaEndpoints.getClassGroupAvg(model.iss!, studyTaskUid),
|
||||
forceCache,
|
||||
0,
|
||||
);
|
||||
|
||||
var items = List<ClassGroupSubjectAverage>.empty(growable: true);
|
||||
try {
|
||||
List<dynamic> rawItems = resp;
|
||||
for (var item in rawItems) {
|
||||
items.add(ClassGroupSubjectAverage.fromJson(item));
|
||||
}
|
||||
} catch (ex) {
|
||||
err = ex.toString();
|
||||
}
|
||||
|
||||
if (ex != null) {
|
||||
err = ex.toString();
|
||||
}
|
||||
|
||||
if (ex == null) {
|
||||
classGroupAveragesCache = ApiResponse(items, 200, null, true);
|
||||
}
|
||||
return ApiResponse(items, status, err, cached);
|
||||
}
|
||||
|
||||
ApiResponse<Student>? studentCache;
|
||||
|
||||
Future<ApiResponse<Student>> getStudent({bool forceCache = true}) async {
|
||||
|
||||
@@ -84,6 +84,9 @@ class KretaEndpoints {
|
||||
static String getClassGroups(String iss) =>
|
||||
ka.KretaEndpoints.getClassGroups(iss);
|
||||
|
||||
static String getClassGroupAvg(String iss, String studyGroupId) =>
|
||||
ka.KretaEndpoints.getClassGroupAvg(iss, studyGroupId);
|
||||
|
||||
static String getNoticeBoard(String iss) =>
|
||||
ka.KretaEndpoints.getNoticeBoard(iss);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ enum CacheId {
|
||||
getSubjectAvg,
|
||||
getLessons,
|
||||
getHomework,
|
||||
getClassGroupAvg,
|
||||
}
|
||||
|
||||
@collection
|
||||
|
||||
@@ -344,7 +344,7 @@ Future<void> showGradeBottomSheet(
|
||||
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
GradeSmallCard([], grade.subject),
|
||||
GradeSmallCard([], null, grade.subject),
|
||||
SizedBox(height: 10),
|
||||
FirkaCard(
|
||||
margin: EdgeInsets.all(0),
|
||||
@@ -384,7 +384,6 @@ Future<void> showGradeBottomSheet(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
context.go('/grades/subject', extra: grade.subject);
|
||||
},
|
||||
),
|
||||
@@ -407,7 +406,7 @@ Future<void> showHomeworkBottomSheet(
|
||||
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
GradeSmallCard([], homework.subject),
|
||||
GradeSmallCard([], null, homework.subject),
|
||||
SizedBox(height: 20),
|
||||
Flexible(
|
||||
fit: FlexFit.loose,
|
||||
|
||||
@@ -34,6 +34,7 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
ApiResponse<List<Lesson>>? week;
|
||||
ApiResponse<List<ClassGroup>>? classGroups;
|
||||
ApiResponse<List<SubjectAverage>>? lessons;
|
||||
ApiResponse<List<ClassGroupSubjectAverage>>? classAvgs;
|
||||
|
||||
void _onRefreshRequested(BuildContext context) async {
|
||||
final cubit = context.read<HomeRefreshCubit>();
|
||||
@@ -50,6 +51,10 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
group,
|
||||
forceCache: false,
|
||||
);
|
||||
classAvgs = await widget.data.client.getClassGroupAverages(
|
||||
group,
|
||||
forceCache: false,
|
||||
);
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
}
|
||||
if (mounted) {
|
||||
@@ -73,6 +78,7 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
if (classGroups?.response?.isNotEmpty ?? false) {
|
||||
var group = classGroups!.response!.first;
|
||||
lessons = await widget.data.client.getSubjectAverage(group);
|
||||
classAvgs = await widget.data.client.getClassGroupAverages(group);
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
}
|
||||
if (mounted) setState(() {});
|
||||
@@ -92,7 +98,10 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
}
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
if (grades == null || week == null) {
|
||||
if (grades == null ||
|
||||
lessons == null ||
|
||||
classAvgs == null ||
|
||||
week == null) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 1.35,
|
||||
child: Column(
|
||||
@@ -105,6 +114,13 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
final allLessons = lessons!.response!;
|
||||
|
||||
final subjectAverage = allGrades.getSubjectAverage();
|
||||
final classAverages = classAvgs!.response!
|
||||
.map((c) => c.classGroupAverage)
|
||||
.nonNulls;
|
||||
|
||||
double? classAverage = classAverages.isNotEmpty
|
||||
? classAverages.reduce((f, s) => f + s)
|
||||
: null;
|
||||
|
||||
final Set<Subject> subjects = HashSet(
|
||||
hashCode: (s) => s.uid.hashCode,
|
||||
@@ -119,7 +135,13 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
in subjects.toList()..sort((s1, s2) => s1.name.compareTo(s2.name))) {
|
||||
gradeCards.add(
|
||||
GestureDetector(
|
||||
child: GradeSmallCard(allGrades, subject),
|
||||
child: GradeSmallCard(
|
||||
allGrades,
|
||||
classAvgs!.response!
|
||||
.firstWhereOrNull((s) => s.subject.uid == subject.uid)
|
||||
?.classGroupAverage,
|
||||
subject,
|
||||
),
|
||||
onTap: () {
|
||||
context.go('/grades/subject', extra: subject);
|
||||
},
|
||||
@@ -209,6 +231,30 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
),
|
||||
),
|
||||
],
|
||||
right: [
|
||||
if (classAverage != null)
|
||||
Container(
|
||||
width: 48,
|
||||
height: 26,
|
||||
decoration: ShapeDecoration(
|
||||
color: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: getGradeColor(classAverage),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
classAverage.toStringAsFixed(2),
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: getGradeColor(classAverage),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
FirkaCard(
|
||||
left: [
|
||||
|
||||
@@ -7,11 +7,16 @@ import 'package:firka_common/ui/shared/class_icon.dart';
|
||||
import 'package:firka_common/ui/theme/style.dart';
|
||||
|
||||
class GradeSmallCard extends StatelessWidget {
|
||||
final double? average;
|
||||
final double? studentAverage;
|
||||
final double? classAverage;
|
||||
final Subject subject;
|
||||
|
||||
GradeSmallCard(List<Grade> grades, this.subject, {super.key})
|
||||
: average = grades.getAverageBySubject(subject);
|
||||
GradeSmallCard(
|
||||
List<Grade> grades,
|
||||
this.classAverage,
|
||||
this.subject, {
|
||||
super.key,
|
||||
}) : studentAverage = grades.getAverageBySubject(subject);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -38,26 +43,45 @@ class GradeSmallCard extends StatelessWidget {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
average == null
|
||||
? const SizedBox()
|
||||
: Container(
|
||||
width: 48,
|
||||
height: 26,
|
||||
decoration: ShapeDecoration(
|
||||
color: getGradeColor(average!).withAlpha(38),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
average!.toStringAsFixed(2),
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: getGradeColor(average!),
|
||||
),
|
||||
),
|
||||
if (classAverage != null)
|
||||
Container(
|
||||
width: 48,
|
||||
height: 26,
|
||||
decoration: ShapeDecoration(
|
||||
color: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: getGradeColor(classAverage!)),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
classAverage!.toStringAsFixed(2),
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: getGradeColor(classAverage!),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (studentAverage != null)
|
||||
Container(
|
||||
width: 48,
|
||||
height: 26,
|
||||
decoration: ShapeDecoration(
|
||||
color: getGradeColor(studentAverage!).withAlpha(38),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
studentAverage!.toStringAsFixed(2),
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: getGradeColor(studentAverage!),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -29,6 +29,9 @@ class KretaEndpoints {
|
||||
static String getSubjectAvg(String iss, String studyGroupId) =>
|
||||
"${kreta(iss)}/ellenorzo/v3/sajat/Ertekelesek/Atlagok/TantargyiAtlagok?oktatasiNevelesiFeladatUid=$studyGroupId&oktatasiNevelesiFeladatUid=$studyGroupId";
|
||||
|
||||
static String getClassGroupAvg(String iss, String studyGroupId) =>
|
||||
"${kreta(iss)}/ellenorzo/v3/sajat/Ertekelesek/Atlagok/OsztalyAtlagok?oktatasiNevelesiFeladatUid=$studyGroupId&oktatasiNevelesiFeladatUid=$studyGroupId";
|
||||
|
||||
static String getTimeTable(String iss) =>
|
||||
"${kreta(iss)}/ellenorzo/v3/sajat/OrarendElemek";
|
||||
|
||||
|
||||
@@ -84,3 +84,30 @@ class SubjectAverage extends UidObj {
|
||||
return 'SubjectAverage(uid: "$uid", name: "${subject.name}", category: "${subject.category.name}", average: $average)';
|
||||
}
|
||||
}
|
||||
|
||||
class ClassGroupSubjectAverage extends UidObj {
|
||||
final Subject subject;
|
||||
final double? studentAverage;
|
||||
final double? classGroupAverage;
|
||||
|
||||
ClassGroupSubjectAverage({
|
||||
required super.uid,
|
||||
required this.subject,
|
||||
this.classGroupAverage,
|
||||
this.studentAverage,
|
||||
});
|
||||
|
||||
factory ClassGroupSubjectAverage.fromJson(Map<String, dynamic> json) {
|
||||
return ClassGroupSubjectAverage(
|
||||
uid: json['Uid'],
|
||||
subject: Subject.fromJson(json['Tantargy']),
|
||||
studentAverage: json.dbl('TanuloAtlag'),
|
||||
classGroupAverage: json.dbl('OsztalyCsoportAtlag'),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ClassGroupSubjectAverage(uid: "$uid", subject: $subject)';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user