From 18944be1e3c608dd0aae9964ce0efe463d6e859f Mon Sep 17 00:00:00 2001 From: alexdivadi Date: Sun, 15 Feb 2026 17:42:26 -0600 Subject: [PATCH 1/2] fix: login flow issues --- lib/bootstrap.dart | 3 ++ lib/core/config/router/url_strategy.dart | 4 ++ lib/core/config/router/url_strategy_stub.dart | 1 + lib/core/config/router/url_strategy_web.dart | 5 +++ lib/core/config/theme/theme_mode.g.dart | 2 +- .../features/auth/data/auth_repository.dart | 18 +++++++-- .../email_confirmed_screen.dart | 36 ++++++++++++++--- .../presentation/sign_up/sign_up_screen.dart | 13 ++++++- .../sign_up/sign_up_screen_controller.dart | 12 +++++- .../sign_up/sign_up_screen_controller.g.dart | 2 +- .../sign_up/sign_up_screen_state.dart | 1 + .../sign_up/sign_up_screen_state.freezed.dart | 39 ++++++++++--------- .../event_detail_form_controller.g.dart | 2 +- .../features/profile/data/current_user.dart | 7 +++- .../features/profile/data/current_user.g.dart | 2 +- .../onboarding_screen_controller.g.dart | 2 +- .../profile/profile_screen_controller.g.dart | 2 +- .../attendee_search_form_controller.g.dart | 2 +- .../sign_up_button_controller.g.dart | 2 +- lib/l10n/app_en.arb | 3 ++ lib/l10n/app_es.arb | 4 +- lib/l10n/generated/app_localizations.dart | 6 +++ lib/l10n/generated/app_localizations_en.dart | 3 ++ lib/l10n/generated/app_localizations_es.dart | 4 ++ pubspec.lock | 2 +- pubspec.yaml | 2 + 26 files changed, 137 insertions(+), 42 deletions(-) create mode 100644 lib/core/config/router/url_strategy.dart create mode 100644 lib/core/config/router/url_strategy_stub.dart create mode 100644 lib/core/config/router/url_strategy_web.dart diff --git a/lib/bootstrap.dart b/lib/bootstrap.dart index 9aa166a..c50d93e 100644 --- a/lib/bootstrap.dart +++ b/lib/bootstrap.dart @@ -7,10 +7,13 @@ import 'package:anystep/core/firebase/firebase.dart'; import 'package:anystep/env/env.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:anystep/core/config/router/url_strategy.dart'; import 'package:posthog_flutter/posthog_flutter.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; void bootstrap(FutureOr Function() builder) async { + setPathUrlStrategy(); + // Ensure that Flutter is initialized WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/core/config/router/url_strategy.dart b/lib/core/config/router/url_strategy.dart new file mode 100644 index 0000000..255edbd --- /dev/null +++ b/lib/core/config/router/url_strategy.dart @@ -0,0 +1,4 @@ +import 'url_strategy_stub.dart' + if (dart.library.html) 'url_strategy_web.dart'; + +void setPathUrlStrategy() => setUrlStrategy(); diff --git a/lib/core/config/router/url_strategy_stub.dart b/lib/core/config/router/url_strategy_stub.dart new file mode 100644 index 0000000..3d45e9d --- /dev/null +++ b/lib/core/config/router/url_strategy_stub.dart @@ -0,0 +1 @@ +void setUrlStrategy() {} diff --git a/lib/core/config/router/url_strategy_web.dart b/lib/core/config/router/url_strategy_web.dart new file mode 100644 index 0000000..e5e0409 --- /dev/null +++ b/lib/core/config/router/url_strategy_web.dart @@ -0,0 +1,5 @@ +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +void setUrlStrategy() { + usePathUrlStrategy(); +} diff --git a/lib/core/config/theme/theme_mode.g.dart b/lib/core/config/theme/theme_mode.g.dart index 9bb7c86..f76792c 100644 --- a/lib/core/config/theme/theme_mode.g.dart +++ b/lib/core/config/theme/theme_mode.g.dart @@ -34,7 +34,7 @@ final class ThemeModeControllerProvider } String _$themeModeControllerHash() => - r'44e810e340321774155818c28ed4502f837cabf3'; + r'5d53d58db17c2969ee54cb4ac4faebb6d1c29a84'; abstract class _$ThemeModeController extends $AsyncNotifier { FutureOr build(); diff --git a/lib/core/features/auth/data/auth_repository.dart b/lib/core/features/auth/data/auth_repository.dart index d21e06b..ff2d992 100644 --- a/lib/core/features/auth/data/auth_repository.dart +++ b/lib/core/features/auth/data/auth_repository.dart @@ -119,11 +119,21 @@ class AuthRepository { await _supabase.signInWithPassword(email: email, password: password); return null; } on AuthApiException catch (e) { - if (e.code == "email_not_confirmed") { - Log.w('Email not confirmed for user: $email'); - return 'Please confirm your email address and try again. An email has been sent to you with instructions.'; + switch (e.code) { + case "email_not_confirmed": + { + Log.w('Email not confirmed for user: $email'); + return 'Please confirm your email address and try again. An email has been sent to you with instructions.'; + } + case "over_email_send_rate_limit": + { + Log.w('Signup email rate limit exceeded for user: $email'); + return 'Too many signup attempts. Please wait and try again later.'; + } + default: + Log.e('Signup failed for user: $email', e); + return 'Signup failed. Please try again.'; } - return 'Signup failed. Please try again.'; } catch (e, st) { Log.e('Signup failed', e, st); return 'An error occurred'; diff --git a/lib/core/features/auth/presentation/email_confirmed/email_confirmed_screen.dart b/lib/core/features/auth/presentation/email_confirmed/email_confirmed_screen.dart index cd96b8d..08a01e3 100644 --- a/lib/core/features/auth/presentation/email_confirmed/email_confirmed_screen.dart +++ b/lib/core/features/auth/presentation/email_confirmed/email_confirmed_screen.dart @@ -1,5 +1,4 @@ import 'package:anystep/core/common/constants/spacing.dart'; -import 'package:anystep/core/common/widgets/any_step_app_bar.dart'; import 'package:anystep/core/common/widgets/any_step_scaffold.dart'; import 'package:anystep/core/common/widgets/max_width_container.dart'; import 'package:anystep/core/features/auth/presentation/login/login_screen.dart'; @@ -16,8 +15,15 @@ class EmailConfirmedScreen extends StatelessWidget { @override Widget build(BuildContext context) { final loc = AppLocalizations.of(context); + final params = GoRouterState.of(context).uri.queryParameters; + final errorDescription = params['error_description']; + final errorCode = params['error_code']; + final hasError = + (params['error']?.isNotEmpty ?? false) || + (errorCode?.isNotEmpty ?? false) || + (errorDescription?.isNotEmpty ?? false); + final errorMessage = errorDescription ?? errorCode ?? params['error']; return AnyStepScaffold( - appBar: AnyStepAppBar(title: Text(loc.emailConfirmedTitle)), body: MaxWidthContainer( child: Padding( padding: const EdgeInsets.all(AnyStepSpacing.md16), @@ -25,10 +31,28 @@ class EmailConfirmedScreen extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(loc.emailConfirmedTitle, style: Theme.of(context).textTheme.titleLarge), - const SizedBox(height: AnyStepSpacing.sm8), - Text(loc.emailConfirmedMessage, style: Theme.of(context).textTheme.bodyMedium), - const SizedBox(height: AnyStepSpacing.md16), + if (hasError) ...[ + Icon(Icons.error_outline, size: 64, color: Theme.of(context).colorScheme.error), + const SizedBox(height: AnyStepSpacing.md16), + Text( + errorMessage ?? loc.failedToLoad, + style: Theme.of( + context, + ).textTheme.titleLarge?.copyWith(color: Theme.of(context).colorScheme.error), + textAlign: TextAlign.center, + ), + ] else ...[ + Icon( + Icons.check_circle_outline, + size: 64, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(height: AnyStepSpacing.md16), + Text(loc.emailConfirmedTitle, style: Theme.of(context).textTheme.titleLarge), + const SizedBox(height: AnyStepSpacing.sm8), + Text(loc.emailConfirmedMessage, style: Theme.of(context).textTheme.bodyMedium), + ], + const SizedBox(height: AnyStepSpacing.md24), ElevatedButton( onPressed: () => context.go(LoginScreen.path), child: Text(loc.login), diff --git a/lib/core/features/auth/presentation/sign_up/sign_up_screen.dart b/lib/core/features/auth/presentation/sign_up/sign_up_screen.dart index 2975ef7..217468f 100644 --- a/lib/core/features/auth/presentation/sign_up/sign_up_screen.dart +++ b/lib/core/features/auth/presentation/sign_up/sign_up_screen.dart @@ -6,8 +6,10 @@ import 'package:anystep/l10n/generated/app_localizations.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:go_router/go_router.dart'; import 'sign_up_screen_controller.dart'; +import 'package:anystep/core/features/auth/presentation/confirm_email_screen.dart'; class SignUpScreen extends ConsumerStatefulWidget { const SignUpScreen({super.key}); @@ -28,6 +30,12 @@ class _SignUpScreenState extends ConsumerState { final state = ref.watch(signUpScreenControllerProvider); final loc = AppLocalizations.of(context); + ref.listen(signUpScreenControllerProvider, (previous, next) { + if (next.needsEmailConfirmation) { + context.go(ConfirmEmailScreen.path); + } + }); + return AnyStepScaffold( appBar: AnyStepAppBar(title: Text(loc.backToLogin)), body: MaxWidthContainer( @@ -77,8 +85,11 @@ class _SignUpScreenState extends ConsumerState { labelText: loc.password, obscureText: true, validator: FormBuilderValidators.password( + minLowercaseCount: 0, + minUppercaseCount: 0, + minNumberCount: 0, minSpecialCharCount: 0, - errorText: '', + errorText: loc.passwordMinLength, ), ), AnyStepTextField( diff --git a/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.dart b/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.dart index b12fa55..3a83833 100644 --- a/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.dart +++ b/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.dart @@ -27,10 +27,18 @@ class SignUpScreenController extends _$SignUpScreenController { ); if (result == null) { await ref.read(eventNotificationsControllerProvider.notifier).enableOnSignup(); - state = state.copyWith(isLoading: false, success: true); + state = state.copyWith(isLoading: false, success: true, needsEmailConfirmation: false); Log.d('Sign up successful, user created'); + } else if (result.contains('confirm your email address')) { + state = state.copyWith( + isLoading: false, + success: true, + needsEmailConfirmation: true, + error: null, + ); } else { - state = state.copyWith(isLoading: false, error: result); + state = state.copyWith(isLoading: false, error: result, needsEmailConfirmation: false); + Log.d('Sign up failed: $result'); } } catch (e, st) { Log.e("Error signing up", e, st); diff --git a/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.g.dart b/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.g.dart index ec130b8..9ef9346 100644 --- a/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.g.dart +++ b/lib/core/features/auth/presentation/sign_up/sign_up_screen_controller.g.dart @@ -42,7 +42,7 @@ final class SignUpScreenControllerProvider } String _$signUpScreenControllerHash() => - r'2719909f07950dd0e5681d2a0c248f4d2f3eb766'; + r'f7f30c117d2c01d14a51f8861c7169f0f51e16c8'; abstract class _$SignUpScreenController extends $Notifier { SignUpScreenState build(); diff --git a/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.dart b/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.dart index 8f4daf7..5e23493 100644 --- a/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.dart +++ b/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.dart @@ -7,6 +7,7 @@ abstract class SignUpScreenState with _$SignUpScreenState { const factory SignUpScreenState({ @Default(false) bool isLoading, @Default(false) bool success, + @Default(false) bool needsEmailConfirmation, String? error, }) = _SignUpScreenState; } diff --git a/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.freezed.dart b/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.freezed.dart index 73e0274..0c20093 100644 --- a/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.freezed.dart +++ b/lib/core/features/auth/presentation/sign_up/sign_up_screen_state.freezed.dart @@ -14,7 +14,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$SignUpScreenState { - bool get isLoading; bool get success; String? get error; + bool get isLoading; bool get success; bool get needsEmailConfirmation; String? get error; /// Create a copy of SignUpScreenState /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -25,16 +25,16 @@ $SignUpScreenStateCopyWith get copyWith => _$SignUpScreenStat @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpScreenState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.success, success) || other.success == success)&&(identical(other.error, error) || other.error == error)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is SignUpScreenState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.success, success) || other.success == success)&&(identical(other.needsEmailConfirmation, needsEmailConfirmation) || other.needsEmailConfirmation == needsEmailConfirmation)&&(identical(other.error, error) || other.error == error)); } @override -int get hashCode => Object.hash(runtimeType,isLoading,success,error); +int get hashCode => Object.hash(runtimeType,isLoading,success,needsEmailConfirmation,error); @override String toString() { - return 'SignUpScreenState(isLoading: $isLoading, success: $success, error: $error)'; + return 'SignUpScreenState(isLoading: $isLoading, success: $success, needsEmailConfirmation: $needsEmailConfirmation, error: $error)'; } @@ -45,7 +45,7 @@ abstract mixin class $SignUpScreenStateCopyWith<$Res> { factory $SignUpScreenStateCopyWith(SignUpScreenState value, $Res Function(SignUpScreenState) _then) = _$SignUpScreenStateCopyWithImpl; @useResult $Res call({ - bool isLoading, bool success, String? error + bool isLoading, bool success, bool needsEmailConfirmation, String? error }); @@ -62,10 +62,11 @@ class _$SignUpScreenStateCopyWithImpl<$Res> /// Create a copy of SignUpScreenState /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? success = null,Object? error = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? isLoading = null,Object? success = null,Object? needsEmailConfirmation = null,Object? error = freezed,}) { return _then(_self.copyWith( isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool,needsEmailConfirmation: null == needsEmailConfirmation ? _self.needsEmailConfirmation : needsEmailConfirmation // ignore: cast_nullable_to_non_nullable as bool,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable as String?, )); @@ -152,10 +153,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( bool isLoading, bool success, String? error)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( bool isLoading, bool success, bool needsEmailConfirmation, String? error)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _SignUpScreenState() when $default != null: -return $default(_that.isLoading,_that.success,_that.error);case _: +return $default(_that.isLoading,_that.success,_that.needsEmailConfirmation,_that.error);case _: return orElse(); } @@ -173,10 +174,10 @@ return $default(_that.isLoading,_that.success,_that.error);case _: /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( bool isLoading, bool success, String? error) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( bool isLoading, bool success, bool needsEmailConfirmation, String? error) $default,) {final _that = this; switch (_that) { case _SignUpScreenState(): -return $default(_that.isLoading,_that.success,_that.error);case _: +return $default(_that.isLoading,_that.success,_that.needsEmailConfirmation,_that.error);case _: throw StateError('Unexpected subclass'); } @@ -193,10 +194,10 @@ return $default(_that.isLoading,_that.success,_that.error);case _: /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool isLoading, bool success, String? error)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool isLoading, bool success, bool needsEmailConfirmation, String? error)? $default,) {final _that = this; switch (_that) { case _SignUpScreenState() when $default != null: -return $default(_that.isLoading,_that.success,_that.error);case _: +return $default(_that.isLoading,_that.success,_that.needsEmailConfirmation,_that.error);case _: return null; } @@ -208,11 +209,12 @@ return $default(_that.isLoading,_that.success,_that.error);case _: class _SignUpScreenState implements SignUpScreenState { - const _SignUpScreenState({this.isLoading = false, this.success = false, this.error}); + const _SignUpScreenState({this.isLoading = false, this.success = false, this.needsEmailConfirmation = false, this.error}); @override@JsonKey() final bool isLoading; @override@JsonKey() final bool success; +@override@JsonKey() final bool needsEmailConfirmation; @override final String? error; /// Create a copy of SignUpScreenState @@ -225,16 +227,16 @@ _$SignUpScreenStateCopyWith<_SignUpScreenState> get copyWith => __$SignUpScreenS @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpScreenState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.success, success) || other.success == success)&&(identical(other.error, error) || other.error == error)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _SignUpScreenState&&(identical(other.isLoading, isLoading) || other.isLoading == isLoading)&&(identical(other.success, success) || other.success == success)&&(identical(other.needsEmailConfirmation, needsEmailConfirmation) || other.needsEmailConfirmation == needsEmailConfirmation)&&(identical(other.error, error) || other.error == error)); } @override -int get hashCode => Object.hash(runtimeType,isLoading,success,error); +int get hashCode => Object.hash(runtimeType,isLoading,success,needsEmailConfirmation,error); @override String toString() { - return 'SignUpScreenState(isLoading: $isLoading, success: $success, error: $error)'; + return 'SignUpScreenState(isLoading: $isLoading, success: $success, needsEmailConfirmation: $needsEmailConfirmation, error: $error)'; } @@ -245,7 +247,7 @@ abstract mixin class _$SignUpScreenStateCopyWith<$Res> implements $SignUpScreenS factory _$SignUpScreenStateCopyWith(_SignUpScreenState value, $Res Function(_SignUpScreenState) _then) = __$SignUpScreenStateCopyWithImpl; @override @useResult $Res call({ - bool isLoading, bool success, String? error + bool isLoading, bool success, bool needsEmailConfirmation, String? error }); @@ -262,10 +264,11 @@ class __$SignUpScreenStateCopyWithImpl<$Res> /// Create a copy of SignUpScreenState /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? success = null,Object? error = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? isLoading = null,Object? success = null,Object? needsEmailConfirmation = null,Object? error = freezed,}) { return _then(_SignUpScreenState( isLoading: null == isLoading ? _self.isLoading : isLoading // ignore: cast_nullable_to_non_nullable as bool,success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable +as bool,needsEmailConfirmation: null == needsEmailConfirmation ? _self.needsEmailConfirmation : needsEmailConfirmation // ignore: cast_nullable_to_non_nullable as bool,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable as String?, )); diff --git a/lib/core/features/events/presentation/event_detail/event_detail_form_controller.g.dart b/lib/core/features/events/presentation/event_detail/event_detail_form_controller.g.dart index fedc266..e4e45a9 100644 --- a/lib/core/features/events/presentation/event_detail/event_detail_form_controller.g.dart +++ b/lib/core/features/events/presentation/event_detail/event_detail_form_controller.g.dart @@ -60,7 +60,7 @@ final class EventDetailFormControllerProvider } String _$eventDetailFormControllerHash() => - r'91d431846ae59e9bda5d897d42a0c1fca9f00a37'; + r'575345c2de216f71d2285b9b413d1451af42bbad'; final class EventDetailFormControllerFamily extends $Family with diff --git a/lib/core/features/profile/data/current_user.dart b/lib/core/features/profile/data/current_user.dart index 58b8569..76b4fe2 100644 --- a/lib/core/features/profile/data/current_user.dart +++ b/lib/core/features/profile/data/current_user.dart @@ -41,7 +41,12 @@ Stream currentUserStream(Ref ref) async* { } try { - if (authState.value == null) throw Exception('No user logged in'); + if (authState.isLoading) { + final resolved = await ref.watch(authStateStreamProvider.future); + if (resolved == null) throw Exception('No user logged in'); + } else if (authState.value == null) { + throw Exception('No user logged in'); + } final user = await ref .read(userRepositoryProvider) diff --git a/lib/core/features/profile/data/current_user.g.dart b/lib/core/features/profile/data/current_user.g.dart index 428ca37..89e2607 100644 --- a/lib/core/features/profile/data/current_user.g.dart +++ b/lib/core/features/profile/data/current_user.g.dart @@ -45,4 +45,4 @@ final class CurrentUserStreamProvider } } -String _$currentUserStreamHash() => r'43c3183a73e3904c16f31140e45565f4cf71113a'; +String _$currentUserStreamHash() => r'3b994d7b1b1557281bc49402a285fc7aae8cde05'; diff --git a/lib/core/features/profile/presentation/onboarding/onboarding_screen_controller.g.dart b/lib/core/features/profile/presentation/onboarding/onboarding_screen_controller.g.dart index c655108..f7d5708 100644 --- a/lib/core/features/profile/presentation/onboarding/onboarding_screen_controller.g.dart +++ b/lib/core/features/profile/presentation/onboarding/onboarding_screen_controller.g.dart @@ -35,7 +35,7 @@ final class OnboardingScreenControllerProvider } String _$onboardingScreenControllerHash() => - r'abcf3fd725b579ae6a2a9e52fe266d7434aedbb7'; + r'a89790454ca594720d6e5e5e3da44ff63b25023a'; abstract class _$OnboardingScreenController extends $AsyncNotifier { FutureOr build(); diff --git a/lib/core/features/profile/presentation/profile/profile_screen_controller.g.dart b/lib/core/features/profile/presentation/profile/profile_screen_controller.g.dart index f778a9a..7629379 100644 --- a/lib/core/features/profile/presentation/profile/profile_screen_controller.g.dart +++ b/lib/core/features/profile/presentation/profile/profile_screen_controller.g.dart @@ -46,7 +46,7 @@ final class ProfileScreenControllerProvider } String _$profileScreenControllerHash() => - r'887975828d543746adcb56c3eeac68c65888b558'; + r'7422402bd949d49ff436f95866732a6dbca104bb'; abstract class _$ProfileScreenController extends $Notifier { diff --git a/lib/core/features/user_events/presentation/attendee_search_form_controller.g.dart b/lib/core/features/user_events/presentation/attendee_search_form_controller.g.dart index fc02273..941f3b3 100644 --- a/lib/core/features/user_events/presentation/attendee_search_form_controller.g.dart +++ b/lib/core/features/user_events/presentation/attendee_search_form_controller.g.dart @@ -53,7 +53,7 @@ final class AttendeeSearchFormControllerProvider } String _$attendeeSearchFormControllerHash() => - r'2288f2afcd834d8e8d91478d3760175cb522fa2a'; + r'9ce6c0c5c76074827c8514f42608701e26a75fe6'; final class AttendeeSearchFormControllerFamily extends $Family with diff --git a/lib/core/features/user_events/presentation/sign_up_button_controller.g.dart b/lib/core/features/user_events/presentation/sign_up_button_controller.g.dart index 407b9ab..ef34b5c 100644 --- a/lib/core/features/user_events/presentation/sign_up_button_controller.g.dart +++ b/lib/core/features/user_events/presentation/sign_up_button_controller.g.dart @@ -34,7 +34,7 @@ final class SignUpButtonControllerProvider } String _$signUpButtonControllerHash() => - r'30c99a52816b8e666fe817352989f9dab9044f1b'; + r'df78a19fa5f056558f5e2eefe08fd40e04b7432d'; abstract class _$SignUpButtonController extends $AsyncNotifier { FutureOr build(); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2aba77a..11574e2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -44,6 +44,9 @@ "login": "Login", "@login": {"description": "Login button label"} , + "passwordMinLength": "Password must be at least 8 characters", + "@passwordMinLength": {"description": "Validation error when password is too short"} + , "reportsTitle": "Reports", "@reportsTitle": {"description": "App bar title for reports screen and navigation label"}, "exportCsv": "Export CSV", diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index c850c8e..93445bc 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -42,7 +42,9 @@ "logout": "Cerrar sesión", "@logout": {"description": "Etiqueta del botón de cerrar sesión"}, "login": "Iniciar sesión", - "@login": {"description": "Etiqueta del botón de iniciar sesión"} + "@login": {"description": "Etiqueta del botón de iniciar sesión"}, + "passwordMinLength": "La contraseña debe tener al menos 8 caracteres", + "@passwordMinLength": {"description": "Error de validación cuando la contraseña es demasiado corta"} , "reportsTitle": "Informes", "@reportsTitle": {"description": "Título de la pantalla de informes"}, diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index e226bb1..194cbb3 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -188,6 +188,12 @@ abstract class AppLocalizations { /// **'Login'** String get login; + /// Validation error when password is too short + /// + /// In en, this message translates to: + /// **'Password must be at least 8 characters'** + String get passwordMinLength; + /// App bar title for reports screen and navigation label /// /// In en, this message translates to: diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index e141e00..6dd46ef 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -64,6 +64,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get login => 'Login'; + @override + String get passwordMinLength => 'Password must be at least 8 characters'; + @override String get reportsTitle => 'Reports'; diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart index 550cf68..8f00520 100644 --- a/lib/l10n/generated/app_localizations_es.dart +++ b/lib/l10n/generated/app_localizations_es.dart @@ -64,6 +64,10 @@ class AppLocalizationsEs extends AppLocalizations { @override String get login => 'Iniciar sesión'; + @override + String get passwordMinLength => + 'La contraseña debe tener al menos 8 caracteres'; + @override String get reportsTitle => 'Informes'; diff --git a/pubspec.lock b/pubspec.lock index 342ddea..f4095ae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -521,7 +521,7 @@ packages: source: sdk version: "0.0.0" flutter_web_plugins: - dependency: transitive + dependency: "direct main" description: flutter source: sdk version: "0.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 04c6399..2c220e1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,8 @@ dependencies: firebase_remote_config: ^6.1.2 flutter: sdk: flutter + flutter_web_plugins: + sdk: flutter flutter_dotenv: ^5.2.1 flutter_form_builder: ^10.0.1 flutter_localizations: From d77ba51d8939234451b909df8ec33eee349f3bc2 Mon Sep 17 00:00:00 2001 From: alexdivadi Date: Sun, 15 Feb 2026 17:43:58 -0600 Subject: [PATCH 2/2] fix: site metadata --- web/index.html | 6 +++--- web/manifest.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/index.html b/web/index.html index a7ab3d9..ff5e99e 100644 --- a/web/index.html +++ b/web/index.html @@ -19,18 +19,18 @@ - + - + - anystep + AnyStep