diff --git a/README.md b/README.md
index 9f31735a..61e1341f 100644
--- a/README.md
+++ b/README.md
@@ -47,12 +47,28 @@ flutter packages pub run build_runner watch --delete-conflicting-outputs
flutter packages pub run build_runner build --delete-conflicting-outputs
```
-## Конфигурация Firebase Analytics и Crashlytics
+## Конфигурация Firebase Analytics
1. Зарегистрируйте приложение в [Firebase](https://console.firebase.google.com/).
1. Выполните шаги для генерации `firebase_options.dart` файла с помощью [FlutterFire CLI](https://firebase.flutter.dev/docs/cli).
2. Firebase Analytics для Android не поддерживает Dart-only конфигурацию. Как только ваше приложение для Android будет зарегистрировано в Firebase, загрузите файл конфигурации с консоли Firebase (файл называется `google-services.json`). Добавьте этот файл в каталог `android/app`.
3. Проект готов для использования с Firebase Analytics и Crashlytics.
+## Переменные окружения
+Приложение использует переменные среды времени компиляции для хранения конфиденциальных данных, таких как ключи API и токены.
+
+Эти переменные должны передаваться при запуске или сборке приложения с помощью аргумента `--dart-define` или установленной переменной окружения. Если вам нужно передать несколько пар ключ-значение, просто определите --dart-define несколько раз.
+
+### Переменные приложения:
+- `SENTRY_DSN` - DSN для отправки отчетов об ошибках в Sentry.
+- `LK_CLIENT_ID` - ID клиента для авторизации в Личном кабинете с помощью OAuth2.
+- `LK_CLIENT_SECRET` - Секретный ключ клиента для авторизации в Личном кабинете с помощью OAuth2.
+
+**Пример:**
+```bash
+flutter run --dart-define=SENTRY_DSN=YOUR_DSN --dart-define=LK_CLIENT_ID=YOUR_CLIENT_ID --dart-define=LK_CLIENT_SECRET=YOUR_CLIENT_SECRET
+```
+
+
## При ошибках
**Исключения платформы**
1. flutter clean
diff --git a/android/build.gradle b/android/build.gradle
index 3ae76140..86c61dc8 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:7.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
- classpath 'com.google.gms:google-services:4.3.8'
+ classpath 'com.google.gms:google-services:4.3.15'
}
}
diff --git a/assets/icons/social-sharing.svg b/assets/icons/social-sharing.svg
new file mode 100644
index 00000000..165d04d9
--- /dev/null
+++ b/assets/icons/social-sharing.svg
@@ -0,0 +1,21 @@
+
diff --git a/lib/data/datasources/user_remote.dart b/lib/data/datasources/user_remote.dart
index 0c984f19..386fa5ef 100644
--- a/lib/data/datasources/user_remote.dart
+++ b/lib/data/datasources/user_remote.dart
@@ -9,6 +9,7 @@ import 'package:rtu_mirea_app/data/models/employee_model.dart';
import 'package:rtu_mirea_app/data/models/nfc_pass_model.dart';
import 'package:rtu_mirea_app/data/models/score_model.dart';
import 'package:rtu_mirea_app/data/models/user_model.dart';
+import 'package:sentry_flutter/sentry_flutter.dart';
abstract class UserRemoteData {
Future auth();
@@ -56,18 +57,25 @@ class UserRemoteDataImpl implements UserRemoteData {
final response = await lksOauth2.oauth2Helper.get(
'$_apiUrl/?action=getData&url=https://lk.mirea.ru/profile/',
);
- var jsonResponse = json.decode(response.body);
log('Status code: ${response.statusCode}, Response: ${response.body}',
name: 'getProfileData');
- if (jsonResponse.containsKey('errors')) {
- throw ServerException(jsonResponse['errors'][0]);
- }
- if (response.statusCode == 200) {
- return UserModel.fromRawJson(response.body);
- } else {
- throw ServerException('Response status code is ${response.statusCode}');
+ try {
+ var jsonResponse = json.decode(response.body);
+
+ if (jsonResponse.containsKey('errors')) {
+ throw ServerException(jsonResponse['errors'][0]);
+ }
+ if (response.statusCode == 200) {
+ return UserModel.fromJson(jsonResponse);
+ } else {
+ throw ServerException('Response status code is ${response.statusCode}');
+ }
+ } catch (e) {
+ Sentry.captureException(e, stackTrace: StackTrace.current);
+
+ throw ServerException(e.toString());
}
}
diff --git a/lib/data/models/edu_program_model.dart b/lib/data/models/edu_program_model.dart
new file mode 100644
index 00000000..6a93d4e2
--- /dev/null
+++ b/lib/data/models/edu_program_model.dart
@@ -0,0 +1,32 @@
+import 'dart:convert';
+
+import 'package:rtu_mirea_app/domain/entities/edu_program.dart';
+
+class EduProgramModel extends EduProgram {
+ const EduProgramModel({
+ required eduProgram,
+ required eduProgramCode,
+ required department,
+ required prodDepartment,
+ required type,
+ }) : super(
+ eduProgram: eduProgram,
+ eduProgramCode: eduProgramCode,
+ department: department,
+ prodDepartment: prodDepartment,
+ type: type,
+ );
+
+ factory EduProgramModel.fromRawJson(String str) =>
+ EduProgramModel.fromJson(json.decode(str));
+
+ factory EduProgramModel.fromJson(Map json) {
+ return EduProgramModel(
+ eduProgramCode: json["PROPERTIES"]["OKSO_CODE"]["VALUE"],
+ eduProgram: json["NAME"],
+ department: json["PROPERTIES"]["DEPARTMENT"]["VALUE_TEXT"],
+ prodDepartment: json["PROPERTIES"]["PROD_DEPARTMENT"]["VALUE_TEXT"],
+ type: json["TYPE"],
+ );
+ }
+}
diff --git a/lib/data/models/student_model.dart b/lib/data/models/student_model.dart
new file mode 100644
index 00000000..4fa2d2af
--- /dev/null
+++ b/lib/data/models/student_model.dart
@@ -0,0 +1,56 @@
+import 'dart:convert';
+
+import 'package:rtu_mirea_app/domain/entities/student.dart';
+
+import 'edu_program_model.dart';
+
+class StudentModel extends Student {
+ const StudentModel({
+ required id,
+ required isActive,
+ required course,
+ required personalNumber,
+ required educationStartDate,
+ required educationEndDate,
+ required academicGroup,
+ required code,
+ required eduProgram,
+ required status,
+ }) : super(
+ id: id,
+ isActive: isActive,
+ eduProgram: eduProgram,
+ course: course,
+ personalNumber: personalNumber,
+ educationStartDate: educationStartDate,
+ educationEndDate: educationEndDate,
+ academicGroup: academicGroup,
+ code: code,
+ status: status,
+ );
+
+ static List fromRawJson(String str) =>
+ StudentModel.fromJson(json.decode(str));
+
+ static List fromJson(Map json) {
+ final studentsRaw = json["STUDENTS"].values.where((element) =>
+ !element["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"].contains("Д") &&
+ !element["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"].contains("Ж"));
+
+ return List.from(studentsRaw.map(
+ (e) => StudentModel(
+ id: e["ID"],
+ isActive: e["ACTIVE"] == "Y",
+ course: int.parse(e["PROPERTIES"]["COURSE"]["VALUE"]),
+ personalNumber: e["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"],
+ educationEndDate: e["PROPERTIES"]["END_DATE"]["VALUE"],
+ academicGroup: e["PROPERTIES"]["ACADEMIC_GROUP"]["VALUE_TEXT"],
+ educationStartDate: e["PROPERTIES"]["START_DATE"]["VALUE"],
+ code: e["CODE"],
+ eduProgram: EduProgramModel.fromJson(
+ json["EDU_PROGRAM"][e["PROPERTIES"]["EDU_PROGRAM"]["VALUE"]]),
+ status: e["PROPERTIES"]["STATUS"]["VALUE_TEXT"],
+ ),
+ ));
+ }
+}
diff --git a/lib/data/models/user_model.dart b/lib/data/models/user_model.dart
index 9a83920f..a7bcad75 100644
--- a/lib/data/models/user_model.dart
+++ b/lib/data/models/user_model.dart
@@ -1,5 +1,6 @@
import 'dart:convert';
+import 'package:rtu_mirea_app/data/models/student_model.dart';
import 'package:rtu_mirea_app/domain/entities/user.dart';
class UserModel extends User {
@@ -10,24 +11,11 @@ class UserModel extends User {
required name,
required lastName,
required secondName,
- required isActive,
required birthday,
- required eduProgram,
- required eduProgramCode,
required photoUrl,
- required authShortlink,
required registerDate,
required lastLoginDate,
- required course,
- required personalNumber,
- required educationStartDate,
- required educationEndDate,
- required academicGroup,
- required department,
- required prodDepartment,
- required type,
- required code,
- required studentId,
+ required students,
}) : super(
id: id,
login: login,
@@ -35,38 +23,17 @@ class UserModel extends User {
name: name,
lastName: lastName,
secondName: secondName,
- isActive: isActive,
birthday: birthday,
- eduProgram: eduProgram,
- eduProgramCode: eduProgramCode,
photoUrl: photoUrl,
- authShortlink: authShortlink,
registerDate: registerDate,
lastLoginDate: lastLoginDate,
- course: course,
- personalNumber: personalNumber,
- educationStartDate: educationStartDate,
- educationEndDate: educationEndDate,
- academicGroup: academicGroup,
- department: department,
- prodDepartment: prodDepartment,
- type: type,
- code: code,
- studentId: studentId,
+ students: students,
);
factory UserModel.fromRawJson(String str) =>
UserModel.fromJson(json.decode(str));
factory UserModel.fromJson(Map json) {
- final student = json["STUDENTS"].values.firstWhere((element) =>
- !element["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"].contains("Д") &&
- !element["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"].contains("Ж"));
-
- final eduProgram = json["EDU_PROGRAM"]
- .values
- .firstWhere((element) => element["ACTIVE"] == "Y");
-
return UserModel(
id: json["ID"],
login: json["arUser"]["LOGIN"],
@@ -74,24 +41,11 @@ class UserModel extends User {
name: json["arUser"]["NAME"],
lastName: json["arUser"]["LAST_NAME"],
secondName: json["arUser"]["SECOND_NAME"],
- isActive: student["ACTIVE"] == "Y",
photoUrl: json["arUser"]["PHOTO"],
- authShortlink: json["arUser"]["UF_AUTH_SHORTLINK"],
lastLoginDate: json["arUser"]["LAST_LOGIN"],
registerDate: json["arUser"]["DATE_REGISTER"],
- course: int.parse(student["PROPERTIES"]["COURSE"]["VALUE"]),
- personalNumber: student["PROPERTIES"]["PERSONAL_NUMBER"]["VALUE"],
birthday: json["arUser"]["PERSONAL_BIRTHDAY"],
- educationStartDate: student["PROPERTIES"]["START_DATE"]["VALUE"],
- educationEndDate: student["PROPERTIES"]["END_DATE"]["VALUE"],
- academicGroup: student["PROPERTIES"]["ACADEMIC_GROUP"]["VALUE_TEXT"],
- eduProgramCode: eduProgram["PROPERTIES"]["OKSO_CODE"]["VALUE"],
- eduProgram: eduProgram["NAME"],
- department: eduProgram["PROPERTIES"]["DEPARTMENT"]["VALUE_TEXT"],
- prodDepartment: eduProgram["PROPERTIES"]["PROD_DEPARTMENT"]["VALUE_TEXT"],
- type: eduProgram["TYPE"],
- code: student["CODE"],
- studentId: student["ID"],
+ students: StudentModel.fromJson(json),
);
}
}
diff --git a/lib/domain/entities/edu_program.dart b/lib/domain/entities/edu_program.dart
new file mode 100644
index 00000000..89f9abf1
--- /dev/null
+++ b/lib/domain/entities/edu_program.dart
@@ -0,0 +1,26 @@
+import 'package:equatable/equatable.dart';
+
+class EduProgram extends Equatable {
+ final String eduProgram;
+ final String eduProgramCode;
+ final String department;
+ final String prodDepartment;
+ final String? type;
+
+ const EduProgram({
+ required this.eduProgram,
+ required this.eduProgramCode,
+ required this.department,
+ required this.prodDepartment,
+ required this.type,
+ });
+
+ @override
+ List