From e7ec9ec272beff3021b82a9b489463be172b1805 Mon Sep 17 00:00:00 2001 From: Sergey Dmitriev <51058739+0niel@users.noreply.github.com> Date: Sat, 6 Jan 2024 23:49:39 +0300 Subject: [PATCH] feat: Create rating system hydrated bloc --- lib/presentation/core/routes/routes.dart | 49 +++-- .../bloc/rating_system_bloc.dart | 62 ++++++ .../bloc/rating_system_bloc.g.dart | 19 ++ .../bloc/rating_system_event.dart | 18 ++ .../bloc/rating_system_state.dart | 55 ++++++ .../models/models.dart | 1 + .../models/subject.dart | 70 +++++++ .../models/subject.g.dart | 30 +++ .../view/about_rating_system_page.dart | 4 - .../view/rating_system_calculator_page.dart | 186 ++++++++---------- .../view/subject_page.dart | 97 +++++++++ .../widgets/short_description_card.dart | 1 - .../widgets/subject_card.dart | 127 ++++++++++++ .../widgets/widgets.dart | 2 + lib/services/view/services_page.dart | 22 +-- 15 files changed, 603 insertions(+), 140 deletions(-) create mode 100644 lib/rating_system_calculator/bloc/rating_system_bloc.dart create mode 100644 lib/rating_system_calculator/bloc/rating_system_bloc.g.dart create mode 100644 lib/rating_system_calculator/bloc/rating_system_event.dart create mode 100644 lib/rating_system_calculator/bloc/rating_system_state.dart create mode 100644 lib/rating_system_calculator/models/models.dart create mode 100644 lib/rating_system_calculator/models/subject.dart create mode 100644 lib/rating_system_calculator/models/subject.g.dart create mode 100644 lib/rating_system_calculator/view/subject_page.dart create mode 100644 lib/rating_system_calculator/widgets/subject_card.dart diff --git a/lib/presentation/core/routes/routes.dart b/lib/presentation/core/routes/routes.dart index 8437bf1a..afd6a3e5 100644 --- a/lib/presentation/core/routes/routes.dart +++ b/lib/presentation/core/routes/routes.dart @@ -22,7 +22,9 @@ import 'package:rtu_mirea_app/presentation/pages/profile/profile_scores_page.dar import 'package:rtu_mirea_app/presentation/pages/profile/profile_page.dart'; import 'package:rtu_mirea_app/presentation/pages/profile/profile_settings_page.dart'; import 'package:rtu_mirea_app/presentation/widgets/images_view_gallery.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart'; import 'package:rtu_mirea_app/rating_system_calculator/view/about_rating_system_page.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/view/subject_page.dart'; import 'package:rtu_mirea_app/schedule/view/schedule_details_page.dart'; import 'package:rtu_mirea_app/rating_system_calculator/view/rating_system_calculator_page.dart'; import 'package:rtu_mirea_app/schedule/view/schedule_page.dart'; @@ -108,25 +110,34 @@ GoRouter createRouter() => GoRouter( ], ), ]), - StatefulShellBranch(navigatorKey: _servicesNavigatorKey, routes: [ - GoRoute( - path: '/services', - builder: (context, state) => const ServicesPage(), - routes: [ - GoRoute( - path: 'rating-system-calculator', - builder: (context, state) => - const RatingSystemCalculatorPage(), - routes: [ - GoRoute( - path: 'about', - builder: (context, state) => - const AboutRatingSystemPage(), - ), - ]), - ], - ), - ]), + StatefulShellBranch( + navigatorKey: _servicesNavigatorKey, + routes: [ + GoRoute( + path: '/services', + builder: (context, state) => const ServicesPage(), + routes: [ + GoRoute( + path: 'rating-system-calculator', + builder: (context, state) => + const RatingSystemCalculatorPage(), + routes: [ + GoRoute( + path: 'about', + builder: (context, state) => + const AboutRatingSystemPage(), + ), + GoRoute( + path: 'subject', + builder: (context, state) => SubjectPage( + subject: state.extra as Subject, + ), + ), + ]), + ], + ), + ], + ), StatefulShellBranch(navigatorKey: _profileNavigatorKey, routes: [ GoRoute( path: '/profile', diff --git a/lib/rating_system_calculator/bloc/rating_system_bloc.dart b/lib/rating_system_calculator/bloc/rating_system_bloc.dart new file mode 100644 index 00000000..aeb0947b --- /dev/null +++ b/lib/rating_system_calculator/bloc/rating_system_bloc.dart @@ -0,0 +1,62 @@ +import 'package:equatable/equatable.dart'; +import 'package:hydrated_bloc/hydrated_bloc.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart'; + +part 'rating_system_bloc.g.dart'; +part 'rating_system_event.dart'; +part 'rating_system_state.dart'; + +typedef Group = String; + +class RatingSystemBloc + extends HydratedBloc { + RatingSystemBloc() : super(const RatingSystemState()) { + on(_onUpdateSubjectsByCurrentSchedule); + } + + void _onUpdateSubjectsByCurrentSchedule( + UpdateSubjectsByCurrentSchedule event, + Emitter emit, + ) { + final actualSubjects = event.subjects; + + final newSubjects = <(Group, Subject)>[]; + + for (final actualSubject in actualSubjects) { + final index = state.subjects.indexWhere( + (element) => + element.$2.name == actualSubject.name && element.$1 == event.group, + ); + + if (index == -1) { + newSubjects.add( + (event.group, actualSubject), + ); + } else { + final subject = state.subjects[index]; + + if (actualSubject.mainScore == 0 && + actualSubject.additionalScore == 0 && + actualSubject.classScore == 0) { + state.subjects.removeAt(index); + } else { + newSubjects.add(subject); + } + } + } + + emit( + state.copyWith( + subjects: newSubjects, + ), + ); + } + + @override + RatingSystemState? fromJson(Map json) => + RatingSystemState.fromJson(json); + + @override + Map? toJson(RatingSystemState state) => state.toJson(); +} diff --git a/lib/rating_system_calculator/bloc/rating_system_bloc.g.dart b/lib/rating_system_calculator/bloc/rating_system_bloc.g.dart new file mode 100644 index 00000000..64e80582 --- /dev/null +++ b/lib/rating_system_calculator/bloc/rating_system_bloc.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'rating_system_bloc.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +RatingSystemState _$RatingSystemStateFromJson(Map json) => + RatingSystemState( + subjects: json['subjects'] == null + ? const [] + : const SubjectsConverter().fromJson(json['subjects'] as List), + ); + +Map _$RatingSystemStateToJson(RatingSystemState instance) => + { + 'subjects': const SubjectsConverter().toJson(instance.subjects), + }; diff --git a/lib/rating_system_calculator/bloc/rating_system_event.dart b/lib/rating_system_calculator/bloc/rating_system_event.dart new file mode 100644 index 00000000..f844bb35 --- /dev/null +++ b/lib/rating_system_calculator/bloc/rating_system_event.dart @@ -0,0 +1,18 @@ +part of 'rating_system_bloc.dart'; + +abstract class RatingSystemEvent extends Equatable { + const RatingSystemEvent(); +} + +class UpdateSubjectsByCurrentSchedule extends RatingSystemEvent { + const UpdateSubjectsByCurrentSchedule({ + required this.group, + required this.subjects, + }); + + final Group group; + final List subjects; + + @override + List get props => [group, subjects]; +} diff --git a/lib/rating_system_calculator/bloc/rating_system_state.dart b/lib/rating_system_calculator/bloc/rating_system_state.dart new file mode 100644 index 00000000..94fed4cd --- /dev/null +++ b/lib/rating_system_calculator/bloc/rating_system_state.dart @@ -0,0 +1,55 @@ +part of 'rating_system_bloc.dart'; + +@JsonSerializable() +class RatingSystemState extends Equatable { + const RatingSystemState({ + this.subjects = const [], + }); + + @SubjectsConverter() + final List<(Group, Subject)> subjects; + + factory RatingSystemState.fromJson(Map json) => + _$RatingSystemStateFromJson(json); + + Map toJson() => _$RatingSystemStateToJson(this); + + RatingSystemState copyWith({ + List<(Group, Subject)>? subjects, + }) { + return RatingSystemState( + subjects: subjects ?? this.subjects, + ); + } + + @override + List get props => [ + subjects, + ]; +} + +class SubjectsConverter + implements JsonConverter, List> { + const SubjectsConverter(); + + @override + List<(Group, Subject)> fromJson(List json) { + return json + .map( + (dynamic e) => (e['group'] as String, Subject.fromJson(e)), + ) + .toList(); + } + + @override + List toJson(List<(Group, Subject)> object) { + return object + .map( + (e) => { + 'group': e.$1, + ...e.$2.toJson(), + }, + ) + .toList(); + } +} diff --git a/lib/rating_system_calculator/models/models.dart b/lib/rating_system_calculator/models/models.dart new file mode 100644 index 00000000..0fb3c0ad --- /dev/null +++ b/lib/rating_system_calculator/models/models.dart @@ -0,0 +1 @@ +export 'subject.dart'; diff --git a/lib/rating_system_calculator/models/subject.dart b/lib/rating_system_calculator/models/subject.dart new file mode 100644 index 00000000..75690172 --- /dev/null +++ b/lib/rating_system_calculator/models/subject.dart @@ -0,0 +1,70 @@ +import 'package:equatable/equatable.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'subject.g.dart'; + +@immutable +@JsonSerializable() +class Subject extends Equatable { + const Subject({ + required this.name, + required this.dates, + this.mainScore, + this.additionalScore, + this.classScore, + this.visitedDays, + }); + + /// {@macro from_json} + factory Subject.fromJson(Map json) => + _$SubjectFromJson(json); + + /// {@macro to_json} + Map toJson() => _$SubjectToJson(this); + + /// Название предмета. + final String name; + + /// Даты занятия. + final List dates; + + /// Основные баллы. + final double? mainScore; + + /// Дополнительные баллы. + final double? additionalScore; + + /// Баллы за работу на занятиях. + final double? classScore; + + /// Посещенные дни. + final List? visitedDays; + + Subject copyWith({ + String? name, + List? dates, + double? mainScore, + double? additionalScore, + double? classScore, + List? visitedDays, + }) { + return Subject( + name: name ?? this.name, + dates: dates ?? this.dates, + mainScore: mainScore ?? this.mainScore, + additionalScore: additionalScore ?? this.additionalScore, + classScore: classScore ?? this.classScore, + visitedDays: visitedDays ?? this.visitedDays, + ); + } + + @override + List get props => [ + name, + dates, + mainScore, + additionalScore, + classScore, + visitedDays, + ]; +} diff --git a/lib/rating_system_calculator/models/subject.g.dart b/lib/rating_system_calculator/models/subject.g.dart new file mode 100644 index 00000000..47789d4e --- /dev/null +++ b/lib/rating_system_calculator/models/subject.g.dart @@ -0,0 +1,30 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'subject.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Subject _$SubjectFromJson(Map json) => Subject( + name: json['name'] as String, + dates: (json['dates'] as List) + .map((e) => DateTime.parse(e as String)) + .toList(), + mainScore: (json['mainScore'] as num?)?.toDouble(), + additionalScore: (json['additionalScore'] as num?)?.toDouble(), + classScore: (json['classScore'] as num?)?.toDouble(), + visitedDays: (json['visitedDays'] as List?) + ?.map((e) => DateTime.parse(e as String)) + .toList(), + ); + +Map _$SubjectToJson(Subject instance) => { + 'name': instance.name, + 'dates': instance.dates.map((e) => e.toIso8601String()).toList(), + 'mainScore': instance.mainScore, + 'additionalScore': instance.additionalScore, + 'classScore': instance.classScore, + 'visitedDays': + instance.visitedDays?.map((e) => e.toIso8601String()).toList(), + }; diff --git a/lib/rating_system_calculator/view/about_rating_system_page.dart b/lib/rating_system_calculator/view/about_rating_system_page.dart index 4d1ed0f1..520d065b 100644 --- a/lib/rating_system_calculator/view/about_rating_system_page.dart +++ b/lib/rating_system_calculator/view/about_rating_system_page.dart @@ -1,11 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter_animate/flutter_animate.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:rtu_mirea_app/presentation/theme.dart'; import 'package:rtu_mirea_app/presentation/typography.dart'; -import 'package:rtu_mirea_app/presentation/widgets/buttons/primary_button.dart'; import 'package:rtu_mirea_app/rating_system_calculator/rating_system_calculator.dart'; -import 'package:rtu_mirea_app/rating_system_calculator/widgets/scores_table.dart'; import 'package:unicons/unicons.dart'; class AboutRatingSystemPage extends StatelessWidget { diff --git a/lib/rating_system_calculator/view/rating_system_calculator_page.dart b/lib/rating_system_calculator/view/rating_system_calculator_page.dart index 5f36fffa..52f5e0ce 100644 --- a/lib/rating_system_calculator/view/rating_system_calculator_page.dart +++ b/lib/rating_system_calculator/view/rating_system_calculator_page.dart @@ -6,8 +6,12 @@ import 'package:rtu_mirea_app/presentation/theme.dart'; import 'package:rtu_mirea_app/presentation/typography.dart'; import 'package:rtu_mirea_app/presentation/widgets/buttons/primary_button.dart'; import 'package:rtu_mirea_app/presentation/widgets/buttons/text_outlined_button.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/bloc/rating_system_bloc.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/widgets/widgets.dart'; import 'package:rtu_mirea_app/schedule/bloc/schedule_bloc.dart'; import 'package:rtu_mirea_app/schedule/models/models.dart'; +import 'package:university_app_server_api/client.dart'; class RatingSystemCalculatorPage extends StatelessWidget { const RatingSystemCalculatorPage({super.key}); @@ -23,10 +27,11 @@ class RatingSystemCalculatorPage extends StatelessWidget { "Бально-рейтинговая система", ), ), - body: const SafeArea( - child: Padding( - padding: EdgeInsets.all(16), - child: RatingSystemCalculatorView(), + body: Padding( + padding: const EdgeInsets.all(16), + child: BlocProvider( + create: (context) => RatingSystemBloc(), + child: const RatingSystemCalculatorView(), ), ), ); @@ -53,9 +58,59 @@ class _RatingSystemCalculatorViewState super.dispose(); } + (String, List)? _getSubjectsByCurrentScheduleState( + ScheduleBloc scheduleBloc, + ) { + final selectedSchedule = scheduleBloc.state.selectedSchedule; + + if (selectedSchedule is SelectedGroupSchedule) { + final subjectNames = selectedSchedule.schedule + .whereType() + .map((e) => e.subject) + .toSet(); + + final selectedGroup = selectedSchedule.group.name; + + List getDatesBySubjectName(String subjectName) { + return selectedSchedule.schedule + .whereType() + .where((e) => e.subject == subjectName) + .map((e) => e.dates) + .expand((element) => element) + .toList(); + } + + return ( + selectedGroup, + subjectNames + .map( + (e) => Subject( + name: e, + dates: getDatesBySubjectName(e), + ), + ) + .toList(), + ); + } else { + return null; + } + } + @override Widget build(BuildContext context) { final scheduleBloc = context.watch(); + final ratingSystemBloc = context.watch(); + + final subjects = _getSubjectsByCurrentScheduleState(scheduleBloc); + + if (subjects != null) { + ratingSystemBloc.add( + UpdateSubjectsByCurrentSchedule( + group: subjects.$1, + subjects: subjects.$2, + ), + ); + } return CustomScrollView( slivers: [ @@ -122,9 +177,7 @@ class _RatingSystemCalculatorViewState end: 0, ), const SizedBox(height: 32), - SubjectsListView( - selectedSchedule: scheduleBloc.state.selectedSchedule, - ), + const SubjectsListView(), ], ), ), @@ -134,109 +187,32 @@ class _RatingSystemCalculatorViewState } class SubjectsListView extends StatelessWidget { - const SubjectsListView({Key? key, this.selectedSchedule}) : super(key: key); - - final SelectedSchedule? selectedSchedule; + const SubjectsListView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { + final selectedSchedule = + context.watch().state.selectedSchedule; + if (selectedSchedule is SelectedGroupSchedule) { - return Column( - children: [ - Card( - color: AppTheme.colors.background02, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 48, - height: 48, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - gradient: const LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [ - Color(0xFF9ADB7F), - Color(0xFF6EA95C), - ], - ), - ), - child: const Icon( - Icons.school, - color: Colors.white, - ), - ), - const SizedBox(width: 16), - Expanded( - child: Text( - "Математический анализ", - style: AppTextStyle.buttonL.copyWith(), - ), + return BlocBuilder( + builder: (context, state) { + return Column( + children: state.subjects + .map( + (e) => SubjectCard( + subject: e.$2, + onTap: (subject) { + context.go( + '/services/rating-system-calculator/subject', + extra: subject, + ); + }, ), - Padding( - padding: const EdgeInsets.only(right: 18.0), - child: Text( - "32", - style: AppTextStyle.buttonL.copyWith( - color: AppTheme.colors.colorful05, - ), - ), - ), - const Icon(Icons.arrow_forward_ios), - ], - ), - ), - ), - Card( - color: AppTheme.colors.background02, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(16), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 48, - height: 48, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - color: AppTheme.colors.colorful02, - ), - child: Icon( - Icons.school, - color: AppTheme.colors.activeLightMode, - ), - ), - const SizedBox(width: 16), - Expanded( - child: Text( - "Линейная алгебра", - style: AppTextStyle.buttonL.copyWith(), - ), - ), - Padding( - padding: const EdgeInsets.only(right: 18.0), - child: Text( - "8", - style: AppTextStyle.buttonL.copyWith( - color: AppTheme.colors.colorful02, - ), - ), - ), - const Icon(Icons.arrow_forward_ios), - ], - ), - ), - ) - ], + ) + .toList(), + ); + }, ); } else { return Padding( diff --git a/lib/rating_system_calculator/view/subject_page.dart b/lib/rating_system_calculator/view/subject_page.dart new file mode 100644 index 00000000..22190212 --- /dev/null +++ b/lib/rating_system_calculator/view/subject_page.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:rtu_mirea_app/presentation/theme.dart'; +import 'package:rtu_mirea_app/presentation/typography.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart'; + +class SubjectPage extends StatelessWidget { + const SubjectPage({ + super.key, + required this.subject, + }); + + final Subject subject; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppTheme.colors.background01, + appBar: AppBar( + backgroundColor: AppTheme.colors.background01, + title: const Text( + "Калькулятор", + ), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(24), + child: RatingSystemCalculatorView(subject: subject), + ), + ), + ); + } +} + +class RatingSystemCalculatorView extends StatefulWidget { + const RatingSystemCalculatorView({super.key, required this.subject}); + + final Subject subject; + + @override + State createState() => + _RatingSystemCalculatorViewState(); +} + +class _RatingSystemCalculatorViewState + extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CustomScrollView( + slivers: [ + SliverList( + delegate: SliverChildListDelegate( + [ + Text( + "Здесь вы можете сохранить свои баллы и отслеживать их в удобном формате.", + style: AppTextStyle.body, + ), + const SizedBox(height: 16), + // Кнопки с выбором посещенных дней. По нажатию на кнопку, она меняет свой цвет. + Wrap( + spacing: 8, + runSpacing: 8, + children: [ + for (final day in widget.subject.dates) + ChoiceChip( + label: Text( + day.toString().split(' ')[0], + style: AppTextStyle.body.copyWith( + color: AppTheme.colors.activeLightMode, + ), + ), + selected: false, + onSelected: (value) {}, + selectedColor: AppTheme.colors.primary, + backgroundColor: AppTheme.colors.background02, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + ), + ], + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/rating_system_calculator/widgets/short_description_card.dart b/lib/rating_system_calculator/widgets/short_description_card.dart index ed637ac5..0e639fd2 100644 --- a/lib/rating_system_calculator/widgets/short_description_card.dart +++ b/lib/rating_system_calculator/widgets/short_description_card.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:rtu_mirea_app/presentation/theme.dart'; import 'package:rtu_mirea_app/presentation/typography.dart'; -import 'package:unicons/unicons.dart'; class ShortDescriptionCard extends StatelessWidget { const ShortDescriptionCard({ diff --git a/lib/rating_system_calculator/widgets/subject_card.dart b/lib/rating_system_calculator/widgets/subject_card.dart new file mode 100644 index 00000000..2eb56f13 --- /dev/null +++ b/lib/rating_system_calculator/widgets/subject_card.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:rtu_mirea_app/presentation/theme.dart'; +import 'package:rtu_mirea_app/presentation/typography.dart'; +import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart'; + +// Card( +// color: AppTheme.colors.background02, +// shape: RoundedRectangleBorder( +// borderRadius: BorderRadius.circular(16), +// ), +// child: Padding( +// padding: const EdgeInsets.all(8.0), +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Container( +// width: 48, +// height: 48, +// decoration: BoxDecoration( +// borderRadius: BorderRadius.circular(16), +// color: AppTheme.colors.colorful02, +// ), +// child: Icon( +// Icons.school, +// color: AppTheme.colors.activeLightMode, +// ), +// ), +// const SizedBox(width: 16), +// Expanded( +// child: Text( +// "Линейная алгебра", +// style: AppTextStyle.buttonL.copyWith(), +// ), +// ), +// Padding( +// padding: const EdgeInsets.only(right: 18.0), +// child: Text( +// "8", +// style: AppTextStyle.buttonL.copyWith( +// color: AppTheme.colors.colorful02, +// ), +// ), +// ), +// const Icon(Icons.arrow_forward_ios), +// ], +// ), +// ), +// ) + +class SubjectCard extends StatelessWidget { + const SubjectCard({ + Key? key, + required this.subject, + required this.onTap, + }) : super(key: key); + + final Subject subject; + final void Function(Subject) onTap; + + double get score { + return (subject.mainScore ?? 0) + + (subject.additionalScore ?? 0) + + (subject.classScore ?? 0); + } + + @override + Widget build(BuildContext context) { + return Card( + color: AppTheme.colors.background02, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: InkWell( + onTap: () => onTap(subject), + borderRadius: BorderRadius.circular(16), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 48, + height: 48, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + gradient: const LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Color(0xFF9ADB7F), + Color(0xFF6EA95C), + ], + ), + ), + child: const Icon( + Icons.school, + color: Colors.white, + ), + ), + const SizedBox(width: 8), + Expanded( + child: Text( + subject.name, + style: AppTextStyle.buttonL.copyWith( + fontSize: 14, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + Padding( + padding: const EdgeInsets.only(right: 18.0), + child: Text( + score.toString(), + style: AppTextStyle.buttonL.copyWith( + color: AppTheme.colors.colorful05, + ), + ), + ), + const Icon(Icons.arrow_forward_ios), + ], + ), + ), + ), + ); + } +} diff --git a/lib/rating_system_calculator/widgets/widgets.dart b/lib/rating_system_calculator/widgets/widgets.dart index 0d562f30..47f7e03c 100644 --- a/lib/rating_system_calculator/widgets/widgets.dart +++ b/lib/rating_system_calculator/widgets/widgets.dart @@ -1 +1,3 @@ export 'short_description_card.dart'; +export 'scores_table.dart'; +export 'subject_card.dart'; diff --git a/lib/services/view/services_page.dart b/lib/services/view/services_page.dart index 001070b2..0c2782ca 100644 --- a/lib/services/view/services_page.dart +++ b/lib/services/view/services_page.dart @@ -70,17 +70,17 @@ class _ServicesViewState extends State { launchMode: LaunchMode.inAppBrowserView, description: 'Найди нужный кабинет', ), - ServiceCard( - title: 'Калькулятор БРС', - onTap: () { - context.go('/services/rating-system-calculator'); - }, - icon: ServiceIcon( - color: AppTheme.colors.colorful02, - iconColor: AppTheme.colors.background01, - icon: Icons.calculate, - ), - ), + // ServiceCard( + // title: 'Калькулятор БРС', + // onTap: () { + // context.go('/services/rating-system-calculator'); + // }, + // icon: ServiceIcon( + // color: AppTheme.colors.colorful02, + // iconColor: AppTheme.colors.background01, + // icon: Icons.calculate, + // ), + // ), ServiceCard( title: 'Бюро находок', url: 'https://finds.mirea.ru/',