1
0
forked from firka/firka

fix: grade subjects page design

This commit is contained in:
checkedear
2026-04-21 22:34:58 +02:00
parent 55dbf12a2f
commit ad9e2c6676
2 changed files with 477 additions and 502 deletions

View File

@@ -1,5 +1,6 @@
import 'package:firka/ui/phone/widgets/grade_summary_bar.dart';
import 'package:firka/ui/phone/widgets/info_card.dart';
import 'package:firka_common/ui/components/filled_circle.dart';
import 'package:kreta_api/kreta_api.dart';
import 'package:firka/core/extensions.dart';
import 'package:firka/ui/components/common_bottom_sheets.dart';
@@ -106,70 +107,122 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
}
Widget _buildContent(BuildContext context) {
if (grades != null && grades!.isNotEmpty && activeSubjectUid != "") {
var aGrade = grades!.first;
var groups = grades!.groupList((grade) => grade.recordDate);
final ghostGradeWidgets = _ghostEntries.reversed.map((e) {
return GestureDetector(
child: FirkaCard(
left: [
if (grades == null || grades!.isEmpty || activeSubjectUid == "") {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
GradeWidget.gradeValue(e.$1, gradeWeight: e.$2),
SizedBox(width: 8),
Text(
'${widget.data.l10n.ghost_grade} ${e.$2}%',
style: appStyle.fonts.B_16SB.apply(
color: appStyle.colors.textPrimary,
Transform.translate(
offset: const Offset(-4, 0),
child: GestureDetector(
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.chevronLeftLine,
color: appStyle.colors.textSecondary,
),
onTap: () {
context.pop();
},
),
),
],
),
],
),
onTap: () {},
);
}).toList();
var gradeWidgets = List<Widget>.empty(growable: true);
if (ghostGradeWidgets.isNotEmpty) {
gradeWidgets.add(
Text(
widget.data.l10n.ghost_grades,
Transform.translate(
offset: const Offset(-4, 1),
child: Text(
widget.data.l10n.subjects,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textPrimary,
),
),
);
gradeWidgets.addAll(ghostGradeWidgets);
}
for (var group in groups.entries) {
gradeWidgets.add(SizedBox(height: 8));
gradeWidgets.add(
),
],
),
SizedBox(height: 16),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
color: appStyle.colors.a15p,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: EdgeInsetsGeometry.all(6),
child: ClassIconWidget(
uid: subjectId,
className: subjectName,
category: subjectCategory,
color: appStyle.colors.accent,
),
),
),
SizedBox(height: 8),
Text(
group.key.format(widget.data.l10n, FormatMode.grades),
style: appStyle.fonts.H_14px.apply(
subjectName,
style: appStyle.fonts.H_H2.apply(
color: appStyle.colors.textPrimary,
),
),
SizedBox(height: 2),
Text(
widget.data.l10n.unknown_teacher,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textSecondary,
),
),
Expanded(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
"assets/images/logos/dave.svg",
width: 48,
height: 48,
),
SizedBox(height: 12),
Text(
widget.data.l10n.no_grades,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textSecondary,
),
),
],
),
),
),
],
),
),
],
),
);
gradeWidgets.add(SizedBox(height: 8));
for (var grade in group.value) {
gradeWidgets.add(InfoCard.gradeDesc(grade));
}
}
var aGrade = grades!.first;
return Material(
color: appStyle.colors.background,
child: Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
final ghostGradeWidgets = _ghostEntries.indexed
.map((e) {
return InfoCard.gradeGhost(
e.$2.$1,
e.$2.$2,
onTap: (ctx) {
setState(() {
_ghostEntries.removeAt(e.$1);
});
},
);
})
.toList()
.reversed;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 12),
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -226,185 +279,94 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
),
],
),
],
),
SizedBox(height: 16),
SizedBox(height: 24),
Expanded(
child: ListView(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
FilledCircle(
diameter: 36,
color: appStyle.colors.a15p,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: EdgeInsetsGeometry.all(6),
child: ClassIconWidget(
uid: aGrade.subject.uid,
className: aGrade.subject.name,
category: aGrade.subject.category.name!,
color: appStyle.colors.accent,
size: 24,
),
),
),
SizedBox(height: 8),
SizedBox(height: 16),
Text(
aGrade.subject.name,
style: appStyle.fonts.H_H2.apply(
color: appStyle.colors.textPrimary,
),
),
SizedBox(height: 2),
SizedBox(height: 4),
Text(
aGrade.teacher,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textSecondary,
),
),
SizedBox(height: 15),
],
),
SizedBox(height: 24),
GradeChartWithInteraction(
grades: _gradesWithGhosts(aGrade.subject),
),
SizedBox(height: 2),
SizedBox(height: 10),
GradeSummaryBar(
grades: _gradesWithGhosts(aGrade.subject),
l10n: widget.data.l10n,
showAverage: ghostGradeWidgets.isNotEmpty,
),
SizedBox(height: 12),
Padding(
padding: EdgeInsets.only(left: 4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: gradeWidgets,
),
),
],
),
),
],
),
),
);
} else {
return Material(
color: appStyle.colors.background,
child: Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
child: Column(
SizedBox(height: 20),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 20,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 10,
children: [
Row(
children: [
Transform.translate(
offset: const Offset(-4, 0),
child: GestureDetector(
child: FirkaIconWidget(
FirkaIconType.majesticons,
Majesticon.chevronLeftLine,
color: appStyle.colors.textSecondary,
),
onTap: () {
context.pop();
},
),
),
Transform.translate(
offset: const Offset(-4, 1),
child: Text(
widget.data.l10n.subjects,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textPrimary,
),
),
),
],
),
],
),
SizedBox(height: 16),
SizedBox(
height:
MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
230,
child: ListView(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Card(
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
color: appStyle.colors.a15p,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: EdgeInsetsGeometry.all(6),
child: ClassIconWidget(
uid: subjectId,
className: subjectName,
category: subjectCategory,
color: appStyle.colors.accent,
),
),
),
SizedBox(height: 8),
if (ghostGradeWidgets.isNotEmpty)
Text(
subjectName,
style: appStyle.fonts.H_H2.apply(
color: appStyle.colors.textPrimary,
),
),
SizedBox(height: 2),
Text(
widget.data.l10n.unknown_teacher,
initData.l10n.ghost_grades,
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textSecondary,
),
),
...ghostGradeWidgets,
],
),
SizedBox(
height:
MediaQuery.of(context).size.height -
MediaQuery.of(context).padding.top -
320,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
...grades!
.groupList((e) => e.recordDate)
.entries
.map(
(e) => Column(
spacing: 10,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(
"assets/images/logos/dave.svg",
width: 48,
height: 48,
),
SizedBox(height: 12),
Text(
widget.data.l10n.no_grades,
e.key.format(widget.data.l10n, FormatMode.main),
style: appStyle.fonts.B_16R.apply(
color: appStyle.colors.textSecondary,
),
),
],
),
),
),
...e.value.map((v) => InfoCard.gradeDesc(v)),
],
),
),
],
),
],
),
),
],
),
);
}
}
}

View File

@@ -156,6 +156,19 @@ class InfoCard extends StatelessWidget {
);
}
factory InfoCard.gradeGhost(
int gradeValue,
int gradeWeigth, {
void Function(BuildContext)? onTap,
}) {
return InfoCard(
icon: GradeWidget.gradeValue(gradeValue, gradeWeight: gradeWeigth),
texts: ["${initData.l10n.ghost_grade} ($gradeWeigth%)"],
right: [],
onTap: onTap,
);
}
factory InfoCard.gradeDesc(
Grade grade, {
void Function(BuildContext)? onTap,