-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release 17/08/2021
Showing
98 changed files
with
5,529 additions
and
2,045 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name: Generate Updated Goldens | ||
on: | ||
push: | ||
branches-ignore: [master, release, dev] # only run on feature branches | ||
paths: | ||
- '**/golden_tests/**.dart' | ||
|
||
workflow_dispatch: | ||
|
||
jobs: | ||
generate-goldens: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
with: | ||
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token. | ||
fetch-depth: 0 | ||
- name: Setup Java JDK | ||
uses: actions/setup-java@v2.2.0 | ||
with: | ||
distribution: 'adopt' | ||
java-version: '12.x' | ||
- name: Checkout Flutter Stable Channel | ||
uses: subosito/flutter-action@v1.5.3 | ||
with: | ||
channel: 'stable' | ||
- name: Get Pub Dependencies | ||
run: flutter pub get | ||
- name: Run Build Runner For Codegen Files | ||
run: flutter packages pub run build_runner build --delete-conflicting-outputs | ||
- name: Run tests | ||
run: flutter test --update-goldens test/golden_tests | ||
- name: Commit Updated Goldens | ||
run: | | ||
git config --global user.name 'arafaysaleem' | ||
git config --global user.email 'arafaysaleem@users.noreply.github.com' | ||
git add -A | ||
git commit -m "test(Goldens): update generated goldens for new changes" | ||
- name: GitHub Push To Repository | ||
uses: ad-m/github-push-action@v0.6.0 | ||
with: | ||
github_token: ${{ secrets.EZ_TICKETS_APP_TOKEN }} | ||
branch: ${{ github.ref }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,7 @@ | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
import '../providers/states/future_state.dart'; | ||
|
||
typedef JSON = Map<String, dynamic>; | ||
typedef QueryParams = Map<String, String>; | ||
typedef QueryParams = Map<String, String>; | ||
typedef StateListener<T> = ProviderListener<StateController<T>>; | ||
typedef FutureStateListener<T> = ProviderListener<StateController<FutureState<T>>>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Services | ||
import '../services/networking/network_exception.dart'; | ||
|
||
//Repositories | ||
import '../services/repositories/auth_repository.dart'; | ||
|
||
//States | ||
import 'states/forgot_password_state.dart'; | ||
|
||
class ForgotPasswordProvider extends StateNotifier<ForgotPasswordState> { | ||
final _otpDigits = ['0', '0', '0', '0']; | ||
final AuthRepository _authRepository; | ||
String? _email; | ||
|
||
ForgotPasswordProvider({ | ||
required AuthRepository authRepository, | ||
required ForgotPasswordState initialState, | ||
}) | ||
: _authRepository = authRepository, super(initialState); | ||
|
||
String get _otpCode => _otpDigits.fold('', (otp, digit) => '$otp$digit'); | ||
|
||
void setOtpDigit(int i, String digit) { | ||
_otpDigits[i] = digit; | ||
} | ||
|
||
Future<void> requestOtpCode(String email) async { | ||
final lastState = state; | ||
state = const ForgotPasswordState.loading(loading: 'Verifying user email'); | ||
try { | ||
final data = {'email': email}; | ||
final result = await _authRepository.sendForgotPasswordData(data: data); | ||
_email = email; | ||
state = ForgotPasswordState.otp(otpSentMessage: result); | ||
} on NetworkException catch (e) { | ||
state = ForgotPasswordState.failed( | ||
reason: e.message, | ||
lastState: lastState, | ||
); | ||
} | ||
} | ||
|
||
Future<void> resendOtpCode() async => requestOtpCode(_email!); | ||
|
||
Future<void> verifyOtp() async { | ||
final lastState = state; | ||
state = const ForgotPasswordState.loading(loading: 'Verifying otp code'); | ||
try { | ||
final data = {'email': _email, 'OTP': _otpCode}; | ||
final result = await _authRepository.sendOtpData(data: data); | ||
state = ForgotPasswordState.resetPassword(otpVerifiedMessage: result); | ||
} on NetworkException catch (e) { | ||
state = ForgotPasswordState.failed( | ||
reason: e.message, | ||
lastState: lastState, | ||
); | ||
} | ||
} | ||
|
||
Future<void> resetPassword({required String password}) async { | ||
final lastState = state; | ||
state = const ForgotPasswordState.loading(loading: 'Resetting password'); | ||
try { | ||
final data = {'email': _email, 'password': password}; | ||
final result = await _authRepository.sendResetPasswordData(data: data); | ||
state = ForgotPasswordState.success( | ||
success: result, | ||
); | ||
} on NetworkException catch (e) { | ||
state = ForgotPasswordState.failed( | ||
reason: e.message, | ||
lastState: lastState, | ||
); | ||
} | ||
} | ||
|
||
void retryForgotPassword(ForgotPasswordState lastState) { | ||
state = lastState; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import 'package:freezed_annotation/freezed_annotation.dart'; | ||
|
||
part 'forgot_password_state.freezed.dart'; | ||
|
||
@freezed | ||
class ForgotPasswordState with _$ForgotPasswordState { | ||
const factory ForgotPasswordState.email() = FORGOT_PW_EMAIL; | ||
|
||
const factory ForgotPasswordState.otp({ | ||
required String otpSentMessage, | ||
}) = FORGOT_PW_OTP; | ||
|
||
const factory ForgotPasswordState.resetPassword({ | ||
required String otpVerifiedMessage, | ||
}) = FORGOT_PW_RESET_PASSWORD; | ||
|
||
const factory ForgotPasswordState.loading({ | ||
required String loading, | ||
}) = LOADING; | ||
|
||
const factory ForgotPasswordState.failed({ | ||
required String reason, | ||
required ForgotPasswordState lastState, | ||
}) = FORGOT_PW_FAILED; | ||
|
||
const factory ForgotPasswordState.success({ | ||
String? success, | ||
}) = FORGOT_PW_SUCCESS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,170 @@ | ||
import 'package:auto_route/annotations.dart'; | ||
// ignore_for_file: constant_identifier_names | ||
import 'package:flutter/material.dart'; | ||
|
||
//Screens | ||
import '../views/screens/app_startup_screen.dart'; | ||
import '../views/screens/change_password_screen.dart'; | ||
import '../views/screens/confirmation_screen.dart'; | ||
import '../views/screens/forgot_password_screen.dart'; | ||
import '../views/screens/home_screen.dart'; | ||
import '../views/screens/login_screen.dart'; | ||
import '../views/screens/register_screen.dart'; | ||
import '../views/screens/movies_screen.dart'; | ||
import '../views/screens/movie_details_screen.dart'; | ||
import '../views/screens/trailer_screen.dart'; | ||
import '../views/screens/movies_screen.dart'; | ||
import '../views/screens/payment_screen.dart'; | ||
import '../views/screens/register_screen.dart'; | ||
import '../views/screens/shows_screen.dart'; | ||
import '../views/screens/theater_screen.dart'; | ||
import '../views/screens/ticket_summary_screen.dart'; | ||
import '../views/screens/payment_screen.dart'; | ||
import '../views/screens/confirmation_screen.dart'; | ||
import '../views/screens/trailer_screen.dart'; | ||
import '../views/screens/user_bookings_screen.dart'; | ||
import '../views/screens/change_password_screen.dart'; | ||
import '../views/screens/welcome_screen.dart'; | ||
|
||
//Routes | ||
import 'routes.dart'; | ||
|
||
/// A utility class provides basic methods for navigation. | ||
/// This class has no constructor and all variables are `static`. | ||
@immutable | ||
class AppRouter { | ||
const AppRouter._(); | ||
|
||
/// The global key used to access navigator without context | ||
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); | ||
|
||
/// The name of the route that loads on app startup | ||
static const String initialRoute = Routes.AppStartupScreenRoute; | ||
|
||
/// This method is used when the app is navigating using named routes. | ||
/// | ||
/// It maps each route name to a specific screen route. | ||
/// | ||
/// In case of unknown route name, it returns a route indicating error. | ||
static Route<dynamic>? generateRoute(RouteSettings settings) { | ||
// final args = settings.arguments; | ||
switch (settings.name) { | ||
case Routes.AppStartupScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const AppStartupScreen(), | ||
settings: const RouteSettings(name: Routes.AppStartupScreenRoute), | ||
); | ||
case Routes.HomeScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const HomeScreen(), | ||
settings: const RouteSettings(name: Routes.HomeScreenRoute), | ||
); | ||
case Routes.LoginScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const LoginScreen(), | ||
settings: const RouteSettings(name: Routes.LoginScreenRoute), | ||
); | ||
case Routes.RegisterScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const RegisterScreen(), | ||
settings: const RouteSettings(name: Routes.RegisterScreenRoute), | ||
); | ||
case Routes.ForgotPasswordScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const ForgotPasswordScreen(), | ||
settings: const RouteSettings(name: Routes.ForgotPasswordScreenRoute), | ||
); | ||
case Routes.WelcomeScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const WelcomeScreen(), | ||
settings: const RouteSettings(name: Routes.WelcomeScreenRoute), | ||
); | ||
case Routes.ChangePasswordScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const ChangePasswordScreen(), | ||
settings: const RouteSettings(name: Routes.ChangePasswordScreenRoute), | ||
); | ||
case Routes.UserBookingsScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const UserBookingsScreen(), | ||
settings: const RouteSettings(name: Routes.UserBookingsScreenRoute), | ||
); | ||
case Routes.MoviesScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const MoviesScreen(), | ||
settings: const RouteSettings(name: Routes.MoviesScreenRoute), | ||
); | ||
case Routes.MovieDetailsScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const MovieDetailsScreen(), | ||
settings: const RouteSettings(name: Routes.MovieDetailsScreenRoute), | ||
); | ||
case Routes.TrailerScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const TrailerScreen(), | ||
settings: const RouteSettings(name: Routes.TrailerScreenRoute), | ||
); | ||
case Routes.ShowsScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const ShowsScreen(), | ||
settings: const RouteSettings(name: Routes.ShowsScreenRoute), | ||
); | ||
case Routes.TheaterScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const TheaterScreen(), | ||
settings: const RouteSettings(name: Routes.TheaterScreenRoute), | ||
); | ||
case Routes.TicketSummaryScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const TicketSummaryScreen(), | ||
settings: const RouteSettings(name: Routes.TicketSummaryScreenRoute), | ||
); | ||
case Routes.PaymentScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const PaymentScreen(), | ||
settings: const RouteSettings(name: Routes.PaymentScreenRoute), | ||
); | ||
case Routes.ConfirmationScreenRoute: | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => const ConfirmationScreen(), | ||
settings: const RouteSettings(name: Routes.ConfirmationScreenRoute), | ||
); | ||
default: | ||
return _errorRoute(); | ||
} | ||
} | ||
|
||
/// This method returns an error page to indicate redirection to an | ||
/// unknown route. | ||
static Route<dynamic> _errorRoute() { | ||
return MaterialPageRoute<dynamic>( | ||
builder: (_) => Scaffold( | ||
appBar: AppBar( | ||
title: const Text('Unknown Route'), | ||
), | ||
body: const Center( | ||
child: Text('Unknown Route'), | ||
), | ||
), | ||
); | ||
} | ||
|
||
/// This method is used to navigate to a screen using it's name | ||
static Future<dynamic> pushNamed(String routeName, {dynamic args}) { | ||
return navigatorKey.currentState!.pushNamed(routeName, arguments: args); | ||
} | ||
|
||
/// This method is used to navigate back to the previous screen. | ||
/// | ||
/// The [result] can contain any value that we want to return to the previous | ||
/// screen. | ||
static Future<void> pop([dynamic result]) async { | ||
navigatorKey.currentState!.pop(result); | ||
} | ||
|
||
/// This method is used to navigate all the way back to a specific screen. | ||
/// | ||
/// The [routeName] is the name of the screen we want to go back to. | ||
static void popUntil(String routeName) { | ||
navigatorKey.currentState!.popUntil(ModalRoute.withName(routeName)); | ||
} | ||
|
||
@MaterialAutoRouter( | ||
routes: <AutoRoute>[ | ||
AutoRoute<Widget>(page: AppStartupScreen, initial: true), | ||
AutoRoute<Widget>(page: RegisterScreen), | ||
AutoRoute<Widget>(page: LoginScreen), | ||
AutoRoute<Widget>(page: MoviesScreen), | ||
AutoRoute<Widget>(page: MovieDetailsScreen), | ||
AutoRoute<Widget>(page: TrailerScreen), | ||
AutoRoute<Widget>(page: ShowsScreen), | ||
AutoRoute<Widget>(page: TheaterScreen), | ||
AutoRoute<Widget>(page: TicketSummaryScreen), | ||
AutoRoute<Widget>(page: PaymentScreen), | ||
AutoRoute<Widget>(page: ConfirmationScreen), | ||
AutoRoute<Widget>(page: UserBookingsScreen), | ||
AutoRoute<Widget>(page: ChangePasswordScreen), | ||
], | ||
) | ||
class $AppRouter{} | ||
/// This method is used to navigate all the way back to the first screen | ||
/// shown on startup i.e. the [initialRoute]. | ||
static void popUntilRoot() { | ||
navigatorKey.currentState!.popUntil(ModalRoute.withName(initialRoute)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// ignore_for_file: constant_identifier_names | ||
import 'package:flutter/material.dart'; | ||
|
||
/// A utility class that holds screen names for named navigation. | ||
/// This class has no constructor and all variables are `static`. | ||
@immutable | ||
class Routes { | ||
const Routes._(); | ||
|
||
/// The name of the route for app startup screen | ||
static const String AppStartupScreenRoute = '/app-startup-screen'; | ||
|
||
/// The name of the route for home screen. | ||
static const String HomeScreenRoute = '/home-screen'; | ||
|
||
/// The name of the route for login screen. | ||
static const String LoginScreenRoute = '/login-screen'; | ||
|
||
/// The name of the route for home screen. | ||
static const String RegisterScreenRoute = '/register-screen'; | ||
|
||
/// The name of the route for login screen. | ||
static const String ForgotPasswordScreenRoute = '/forgot-password-screen'; | ||
|
||
/// The name of the route for home screen. | ||
static const String WelcomeScreenRoute = '/welcome-screen'; | ||
|
||
/// The name of the route for login screen. | ||
static const String ChangePasswordScreenRoute = '/change-password-screen'; | ||
|
||
/// The name of the route for user bookings screen. | ||
static const String UserBookingsScreenRoute = '/user-bookings-screen'; | ||
|
||
/// The name of the route for movies screen. | ||
static const String MoviesScreenRoute = '/movies-screen'; | ||
|
||
/// The name of the route for movie details screen. | ||
static const String MovieDetailsScreenRoute = '/movie-details-screen'; | ||
|
||
/// The name of the route for trailer screen. | ||
static const String TrailerScreenRoute = '/trailer-screen'; | ||
|
||
/// The name of the route for shows screen. | ||
static const String ShowsScreenRoute = '/shows-screen'; | ||
|
||
/// The name of the route for theater map screen. | ||
static const String TheaterScreenRoute = '/theater-screen'; | ||
|
||
/// The name of the route for ticket summary screen. | ||
static const String TicketSummaryScreenRoute = '/ticket-summary-screen'; | ||
|
||
/// The name of the route for payment screen. | ||
static const String PaymentScreenRoute = '/payment-screen'; | ||
|
||
/// The name of the route for payment/booking confirmation screen. | ||
static const String ConfirmationScreenRoute = '/confirmation-screen'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../helper/utils/constants.dart'; | ||
|
||
//Providers | ||
import '../../providers/all_providers.dart'; | ||
|
||
//Routing | ||
import '../../routes/app_router.dart'; | ||
|
||
//States | ||
import '../../providers/states/forgot_password_state.dart'; | ||
|
||
//Widgets | ||
import '../widgets/common/custom_dialog.dart'; | ||
import '../widgets/common/rounded_bottom_container.dart'; | ||
import '../widgets/common/scrollable_column.dart'; | ||
import '../widgets/forgot_password/forgot_button_widget.dart'; | ||
import '../widgets/forgot_password/forgot_message_widget.dart'; | ||
import '../widgets/forgot_password/forgot_name_widget.dart'; | ||
import '../widgets/forgot_password/forgot_resend_widget.dart'; | ||
import '../widgets/forgot_password/forgot_text_fields.dart'; | ||
|
||
class ForgotPasswordScreen extends HookWidget { | ||
const ForgotPasswordScreen(); | ||
|
||
Future<bool> _showConfirmDialog(BuildContext context) async { | ||
final doPop = await showDialog<bool>( | ||
context: context, | ||
barrierColor: Constants.barrierColor, | ||
builder: (ctx) => const CustomDialog.confirm( | ||
title: 'Are you sure?', | ||
body: 'Do you want to go back without resetting your password?', | ||
trueButtonText: 'Yes', | ||
falseButtonText: 'No', | ||
), | ||
); | ||
final popTheScreen = doPop != null && doPop; | ||
return Future<bool>.value(popTheScreen); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
late final emailController = useTextEditingController(); | ||
late final newPasswordController = useTextEditingController(); | ||
late final cNewPasswordController = useTextEditingController(); | ||
late final _formKey = useMemoized(() => GlobalKey<FormState>()); | ||
return Scaffold( | ||
body: ProviderListener<ForgotPasswordState>( | ||
provider: forgotPasswordProvider, | ||
onChange: (context, forgotPwState) async => forgotPwState.maybeWhen( | ||
success: (_) async { | ||
emailController.clear(); | ||
newPasswordController.clear(); | ||
cNewPasswordController.clear(); | ||
AppRouter.pop().then<bool?>((_) async { | ||
return await showDialog<bool>( | ||
context: context, | ||
barrierColor: Constants.barrierColor.withOpacity(0.75), | ||
builder: (ctx) => const CustomDialog.alert( | ||
title: 'Password Reset Successful', | ||
body: "In order to proceed, you'll have to login again with " | ||
'your new password', | ||
buttonText: 'Okay', | ||
), | ||
); | ||
}); | ||
}, | ||
failed: (reason, lastState) async => await showDialog<bool>( | ||
context: context, | ||
barrierColor: Constants.barrierColor.withOpacity(0.75), | ||
builder: (ctx) => CustomDialog.alert( | ||
title: 'Password Reset Failure', | ||
body: reason, | ||
buttonText: 'Retry', | ||
onButtonPressed: (){ | ||
final forgotProv = context.read(forgotPasswordProvider.notifier); | ||
forgotProv.retryForgotPassword(lastState); | ||
}, | ||
), | ||
), | ||
orElse: () {}, | ||
), | ||
child: GestureDetector( | ||
onTap: () => FocusScope.of(context).unfocus(), | ||
child: ScrollableColumn( | ||
children: [ | ||
//Input card | ||
Form( | ||
key: _formKey, | ||
onWillPop: () => _showConfirmDialog(context), | ||
child: RoundedBottomContainer( | ||
padding: const EdgeInsets.fromLTRB(25.0, 28, 25.0, 20), | ||
children: [ | ||
//Relevant Page Name | ||
const ForgotNameWidget(), | ||
|
||
const SizedBox(height: 20), | ||
|
||
//Relevant Input Fields | ||
ForgotTextFields( | ||
emailController: emailController, | ||
newPasswordController: newPasswordController, | ||
cNewPasswordController: cNewPasswordController, | ||
), | ||
|
||
const SizedBox(height: 10), | ||
|
||
//Resend message | ||
const ForgotResendWidget(), | ||
], | ||
), | ||
), | ||
|
||
const SizedBox(height: 20), | ||
|
||
//Relevant Response Message | ||
const Padding( | ||
padding: EdgeInsets.symmetric(horizontal: 25), | ||
child: ForgotMessageWidget(), | ||
), | ||
|
||
const Spacer(), | ||
|
||
//Reset Password Button | ||
ForgotButtonWidget( | ||
emailController: emailController, | ||
newPasswordController: newPasswordController, | ||
formKey: _formKey, | ||
), | ||
], | ||
), | ||
), | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
lib/views/widgets/forgot_password/forgot_button_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:flutter_spinkit/flutter_spinkit.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/utils/constants.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
//Widgets | ||
import '../common/custom_text_button.dart'; | ||
|
||
class ForgotButtonWidget extends StatefulHookWidget { | ||
final TextEditingController emailController; | ||
final TextEditingController newPasswordController; | ||
final GlobalKey<FormState> formKey; | ||
|
||
const ForgotButtonWidget({ | ||
Key? key, | ||
required this.emailController, | ||
required this.newPasswordController, | ||
required this.formKey, | ||
}) : super(key: key); | ||
|
||
@override | ||
_PageButtonWidgetState createState() => _PageButtonWidgetState(); | ||
} | ||
|
||
class _PageButtonWidgetState extends State<ForgotButtonWidget> { | ||
late Widget _currentPageButton; | ||
|
||
void _onPressed({ | ||
bool isEmail = false, | ||
bool isOtp = false, | ||
bool isReset = false, | ||
}) { | ||
if (widget.formKey.currentState!.validate()) { | ||
widget.formKey.currentState!.save(); | ||
final _forgotPasswordProv = context.read(forgotPasswordProvider.notifier); | ||
if (isEmail) { | ||
_forgotPasswordProv.requestOtpCode(widget.emailController.text); | ||
} else if (isOtp) { | ||
_forgotPasswordProv.verifyOtp(); | ||
} else if (isReset) { | ||
_forgotPasswordProv.resetPassword( | ||
password: widget.newPasswordController.text, | ||
); | ||
} | ||
} | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final _forgotPasswordState = useProvider(forgotPasswordProvider); | ||
return Padding( | ||
padding: const EdgeInsets.fromLTRB(20, 40, 20, Constants.bottomInsets), | ||
child: _forgotPasswordState.when( | ||
email: () { | ||
_currentPageButton = CustomTextButton.gradient( | ||
width: double.infinity, | ||
onPressed: () => _onPressed(isEmail: true), | ||
gradient: Constants.buttonGradientOrange, | ||
child: const Center( | ||
child: Text( | ||
'SEND OTP', | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: 15, | ||
letterSpacing: 0.7, | ||
fontWeight: FontWeight.w600, | ||
), | ||
), | ||
), | ||
); | ||
return _currentPageButton; | ||
}, | ||
otp: (_) { | ||
_currentPageButton = CustomTextButton.gradient( | ||
width: double.infinity, | ||
onPressed: () => _onPressed(isOtp: true), | ||
gradient: Constants.buttonGradientOrange, | ||
child: const Center( | ||
child: Text('VERIFY OTP', | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: 15, | ||
letterSpacing: 0.7, | ||
fontWeight: FontWeight.w600, | ||
)), | ||
), | ||
); | ||
return _currentPageButton; | ||
}, | ||
resetPassword: (_) { | ||
_currentPageButton = CustomTextButton.gradient( | ||
width: double.infinity, | ||
onPressed: () => _onPressed(isReset: true), | ||
gradient: Constants.buttonGradientOrange, | ||
child: const Center( | ||
child: Text( | ||
'RESET PASSWORD', | ||
style: TextStyle( | ||
color: Colors.white, | ||
fontSize: 15, | ||
letterSpacing: 0.7, | ||
fontWeight: FontWeight.w600, | ||
), | ||
), | ||
), | ||
); | ||
return _currentPageButton; | ||
}, | ||
loading: (_) => CustomTextButton.gradient( | ||
width: double.infinity, | ||
onPressed: () {}, | ||
gradient: Constants.buttonGradientOrange, | ||
child: const Center( | ||
child: SpinKitRing( | ||
color: Colors.white, | ||
size: 30, | ||
lineWidth: 4, | ||
duration: Duration(milliseconds: 1100), | ||
), | ||
), | ||
), | ||
failed: (_, __) => _currentPageButton, | ||
success: (_) => const SizedBox.shrink(), | ||
), | ||
); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
lib/views/widgets/forgot_password/forgot_message_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/extensions/context_extensions.dart'; | ||
import '../../../helper/utils/constants.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
class ForgotMessageWidget extends HookWidget { | ||
const ForgotMessageWidget({ | ||
Key? key, | ||
}) : super(key: key); | ||
|
||
Text _buildMessageText(BuildContext ctx, String message) { | ||
return Text( | ||
message, | ||
textAlign: TextAlign.center, | ||
style: ctx.bodyText1.copyWith( | ||
color: Constants.textGreyColor, | ||
fontSize: 16, | ||
), | ||
); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final _forgotPasswordState = useProvider(forgotPasswordProvider); | ||
return _forgotPasswordState.maybeWhen( | ||
email: () => _buildMessageText( | ||
context, | ||
'A 4 digit OTP will be sent to this email once verified', | ||
), | ||
otp: (message) => _buildMessageText(context, message), | ||
resetPassword: (message) => _buildMessageText(context, message), | ||
loading: (message) => _buildMessageText(context, message), | ||
orElse: () => const SizedBox.shrink(), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/extensions/context_extensions.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
class ForgotNameWidget extends StatefulHookWidget { | ||
const ForgotNameWidget({ | ||
Key? key, | ||
}) : super(key: key); | ||
|
||
@override | ||
_PageNameWidgetState createState() => _PageNameWidgetState(); | ||
} | ||
|
||
class _PageNameWidgetState extends State<ForgotNameWidget> { | ||
late Text currentPageText; | ||
|
||
Text _buildText(String pageName) { | ||
return Text( | ||
pageName, | ||
style: context.headline3.copyWith(fontSize: 22), | ||
); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final _forgotPasswordState = useProvider(forgotPasswordProvider); | ||
return _forgotPasswordState.maybeWhen( | ||
email: () { | ||
currentPageText = _buildText('Forgot Password'); | ||
return currentPageText; | ||
}, | ||
otp: (_) { | ||
currentPageText = _buildText('Verify Otp'); | ||
return currentPageText; | ||
}, | ||
resetPassword: (_) { | ||
currentPageText = _buildText('Reset Password'); | ||
return currentPageText; | ||
}, | ||
success: (_) => const SizedBox.shrink(), | ||
orElse: () => currentPageText, | ||
); | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
lib/views/widgets/forgot_password/forgot_resend_widget.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/extensions/context_extensions.dart'; | ||
import '../../../helper/utils/constants.dart'; | ||
|
||
class ForgotResendWidget extends HookWidget { | ||
const ForgotResendWidget({ | ||
Key? key, | ||
}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final _forgotPasswordState = useProvider(forgotPasswordProvider); | ||
return _forgotPasswordState.maybeWhen( | ||
otp: (_) => Row( | ||
mainAxisAlignment: MainAxisAlignment.center, | ||
children: [ | ||
GestureDetector( | ||
onTap: () { | ||
context.read(forgotPasswordProvider.notifier).resendOtpCode(); | ||
}, | ||
child: Text( | ||
'Resend OTP', | ||
style: context.headline3.copyWith( | ||
fontSize: 17, | ||
color: Constants.primaryColor | ||
), | ||
), | ||
), | ||
], | ||
), | ||
orElse: () => const SizedBox.shrink(), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_hooks/flutter_hooks.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/utils/form_validator.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
//Widgets | ||
import '../common/custom_textfield.dart'; | ||
import 'reset_password_fields.dart'; | ||
import 'otp_code_fields.dart'; | ||
|
||
class ForgotTextFields extends StatefulHookWidget { | ||
const ForgotTextFields({ | ||
Key? key, | ||
required this.emailController, | ||
required this.newPasswordController, | ||
required this.cNewPasswordController, | ||
}) : super(key: key); | ||
|
||
final TextEditingController emailController; | ||
final TextEditingController newPasswordController; | ||
final TextEditingController cNewPasswordController; | ||
|
||
@override | ||
_ForgotPasswordFieldsState createState() => _ForgotPasswordFieldsState(); | ||
} | ||
|
||
class _ForgotPasswordFieldsState extends State<ForgotTextFields> { | ||
late Widget currentTextFields; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final _forgotPasswordState = useProvider(forgotPasswordProvider); | ||
return _forgotPasswordState.maybeWhen( | ||
email: () { | ||
currentTextFields = CustomTextField( | ||
controller: widget.emailController, | ||
floatingText: 'Email', | ||
hintText: 'Type your email address', | ||
keyboardType: TextInputType.emailAddress, | ||
textInputAction: TextInputAction.next, | ||
validator: FormValidator.emailValidator, | ||
); | ||
return currentTextFields; | ||
}, | ||
otp: (_) { | ||
currentTextFields = const OtpCodeFields(); | ||
return currentTextFields; | ||
}, | ||
resetPassword: (_) { | ||
currentTextFields = ResetPasswordFields( | ||
newPasswordController: widget.newPasswordController, | ||
cNewPasswordController: widget.cNewPasswordController, | ||
); | ||
return currentTextFields; | ||
}, | ||
success: (_) => const SizedBox.shrink(), | ||
orElse: () => currentTextFields, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Helpers | ||
import '../../../helper/utils/constants.dart'; | ||
import '../../../helper/utils/form_validator.dart'; | ||
|
||
//Providers | ||
import '../../../providers/all_providers.dart'; | ||
|
||
//Widgets | ||
import '../common/custom_textfield.dart'; | ||
|
||
class OtpCodeFields extends StatelessWidget { | ||
const OtpCodeFields({ | ||
Key? key, | ||
}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
children: [ | ||
Row( | ||
mainAxisAlignment: MainAxisAlignment.spaceAround, | ||
children: [ | ||
//Digit 1-4 | ||
for (int i = 0; i < 4; i++) | ||
CustomTextField( | ||
maxLength: 1, | ||
width: 60, | ||
height: 60, | ||
contentPadding: const EdgeInsets.only(bottom: 10), | ||
inputStyle: const TextStyle( | ||
fontSize: 35, | ||
color: Constants.textWhite80Color, | ||
), | ||
showErrorBorder: true, | ||
textAlign: TextAlign.center, | ||
errorAlign: Alignment.topCenter, | ||
keyboardType: TextInputType.phone, | ||
textInputAction: TextInputAction.next, | ||
validator: FormValidator.otpDigitValidator, | ||
onSaved: (digit) { | ||
final forgotProv = context.read(forgotPasswordProvider.notifier); | ||
forgotProv.setOtpDigit(i, digit!); | ||
}, | ||
onChanged: (digit) { | ||
if (digit!.length == 1) { | ||
FocusScope.of(context).nextFocus(); | ||
} else if (digit.isEmpty) { | ||
FocusScope.of(context).previousFocus(); | ||
} | ||
}, | ||
), | ||
], | ||
), | ||
], | ||
); | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
lib/views/widgets/forgot_password/reset_password_fields.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
//Helper | ||
import '../../../helper/utils/form_validator.dart'; | ||
|
||
//Widget | ||
import '../common/custom_textfield.dart'; | ||
|
||
class ResetPasswordFields extends StatelessWidget { | ||
final TextEditingController newPasswordController; | ||
final TextEditingController cNewPasswordController; | ||
|
||
const ResetPasswordFields({ | ||
Key? key, | ||
required this.newPasswordController, | ||
required this.cNewPasswordController, | ||
}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Column( | ||
children: [ | ||
//New Password Field | ||
CustomTextField( | ||
hintText: 'Type your password', | ||
floatingText: 'New Password', | ||
controller: newPasswordController, | ||
keyboardType: TextInputType.visiblePassword, | ||
textInputAction: TextInputAction.next, | ||
validator: FormValidator.passwordValidator, | ||
), | ||
|
||
const SizedBox(height: 25), | ||
|
||
//Confirm New Password Field | ||
CustomTextField( | ||
hintText: 'Retype your password', | ||
floatingText: 'Confirm Password', | ||
controller: cNewPasswordController, | ||
keyboardType: TextInputType.visiblePassword, | ||
textInputAction: TextInputAction.done, | ||
validator: (confirmPw) => FormValidator.confirmPasswordValidator( | ||
confirmPw, | ||
newPasswordController.text, | ||
), | ||
), | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import 'dart:async'; | ||
import 'dart:io'; | ||
|
||
import 'package:golden_toolkit/golden_toolkit.dart'; | ||
|
||
//Theme | ||
import 'package:ez_ticketz_app/helper/utils/custom_theme.dart'; | ||
|
||
Future<void> testExecutable(FutureOr<void> Function() testMain) async { | ||
return GoldenToolkit.runWithConfiguration( | ||
() async { | ||
await loadAppFonts(); | ||
await testMain(); | ||
}, | ||
config: GoldenToolkitConfiguration( | ||
defaultDevices: const [GoldensGlobalConfig.defaultDevice], | ||
fileNameFactory: (name) { | ||
if(Platform.isWindows) { | ||
return 'goldens_local/$name.png'; | ||
} | ||
else { | ||
return 'goldens/$name.png'; | ||
} | ||
} | ||
), | ||
); | ||
} | ||
|
||
abstract class GoldensGlobalConfig { | ||
static final globalAppWrapper = materialAppWrapper( | ||
theme: CustomTheme.mainTheme, | ||
); | ||
|
||
static const defaultDevice = Device.iphone11; | ||
|
||
static final defaultSurfaceSize = defaultDevice.size; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:golden_toolkit/golden_toolkit.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Providers | ||
import 'package:ez_ticketz_app/providers/all_providers.dart'; | ||
import 'common_mocked_providers.dart'; | ||
|
||
//Screens | ||
import 'package:ez_ticketz_app/views/screens/change_password_screen.dart'; | ||
|
||
//Config | ||
import '../flutter_test_config.dart'; | ||
|
||
void main() { | ||
group('ChangePasswordScreen', () { | ||
testGoldens( | ||
'GIVEN the change password icon is pressed ' | ||
'WHEN the change password screen is shown ' | ||
'THEN it looks like change_password_screen_golden.png', | ||
(tester) async { | ||
//when | ||
await tester.pumpWidgetBuilder( | ||
ProviderScope( | ||
overrides: [ | ||
authProvider.overrideWithProvider(mockAuthProvider) | ||
], | ||
child: const ChangePasswordScreen(), | ||
), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//then | ||
await screenMatchesGolden(tester, 'change_password_screen_golden'); | ||
}, | ||
); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import 'package:flutter/foundation.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
import 'package:mockito/mockito.dart'; | ||
|
||
//Models | ||
import 'package:ez_ticketz_app/models/user_model.dart'; | ||
|
||
//Providers | ||
import 'package:ez_ticketz_app/providers/auth_provider.dart'; | ||
|
||
//States | ||
import 'package:ez_ticketz_app/providers/states/auth_state.dart'; | ||
|
||
//Services | ||
import 'package:ez_ticketz_app/services/local_storage/key_value_storage_service.dart'; | ||
import 'package:ez_ticketz_app/services/repositories/auth_repository.dart'; | ||
|
||
//Mocks | ||
class _MockKVStorageService extends Mock implements KeyValueStorageService { | ||
@override | ||
bool getAuthState() => false; | ||
|
||
@override | ||
UserModel? getAuthUser() => null; | ||
|
||
@override | ||
Future<String> getAuthPassword() => SynchronousFuture(''); | ||
|
||
@override | ||
void resetKeys() {} | ||
} | ||
|
||
//Fakes | ||
class MockAuthRepository extends Fake implements AuthRepository {} | ||
|
||
//Providers | ||
final mockAuthProvider = StateNotifierProvider<AuthProvider, AuthState>((ref) { | ||
return AuthProvider( | ||
reader: ref.read, | ||
authRepository: MockAuthRepository(), | ||
keyValueStorageService: _MockKVStorageService(), | ||
); | ||
}); |
118 changes: 118 additions & 0 deletions
118
test/golden_tests/forgot_password_screen_golden_test.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:golden_toolkit/golden_toolkit.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Providers | ||
import 'package:ez_ticketz_app/providers/all_providers.dart'; | ||
import 'package:ez_ticketz_app/providers/forgot_password_provider.dart'; | ||
import 'package:ez_ticketz_app/providers/states/forgot_password_state.dart'; | ||
import 'common_mocked_providers.dart'; | ||
|
||
//Screens | ||
import 'package:ez_ticketz_app/views/screens/forgot_password_screen.dart'; | ||
|
||
//Config | ||
import '../flutter_test_config.dart'; | ||
|
||
void main() { | ||
group( | ||
'ForgotPasswordScreen', | ||
() { | ||
const forgotPasswordScreen = ForgotPasswordScreen(); | ||
|
||
testGoldens( | ||
'GIVEN the forgot password link is pressed ' | ||
'WHEN the forgot password screen is shown ' | ||
'THEN it looks like forgot_password_screen_email_golden.png', | ||
(tester) async { | ||
//when | ||
await tester.pumpWidgetBuilder( | ||
const ProviderScope( | ||
child: forgotPasswordScreen, | ||
), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//then | ||
await screenMatchesGolden( | ||
tester, | ||
'forgot_password_screen_email_golden', | ||
); | ||
}, | ||
); | ||
|
||
testGoldens( | ||
'GIVEN we are on forgot password screen ' | ||
'AND the otp has been sent ' | ||
'WHEN the screen is rebuilt ' | ||
'THEN it looks like forgot_password_screen_otp_golden.png', | ||
(tester) async { | ||
//given | ||
await tester.pumpWidgetBuilder( | ||
ProviderScope( | ||
overrides: [ | ||
forgotPasswordProvider.overrideWithValue( | ||
ForgotPasswordProvider( | ||
authRepository: MockAuthRepository(), | ||
initialState: const ForgotPasswordState.otp( | ||
otpSentMessage: 'otpSentMessage', | ||
), | ||
), | ||
) | ||
], | ||
child: forgotPasswordScreen, | ||
), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//rebuild screen | ||
await tester.pump(); | ||
|
||
//then | ||
await screenMatchesGolden( | ||
tester, | ||
'forgot_password_screen_otp_golden', | ||
); | ||
}, | ||
); | ||
|
||
testGoldens( | ||
'GIVEN we are on forgot password screen ' | ||
'AND the otp has been verified ' | ||
'WHEN the screen is rebuilt ' | ||
'THEN it looks like forgot_password_screen_resetPw_golden.png', | ||
(tester) async { | ||
//given | ||
await tester.pumpWidgetBuilder( | ||
ProviderScope( | ||
overrides: [ | ||
forgotPasswordProvider.overrideWithValue( | ||
ForgotPasswordProvider( | ||
authRepository: MockAuthRepository(), | ||
initialState: const ForgotPasswordState.resetPassword( | ||
otpVerifiedMessage: 'otpVerifiedMessage', | ||
), | ||
), | ||
) | ||
], | ||
child: forgotPasswordScreen, | ||
), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//rebuild screen | ||
await tester.pump(); | ||
|
||
//then | ||
await screenMatchesGolden( | ||
tester, | ||
'forgot_password_screen_resetPw_golden', | ||
); | ||
}, | ||
); | ||
}, | ||
); | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:golden_toolkit/golden_toolkit.dart'; | ||
|
||
//Screens | ||
import 'package:ez_ticketz_app/views/screens/home_screen.dart'; | ||
|
||
//Config | ||
import '../flutter_test_config.dart'; | ||
|
||
void main() { | ||
group('HomeScreen', () { | ||
testGoldens( | ||
'GIVEN the app is started ' | ||
'WHEN the home screen is shown ' | ||
'THEN it looks like home_screen_golden.png', | ||
(tester) async { | ||
//when | ||
await tester.pumpWidgetBuilder( | ||
const HomeScreen(), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//then | ||
await screenMatchesGolden(tester, 'home_screen_golden'); | ||
}, | ||
); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import 'package:flutter_test/flutter_test.dart'; | ||
import 'package:golden_toolkit/golden_toolkit.dart'; | ||
import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||
|
||
//Providers | ||
import 'package:ez_ticketz_app/providers/all_providers.dart'; | ||
import 'common_mocked_providers.dart'; | ||
|
||
//Screens | ||
import 'package:ez_ticketz_app/views/screens/login_screen.dart'; | ||
|
||
//Config | ||
import '../flutter_test_config.dart'; | ||
|
||
void main() { | ||
group('LoginScreen', () { | ||
testGoldens( | ||
'GIVEN the login button is pressed ' | ||
'WHEN the login screen is shown ' | ||
'THEN it looks like login_screen_golden.png', | ||
(tester) async { | ||
//when | ||
await tester.pumpWidgetBuilder( | ||
ProviderScope( | ||
overrides: [ | ||
authProvider.overrideWithProvider(mockAuthProvider), | ||
], | ||
child: const LoginScreen(), | ||
), | ||
surfaceSize: GoldensGlobalConfig.defaultSurfaceSize, | ||
wrapper: GoldensGlobalConfig.globalAppWrapper, | ||
); | ||
|
||
//then | ||
await screenMatchesGolden(tester, 'login_screen_golden'); | ||
}, | ||
); | ||
}); | ||
} |
Oops, something went wrong.