From c0c165eba47c8f538396f1dd84416c3cdccc323b Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 <50428976+WaseemAbbasi22@users.noreply.github.com> Date: Thu, 9 Jul 2026 16:12:28 +0300 Subject: [PATCH] Added error and success dialog for signup screen --- lib/extensions/context_extension.dart | 42 +++- .../signup/providers/signup_provider.dart | 40 ++-- lib/modules/signup/screens/signup_screen.dart | 187 +++++++++--------- 3 files changed, 156 insertions(+), 113 deletions(-) diff --git a/lib/extensions/context_extension.dart b/lib/extensions/context_extension.dart index 84d41a33..0bde12f1 100644 --- a/lib/extensions/context_extension.dart +++ b/lib/extensions/context_extension.dart @@ -1,8 +1,12 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart'; import 'package:test_sa/new_views/swipe_module/dialoge/info_dialog.dart'; @@ -43,6 +47,41 @@ extension BuildContextExtension on BuildContext { builder: (BuildContext cxt) => InfoDialog(message: message, onTap: onTap, title: title, okTitle: okTitle, content: content), ); + // + void showSingleBtnDialog(String message, {String? title, VoidCallback? onTap, String? okTitle}) => showDialog( + context: this, + builder: (BuildContext cxt) => Platform.isIOS + ? CupertinoAlertDialog( + title: Text(title ?? 'Error'), + content: Text(message), + actions: [ + CupertinoButton( + onPressed: onTap ?? + () { + Navigator.pop(cxt); + }, + child: Text(okTitle ?? "Ok"), + ) + ], + ) + : AlertDialog( + title: Text(title ?? 'Error'), + content: Text(message), + actionsAlignment: MainAxisAlignment.center, + contentPadding: const EdgeInsets.only(left: 24.0, top: 20.0, right: 24.0, bottom: 16.0), + actions: [ + FilledButton( + style: ButtonStyle(backgroundColor: WidgetStateProperty.all(AppColor.primary10)), + onPressed: onTap ?? + () { + Navigator.pop(cxt); + }, + child: Text(okTitle ?? "Ok"), + ) + ], + ), + ); + Future showBottomSheet(Widget childWidget, {bool? isDismissible, String? title, bool showCancelButton = false}) => showModalBottomSheet( context: this, useSafeArea: true, @@ -50,6 +89,7 @@ extension BuildContextExtension on BuildContext { isDismissible: isDismissible ?? true, enableDrag: isDismissible ?? true, backgroundColor: Colors.transparent, - builder: (context) => SingleChildScrollView(padding: const EdgeInsets.all(0), child: childWidget.bottomSafeArea).bottomSheetContainerNew(context, title: title,showCancelButton: showCancelButton), + builder: (context) => + SingleChildScrollView(padding: const EdgeInsets.all(0), child: childWidget.bottomSafeArea).bottomSheetContainerNew(context, title: title, showCancelButton: showCancelButton), ); } diff --git a/lib/modules/signup/providers/signup_provider.dart b/lib/modules/signup/providers/signup_provider.dart index 1e9f292e..108a7c8a 100644 --- a/lib/modules/signup/providers/signup_provider.dart +++ b/lib/modules/signup/providers/signup_provider.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/modules/signup/models/employee_erp_model.dart'; import 'package:test_sa/modules/signup/models/signup_request_model.dart'; @@ -10,6 +11,7 @@ import 'package:test_sa/modules/signup/models/department_model.dart'; class SignUpProvider extends ChangeNotifier { bool _loading = false; + bool get loading => _loading; set loading(bool value) { @@ -18,25 +20,30 @@ class SignUpProvider extends ChangeNotifier { } EmployeeERPModel? _employeeData; + EmployeeERPModel? get employeeData => _employeeData; List _sites = []; + List get sites => _sites; List _departments = []; + List get departments => _departments; String? _errorMessage; + String? get errorMessage => _errorMessage; String? _successMessage; + String? get successMessage => _successMessage; /// Get headers without authentication token for signup APIs Map get _unauthenticatedHeaders => { - 'Content-Type': 'application/json', - 'X-Timezone-Offset': DateTime.now().timeZoneOffset.toString().split(".").first, - }; + 'Content-Type': 'application/json', + 'X-Timezone-Offset': DateTime.now().timeZoneOffset.toString().split(".").first, + }; /// Fetch employee details from ERP Future getEmployeeFromERP(String employeeId) async { @@ -49,10 +56,7 @@ class SignUpProvider extends ChangeNotifier { try { final url = '${URLs.signUpGetEmployeeFromERP}?employeeId=$employeeId'; - final response = await http.get( - Uri.parse(url), - headers: _unauthenticatedHeaders, - ); + final response = await ApiManager.instance.get(url, headers: _unauthenticatedHeaders); if (response.statusCode >= 200 && response.statusCode < 300) { final data = json.decode(response.body); @@ -95,11 +99,7 @@ class SignUpProvider extends ChangeNotifier { notifyListeners(); try { - final response = await http.post( - Uri.parse(URLs.createSignUpRequest), - headers: _unauthenticatedHeaders, - body: json.encode(request.toJson()), - ); + final response = await ApiManager.instance.post(URLs.createSignUpRequest, headers: _unauthenticatedHeaders, body: request.toJson(), showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { final data = json.decode(response.body); @@ -131,17 +131,15 @@ class SignUpProvider extends ChangeNotifier { try { final url = '${URLs.signUpGetSiteList}?assetGroupId=$assetGroupId'; - final response = await http.get( - Uri.parse(url), + final response = await ApiManager.instance.get( + url, headers: _unauthenticatedHeaders, ); if (response.statusCode >= 200 && response.statusCode < 300) { final data = json.decode(response.body); if (data['data'] != null && data['data'] is List) { - _sites = (data['data'] as List) - .map((site) => SiteModel.fromJson(site)) - .toList(); + _sites = (data['data'] as List).map((site) => SiteModel.fromJson(site)).toList(); } loading = false; notifyListeners(); @@ -170,8 +168,8 @@ class SignUpProvider extends ChangeNotifier { try { final url = '${URLs.signUpGetDepartmentAutoComplete}?assetGroupId=$assetGroupId'; - final response = await http.get( - Uri.parse(url), + final response = await ApiManager.instance.get( + url, headers: _unauthenticatedHeaders, ); @@ -179,9 +177,7 @@ class SignUpProvider extends ChangeNotifier { final data = json.decode(response.body); // The response is directly an array, not wrapped in a data object if (data is List) { - _departments = data - .map((dept) => DepartmentModel.fromJson(dept)) - .toList(); + _departments = data.map((dept) => DepartmentModel.fromJson(dept)).toList(); } loading = false; notifyListeners(); diff --git a/lib/modules/signup/screens/signup_screen.dart b/lib/modules/signup/screens/signup_screen.dart index 4d0d379b..1c41e343 100644 --- a/lib/modules/signup/screens/signup_screen.dart +++ b/lib/modules/signup/screens/signup_screen.dart @@ -1,7 +1,11 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/validator/validator.dart'; +import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; @@ -24,6 +28,8 @@ import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +import 'package:test_sa/new_views/swipe_module/dialoge/single_btn_dialog.dart'; +import 'package:test_sa/views/widgets/dialogs/dialog.dart'; class SignUpScreen extends StatefulWidget { static const String routeName = "/signup_screen"; @@ -401,16 +407,16 @@ class _SignUpScreenState extends State { if (employee != null) { // Check if the error message indicates duplicate account - if (_signUpProvider.errorMessage != null && _signUpProvider.errorMessage!.toLowerCase().contains('already')) { - // Show duplicate account popup - _showDuplicateAccountDialog(); - setState(() { - _employeeFetched = false; - _employeeERPData = null; - _employeeIdController.clear(); - }); - return; - } + // if (_signUpProvider.errorMessage != null && _signUpProvider.errorMessage!.toLowerCase().contains('already')) { + // // Show duplicate account popup + // _showDuplicateAccountDialog(); + // setState(() { + // _employeeFetched = false; + // _employeeERPData = null; + // _employeeIdController.clear(); + // }); + // return; + // } setState(() { _employeeFetched = true; @@ -423,28 +429,28 @@ class _SignUpScreenState extends State { _siteController.text = employee.branchCode ?? ''; }); } else { + setState(() { + _employeeFetched = false; + _employeeERPData = null; + // _employeeIdController.clear(); + }); // Check if it's a duplicate account error - if (_signUpProvider.errorMessage != null && - (_signUpProvider.errorMessage!.toLowerCase().contains('already') || - _signUpProvider.errorMessage!.toLowerCase().contains('exists') || - _signUpProvider.errorMessage!.toLowerCase().contains('account'))) { - _showDuplicateAccountDialog(); - setState(() { - _employeeFetched = false; - _employeeERPData = null; - _employeeIdController.clear(); - }); - } else { - setState(() { - _employeeFetched = false; - _employeeERPData = null; - }); - if (_signUpProvider.errorMessage != null) { - Fluttertoast.showToast( - msg: _signUpProvider.errorMessage!, - ); - } - } + // if (_signUpProvider.errorMessage != null && + // (_signUpProvider.errorMessage!.toLowerCase().contains('already') || + // _signUpProvider.errorMessage!.toLowerCase().contains('exists') || + // _signUpProvider.errorMessage!.toLowerCase().contains('account'))) { + // _showDuplicateAccountDialog(); + // setState(() { + // _employeeFetched = false; + // _employeeERPData = null; + // _employeeIdController.clear(); + // }); + // } else { + // setState(() { + // _employeeFetched = false; + // _employeeERPData = null; + // }); + // } } } @@ -638,69 +644,70 @@ class _SignUpScreenState extends State { } } else { if (_signUpProvider.errorMessage != null) { - Fluttertoast.showToast( - msg: _signUpProvider.errorMessage!, - ); + context.showSingleBtnDialog(_signUpProvider.errorMessage!); } } } void _showSuccessDialog() { - final successMessage = _signUpProvider.successMessage ?? 'Your signup request has been submitted successfully'; - - showDialog( - context: context, - builder: (context) => Dialog( - backgroundColor: Colors.white, - shape: const RoundedRectangleBorder(), - insetPadding: const EdgeInsets.only(left: 21, right: 21), - child: Padding( - padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Text( - "Success", - style: const TextStyle( - fontSize: 24, - fontWeight: FontWeight.w600, - color: Colors.black87, - height: 35 / 24, - letterSpacing: -0.96, - ), - ).paddingOnly(top: 16), - ), - IconButton( - padding: EdgeInsets.zero, - icon: const Icon(Icons.close), - color: Colors.black87, - constraints: const BoxConstraints(), - onPressed: () { - Navigator.pop(context); // Close dialog - Navigator.pop(context); // Go back to login - }, - ) - ], - ), - successMessage.bodyText(context), - 28.height, - AppFilledButton( - label: "OK", - onPressed: () { - Navigator.pop(context); // Close dialog - Navigator.pop(context); // Go back to login - }, - textColor: Colors.white, - ), - ], - ), - ), - ), - ); + final successMessage = _signUpProvider.successMessage ?? 'Your signup request has been submitted'; + context.showSingleBtnDialog(successMessage, title: 'Success', onTap: () { + Navigator.pop(context); // Close dialog + Navigator.pop(context); + }); + // showDialog( + // context: context, + // builder: (context) => Dialog( + // backgroundColor: Colors.white, + // shape: const RoundedRectangleBorder(), + // insetPadding: const EdgeInsets.only(left: 21, right: 21), + // child: Padding( + // padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Expanded( + // child: Text( + // "Success", + // style: const TextStyle( + // fontSize: 24, + // fontWeight: FontWeight.w600, + // color: Colors.black87, + // height: 35 / 24, + // letterSpacing: -0.96, + // ), + // ).paddingOnly(top: 16), + // ), + // IconButton( + // padding: EdgeInsets.zero, + // icon: const Icon(Icons.close), + // color: Colors.black87, + // constraints: const BoxConstraints(), + // onPressed: () { + // Navigator.pop(context); // Close dialog + // Navigator.pop(context); // Go back to login + // }, + // ) + // ], + // ), + // successMessage.bodyText(context), + // 28.height, + // AppFilledButton( + // label: "OK", + // onPressed: () { + // Navigator.pop(context); // Close dialog + // Navigator.pop(context); // Go back to login + // }, + // textColor: Colors.white, + // ), + // ], + // ), + // ), + // ), + // ); } }