diff --git a/CHANGELOG.md b/CHANGELOG.md index beefc974..a04b9318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Profile current phase section for the authenticated `/profile` tab, reusing the bootstrap profile phase snapshot plus aggregate statistics frequency summary to render the read-only phase block without a standalone phase slice. - Introduce personal parameters section for the authenticated `/profile` tab, including canonical `user-parameters` read/update flow, editable profile form card, weekly-goal save support, and selective workouts overview refresh when goal, equipment, or level changes regenerate the personal plan. - Add profile bottom section for the authenticated `/profile` tab, including logout and delete-profile confirmation actions plus direct links to the bundled legal documents. +- Sign-up page now redirects users with unverified emails to the verify-email screen: shows a brief non-dismissible feedback dialog, then automatically pushes the verify-email route after 2 seconds, matching the existing sign-in behavior. - Profile subscription section for the authenticated `/profile` tab, including active and empty subscription states, catalog entrypoints, profile-local subscription card hydration by `subscriptionId`, cancel-subscription confirmation flow and profile page refresh after cancellation. - Profile saved cards section for the authenticated `/profile` tab, including dedicated cards API/repository flow, saved-cards list rendering, add-card dialog with manual card form, default-card command, delete-card confirmation, and local refresh after successful actions. - Authenticated subscriptions catalog screen, including dedicated subscriptions route, catalog Cubit, card UI with normalized remote images, and a profile CTA for opening available subscription plans. diff --git a/lib/features/auth/presentation/pages/sign_up_page.dart b/lib/features/auth/presentation/pages/sign_up_page.dart index c1f7b451..5e045657 100644 --- a/lib/features/auth/presentation/pages/sign_up_page.dart +++ b/lib/features/auth/presentation/pages/sign_up_page.dart @@ -1,9 +1,12 @@ +import 'dart:async'; + import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/constants/app_strings.dart'; +import '../../../../core/failures/feature/auth/auth_failure.dart'; import '../../../../core/router/router_paths.dart'; import '../../../../uikit/buttons/button_state.dart'; import '../../../../uikit/buttons/main_button.dart'; @@ -36,14 +39,48 @@ class _SignUpPageState extends State { bool _isAgree = false; + NavigatorState? _rootNavigator; + Timer? _redirectTimer; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _rootNavigator ??= Navigator.of(context, rootNavigator: true); + } + @override void dispose() { + _redirectTimer?.cancel(); _nameController.dispose(); _emailController.dispose(); _passwordController.dispose(); super.dispose(); } + void _redirectUnverifiedUser({required String dialogMessage}) { + if (_redirectTimer != null) return; + + showAppFeedbackDialog( + context, + title: AppStrings.feedbackErrorTitle, + message: dialogMessage, + isBarrierDismissible: false, + ); + + _redirectTimer = Timer(const Duration(seconds: 2), () { + _redirectTimer = null; + if (!mounted) return; + _rootNavigator?.pop(); + context.push( + AppRoutePaths.verifyEmailPath, + extra: VerifyEmailRouteArgs( + email: _emailController.text.trim(), + resendOnOpen: true, + ), + ); + }); + } + void _submit() { final form = _formKey.currentState; if (form == null || !form.validate()) { @@ -82,11 +119,13 @@ class _SignUpPageState extends State { }, failed: (failure) { if (failure.message.isNotEmpty) { - showAppFeedbackDialog( - context, - title: AppStrings.feedbackErrorTitle, - message: failure.message, - ); + failure is EmailNotVerifiedFailure + ? _redirectUnverifiedUser(dialogMessage: failure.message) + : showAppFeedbackDialog( + context, + title: AppStrings.feedbackErrorTitle, + message: failure.message, + ); } }, );