forked from eatvio/eatvio_app
feat(verify): phone + email
This commit is contained in:
@@ -77,7 +77,7 @@ class AppRouter {
|
||||
name: 'authScreen',
|
||||
builder: (context, state) => const AuthScreen(),
|
||||
routes: [
|
||||
GoRoute(path: 'webView-registration-screen', name: 'webViewRegistrationScreen', builder: (context, state) => const WebViewRegistrationScreen()),
|
||||
// GoRoute(path: 'webView-registration-screen', name: 'webViewRegistrationScreen', builder: (context, state) => const WebViewRegistrationScreen()),
|
||||
GoRoute(path: 'registration-screen', name: 'registrationScreen', builder: (context, state) => const RegistrationScreen()),
|
||||
],
|
||||
),
|
||||
|
||||
29
lib/core/dio/phone_verify_error_interceptor.dart
Normal file
29
lib/core/dio/phone_verify_error_interceptor.dart
Normal file
@@ -0,0 +1,29 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class PhoneVerifyErrorInterceptor extends Interceptor {
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) async {
|
||||
if (err.response?.statusCode == 405) {
|
||||
final data = err.response?.data;
|
||||
|
||||
if (data is Map<String, dynamic> && data['type'] == 'unverificated_phone') {
|
||||
final String phone = await sl<ProfileRepository>().getMyPhone();
|
||||
final String passKey = await sl<ProfileRepository>().getPassKey(phone);
|
||||
AppRouter.navigatorKey.currentContext?.pushNamed('verifyScreen', extra: passKey);
|
||||
return handler.reject(
|
||||
DioException(
|
||||
requestOptions: err.requestOptions,
|
||||
response: err.response,
|
||||
error: 'Phone number not verified',
|
||||
type: DioExceptionType.badResponse,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return handler.next(err);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/dio/phone_verify_error_interceptor.dart';
|
||||
import 'package:eatvio_app/core/interceptors/token_interceptor.dart';
|
||||
import 'package:eatvio_app/core/websockets/ws_manager.dart';
|
||||
import 'package:eatvio_app/core/websockets/ws_service.dart';
|
||||
@@ -191,7 +192,20 @@ Future<void> init() async {
|
||||
|
||||
// External
|
||||
sl.registerLazySingleton(
|
||||
() => Dio(BaseOptions(baseUrl: baseUrl, headers: {'accept': 'application/json', 'content-type': 'application/json'}))..interceptors.add(TokenInterceptor()),
|
||||
() => Dio(
|
||||
BaseOptions(
|
||||
baseUrl: baseUrl,
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
),
|
||||
)..interceptors.addAll(
|
||||
[
|
||||
TokenInterceptor(),
|
||||
PhoneVerifyErrorInterceptor(),
|
||||
],
|
||||
),
|
||||
);
|
||||
sl.registerLazySingleton(() async => const FlutterSecureStorage());
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
children: [
|
||||
const Text('Нет аккаунта? '),
|
||||
GestureDetector(
|
||||
onTap: () => GoRouter.of(context).goNamed('webViewRegistrationScreen'),
|
||||
onTap: () => GoRouter.of(context).goNamed('registrationScreen'),
|
||||
child: Text(
|
||||
'Зарегистрироваться',
|
||||
style: TextStyle(
|
||||
|
||||
@@ -36,10 +36,6 @@ class ProfileCubit extends Cubit<ProfileState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getPassKey(String phone) async {
|
||||
return (await profileRepository.getPassKey('+79150626151'));
|
||||
}
|
||||
|
||||
Future<void> getMyProfile({
|
||||
String period = '1',
|
||||
}) async {
|
||||
|
||||
@@ -26,6 +26,7 @@ import 'package:eatvio_app/features/profile/presentation/widgets/profile_blog_po
|
||||
import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -54,6 +55,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
final List<String> chipsLabelList = ['Вес', 'Замеры', 'ИМТ'];
|
||||
final List<String> chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ'];
|
||||
final List<String> chipsIntervalList = ['1', '3', '6', '12', 'all'];
|
||||
final TextEditingController controller = TextEditingController();
|
||||
|
||||
List<WeightModel> weightPoints = [];
|
||||
List<CircumferenceModel> circumferencePoints = [];
|
||||
@@ -222,9 +224,14 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(onPressed: () async {
|
||||
final String passKey = await profileCubit.getPassKey('+79150626151');
|
||||
GoRouter.of(context).pushNamed('verifyScreen', extra: passKey);
|
||||
}, child: Text('phone verify')),
|
||||
await sl<ProfileRepository>().sendEmailCode();
|
||||
}, child: Text('send email verify code')),
|
||||
TextFormField(
|
||||
controller: controller,
|
||||
),
|
||||
ElevatedButton(onPressed: () async {
|
||||
await sl<ProfileRepository>().tryVerifyEmailByCode(controller.text);
|
||||
}, child: Text('try verify email by code')),
|
||||
_header(state),
|
||||
if (state.profile.roles.contains('consultant'))
|
||||
Column(
|
||||
|
||||
@@ -185,4 +185,16 @@ class ProfileRepository {
|
||||
Future<String> getPassKey(String phone) async {
|
||||
return (jsonDecode((await profileService.getPassKey(json: '{"route_name": "user_detailz.change-phone-verify", "route_params": {"phone": "$phone"}}'))))['key_is']!;
|
||||
}
|
||||
|
||||
Future<String> getMyPhone() async {
|
||||
return (jsonDecode(await profileService.getMyPhone())['phone']);
|
||||
}
|
||||
|
||||
Future<void> sendEmailCode() async {
|
||||
return await profileService.sendEmailCode();
|
||||
}
|
||||
|
||||
Future<void> tryVerifyEmailByCode(String code) async {
|
||||
return await profileService.tryVerifyEmailByCode(code: "{\"code\": \"$code\"}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,4 +108,15 @@ abstract class ProfileService {
|
||||
Future<String> getPassKey({
|
||||
@Body() required String json,
|
||||
});
|
||||
|
||||
@GET('/api/profile/my_phone')
|
||||
Future<String> getMyPhone();
|
||||
|
||||
@POST('/api/profile/send_email_code')
|
||||
Future<void> sendEmailCode();
|
||||
|
||||
@POST('/api/profile/verificate_email_code')
|
||||
Future<void> tryVerifyEmailByCode({
|
||||
@Body() required String code,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ abstract class UserRegistrationSheet with _$UserRegistrationSheet {
|
||||
required String birthdate,
|
||||
required String gender,
|
||||
required String location,
|
||||
@JsonKey(name: 'response_body') required String responseBody,
|
||||
@JsonKey(name: 'response_body', defaultValue: '{}') required String responseBody,
|
||||
required String lang,
|
||||
required int weight,
|
||||
required int height,
|
||||
|
||||
@@ -25,7 +25,7 @@ class RegistrationCubit extends Cubit<RegistrationState> {
|
||||
birthdate: '',
|
||||
gender: '',
|
||||
location: '',
|
||||
responseBody: '',
|
||||
responseBody: '{}',
|
||||
lang: 'Русский',
|
||||
weight: 0,
|
||||
height: 0,
|
||||
@@ -54,6 +54,7 @@ class RegistrationCubit extends Cubit<RegistrationState> {
|
||||
final token = await registrationRepository.tryRegister(
|
||||
state.sheet.copyWith(
|
||||
phone: state.sheet.phone.replaceAll(' ', '').replaceAll('(', '').replaceAll(')', ''),
|
||||
responseBody: '{}',
|
||||
),
|
||||
);
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
|
||||
@@ -478,4 +478,49 @@ class MockProfileService extends _i1.Mock implements _i5.ProfileService {
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<String>);
|
||||
|
||||
@override
|
||||
_i6.Future<String> getMyPhone() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMyPhone,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<String>.value(_i11.dummyValue<String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyPhone,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
returnValueForMissingStub:
|
||||
_i6.Future<String>.value(_i11.dummyValue<String>(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMyPhone,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i6.Future<String>);
|
||||
|
||||
@override
|
||||
_i6.Future<void> sendEmailCode() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#sendEmailCode,
|
||||
[],
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
|
||||
@override
|
||||
_i6.Future<void> tryVerifyEmailByCode({required String? code}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#tryVerifyEmailByCode,
|
||||
[],
|
||||
{#code: code},
|
||||
),
|
||||
returnValue: _i6.Future<void>.value(),
|
||||
returnValueForMissingStub: _i6.Future<void>.value(),
|
||||
) as _i6.Future<void>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user