forked from eatvio/eatvio_app
feat: appmetrica
This commit is contained in:
@@ -8,62 +8,61 @@ import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/features/registration/models/user_registration_model.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
|
||||
import 'package:eatvio_app/features/registration/repositories/registration_repository.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class RegistrationCubit extends Cubit<RegistrationState> {
|
||||
final RegistrationRepository registrationRepository;
|
||||
|
||||
RegistrationCubit({
|
||||
required this.registrationRepository,
|
||||
}) : super(
|
||||
const RegistrationState(
|
||||
sheet: UserRegistrationSheet(
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
password: '',
|
||||
passwordConfirmation: '',
|
||||
birthdate: '',
|
||||
gender: '',
|
||||
location: '',
|
||||
responseBody: '{}',
|
||||
lang: 'Русский',
|
||||
weight: 0,
|
||||
height: 0,
|
||||
chestCircumference: 0,
|
||||
waistCircumference: 0,
|
||||
hipCircumference: 0,
|
||||
bloodPressureUp: 0,
|
||||
bloodPressureDown: 0,
|
||||
hasHypo: 0,
|
||||
hasHyper: 0,
|
||||
aboutAllergy: '',
|
||||
aboutTakingPils: '',
|
||||
aboutSportHobbies: '',
|
||||
favoriteFoods: '',
|
||||
unfavoriteFoods: '',
|
||||
additionalInfo: '',
|
||||
phone: '',
|
||||
),
|
||||
RegistrationCubit({required this.registrationRepository})
|
||||
: super(
|
||||
const RegistrationState(
|
||||
sheet: UserRegistrationSheet(
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
password: '',
|
||||
passwordConfirmation: '',
|
||||
birthdate: '',
|
||||
gender: '',
|
||||
location: '',
|
||||
responseBody: '{}',
|
||||
lang: 'Русский',
|
||||
weight: 0,
|
||||
height: 0,
|
||||
chestCircumference: 0,
|
||||
waistCircumference: 0,
|
||||
hipCircumference: 0,
|
||||
bloodPressureUp: 0,
|
||||
bloodPressureDown: 0,
|
||||
hasHypo: 0,
|
||||
hasHyper: 0,
|
||||
aboutAllergy: '',
|
||||
aboutTakingPils: '',
|
||||
aboutSportHobbies: '',
|
||||
favoriteFoods: '',
|
||||
unfavoriteFoods: '',
|
||||
additionalInfo: '',
|
||||
phone: '',
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
|
||||
void updateSheet(UserRegistrationSheet sheet) => emit(RegistrationState(sheet: sheet));
|
||||
|
||||
Future<void> tryRegistration() async {
|
||||
try {
|
||||
final token = await registrationRepository.tryRegister(
|
||||
state.sheet.copyWith(
|
||||
phone: state.sheet.phone.replaceAll(' ', '').replaceAll('(', '').replaceAll(')', ''),
|
||||
responseBody: '{}',
|
||||
),
|
||||
state.sheet.copyWith(phone: state.sheet.phone.replaceAll(' ', '').replaceAll('(', '').replaceAll(')', ''), responseBody: '{}'),
|
||||
);
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
await sl<FirebaseApi>().registerPushToken();
|
||||
RegistrationAnalyticsService.reportRegistrationComplete();
|
||||
AppRouter.navigatorKey.currentContext?.replaceNamed('verifyEmailScreen');
|
||||
} catch (e, st) {
|
||||
log(e.toString(), stackTrace: st);
|
||||
RegistrationAnalyticsService.reportRegistrationError(e.toString());
|
||||
emit(RegistrationState(sheet: state.sheet, error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_state.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
final ProfileRepository profileRepository;
|
||||
|
||||
VerifyEmailCubit({
|
||||
required this.profileRepository,
|
||||
}) : super(const VerifyEmailState.loading());
|
||||
VerifyEmailCubit({required this.profileRepository}) : super(const VerifyEmailState.loading());
|
||||
|
||||
Future<void> sendEmailCode() async {
|
||||
try {
|
||||
@@ -24,6 +23,7 @@ class VerifyEmailCubit extends Cubit<VerifyEmailState> {
|
||||
emit(const VerifyEmailState.verifyLoading());
|
||||
final result = await profileRepository.tryVerifyEmailByCode(code);
|
||||
if (result == true) {
|
||||
RegistrationAnalyticsService.reportEmailVerification();
|
||||
emit(const VerifyEmailState.verifySuccess());
|
||||
} else {
|
||||
emit(const VerifyEmailState.verifyError());
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:eatvio_app/features/registration/presentation/pages/medicine_int
|
||||
import 'package:eatvio_app/features/registration/presentation/pages/name_screen.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/pages/phone_screen.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/pages/weight_screen.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
@@ -51,12 +52,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка при регистрации'),
|
||||
content: Text(state.error!),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -76,22 +72,14 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
highlightElevation: 0,
|
||||
focusElevation: 0,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
backgroundColor: const Color(0xFFEAF2FD),
|
||||
onPressed: () async {
|
||||
setState(() {
|
||||
pageController.previousPage(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
pageController.previousPage(duration: const Duration(milliseconds: 350), curve: Curves.easeInOut);
|
||||
});
|
||||
},
|
||||
label: Icon(
|
||||
Icons.arrow_back_ios_new_rounded,
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
label: Icon(Icons.arrow_back_ios_new_rounded, color: appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
@@ -103,24 +91,16 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
backgroundColor: appTheme.blueA400,
|
||||
onPressed: () async {
|
||||
if (await canGoNext(state, context)) {
|
||||
setState(() {
|
||||
pageController.nextPage(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
);
|
||||
pageController.nextPage(duration: const Duration(milliseconds: 350), curve: Curves.easeInOut);
|
||||
});
|
||||
}
|
||||
},
|
||||
label: Text(
|
||||
'Продолжить',
|
||||
style: theme.textTheme.titleSmall!.copyWith(color: Colors.white),
|
||||
),
|
||||
label: Text('Продолжить', style: theme.textTheme.titleSmall!.copyWith(color: Colors.white)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -128,23 +108,11 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
appBar: AppBar(
|
||||
automaticallyImplyLeading: false,
|
||||
leading: Builder(
|
||||
builder: (context) => IconButton(
|
||||
icon: const Icon(Icons.close_rounded),
|
||||
onPressed: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
builder: (context) => IconButton(icon: const Icon(Icons.close_rounded), onPressed: () => GoRouter.of(context).pop()),
|
||||
),
|
||||
centerTitle: true,
|
||||
title: SvgPicture.asset(
|
||||
ImageConstant.imgLogoEatvio,
|
||||
height: 48,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 16),
|
||||
child: Text('шаг $step из 15'),
|
||||
),
|
||||
],
|
||||
title: SvgPicture.asset(ImageConstant.imgLogoEatvio, height: 48, fit: BoxFit.contain),
|
||||
actions: [Padding(padding: const EdgeInsets.only(right: 16), child: Text('шаг $step из 15'))],
|
||||
bottom: PreferredSize(
|
||||
preferredSize: Size(MediaQuery.of(context).size.width, 32),
|
||||
child: Padding(
|
||||
@@ -152,10 +120,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
child: TweenAnimationBuilder<double>(
|
||||
duration: const Duration(milliseconds: 350),
|
||||
curve: Curves.easeInOut,
|
||||
tween: Tween<double>(
|
||||
begin: 1 / 15,
|
||||
end: progressValue,
|
||||
),
|
||||
tween: Tween<double>(begin: 1 / 15, end: progressValue),
|
||||
builder: (context, value, _) => LinearProgressIndicator(
|
||||
value: value,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
@@ -175,6 +140,8 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
step = index + 1;
|
||||
progressValue = step / 15;
|
||||
});
|
||||
// Report analytics for step completion
|
||||
RegistrationAnalyticsService.reportRegistrationStep(step);
|
||||
},
|
||||
children: [
|
||||
// LanguageSelectScreen(sheet: state.sheet),
|
||||
@@ -211,12 +178,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: const Text('Введите корректный номер телефона'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
@@ -224,12 +186,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
return true;
|
||||
}
|
||||
case 2:
|
||||
List<String> errors = validateCredentialsFields(
|
||||
state.sheet.email,
|
||||
state.sheet.password,
|
||||
state.sheet.passwordConfirmation,
|
||||
context,
|
||||
);
|
||||
List<String> errors = validateCredentialsFields(state.sheet.email, state.sheet.password, state.sheet.passwordConfirmation, context);
|
||||
if (errors.isEmpty) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -244,22 +201,13 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
case 3:
|
||||
List<String> errors = validateNameFields(
|
||||
state.sheet.firstName.toString(),
|
||||
state.sheet.lastName.toString(),
|
||||
context,
|
||||
);
|
||||
List<String> errors = validateNameFields(state.sheet.firstName.toString(), state.sheet.lastName.toString(), context);
|
||||
if (errors.isEmpty) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -274,12 +222,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
@@ -293,12 +236,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: const Text('Выберете пол'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
@@ -312,12 +250,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: const Text('Заполните все поля'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
@@ -343,12 +276,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: Text(errorMessage),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('OK'),
|
||||
),
|
||||
],
|
||||
actions: [TextButton(onPressed: () => Navigator.pop(context), child: const Text('OK'))],
|
||||
),
|
||||
);
|
||||
return false;
|
||||
@@ -359,10 +287,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
barrierDismissible: false,
|
||||
useSafeArea: false,
|
||||
context: context,
|
||||
builder: (context) => const PopScope(
|
||||
canPop: false,
|
||||
child: Loader(),
|
||||
),
|
||||
builder: (context) => const PopScope(canPop: false, child: Loader()),
|
||||
);
|
||||
await registrationCubit.tryRegistration();
|
||||
if (context.mounted) {
|
||||
@@ -373,9 +298,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => const AlertDialog(
|
||||
title: Text('Ошибка при попытке регистрации'),
|
||||
),
|
||||
builder: (context) => const AlertDialog(title: Text('Ошибка при попытке регистрации')),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -385,12 +308,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
List<String> validateCircumferencesFields(
|
||||
String chestCircumference,
|
||||
String waistCircumference,
|
||||
String hipCircumference,
|
||||
BuildContext context,
|
||||
) {
|
||||
List<String> validateCircumferencesFields(String chestCircumference, String waistCircumference, String hipCircumference, BuildContext context) {
|
||||
final s = S.of(context);
|
||||
|
||||
List<String> errors = [];
|
||||
@@ -406,12 +324,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
return errors;
|
||||
}
|
||||
|
||||
List<String> validateCredentialsFields(
|
||||
String email,
|
||||
String password,
|
||||
String passwordConfirmation,
|
||||
BuildContext context,
|
||||
) {
|
||||
List<String> validateCredentialsFields(String email, String password, String passwordConfirmation, BuildContext context) {
|
||||
final s = S.of(context);
|
||||
|
||||
List<String> errors = [];
|
||||
@@ -435,11 +348,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
|
||||
return errors;
|
||||
}
|
||||
|
||||
List<String> validateNameFields(
|
||||
String firstName,
|
||||
String lastName,
|
||||
BuildContext context,
|
||||
) {
|
||||
List<String> validateNameFields(String firstName, String lastName, BuildContext context) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (firstName.isEmpty) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:eatvio_app/core/utils/toasts.dart';
|
||||
import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_cubit.dart';
|
||||
import 'package:eatvio_app/features/registration/presentation/bloc/verify_email_cubit/verify_email_state.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@@ -29,8 +30,10 @@ class _VerifyEmailScreenState extends State<VerifyEmailScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
goRouter = GoRouter.of(context);
|
||||
goRouter = GoRouter.of(context);
|
||||
_startTimer();
|
||||
// Report email verification screen opened
|
||||
RegistrationAnalyticsService.reportRegistrationStep(16); // Email verification step
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:lottie/lottie.dart';
|
||||
@@ -9,10 +10,7 @@ import 'package:webview_flutter/webview_flutter.dart';
|
||||
class VerifyScreen extends StatefulWidget {
|
||||
final String passKey;
|
||||
|
||||
const VerifyScreen({
|
||||
super.key,
|
||||
required this.passKey,
|
||||
});
|
||||
const VerifyScreen({super.key, required this.passKey});
|
||||
|
||||
@override
|
||||
State<VerifyScreen> createState() => _VerifyScreenState();
|
||||
@@ -25,6 +23,8 @@ class _VerifyScreenState extends State<VerifyScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Report phone verification screen opened
|
||||
RegistrationAnalyticsService.reportRegistrationStep(17); // Phone verification step
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setNavigationDelegate(
|
||||
@@ -36,6 +36,8 @@ class _VerifyScreenState extends State<VerifyScreen> {
|
||||
},
|
||||
onNavigationRequest: (NavigationRequest request) async {
|
||||
if (request.url.contains('user_detailz') && !request.url.contains('change-phone-verify') || request.url.contains('email/verify')) {
|
||||
// Report phone verification success
|
||||
RegistrationAnalyticsService.reportPhoneVerification();
|
||||
GoRouter.of(context).pop();
|
||||
await showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
@@ -50,27 +52,15 @@ class _VerifyScreenState extends State<VerifyScreen> {
|
||||
const Text(
|
||||
'Номер телефона\nуспешно привязан',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(fontSize: 20, height: 1, fontWeight: FontWeight.w600),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Lottie.asset(
|
||||
'assets/lottie_animations/success.json',
|
||||
width: 160,
|
||||
height: 160,
|
||||
),
|
||||
Lottie.asset('assets/lottie_animations/success.json', width: 160, height: 160),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
'Теперь Вам доступен весь функционал!',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
height: 1,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
style: TextStyle(fontSize: 16, height: 1, fontWeight: FontWeight.w500),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
InkWell(
|
||||
@@ -80,18 +70,11 @@ class _VerifyScreenState extends State<VerifyScreen> {
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
height: 52,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: appTheme.blueA400,
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: appTheme.blueA400),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
'Закрыть',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -117,10 +100,7 @@ class _VerifyScreenState extends State<VerifyScreen> {
|
||||
child: Stack(
|
||||
children: [
|
||||
WebViewWidget(controller: _controller),
|
||||
if (_isLoading)
|
||||
const Center(
|
||||
child: Loader(),
|
||||
),
|
||||
if (_isLoading) const Center(child: Loader()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:developer';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/features/auth/presentation/bloc/auth_cubit/auth_cubit.dart';
|
||||
import 'package:eatvio_app/features/registration/services/registration_analytics_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
@@ -24,6 +25,8 @@ class _WebViewRegistrationScreenState extends State<WebViewRegistrationScreen> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
authCubit = sl<AuthCubit>();
|
||||
// Report webview registration started
|
||||
RegistrationAnalyticsService.reportRegistrationStep(18); // Webview registration step
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..addJavaScriptChannel(
|
||||
@@ -43,10 +46,9 @@ class _WebViewRegistrationScreenState extends State<WebViewRegistrationScreen> {
|
||||
NavigationDelegate(
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
if (request.url.contains('profile')) {
|
||||
authCubit.getTokenByCredentials(
|
||||
email!,
|
||||
password!,
|
||||
);
|
||||
// Report webview registration completion
|
||||
RegistrationAnalyticsService.reportRegistrationComplete();
|
||||
authCubit.getTokenByCredentials(email!, password!);
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
@@ -86,12 +88,8 @@ class _WebViewRegistrationScreenState extends State<WebViewRegistrationScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
),
|
||||
body: SafeArea(
|
||||
child: WebViewWidget(controller: _controller),
|
||||
),
|
||||
appBar: AppBar(toolbarHeight: 0),
|
||||
body: SafeArea(child: WebViewWidget(controller: _controller)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import 'package:appmetrica_plugin/appmetrica_plugin.dart';
|
||||
|
||||
class RegistrationAnalyticsService {
|
||||
static const String _eventPrefix = 'registration_step';
|
||||
|
||||
/// Reports registration step completion
|
||||
static void reportRegistrationStep(int stepNumber) {
|
||||
AppMetrica.reportEvent('$_eventPrefix $stepNumber');
|
||||
}
|
||||
|
||||
/// Reports email verification completion
|
||||
static void reportEmailVerification() {
|
||||
AppMetrica.reportEvent('registration_email_verify');
|
||||
}
|
||||
|
||||
/// Reports phone verification completion
|
||||
static void reportPhoneVerification() {
|
||||
AppMetrica.reportEvent('registration_phone_verify');
|
||||
}
|
||||
|
||||
/// Reports registration completion
|
||||
static void reportRegistrationComplete() {
|
||||
AppMetrica.reportEvent('registration_complete');
|
||||
}
|
||||
|
||||
/// Reports registration error
|
||||
static void reportRegistrationError(String error) {
|
||||
AppMetrica.reportEvent('registration_error');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user