forked from firka/firka
778 lines
23 KiB
Dart
778 lines
23 KiB
Dart
import 'package:firka/ui/phone/widgets/info_card.dart';
|
|
import 'package:firka_common/ui/components/filled_circle.dart';
|
|
import 'package:firka_common/ui/shared/grade_small_card.dart';
|
|
import 'package:kreta_api/kreta_api.dart';
|
|
import 'package:firka/data/models/homework_cache_model.dart';
|
|
import 'package:firka/core/extensions.dart';
|
|
import 'package:firka/core/settings.dart';
|
|
import 'package:firka/ui/shared/firka_icon.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_html/flutter_html.dart';
|
|
import 'package:flutter_svg/svg.dart';
|
|
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'package:firka/app/app_state.dart';
|
|
import 'package:firka/ui/theme/style.dart';
|
|
import 'package:firka/ui/phone/widgets/lesson.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:firka/ui/shared/class_icon.dart';
|
|
import 'package:firka/ui/components/firka_card.dart';
|
|
import 'package:firka/ui/components/grade.dart';
|
|
import 'package:firka/ui/components/grade_helpers.dart';
|
|
|
|
Future<void> showFirkaBottomSheet(
|
|
BuildContext context,
|
|
List<Widget> children,
|
|
) async {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
elevation: 100,
|
|
isScrollControlled: true,
|
|
enableDrag: true,
|
|
backgroundColor: Colors.transparent,
|
|
barrierColor: appStyle.colors.a15p,
|
|
builder: (BuildContext context) => Stack(
|
|
children: [
|
|
Positioned.fill(child: GestureDetector(onTap: () => context.pop())),
|
|
Align(
|
|
alignment: AlignmentGeometry.bottomCenter,
|
|
child: Container(
|
|
padding: const EdgeInsets.all(20) - EdgeInsets.only(top: 20),
|
|
decoration: BoxDecoration(
|
|
color: appStyle.colors.background,
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Align(
|
|
heightFactor: 0,
|
|
alignment: Alignment.topCenter,
|
|
child: Container(
|
|
margin: EdgeInsets.only(top: 18),
|
|
width: 40,
|
|
height: 4,
|
|
foregroundDecoration: ShapeDecoration(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadiusGeometry.circular(2),
|
|
),
|
|
color: appStyle.colors.shadowColor,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 40),
|
|
...children,
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> showLessonBottomSheet(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Lesson lesson,
|
|
Color accent,
|
|
Color secondary,
|
|
Color bgColor,
|
|
Test? test,
|
|
) async {
|
|
final statsForNerdsEnabled = data.settings
|
|
.group("settings")
|
|
.subGroup("developer")
|
|
.boolean("stats_for_nerds");
|
|
|
|
Widget? statsForNerds;
|
|
|
|
final y2k = DateTime(2000, 1);
|
|
|
|
if (statsForNerdsEnabled) {
|
|
final stats =
|
|
"${data.l10n.stats_date}: ${lesson.start.isAfter(y2k) ? lesson.start.format(data.l10n, FormatMode.yyyymmddhhmmss) : "N/A"}\n"
|
|
"${data.l10n.stats_created_at}: ${lesson.createdAt.isAfter(y2k) ? lesson.createdAt.format(data.l10n, FormatMode.yyyymmddhhmmss) : "N/A"}\n"
|
|
"${data.l10n.stats_last_mod}: ${lesson.lastModifiedAt.isAfter(y2k) ? lesson.lastModifiedAt.format(data.l10n, FormatMode.yyyymmddhhmmss) : "N/A"}";
|
|
statsForNerds = Text(
|
|
stats,
|
|
style: appStyle.fonts.B_16R.apply(color: appStyle.colors.textPrimary),
|
|
);
|
|
}
|
|
showFirkaBottomSheet(context, [
|
|
Row(
|
|
children: [
|
|
lesson.lessonNumber == null
|
|
? SizedBox()
|
|
: SizedBox(
|
|
width: 24,
|
|
height: 24,
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
SvgPicture.asset(
|
|
"assets/icons/subtract.svg",
|
|
color: bgColor,
|
|
width: 24,
|
|
height: 24,
|
|
),
|
|
Text(
|
|
lesson.lessonNumber!.toString(),
|
|
style: appStyle.fonts.B_16R.apply(color: secondary),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
FilledCircle(
|
|
diameter: 40,
|
|
color: bgColor,
|
|
child: ClassIconWidget.subject(
|
|
subject: lesson.subject!,
|
|
color: accent,
|
|
size: 26,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 20),
|
|
Row(
|
|
children: [
|
|
Text(
|
|
"${lesson.name} ${statsForNerdsEnabled ? "(${lesson.classGroup?.name ?? ''})" : ""}",
|
|
style: appStyle.fonts.H_18px.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 2),
|
|
Text(
|
|
lesson.teacher ?? 'N/A',
|
|
style: appStyle.fonts.B_14R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
decoration: lesson.substituteTeacher != null
|
|
? TextDecoration.lineThrough
|
|
: TextDecoration.none,
|
|
),
|
|
),
|
|
if (lesson.substituteTeacher != null)
|
|
Text(
|
|
lesson.substituteTeacher!,
|
|
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
|
),
|
|
SizedBox(height: 8),
|
|
Text(
|
|
'${lesson.start.format(data.l10n, FormatMode.hmm)} - ${lesson.end.format(data.l10n, FormatMode.hmm)}',
|
|
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
|
),
|
|
SizedBox(height: 20),
|
|
FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
padding: EdgeInsets.all(14),
|
|
left: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
spacing: 8,
|
|
children: [
|
|
Text(
|
|
data.l10n.lesson_subject,
|
|
style: appStyle.fonts.H_14px.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: MediaQuery.of(context).size.width * 0.7,
|
|
child: Text(
|
|
lesson.theme ?? 'N/A',
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
maxLines: 3,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
?statsForNerds,
|
|
],
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 6),
|
|
if (test != null) InfoCard.testDesc(test),
|
|
SizedBox(height: 16),
|
|
GestureDetector(
|
|
child: FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
left: [],
|
|
center: [
|
|
Text(
|
|
data.l10n.view_subject_btn,
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
color: appStyle.colors.buttonSecondaryFill,
|
|
),
|
|
onTap: () {
|
|
context.go('/timetable/subject', extra: lesson.subject);
|
|
},
|
|
),
|
|
]);
|
|
}
|
|
|
|
Future<void> showTestBottomSheet(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Test test,
|
|
) async {
|
|
final date = test.date;
|
|
final formattedDate =
|
|
"${date.format(data.l10n, FormatMode.yearly).firstUpper()}, ${DateFormat.EEEE(data.l10n.localeName).format(date).firstUpper()}";
|
|
|
|
showFirkaBottomSheet(context, [
|
|
FilledCircle(
|
|
diameter: 40,
|
|
color: appStyle.colors.a15p,
|
|
child: FirkaIconWidget(
|
|
FirkaIconType.majesticons,
|
|
Majesticon.editPen4Solid,
|
|
size: 26.0,
|
|
color: appStyle.colors.accent,
|
|
),
|
|
),
|
|
SizedBox(height: 20),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
mainAxisSize: MainAxisSize.min,
|
|
spacing: 4,
|
|
children: [
|
|
Text(
|
|
"${test.theme}",
|
|
style: appStyle.fonts.H_18px.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
Text(
|
|
test.method.description,
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 20),
|
|
FirkaCard.single(
|
|
height: 48,
|
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
|
margin: EdgeInsets.all(0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
"${data.l10n.date}: $formattedDate",
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 10),
|
|
FirkaCard.single(
|
|
height: 64,
|
|
margin: EdgeInsets.all(0),
|
|
padding: EdgeInsets.only(left: 14, right: 16),
|
|
color: appStyle.colors.card,
|
|
child: Column(
|
|
spacing: 12,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
SizedBox(
|
|
width: 18,
|
|
height: 18,
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
SvgPicture.asset(
|
|
"assets/icons/subtract.svg",
|
|
color: appStyle.colors.a15p,
|
|
width: 18,
|
|
height: 18,
|
|
),
|
|
Text(
|
|
test.lessonNumber.toString(),
|
|
style: appStyle.fonts.B_14SB.apply(
|
|
color: appStyle.colors.secondary,
|
|
),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
FilledCircle(
|
|
diameter: 36,
|
|
color: appStyle.colors.a15p,
|
|
child: ClassIconWidget(
|
|
uid: test.uid,
|
|
className: test.subjectName,
|
|
category: test.subject.name,
|
|
color: appStyle.colors.accent,
|
|
size: 24,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
test.subject.name,
|
|
style: appStyle.fonts.B_16SB.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
]);
|
|
}
|
|
|
|
Future<void> showGradeBottomSheet(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Grade grade,
|
|
) async {
|
|
showFirkaBottomSheet(context, [
|
|
grade.numericValue == null
|
|
? Container(
|
|
height: 40,
|
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
|
decoration: ShapeDecoration(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(20),
|
|
),
|
|
color: appStyle.colors.a15p,
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
grade.strValue,
|
|
style: appStyle.fonts.H_18px.apply(
|
|
color: appStyle.colors.accent,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
: GradeWidget(grade, size: 40),
|
|
SizedBox(height: 20),
|
|
Text(
|
|
(grade.topic ?? grade.type.description).firstUpper(),
|
|
style: appStyle.fonts.H_18px.apply(color: appStyle.colors.textPrimary),
|
|
),
|
|
grade.mode != null
|
|
? Text(
|
|
grade.mode!.description,
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
),
|
|
)
|
|
: SizedBox(),
|
|
SizedBox(height: 8),
|
|
Text(
|
|
grade.recordDate.format(data.l10n, FormatMode.yyyymmdd),
|
|
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
|
),
|
|
SizedBox(height: 20),
|
|
GradeSmallCard([], null, grade.subject),
|
|
SizedBox(height: 10),
|
|
FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
left: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"${data.l10n.grade_teacherName}${grade.teacher}",
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
Text(
|
|
"${data.l10n.tt_added}${grade.creationDate.format(data.l10n, FormatMode.yyyymmdd)}",
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 20),
|
|
GestureDetector(
|
|
child: FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
left: [],
|
|
center: [
|
|
Text(
|
|
data.l10n.view_subject_btn,
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
color: appStyle.colors.buttonSecondaryFill,
|
|
),
|
|
onTap: () {
|
|
context.go('/grades/subject', extra: grade.subject);
|
|
},
|
|
),
|
|
]);
|
|
}
|
|
|
|
Future<void> showHomeworkBottomSheet(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Homework homework,
|
|
) async {
|
|
showFirkaBottomSheet(context, [
|
|
Text(
|
|
data.l10n.homework,
|
|
style: appStyle.fonts.H_18px.apply(color: appStyle.colors.textPrimary),
|
|
),
|
|
SizedBox(height: 4),
|
|
Text(
|
|
homework.dueDate.format(data.l10n, FormatMode.yyyymmdd),
|
|
style: appStyle.fonts.B_14R.apply(color: appStyle.colors.textSecondary),
|
|
),
|
|
SizedBox(height: 20),
|
|
GradeSmallCard([], null, homework.subject),
|
|
SizedBox(height: 20),
|
|
Flexible(
|
|
fit: FlexFit.loose,
|
|
child: FirkaCard.single(
|
|
margin: EdgeInsets.all(0),
|
|
padding: EdgeInsets.all(12),
|
|
child: Html(
|
|
data: homework.description,
|
|
style: {
|
|
"*": Style.fromTextStyle(
|
|
appStyle.fonts.B_16R.apply(color: appStyle.colors.textPrimary),
|
|
),
|
|
},
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 20),
|
|
FutureBuilder<bool>(
|
|
future: isHomeworkDone(data.isar, homework.uid),
|
|
builder: (context, snapshot) {
|
|
if (!snapshot.hasData) {
|
|
return SizedBox(); // or a loading indicator
|
|
}
|
|
|
|
final done = snapshot.data!;
|
|
|
|
return Column(
|
|
children: [
|
|
GestureDetector(
|
|
child: FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
left: [],
|
|
center: [
|
|
Text(
|
|
!done ? data.l10n.mark_as_done : data.l10n.mark_as_not_done,
|
|
style: appStyle.fonts.B_16SB.apply(
|
|
color: appStyle.colors.textPrimaryLight,
|
|
),
|
|
),
|
|
],
|
|
color: appStyle.colors.accent,
|
|
),
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
!done
|
|
? markAsDone(data.isar, homework.uid)
|
|
: markAsNotDone(data.isar, homework.uid);
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
SizedBox(height: 8),
|
|
GestureDetector(
|
|
child: FirkaCard(
|
|
margin: EdgeInsets.all(0),
|
|
left: [],
|
|
center: [
|
|
Text(
|
|
data.l10n.view_subject_btn,
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textSecondary,
|
|
),
|
|
),
|
|
],
|
|
color: appStyle.colors.buttonSecondaryFill,
|
|
),
|
|
onTap: () {
|
|
context.go('/home/subject', extra: homework.subject);
|
|
},
|
|
),
|
|
]);
|
|
}
|
|
|
|
Future<void> showGradeCalculatorBottomSheet(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Subject subject, {
|
|
void Function(int grade, int weight)? onAdd,
|
|
}) async {
|
|
showFirkaBottomSheet(context, [
|
|
_GradeCalculatorSheetContent(data: data, subject: subject, onAdd: onAdd),
|
|
]);
|
|
}
|
|
|
|
class _GradeCalculatorSheetContent extends StatefulWidget {
|
|
final AppInitialization data;
|
|
final Subject subject;
|
|
final void Function(int grade, int weight)? onAdd;
|
|
|
|
const _GradeCalculatorSheetContent({
|
|
required this.data,
|
|
required this.subject,
|
|
this.onAdd,
|
|
});
|
|
|
|
@override
|
|
State<_GradeCalculatorSheetContent> createState() =>
|
|
_GradeCalculatorSheetContentState();
|
|
}
|
|
|
|
class _GradeCalculatorSheetContentState
|
|
extends State<_GradeCalculatorSheetContent> {
|
|
int selectedGrade = 3;
|
|
int weightIndex = 1; // 0-based index into _snapPoints
|
|
final List<(int grade, int weight)> entries = [];
|
|
|
|
static const _snapPoints = [50, 100, 200, 300, 400, 500];
|
|
|
|
int get weightPercent => _snapPoints[weightIndex];
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
widget.data.l10n.grade_calculator,
|
|
style: appStyle.fonts.H_H2.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
),
|
|
GestureDetector(
|
|
onTap: () => Navigator.pop(context),
|
|
child: Container(
|
|
width: 32,
|
|
height: 32,
|
|
decoration: BoxDecoration(
|
|
color: appStyle.colors.buttonSecondaryFill,
|
|
borderRadius: BorderRadius.circular(8),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: appStyle.colors.shadowColor,
|
|
blurRadius: appStyle.colors.shadowBlur.toDouble(),
|
|
offset: Offset(0, 1),
|
|
),
|
|
],
|
|
),
|
|
child: Icon(
|
|
Icons.close,
|
|
size: 20,
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 20),
|
|
Container(
|
|
height: 64,
|
|
padding: const EdgeInsets.all(6),
|
|
decoration: BoxDecoration(
|
|
color: appStyle.colors.card,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: appStyle.colors.shadowColor,
|
|
blurRadius: appStyle.colors.shadowBlur.toDouble(),
|
|
offset: Offset(0, 1),
|
|
),
|
|
],
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [1, 2, 3, 4, 5].map((grade) {
|
|
final isSelected = selectedGrade == grade;
|
|
return GestureDetector(
|
|
onTap: () => setState(() => selectedGrade = grade),
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 16,
|
|
vertical: 8,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: isSelected
|
|
? getGradeColor(grade.toDouble()).withAlpha(15)
|
|
: Colors.transparent,
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Center(child: GradeWidget.gradeValue(grade, size: 32)),
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
SizedBox(height: 12),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
decoration: BoxDecoration(
|
|
color: appStyle.colors.card,
|
|
borderRadius: BorderRadius.circular(24),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: appStyle.colors.shadowColor,
|
|
blurRadius: appStyle.colors.shadowBlur.toDouble(),
|
|
offset: Offset(0, 1),
|
|
),
|
|
],
|
|
),
|
|
child: SliderTheme(
|
|
data: SliderThemeData(
|
|
activeTrackColor: appStyle.colors.accent,
|
|
inactiveTrackColor: appStyle.colors.card,
|
|
thumbColor: appStyle.colors.accent,
|
|
overlayColor: appStyle.colors.a10p,
|
|
trackHeight: 8,
|
|
),
|
|
child: Slider(
|
|
value: weightIndex.toDouble(),
|
|
min: 0,
|
|
max: (_snapPoints.length - 1).toDouble(),
|
|
divisions: _snapPoints.length - 1,
|
|
label: '${weightPercent}%',
|
|
onChanged: (v) => setState(() => weightIndex = v.round()),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 12),
|
|
SizedBox(
|
|
width: 56,
|
|
child: Text(
|
|
'$weightPercent%',
|
|
style: appStyle.fonts.B_16R.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 12),
|
|
SizedBox(
|
|
width: double.infinity,
|
|
height: 48,
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: appStyle.colors.accent,
|
|
foregroundColor: appStyle.colors.textPrimary,
|
|
elevation: 1,
|
|
shadowColor: appStyle.colors.shadowColor,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
),
|
|
onPressed: () {
|
|
setState(() {
|
|
entries.add((selectedGrade, weightPercent));
|
|
});
|
|
widget.onAdd?.call(selectedGrade, weightPercent);
|
|
},
|
|
child: Text(
|
|
widget.data.l10n.grade_calculator_add,
|
|
style: appStyle.fonts.H_18px.apply(
|
|
color: appStyle.colors.textPrimaryLight,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> showSubjectBottomSheetSettings(
|
|
BuildContext context,
|
|
AppInitialization data,
|
|
Subject subject, {
|
|
void Function(int grade, int weight)? onAddFromCalculator,
|
|
}) async {
|
|
showFirkaBottomSheet(context, [
|
|
Text(
|
|
data.l10n.subject,
|
|
style: appStyle.fonts.H_H2.apply(color: appStyle.colors.textPrimary),
|
|
),
|
|
SizedBox(height: 20),
|
|
GestureDetector(
|
|
onTap: () {
|
|
Navigator.pop(context);
|
|
showGradeCalculatorBottomSheet(
|
|
context,
|
|
data,
|
|
subject,
|
|
onAdd: onAddFromCalculator,
|
|
);
|
|
},
|
|
child: FirkaCard.single(
|
|
margin: EdgeInsets.all(0),
|
|
height: 56,
|
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
|
child: Row(
|
|
children: [
|
|
FirkaIconWidget(
|
|
FirkaIconType.majesticons,
|
|
Majesticon.calculatorSolid,
|
|
size: 24,
|
|
color: appStyle.colors.accent,
|
|
),
|
|
SizedBox(width: 8),
|
|
Text(
|
|
data.l10n.grade_calculator,
|
|
style: appStyle.fonts.B_16SB.apply(
|
|
color: appStyle.colors.textPrimary,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
]);
|
|
}
|