forked from yaso_meth/mih-project
Mih AUth Forgot and Reset router update
This commit is contained in:
@@ -5,9 +5,10 @@ import 'package:mzansi_innovation_hub/mih_components/mih_objects/arguments.dart'
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/Example/package_test.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/about_mih/about_mih.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/access_review/mih_access.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/authentication/forgot_password.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/calculator/mih_calculator.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/calendar/mzansi_calendar.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_auth_forgot_password.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_auth_password_reset.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/mih_authentication.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_home/mih_home.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_ai/mzansi_ai.dart';
|
||||
@@ -19,11 +20,12 @@ import 'package:ken_logger/ken_logger.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/components/mih_barcode_scanner.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mzansi_wallet/mih_wallet.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/add_or_view_patient.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/patient_profile/pat_profile/patient_edit.dart';
|
||||
import 'package:supertokens_flutter/supertokens.dart';
|
||||
|
||||
class MihGoRouterPaths {
|
||||
// External
|
||||
static const String resetPasswordExternal = '/auth/reset-password';
|
||||
static const String resetPassword = '/auth/reset-password';
|
||||
static const String privacyPolicyExternal = '/privacy-policy';
|
||||
static const String termsOfServiceExternal = '/terms-of-service';
|
||||
|
||||
@@ -32,7 +34,7 @@ class MihGoRouterPaths {
|
||||
static const String mihAuthentication = '/mih-authentication';
|
||||
static const String mihHome = '/';
|
||||
static const String notifications = '/notifications';
|
||||
static const String forgotPassword = '/forgot-password';
|
||||
static const String forgotPassword = '/mih-authentication/forgot-password';
|
||||
static const String aboutMih = '/about';
|
||||
static const String mzansiProfileManage = '/mzansi-profile';
|
||||
static const String mzansiProfileView = '/mzansi-profile/view';
|
||||
@@ -62,31 +64,22 @@ class MihGoRouter {
|
||||
initialLocation: MihGoRouterPaths.mihHome,
|
||||
redirect: (BuildContext context, GoRouterState state) async {
|
||||
final bool isUserSignedIn = await SuperTokens.doesSessionExist();
|
||||
|
||||
// Only redirect if absolutely necessary
|
||||
if (!isUserSignedIn &&
|
||||
state.fullPath != MihGoRouterPaths.mihAuthentication) {
|
||||
final unauthenticatedPaths = [
|
||||
MihGoRouterPaths.mihAuthentication,
|
||||
MihGoRouterPaths.forgotPassword,
|
||||
MihGoRouterPaths.resetPassword,
|
||||
];
|
||||
if (!isUserSignedIn && !unauthenticatedPaths.contains(state.fullPath)) {
|
||||
return MihGoRouterPaths.mihAuthentication;
|
||||
}
|
||||
|
||||
if (isUserSignedIn &&
|
||||
state.fullPath == MihGoRouterPaths.mihAuthentication) {
|
||||
if (isUserSignedIn && unauthenticatedPaths.contains(state.fullPath)) {
|
||||
return MihGoRouterPaths.mihHome;
|
||||
}
|
||||
|
||||
return null; // Stay on current route
|
||||
},
|
||||
routes: [
|
||||
// External Routes - use `GoRoute` with `path` and `builder`
|
||||
// GoRoute(
|
||||
// name: "resetPasswordExternal",
|
||||
// path: MihGoRouterPaths.resetPasswordExternal,
|
||||
// builder: (BuildContext context, GoRouterState state) {
|
||||
// final token = state.queryParameters['token'];
|
||||
// return ResetPassword(token: token);
|
||||
// },
|
||||
// ),
|
||||
// GoRoute(
|
||||
// name: "privacyPolicyExternal",
|
||||
// path: MihGoRouterPaths.privacyPolicyExternal,
|
||||
// builder: (BuildContext context, GoRouterState state) =>
|
||||
@@ -100,27 +93,7 @@ class MihGoRouter {
|
||||
// ),
|
||||
|
||||
// Internal Routes - handle arguments via `extra` or path parameters
|
||||
// ========================== Mih Auth ==================================
|
||||
// GoRoute(
|
||||
// name: "mihHome",
|
||||
// path: MihGoRouterPaths.authCheck,
|
||||
// builder: (BuildContext context, GoRouterState state) {
|
||||
// final AuthArguments? args = state.extra as AuthArguments?;
|
||||
// KenLogger.success("MihGoRouter: home");
|
||||
// return AuthCheck(
|
||||
// personalSelected: args?.personalSelected ?? true,
|
||||
// firstBoot: args?.firstBoot ?? true,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// GoRoute(
|
||||
// name: "mihAuthCheck",
|
||||
// path: MihGoRouterPaths.authCheck,
|
||||
// builder: (BuildContext context, GoRouterState state) {
|
||||
// KenLogger.success("MihGoRouter: mihAuthCheck");
|
||||
// return MihAuthCheck();
|
||||
// },
|
||||
// ),
|
||||
// ========================== MIH Auth ==================================
|
||||
GoRoute(
|
||||
name: "mihAuthentication",
|
||||
path: MihGoRouterPaths.mihAuthentication,
|
||||
@@ -134,7 +107,21 @@ class MihGoRouter {
|
||||
path: MihGoRouterPaths.forgotPassword,
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
KenLogger.success("MihGoRouter: forgotPassword");
|
||||
return const ForgotPassword();
|
||||
return const MihAuthForgotPassword();
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: "resetPassword",
|
||||
path: MihGoRouterPaths.resetPassword,
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
String? token = state.uri.queryParameters['token'];
|
||||
if (token == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return MihAuthPasswordReset(token: token);
|
||||
},
|
||||
),
|
||||
// ========================== MIH Home ==================================
|
||||
@@ -208,9 +195,15 @@ class MihGoRouter {
|
||||
KenLogger.success("MihGoRouter: businessProfileView");
|
||||
final BusinessViewArguments? args =
|
||||
state.extra as BusinessViewArguments?;
|
||||
if (args == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return MzansiBusinessProfileView(
|
||||
key: UniqueKey(),
|
||||
arguments: args!,
|
||||
arguments: args,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -320,9 +313,15 @@ class MihGoRouter {
|
||||
path: MihGoRouterPaths.mihAccess,
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
final AppUser? signedInUser = state.extra as AppUser?;
|
||||
if (signedInUser == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return MihAccess(
|
||||
key: UniqueKey(),
|
||||
signedInUser: signedInUser!,
|
||||
signedInUser: signedInUser,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -331,14 +330,38 @@ class MihGoRouter {
|
||||
name: "patientProfile",
|
||||
path: MihGoRouterPaths.patientProfile,
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
final PatientViewArguments args = state.extra as PatientViewArguments;
|
||||
|
||||
final PatientViewArguments? args =
|
||||
state.extra as PatientViewArguments?;
|
||||
if (args == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return AddOrViewPatient(
|
||||
key: UniqueKey(),
|
||||
arguments: args,
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
name: "patientProfileEdit",
|
||||
path: MihGoRouterPaths.patientProfileEdit,
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
final PatientEditArguments? args =
|
||||
state.extra as PatientEditArguments?;
|
||||
if (args == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return EditPatient(
|
||||
signedInUser: args.signedInUser,
|
||||
selectedPatient: args.selectedPatient,
|
||||
);
|
||||
},
|
||||
),
|
||||
// ========================== Mzansi Directory ==================================
|
||||
GoRoute(
|
||||
name: "mzansiDirectory",
|
||||
@@ -346,7 +369,13 @@ class MihGoRouter {
|
||||
builder: (BuildContext context, GoRouterState state) {
|
||||
final MzansiDirectoryArguments? args =
|
||||
state.extra as MzansiDirectoryArguments?;
|
||||
return MzansiDirectory(arguments: args!);
|
||||
if (args == null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
context.go(MihGoRouterPaths.mihHome);
|
||||
});
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return MzansiDirectory(arguments: args);
|
||||
},
|
||||
),
|
||||
// ========================== End ==================================
|
||||
@@ -390,17 +419,6 @@ class MihGoRouter {
|
||||
// return AddPatient(signedInUser: signedInUser!);
|
||||
// },
|
||||
// ),
|
||||
// GoRoute(
|
||||
// name: "patientProfileEdit",
|
||||
// path: MihGoRouterPaths.patientProfileEdit,
|
||||
// builder: (BuildContext context, GoRouterState state) {
|
||||
// final PatientEditArguments? args = state.extra as PatientEditArguments?;
|
||||
// return EditPatient(
|
||||
// signedInUser: args!.signedInUser,
|
||||
// selectedPatient: args.selectedPatient,
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// // Note: You can't have two separate GoRoutes with the same path.
|
||||
// // 'appointments' and 'calendar' now need a distinct path, or be sub-routes.
|
||||
// // Here, we'll assume they should be separate.
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_forgot_password.dart';
|
||||
|
||||
class MihAuthForgotPassword extends StatefulWidget {
|
||||
const MihAuthForgotPassword({super.key});
|
||||
|
||||
@override
|
||||
State<MihAuthForgotPassword> createState() => _MihAuthForgotPasswordState();
|
||||
}
|
||||
|
||||
class _MihAuthForgotPasswordState extends State<MihAuthForgotPassword> {
|
||||
int _selcetedIndex = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackage(
|
||||
appActionButton: getAction(),
|
||||
appTools: getTools(),
|
||||
appBody: getToolBody(),
|
||||
selectedbodyIndex: _selcetedIndex,
|
||||
onIndexChange: (newValue) {
|
||||
setState(() {
|
||||
_selcetedIndex = newValue;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
MihPackageAction getAction() {
|
||||
return MihPackageAction(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
iconSize: 35,
|
||||
onTap: () {
|
||||
context.goNamed(
|
||||
'mihHome',
|
||||
extra: true,
|
||||
);
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
MihPackageTools getTools() {
|
||||
Map<Widget, void Function()?> temp = {};
|
||||
temp[const Icon(Icons.question_mark_rounded)] = () {
|
||||
setState(() {
|
||||
_selcetedIndex = 0;
|
||||
});
|
||||
};
|
||||
return MihPackageTools(
|
||||
tools: temp,
|
||||
selcetedIndex: _selcetedIndex,
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> getToolBody() {
|
||||
List<Widget> toolBodies = [
|
||||
MihForgotPassword(),
|
||||
];
|
||||
return toolBodies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_icons.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_action.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tools.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_packages/mih_authentication/package_tools/mih_reset_password.dart';
|
||||
|
||||
class MihAuthPasswordReset extends StatefulWidget {
|
||||
final String token;
|
||||
const MihAuthPasswordReset({
|
||||
super.key,
|
||||
required this.token,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihAuthPasswordReset> createState() => _MihAuthPasswordResetState();
|
||||
}
|
||||
|
||||
class _MihAuthPasswordResetState extends State<MihAuthPasswordReset> {
|
||||
int _selcetedIndex = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MihPackage(
|
||||
appActionButton: getAction(),
|
||||
appTools: getTools(),
|
||||
appBody: getToolBody(),
|
||||
selectedbodyIndex: _selcetedIndex,
|
||||
onIndexChange: (newValue) {
|
||||
setState(() {
|
||||
_selcetedIndex = newValue;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget getAction() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 5.0),
|
||||
child: MihPackageAction(
|
||||
icon: const Icon(MihIcons.mihLogo),
|
||||
iconSize: 45,
|
||||
onTap: () {
|
||||
context.goNamed(
|
||||
'mihHome',
|
||||
extra: true,
|
||||
);
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
MihPackageTools getTools() {
|
||||
Map<Widget, void Function()?> temp = {};
|
||||
temp[const Icon(Icons.password_rounded)] = () {
|
||||
setState(() {
|
||||
_selcetedIndex = 0;
|
||||
});
|
||||
};
|
||||
return MihPackageTools(
|
||||
tools: temp,
|
||||
selcetedIndex: _selcetedIndex,
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> getToolBody() {
|
||||
List<Widget> toolBodies = [
|
||||
MihResetPassword(
|
||||
token: widget.token,
|
||||
),
|
||||
];
|
||||
return toolBodies;
|
||||
}
|
||||
}
|
||||
@@ -68,20 +68,16 @@ class _MihAuthenticationState extends State<MihAuthentication> {
|
||||
);
|
||||
}
|
||||
|
||||
MihPackageAction getAction() {
|
||||
return MihPackageAction(
|
||||
icon: Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0),
|
||||
child: const Icon(MihIcons.mihLogo),
|
||||
Widget getAction() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 5.0),
|
||||
child: MihPackageAction(
|
||||
icon: const Icon(MihIcons.mihLogo),
|
||||
iconSize: 45,
|
||||
onTap: () {
|
||||
context.goNamed("aboutMih", extra: 0);
|
||||
},
|
||||
),
|
||||
iconSize: 45,
|
||||
onTap: () {
|
||||
context.goNamed("aboutMih", extra: 0);
|
||||
// Navigator.of(context).pushNamed(
|
||||
// '/about',
|
||||
// arguments: 0,
|
||||
// );
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
||||
|
||||
class MihForgotPassword extends StatefulWidget {
|
||||
const MihForgotPassword({super.key});
|
||||
|
||||
@override
|
||||
State<MihForgotPassword> createState() => _MihForgotPasswordState();
|
||||
}
|
||||
|
||||
class _MihForgotPasswordState extends State<MihForgotPassword> {
|
||||
final emailController = TextEditingController();
|
||||
bool successfulForgotPassword = false;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
bool acceptWarning = false;
|
||||
|
||||
Future<void> submitPasswodReset() async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const Mihloadingcircle();
|
||||
},
|
||||
);
|
||||
try {
|
||||
var resetPassEmailSent = await MihAuthenticationServices()
|
||||
.forgotPassword(emailController.text);
|
||||
context.pop();
|
||||
if (resetPassEmailSent) {
|
||||
setState(() {
|
||||
successfulForgotPassword = true;
|
||||
});
|
||||
}
|
||||
} on Exception {
|
||||
//loginError();
|
||||
}
|
||||
}
|
||||
|
||||
void prePassResteWarning() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MihPackageAlert(
|
||||
alertIcon: Icon(
|
||||
Icons.warning_amber_rounded,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
alertTitle: "Password Reset Confirmation",
|
||||
alertBody: Column(
|
||||
//mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
||||
child: Text(
|
||||
"Before you reset your password, please be aware that you'll receive an email with a link to confirm your identity and set a new password. Make sure to check your inbox, including spam or junk folders. If you don't receive the email within a few minutes, please try resending the reset request.",
|
||||
style: TextStyle(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
MihButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
acceptWarning = true;
|
||||
});
|
||||
Navigator.of(context).pop();
|
||||
validateInput();
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Continue",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
alertColour: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void resetLinkSentSuccessfully() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MihPackageAlert(
|
||||
alertIcon: Icon(
|
||||
Icons.check_circle_outline_rounded,
|
||||
size: 150,
|
||||
color: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
alertTitle: "Successfully Sent Reset Link",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours",
|
||||
style: TextStyle(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
context.goNamed(
|
||||
'mihHome',
|
||||
extra: true,
|
||||
);
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
elevation: 10,
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Dismiss",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
alertColour: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
);
|
||||
// return const MIHSuccessMessage(
|
||||
// successType: "Success",
|
||||
// successMessage:
|
||||
// "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void validateInput() async {
|
||||
if (emailController.text.isEmpty) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Input Error");
|
||||
},
|
||||
);
|
||||
} else {
|
||||
await submitPasswodReset();
|
||||
if (successfulForgotPassword) {
|
||||
// Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false);
|
||||
resetLinkSentSuccessfully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double screenWidth = MediaQuery.of(context).size.width;
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
bodyItem: getBody(screenWidth),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBody(double width) {
|
||||
return KeyboardListener(
|
||||
focusNode: _focusNode,
|
||||
autofocus: true,
|
||||
onKeyEvent: (event) async {
|
||||
if (event is KeyDownEvent &&
|
||||
event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
validateInput();
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: MzansiInnovationHub.of(context)!.theme.screenType ==
|
||||
"desktop"
|
||||
? EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(vertical: 25, horizontal: width * 0.075),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
//logo
|
||||
Icon(
|
||||
Icons.lock,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 10),
|
||||
//Heading
|
||||
Text(
|
||||
'Forgot Password',
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
controller: emailController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
hintText: "Email",
|
||||
validator: (value) {
|
||||
return MihValidationServices().validateEmail(value);
|
||||
},
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 20),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
prePassResteWarning();
|
||||
} else {
|
||||
MihAlertServices().formNotFilledCompletely(context);
|
||||
}
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Reset Password",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:mzansi_innovation_hub/main.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_button.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_form.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_alert.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_package_tool_body.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_package_components/mih_text_form_field.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_error_message.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_components/mih_pop_up_messages/mih_loading_circle.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_config/mih_colors.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_alert_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_authentication_services.dart';
|
||||
import 'package:mzansi_innovation_hub/mih_services/mih_validation_services.dart';
|
||||
|
||||
class MihResetPassword extends StatefulWidget {
|
||||
final String token;
|
||||
const MihResetPassword({
|
||||
super.key,
|
||||
required this.token,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MihResetPassword> createState() => _MihResetPasswordState();
|
||||
}
|
||||
|
||||
class _MihResetPasswordState extends State<MihResetPassword> {
|
||||
final passwordController = TextEditingController();
|
||||
final confirmPasswordController = TextEditingController();
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
void submitFormInput() async {
|
||||
if (passwordController.text != confirmPasswordController.text) {
|
||||
passwordError();
|
||||
} else {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const Mihloadingcircle();
|
||||
},
|
||||
);
|
||||
bool successfulResetPassword = await MihAuthenticationServices()
|
||||
.resetPassword(widget.token, passwordController.text);
|
||||
context.pop();
|
||||
if (successfulResetPassword) {
|
||||
resetSuccessfully();
|
||||
} else {
|
||||
loginError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resetSuccessfully() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return MihPackageAlert(
|
||||
alertIcon: Icon(
|
||||
Icons.check_circle_outline_rounded,
|
||||
size: 150,
|
||||
color: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
alertTitle: "Successfully Reset Password",
|
||||
alertBody: Column(
|
||||
children: [
|
||||
Text(
|
||||
"Great news! Your password reset is complete. You can now log in to Mzansi Innovation Hub using your new password.",
|
||||
style: TextStyle(
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 25),
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
context.goNamed(
|
||||
'mihHome',
|
||||
extra: true,
|
||||
);
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
elevation: 10,
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Dismiss",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
alertColour: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
);
|
||||
// return const MIHSuccessMessage(
|
||||
// successType: "Success",
|
||||
// successMessage:
|
||||
// "We've sent a password reset link to your email address. Please check your inbox, including spam or junk folders.\n\nOnce you find the email, click on the link to reset your password.\n\nIf you don't receive the email within a few minutes, please try resending the reset request.\n\nThe reset link will expire after 2 hours");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void loginError() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Invalid Credentials");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void passwordError() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const MIHErrorMessage(errorType: "Password Match");
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double screenWidth = MediaQuery.of(context).size.width;
|
||||
return MihPackageToolBody(
|
||||
borderOn: false,
|
||||
bodyItem: getBody(screenWidth),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBody(double width) {
|
||||
return KeyboardListener(
|
||||
focusNode: _focusNode,
|
||||
autofocus: true,
|
||||
onKeyEvent: (event) async {
|
||||
if (event is KeyDownEvent &&
|
||||
event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
submitFormInput();
|
||||
} else {
|
||||
MihAlertServices().formNotFilledCompletely(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: SafeArea(
|
||||
child: Center(
|
||||
child: SingleChildScrollView(
|
||||
physics: const BouncingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding:
|
||||
MzansiInnovationHub.of(context)!.theme.screenType == "desktop"
|
||||
? EdgeInsets.symmetric(horizontal: width * 0.2)
|
||||
: EdgeInsets.symmetric(horizontal: width * 0.075),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
//logo
|
||||
Icon(
|
||||
Icons.lock,
|
||||
size: 100,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode == "Dark"),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 10),
|
||||
//Heading
|
||||
Text(
|
||||
'Reset Password',
|
||||
style: TextStyle(
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
),
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 25),
|
||||
MihForm(
|
||||
formKey: _formKey,
|
||||
formFields: [
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
controller: passwordController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
hintText: "Password",
|
||||
passwordMode: true,
|
||||
autofillHints: const [AutofillHints.password],
|
||||
validator: (value) {
|
||||
return MihValidationServices()
|
||||
.validatePassword(value);
|
||||
},
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 10),
|
||||
MihTextFormField(
|
||||
fillColor: MihColors.getSecondaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
inputColor: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
controller: confirmPasswordController,
|
||||
multiLineInput: false,
|
||||
requiredText: true,
|
||||
hintText: "Confirm Password",
|
||||
passwordMode: true,
|
||||
autofillHints: const [AutofillHints.password],
|
||||
validator: (value) {
|
||||
return MihValidationServices()
|
||||
.validatePassword(value);
|
||||
},
|
||||
),
|
||||
//spacer
|
||||
const SizedBox(height: 25),
|
||||
// sign in button
|
||||
Center(
|
||||
child: MihButton(
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
submitFormInput();
|
||||
} else {
|
||||
MihAlertServices()
|
||||
.formNotFilledCompletely(context);
|
||||
}
|
||||
},
|
||||
buttonColor: MihColors.getGreenColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
width: 300,
|
||||
child: Text(
|
||||
"Reset Password",
|
||||
style: TextStyle(
|
||||
color: MihColors.getPrimaryColor(
|
||||
MzansiInnovationHub.of(context)!.theme.mode ==
|
||||
"Dark"),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -114,6 +114,54 @@ class MihAuthenticationServices {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> forgotPassword(
|
||||
String email,
|
||||
) async {
|
||||
var response = await http.post(
|
||||
Uri.parse("$baseAPI/auth/user/password/reset/token"),
|
||||
body: '{"formFields": [{"id": "email","value": "$email"}]}',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
var userSignedin = jsonDecode(response.body);
|
||||
if (userSignedin["status"] == "OK") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> resetPassword(
|
||||
String token,
|
||||
String password,
|
||||
) async {
|
||||
var response = await http.post(
|
||||
Uri.parse("$baseAPI/auth/user/password/reset"),
|
||||
body:
|
||||
'{"method": "token","formFields": [{"id": "password","value": "$password"}],"token": "$token"}',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
var userSignedin = jsonDecode(response.body);
|
||||
if (userSignedin["status"] == "OK") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void internetConnectionPopUp(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
|
||||
Reference in New Issue
Block a user