diff --git a/lib/core/routes/route_name.dart b/lib/core/routes/route_name.dart index f544b36..feb59b7 100644 --- a/lib/core/routes/route_name.dart +++ b/lib/core/routes/route_name.dart @@ -58,4 +58,7 @@ class RouteName { //delete Account static const String deleteAccountScreen = 'deleteAccountScreen'; + + //change password + static const String changePasswordScreen = "changePasswordScreen"; } diff --git a/lib/core/routes/routes.dart b/lib/core/routes/routes.dart index 96a93cc..73c2dc3 100644 --- a/lib/core/routes/routes.dart +++ b/lib/core/routes/routes.dart @@ -8,6 +8,7 @@ import 'package:tanami_app/features/MainScreens/Portfolio/presentation/pages/por import 'package:tanami_app/features/MainScreens/Wallet/presentation/pages/walletDetails.dart'; import 'package:tanami_app/features/biometric/presentation/pages/biometric_screen.dart'; +import 'package:tanami_app/features/changePassword/presentation/pages/change_password_screen.dart'; import 'package:tanami_app/features/contactAdmin/presentation/pages/contact_admin_screen.dart'; import 'package:tanami_app/features/countrySelection/presentation/pages/choose_country_screen.dart'; @@ -185,15 +186,14 @@ final goRouter = GoRouter( return const DeleteAccountScreen(); }, ), + GoRoute( + name: RouteName.changePasswordScreen, + path: RouteName.changePasswordScreen, + builder: (context, state) { + return const ChangePasswordScreen(); + }, + ), ], ), - // GoRoute( - // path: '/profile/:userId', - // builder: (context, state) { - // final userId = state.params['userId']; - // return MaterialPage(child: ProfilePage(userId: userId)); - // }, - // ), - // Add more routes as needed ], ); diff --git a/lib/core/styles/app_text.dart b/lib/core/styles/app_text.dart index c6b8344..9ed6ab8 100644 --- a/lib/core/styles/app_text.dart +++ b/lib/core/styles/app_text.dart @@ -153,6 +153,11 @@ class AppText { static const String faqText = "FAQ"; static const String logoutText = "Log Out"; static const String deleteAccountText = "Delete account"; + static const String areYouSureWantToLogoutText = + "Are you sure you want to Logout?"; + static const String noText = "No"; + static const String yesText = "Yes"; + static const String pinUpdatedSucess = "Pin updated Sucessfully !"; //Contact Admin static const String byPhoneText = "By phone"; diff --git a/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart index e627b56..e89a6c3 100644 --- a/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart +++ b/lib/features/MainScreens/Settings/presentation/widgets/privacy_settings_section.dart @@ -7,6 +7,8 @@ import 'package:tanami_app/core/styles/app_text.dart'; import 'package:tanami_app/shared/components/bloc/toggle/toggle_bloc.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; +import '../../../../../core/routes/route_name.dart'; +import '../../../../../core/routes/routes.dart'; import '../../../../../shared/components/toggle_widget.dart'; import 'settings_list_tile_item.dart'; @@ -45,7 +47,11 @@ class PrivacySettingsSection extends StatelessWidget { ), const Gap(8), SettingsListItem( - onTapFunc: () {}, + onTapFunc: () { + goRouter.pushNamed(RouteName.pinScreen, pathParameters: { + "fromScreen": "reset-pin", + }); + }, icon: AppImages.resetPinIcon, title: AppText.resetPinCodeText, trailing: "", diff --git a/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart b/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart index 0ed36b8..096ac6f 100644 --- a/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart +++ b/lib/features/MainScreens/Settings/presentation/widgets/settings_bottom_section.dart @@ -8,6 +8,7 @@ import 'package:tanami_app/core/routes/routes.dart'; import '../../../../../core/styles/app_color.dart'; import '../../../../../core/styles/app_text.dart'; import '../../../../../shared/components/button_widget.dart'; +import '../../../../../shared/components/log_out_dialog.dart'; import '../../../../../shared/components/text_widget.dart'; class SettingsBottomSection extends StatelessWidget { @@ -27,9 +28,8 @@ class SettingsBottomSection extends StatelessWidget { child: ButtonWidget().elevatedBtn( txtClr: AppColor.plainWhite, function: () { - goRouter.goNamed(RouteName.loginScreen, pathParameters: { - "fromScreen": "registerStep", - }); + buildprofilelogoutdialog(context); + }, text: AppText.logoutText, clr: AppColor.primaryColor2, diff --git a/lib/features/changePassword/presentation/bloc/restore_password_bloc.dart b/lib/features/changePassword/presentation/bloc/restore_password_bloc.dart new file mode 100644 index 0000000..49d732e --- /dev/null +++ b/lib/features/changePassword/presentation/bloc/restore_password_bloc.dart @@ -0,0 +1,76 @@ +import 'package:bloc/bloc.dart'; +import 'package:flutter/material.dart'; + +import 'restore_password_event.dart'; +import 'restore_password_state.dart'; + +class RestorePasswordBloc + extends Bloc { + final GlobalKey formKey = GlobalKey(); + final TextEditingController passwordTextField = TextEditingController(); + final TextEditingController repeatPasswordTextField = TextEditingController(); + + GlobalKey getFormKey() { + return formKey; + } + + RestorePasswordBloc() : super(RestorePasswordInitial()) { + passwordTextField.addListener(_onFormFieldChanged); + repeatPasswordTextField.addListener(_onFormFieldChanged); + on(_onLoginFormChanged); + on((event, emit) async { + if (!formKey.currentState!.validate()) { + return; + } + emit(RestorePasswordLoading()); + try { + // Simulate API call + await Future.delayed(const Duration(seconds: 2)); + // Replace the next line with actual API call + final isSuccess = await _mockLoginApi(event.password); + if (isSuccess) { + emit(RestorePasswordSuccess()); + } else { + emit(const RestorePasswordFailure( + "Failed. Please check your credentials.")); + } + } catch (e) { + emit(RestorePasswordFailure(e.toString())); + } + }); + } + void _onFormFieldChanged() { + add(RestorePasswordFormChanged( + passwordTextField.text, + repeatPasswordTextField.text, + )); + } + + void _onLoginFormChanged( + RestorePasswordFormChanged event, Emitter emit) { + final areFieldsFilled = + event.password.isNotEmpty && event.repeatPassword.isNotEmpty; + emit(RestorePasswordFieldsState(areFieldsFilled)); + } + + // Method to reset text fields + void resetFields() { + passwordTextField.clear(); + repeatPasswordTextField.clear(); + } + + // Mock API function, replace with actual API call + Future _mockLoginApi( + String phoneNumber, + ) async { + return true; + } + + @override + Future close() { + passwordTextField.dispose(); + repeatPasswordTextField.dispose(); + + return super.close(); + } +} diff --git a/lib/features/changePassword/presentation/bloc/restore_password_event.dart b/lib/features/changePassword/presentation/bloc/restore_password_event.dart new file mode 100644 index 0000000..1ee3d13 --- /dev/null +++ b/lib/features/changePassword/presentation/bloc/restore_password_event.dart @@ -0,0 +1,31 @@ +import 'package:equatable/equatable.dart'; + +abstract class RestorePasswordEvent extends Equatable { + const RestorePasswordEvent(); + + @override + List get props => []; +} + +class RestorePasswordSubmitted extends RestorePasswordEvent { + final String password; + final String repeatPassword; + + const RestorePasswordSubmitted( + this.password, + this.repeatPassword, + ); + + @override + List get props => [password, repeatPassword]; +} + +class RestorePasswordFormChanged extends RestorePasswordEvent { + final String password; + final String repeatPassword; + + const RestorePasswordFormChanged(this.password, this.repeatPassword); + + @override + List get props => [password, repeatPassword]; +} diff --git a/lib/features/changePassword/presentation/bloc/restore_password_state.dart b/lib/features/changePassword/presentation/bloc/restore_password_state.dart new file mode 100644 index 0000000..97c1591 --- /dev/null +++ b/lib/features/changePassword/presentation/bloc/restore_password_state.dart @@ -0,0 +1,32 @@ +import 'package:equatable/equatable.dart'; + +abstract class RestorePasswordState extends Equatable { + const RestorePasswordState(); + + @override + List get props => []; +} + +class RestorePasswordInitial extends RestorePasswordState {} + +class RestorePasswordLoading extends RestorePasswordState {} + +class RestorePasswordSuccess extends RestorePasswordState {} + +class RestorePasswordFailure extends RestorePasswordState { + final String error; + + const RestorePasswordFailure(this.error); + + @override + List get props => [error]; +} + +class RestorePasswordFieldsState extends RestorePasswordState { + final bool areFieldsFilled; + + const RestorePasswordFieldsState(this.areFieldsFilled); + + @override + List get props => [areFieldsFilled]; +} diff --git a/lib/features/changePassword/presentation/pages/change_password_layout.dart b/lib/features/changePassword/presentation/pages/change_password_layout.dart new file mode 100644 index 0000000..0445e8d --- /dev/null +++ b/lib/features/changePassword/presentation/pages/change_password_layout.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; + +import '../widgets/restore_password_bottom_section.dart'; +import '../widgets/restore_password_form.dart'; +import '../widgets/restore_password_top_section.dart'; + +class ChangePasswordLayout extends StatelessWidget { + const ChangePasswordLayout({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: ListView( + children: const [ + RestorePasswordTopSection(), + RestorePasswordForm(), + Gap(150), + RestorePasswordBottomSection(), + ], + )); + } +} diff --git a/lib/features/changePassword/presentation/pages/change_password_screen.dart b/lib/features/changePassword/presentation/pages/change_password_screen.dart new file mode 100644 index 0000000..5eb91c9 --- /dev/null +++ b/lib/features/changePassword/presentation/pages/change_password_screen.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../bloc/restore_password_bloc.dart'; +import 'change_password_layout.dart'; + +class ChangePasswordScreen extends StatelessWidget { + const ChangePasswordScreen({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: true, + body: MultiBlocProvider( + // Define the providers for the OnboardingBloc and other blocs + providers: [ + BlocProvider( + // Create an instance of the OnboardingBloc + create: (context) => RestorePasswordBloc(), + ), + ], + child: const ChangePasswordLayout(), + ), + ); + } +} diff --git a/lib/features/changePassword/presentation/widgets/restore_password_bottom_section.dart b/lib/features/changePassword/presentation/widgets/restore_password_bottom_section.dart new file mode 100644 index 0000000..5942f4a --- /dev/null +++ b/lib/features/changePassword/presentation/widgets/restore_password_bottom_section.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/shared/components/loader.dart'; +import 'package:tanami_app/shared/components/toast_message.dart'; + +import '../../../../core/routes/route_name.dart'; +import '../../../../core/routes/routes.dart'; +import '../../../../core/styles/app_color.dart'; +import '../../../../core/styles/app_text.dart'; +import '../../../../shared/components/button_widget.dart'; +import '../../../../shared/components/text_widget.dart'; +import '../../../countrySelection/presentation/bloc/choose_country_bloc.dart'; +import '../bloc/restore_password_bloc.dart'; +import '../bloc/restore_password_event.dart'; +import '../bloc/restore_password_state.dart'; + +class RestorePasswordBottomSection extends StatelessWidget { + const RestorePasswordBottomSection({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final radioBloc = context.read(); + return Column( + children: [ + BlocConsumer( + listener: (context, state) { + if (state is RestorePasswordLoading) { + Loader.loader(context); + } else if (state is RestorePasswordSuccess) { + successToastMessage(context, "Password resetted successful !"); + goRouter.pop(); + radioBloc.resetSelection(); + goRouter.goNamed(RouteName.loginScreen, pathParameters: { + "fromScreen": "registerStep", + }); + } else if (state is RestorePasswordFailure) { + goRouter.pop(); + errorToastMessage( + context, + state.error, + ); + } + }, + builder: (context, state) { + bool isButtonEnabled = false; + if (state is RestorePasswordFieldsState) { + isButtonEnabled = state.areFieldsFilled; + } else if (state is RestorePasswordSuccess || + state is RestorePasswordFailure) { + isButtonEnabled = true; + } + return Container( + margin: const EdgeInsets.symmetric( + horizontal: 16, + ), + width: 1.sw, + height: 56.h, + child: ButtonWidget().elevatedBtn( + txtClr: isButtonEnabled + ? AppColor.plainWhite + : AppColor.inactiveBtnTxtColor, + function: () { + isButtonEnabled + ? context.read().add( + RestorePasswordSubmitted( + context + .read() + .passwordTextField + .text, + ""), + ) + : null; + }, + text: AppText.submitText, + clr: isButtonEnabled + ? AppColor.primaryColor2 + : AppColor.inactiveBtnColor, + ), + ); + }, + ), + const Gap(5), + ButtonWidget().textBtn( + function: () { + goRouter.pop(); + }, + text: TextWidget().text14W700(AppText.backText, + clr: AppColor.textLabelColor, + textDecoration: TextDecoration.underline)), + ], + ); + } +} diff --git a/lib/features/changePassword/presentation/widgets/restore_password_form.dart b/lib/features/changePassword/presentation/widgets/restore_password_form.dart new file mode 100644 index 0000000..d6be1e7 --- /dev/null +++ b/lib/features/changePassword/presentation/widgets/restore_password_form.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; +import 'package:tanami_app/features/forgotPassword/presentation/bloc/restore_password_bloc.dart'; + +import '../../../../shared/components/bloc/password_field/password_visibility_bloc.dart'; +import '../../../../shared/components/form_label_textfield.dart'; + +class RestorePasswordForm extends StatelessWidget { + const RestorePasswordForm({super.key}); + + @override + Widget build(BuildContext context) { + final restorePasswordBloc = context.read(); + + // Reset fields when the screen is built + restorePasswordBloc.resetFields(); + + return Form( + key: restorePasswordBloc.formKey, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 14, + ), + child: Align( + alignment: Alignment.topLeft, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Gap(50), + BlocProvider( + create: (_) => PasswordVisibilityBloc(), + child: FormLabelTextField( + hintText: AppText.enterPassword, + title: AppText.password, + type: AppText.password.toLowerCase(), + textEditingController: restorePasswordBloc.passwordTextField, + ), + ), + const Gap(12), + BlocProvider( + create: (_) => PasswordVisibilityBloc(), + child: FormLabelTextField( + hintText: AppText.repeatPasswordText, + title: AppText.repeatPasswordText, + type: AppText.password.toLowerCase(), + textEditingController: + restorePasswordBloc.repeatPasswordTextField, + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/features/changePassword/presentation/widgets/restore_password_top_section.dart b/lib/features/changePassword/presentation/widgets/restore_password_top_section.dart new file mode 100644 index 0000000..4340449 --- /dev/null +++ b/lib/features/changePassword/presentation/widgets/restore_password_top_section.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_images.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; +import 'package:tanami_app/shared/components/text_widget.dart'; + +class RestorePasswordTopSection extends StatelessWidget { + const RestorePasswordTopSection({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Gap(85), + Center( + child: SvgPicture.asset( + AppImages.weclomeLogo, + ), + ), + const Gap(60), + TextWidget().text20W700( + AppText.restorePasswordText, + clr: AppColor.charcoalColor, + ), + const Gap(10), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 75), + child: TextWidget().text14W500( + AppText.createNewPasswordText, + clr: AppColor.smokeGrayColor, + ), + ), + ], + ); + } +} diff --git a/lib/features/deleteAccount/presentation/widgets/bottom_section.dart b/lib/features/deleteAccount/presentation/widgets/bottom_section.dart index 2462071..ef11ca7 100644 --- a/lib/features/deleteAccount/presentation/widgets/bottom_section.dart +++ b/lib/features/deleteAccount/presentation/widgets/bottom_section.dart @@ -16,6 +16,7 @@ import '../../../../shared/components/toast_message.dart'; import '../bloc/delete_account_bloc.dart'; import '../bloc/delete_account_event.dart'; import '../bloc/delete_account_state.dart'; +import 'delete_account_dialog.dart'; Widget bottomSection(BuildContext context) { final deleteAccountBloc = context.read(); @@ -45,6 +46,14 @@ Widget bottomSection(BuildContext context) { Loader.loader(context); } else if (state is DeleteAccountSuccess) { goRouter.pop(); + context.read().add(ToggleCheckbox()); + deleteAccountBloc.descriptionTextField.clear(); + showDialog( + context: context, + builder: (context) { + return const AccountDeletionDialog(); + }, + ); } else if (state is DeleteAccountFailure) { goRouter.pop(); errorToastMessage( diff --git a/lib/features/deleteAccount/presentation/widgets/delete_account_dialog.dart b/lib/features/deleteAccount/presentation/widgets/delete_account_dialog.dart new file mode 100644 index 0000000..00e3fb2 --- /dev/null +++ b/lib/features/deleteAccount/presentation/widgets/delete_account_dialog.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:gap/gap.dart'; +import 'package:tanami_app/core/routes/routes.dart'; +import 'package:tanami_app/core/styles/app_color.dart'; +import 'package:tanami_app/core/styles/app_text.dart'; + +import '../../../../shared/components/text_widget.dart'; + +class AccountDeletionDialog extends StatelessWidget { + const AccountDeletionDialog({super.key}); + + @override + Widget build(BuildContext context) { + return AlertDialog( + backgroundColor: AppColor.plainWhite, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + title: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + IconButton( + icon: const Icon( + Icons.close, + color: AppColor.hintTextColor, + ), + onPressed: () { + goRouter.pop(); + }, + ), + TextWidget().text17W700( + AppText.weHaveReceivedYourRequestToDeleteAccount, + clr: AppColor.textLabelColor, + ), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextWidget().text15W500( + AppText.theRequestWillBeProcessed, + clr: AppColor.hintTextColor, + ), + const Gap(20), + GestureDetector( + onTap: () { + goRouter.pop(); + }, + child: TextWidget().text14W500(AppText.closeText, + textDecoration: TextDecoration.underline, + clr: AppColor.otpTextColor), + ), + ], + ), + ); + } +} diff --git a/lib/features/securePin/presentation/pages/pin_layout.dart b/lib/features/securePin/presentation/pages/pin_layout.dart index 66ec129..3448cd1 100644 --- a/lib/features/securePin/presentation/pages/pin_layout.dart +++ b/lib/features/securePin/presentation/pages/pin_layout.dart @@ -8,14 +8,22 @@ class PinLayout extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - body: ListView( - children: [ - PinTopSection(fromScreen: fromScreen), - PinKey( - fromScreen: fromScreen, + return Scaffold(body: LayoutBuilder(builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: Column( + children: [ + PinTopSection(fromScreen: fromScreen), + PinKey( + fromScreen: fromScreen, + ), + ], + ), ), - ], - )); + ); + })); } } diff --git a/lib/features/securePin/presentation/pages/pin_screen.dart b/lib/features/securePin/presentation/pages/pin_screen.dart index b9f464d..4346baa 100644 --- a/lib/features/securePin/presentation/pages/pin_screen.dart +++ b/lib/features/securePin/presentation/pages/pin_screen.dart @@ -15,11 +15,13 @@ class PinScreen extends StatelessWidget { Widget build(BuildContext context) { final secureStorageService = SecureStorageService(); return Scaffold( - appBar: fromScreen == "register" - ? const AppBarWidget( + appBar: fromScreen == "register" || fromScreen == "reset-pin" + ? AppBarWidget( height: 75, - titleTxt: AppText.createPinCode, - showLeading: false, + titleTxt: fromScreen == "reset-pin" + ? AppText.changePinCode + : AppText.createPinCode, + showLeading: fromScreen == "reset-pin" ? true : false, ) : null, resizeToAvoidBottomInset: true, diff --git a/lib/features/securePin/presentation/widgets/pin_keypad_section.dart b/lib/features/securePin/presentation/widgets/pin_keypad_section.dart index a7a632d..05f9ec1 100644 --- a/lib/features/securePin/presentation/widgets/pin_keypad_section.dart +++ b/lib/features/securePin/presentation/widgets/pin_keypad_section.dart @@ -7,6 +7,7 @@ import 'package:tanami_app/core/styles/app_color.dart'; import 'package:tanami_app/core/styles/app_text.dart'; import 'package:tanami_app/features/securePin/presentation/widgets/forgot_pin_dialog.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; +import 'package:tanami_app/shared/components/toast_message.dart'; import '../bloc/pin_bloc.dart'; @@ -28,6 +29,9 @@ class PinKey extends StatelessWidget { if (state.pinComplete) { if (fromScreen == "login") { goRouter.pushNamed(RouteName.mainScreen); + } else if (fromScreen == "reset-pin") { + successToastMessage(context, AppText.pinUpdatedSucess); + goRouter.pop(); } else { context.read().add(SavePinPressed()); goRouter.pushNamed(RouteName.confirmPinScreen); @@ -78,9 +82,10 @@ class PinKey extends StatelessWidget { ), ) : const SizedBox(), - const Gap(50), + const Gap(30), GridView.builder( shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, childAspectRatio: 1.3, diff --git a/lib/features/securePin/presentation/widgets/pin_top_section.dart b/lib/features/securePin/presentation/widgets/pin_top_section.dart index 228bfc7..187c7e2 100644 --- a/lib/features/securePin/presentation/widgets/pin_top_section.dart +++ b/lib/features/securePin/presentation/widgets/pin_top_section.dart @@ -18,13 +18,13 @@ class PinTopSection extends StatelessWidget { Widget build(BuildContext context) { return Column( children: [ - const Gap(85), + const Gap(70), Center( child: SvgPicture.asset( AppImages.weclomeLogo, ), ), - const Gap(60), + const Gap(40), fromScreen == "login" ? Column( mainAxisAlignment: MainAxisAlignment.center, @@ -49,7 +49,7 @@ class PinTopSection extends StatelessWidget { ) ], ) - : fromScreen == "forgot-pin" + : fromScreen == "forgot-pin" || fromScreen == "reset-pin" ? TextWidget().text14W500( AppText.changePinCode, clr: AppColor.textLabelColor, diff --git a/lib/main.dart b/lib/main.dart index 71504dc..932b43b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,8 +63,8 @@ class _MyAppState extends State with WidgetsBindingObserver { builder: (BuildContext context, Widget? child) => MaterialApp.router( title: 'Tanami Capital', theme: ThemeData( - useMaterial3: true, - ), + // useMaterial3: true, + ), debugShowCheckedModeBanner: false, routerConfig: goRouter, ), diff --git a/lib/shared/components/bloc/checkbox/checkbox_bloc.dart b/lib/shared/components/bloc/checkbox/checkbox_bloc.dart index 1f897e8..af4a08a 100644 --- a/lib/shared/components/bloc/checkbox/checkbox_bloc.dart +++ b/lib/shared/components/bloc/checkbox/checkbox_bloc.dart @@ -11,7 +11,7 @@ class CheckboxBloc extends Bloc { } void _onToggleCheckbox(ToggleCheckbox event, Emitter emit) { - if (state is CheckboxUnchecked) { + if (state is CheckboxUnchecked || state is CheckboxError) { emit(CheckboxChecked()); } else { emit(CheckboxUnchecked()); diff --git a/lib/shared/components/button_widget.dart b/lib/shared/components/button_widget.dart index c40420a..29ee744 100644 --- a/lib/shared/components/button_widget.dart +++ b/lib/shared/components/button_widget.dart @@ -1,32 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:tanami_app/core/styles/app_color.dart'; import 'package:tanami_app/shared/components/text_widget.dart'; class ButtonWidget { + //Text Button Widget textBtn({ required Widget text, - Color? clr, required VoidCallback function, }) { - return InkWell( - onTap: function, - child: Container( - clipBehavior: Clip.antiAlias, - decoration: ShapeDecoration( - shape: RoundedRectangleBorder( - side: const BorderSide(width: 1, color: AppColor.txtBorderColor), - borderRadius: BorderRadius.circular(30), - ), - ), - margin: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 10, - ), - width: 1.sw, - height: 56.h, - child: Center(child: text), - ), + return TextButton( + onPressed: function, + child: text, ); } diff --git a/lib/shared/components/exit_app_dialog.dart b/lib/shared/components/exit_app_dialog.dart index 2112358..94de24b 100644 --- a/lib/shared/components/exit_app_dialog.dart +++ b/lib/shared/components/exit_app_dialog.dart @@ -3,10 +3,13 @@ import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:gap/gap.dart'; +import 'package:tanami_app/core/routes/routes.dart'; import 'package:tanami_app/core/styles/app_color.dart'; import 'package:tanami_app/core/styles/app_images.dart'; import 'package:tanami_app/core/styles/app_text.dart'; +import 'text_widget.dart'; + exitAppDialog( context, ) { @@ -17,17 +20,17 @@ exitAppDialog( children: [ AlertDialog( insetPadding: const EdgeInsets.symmetric(horizontal: 16), - backgroundColor: const Color(0XFFFFFFFF), - //contentPadding: EdgeInsets.fromLTRB(96, 32, 96, 28), + backgroundColor: AppColor.plainWhite, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(20)), - side: BorderSide(color: Color(0XFFFFFFFF)), + side: BorderSide( + color: AppColor.plainWhite, + ), ), content: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - //sizedBoxHeight(32.h), Align( alignment: Alignment.center, child: CircleAvatar( @@ -49,24 +52,21 @@ exitAppDialog( ), Align( alignment: Alignment.center, - child: Text( - AppText.areYouSureYouWantToExitText, - textAlign: TextAlign.center, - style: TextStyle( - color: Colors.black, - fontSize: 22.sp, - //fontWeight: FontWeight.w600, + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 30), + child: TextWidget().text17W700( + AppText.areYouSureYouWantToExitText, + clr: AppColor.textLabelColor, ), ), ), - Gap(21.h), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ InkWell( onTap: () { - Navigator.pop(context); + goRouter.pop(); }, child: Container( height: 48.h, @@ -79,10 +79,9 @@ exitAppDialog( color: AppColor.plainWhite, ), child: Center( - child: Text( + child: TextWidget().text18W700( AppText.cancelText, - style: TextStyle( - color: AppColor.primaryColor, fontSize: 18.sp), + clr: AppColor.primaryColor2, ), ), ), @@ -100,10 +99,9 @@ exitAppDialog( borderRadius: BorderRadius.circular(10.h), color: AppColor.primaryColor), child: Center( - child: Text( + child: TextWidget().text18W700( AppText.exitText, - style: TextStyle( - color: AppColor.plainWhite, fontSize: 18.sp), + clr: AppColor.plainWhite, ), ), ), diff --git a/lib/shared/components/log_out_dialog.dart b/lib/shared/components/log_out_dialog.dart new file mode 100644 index 0000000..060914d --- /dev/null +++ b/lib/shared/components/log_out_dialog.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:gap/gap.dart'; + +import '../../core/routes/route_name.dart'; +import '../../core/routes/routes.dart'; +import '../../core/styles/app_color.dart'; +import '../../core/styles/app_text.dart'; +import 'text_widget.dart'; + +buildprofilelogoutdialog(context) { + return showDialog( + context: context, + builder: (context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + AlertDialog( + insetPadding: const EdgeInsets.symmetric(horizontal: 16), + backgroundColor: AppColor.plainWhite, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20)), + side: BorderSide( + color: AppColor.plainWhite, + ), + ), + content: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Align( + alignment: Alignment.center, + child: CircleAvatar( + radius: 25, + backgroundColor: AppColor.inactiveBtnColor, + child: Center( + child: Icon( + Icons.logout_rounded, + color: AppColor.primaryColor, + size: 30, + ), + ), + ), + ), + Gap(15.h), + Align( + alignment: Alignment.center, + child: Container( + margin: const EdgeInsets.symmetric(horizontal: 20), + child: TextWidget().text17W700( + AppText.areYouSureWantToLogoutText, + clr: AppColor.textLabelColor, + ), + ), + ), + Gap(21.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + InkWell( + onTap: () { + goRouter.pop(); + }, + child: Container( + height: 48.h, + width: 140.w, + decoration: BoxDecoration( + border: Border.all( + color: AppColor.primaryColor2, + ), + borderRadius: BorderRadius.circular(10.h), + color: AppColor.plainWhite), + child: Center( + child: TextWidget().text18W700( + AppText.noText, + clr: AppColor.primaryColor2, + ), + ), + ), + ), + Gap(28.w), + InkWell( + onTap: () { + goRouter.goNamed(RouteName.loginScreen, pathParameters: { + "fromScreen": "registerStep", + }); + }, + child: Container( + height: 48.h, + width: 140.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.h), + color: AppColor.primaryColor), + child: Center( + child: TextWidget().text18W700( + AppText.yesText, + clr: AppColor.plainWhite, + ), + ), + ), + ), + ], + ), + ], + ), + ), + ], + ), + ); +} diff --git a/lib/shared/components/text_widget.dart b/lib/shared/components/text_widget.dart index 8f95d99..1398b21 100644 --- a/lib/shared/components/text_widget.dart +++ b/lib/shared/components/text_widget.dart @@ -195,6 +195,23 @@ class TextWidget { color: clr ?? AppColor.plainWhite)); } + //Text Size 18 + + Widget text18W700( + String text, { + Color? clr, + TextDecoration? textDecoration, + }) { + return Text(text, + textAlign: TextAlign.center, + style: GoogleFonts.dmSans( + fontSize: 18, + decorationColor: AppColor.hintTextColor, + decoration: textDecoration ?? TextDecoration.none, + fontWeight: FontWeight.w700, + color: clr ?? AppColor.plainWhite)); + } + //Text Size 22 Widget text22W700(String text, {Color? clr}) { return Text(text,