Added error and success dialog for signup screen

export_module_ui_ux_enhancement_signup
WaseemAbbasi22 4 weeks ago
parent 66bbb473b3
commit c0c165eba4

@ -1,8 +1,12 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:localization/localization.dart'; import 'package:localization/localization.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/widget_extensions.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/confirm_dialog.dart';
import 'package:test_sa/new_views/swipe_module/dialoge/info_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), 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( Future showBottomSheet(Widget childWidget, {bool? isDismissible, String? title, bool showCancelButton = false}) => showModalBottomSheet(
context: this, context: this,
useSafeArea: true, useSafeArea: true,
@ -50,6 +89,7 @@ extension BuildContextExtension on BuildContext {
isDismissible: isDismissible ?? true, isDismissible: isDismissible ?? true,
enableDrag: isDismissible ?? true, enableDrag: isDismissible ?? true,
backgroundColor: Colors.transparent, 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),
); );
} }

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; 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/controllers/api_routes/urls.dart';
import 'package:test_sa/modules/signup/models/employee_erp_model.dart'; import 'package:test_sa/modules/signup/models/employee_erp_model.dart';
import 'package:test_sa/modules/signup/models/signup_request_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 { class SignUpProvider extends ChangeNotifier {
bool _loading = false; bool _loading = false;
bool get loading => _loading; bool get loading => _loading;
set loading(bool value) { set loading(bool value) {
@ -18,25 +20,30 @@ class SignUpProvider extends ChangeNotifier {
} }
EmployeeERPModel? _employeeData; EmployeeERPModel? _employeeData;
EmployeeERPModel? get employeeData => _employeeData; EmployeeERPModel? get employeeData => _employeeData;
List<SiteModel> _sites = []; List<SiteModel> _sites = [];
List<SiteModel> get sites => _sites; List<SiteModel> get sites => _sites;
List<DepartmentModel> _departments = []; List<DepartmentModel> _departments = [];
List<DepartmentModel> get departments => _departments; List<DepartmentModel> get departments => _departments;
String? _errorMessage; String? _errorMessage;
String? get errorMessage => _errorMessage; String? get errorMessage => _errorMessage;
String? _successMessage; String? _successMessage;
String? get successMessage => _successMessage; String? get successMessage => _successMessage;
/// Get headers without authentication token for signup APIs /// Get headers without authentication token for signup APIs
Map<String, String> get _unauthenticatedHeaders => { Map<String, String> get _unauthenticatedHeaders => {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Timezone-Offset': DateTime.now().timeZoneOffset.toString().split(".").first, 'X-Timezone-Offset': DateTime.now().timeZoneOffset.toString().split(".").first,
}; };
/// Fetch employee details from ERP /// Fetch employee details from ERP
Future<EmployeeERPModel?> getEmployeeFromERP(String employeeId) async { Future<EmployeeERPModel?> getEmployeeFromERP(String employeeId) async {
@ -49,10 +56,7 @@ class SignUpProvider extends ChangeNotifier {
try { try {
final url = '${URLs.signUpGetEmployeeFromERP}?employeeId=$employeeId'; final url = '${URLs.signUpGetEmployeeFromERP}?employeeId=$employeeId';
final response = await http.get( final response = await ApiManager.instance.get(url, headers: _unauthenticatedHeaders);
Uri.parse(url),
headers: _unauthenticatedHeaders,
);
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
final data = json.decode(response.body); final data = json.decode(response.body);
@ -95,11 +99,7 @@ class SignUpProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
try { try {
final response = await http.post( final response = await ApiManager.instance.post(URLs.createSignUpRequest, headers: _unauthenticatedHeaders, body: request.toJson(), showToast: false);
Uri.parse(URLs.createSignUpRequest),
headers: _unauthenticatedHeaders,
body: json.encode(request.toJson()),
);
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
final data = json.decode(response.body); final data = json.decode(response.body);
@ -131,17 +131,15 @@ class SignUpProvider extends ChangeNotifier {
try { try {
final url = '${URLs.signUpGetSiteList}?assetGroupId=$assetGroupId'; final url = '${URLs.signUpGetSiteList}?assetGroupId=$assetGroupId';
final response = await http.get( final response = await ApiManager.instance.get(
Uri.parse(url), url,
headers: _unauthenticatedHeaders, headers: _unauthenticatedHeaders,
); );
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
final data = json.decode(response.body); final data = json.decode(response.body);
if (data['data'] != null && data['data'] is List) { if (data['data'] != null && data['data'] is List) {
_sites = (data['data'] as List) _sites = (data['data'] as List).map((site) => SiteModel.fromJson(site)).toList();
.map((site) => SiteModel.fromJson(site))
.toList();
} }
loading = false; loading = false;
notifyListeners(); notifyListeners();
@ -170,8 +168,8 @@ class SignUpProvider extends ChangeNotifier {
try { try {
final url = '${URLs.signUpGetDepartmentAutoComplete}?assetGroupId=$assetGroupId'; final url = '${URLs.signUpGetDepartmentAutoComplete}?assetGroupId=$assetGroupId';
final response = await http.get( final response = await ApiManager.instance.get(
Uri.parse(url), url,
headers: _unauthenticatedHeaders, headers: _unauthenticatedHeaders,
); );
@ -179,9 +177,7 @@ class SignUpProvider extends ChangeNotifier {
final data = json.decode(response.body); final data = json.decode(response.body);
// The response is directly an array, not wrapped in a data object // The response is directly an array, not wrapped in a data object
if (data is List) { if (data is List) {
_departments = data _departments = data.map((dept) => DepartmentModel.fromJson(dept)).toList();
.map((dept) => DepartmentModel.fromJson(dept))
.toList();
} }
loading = false; loading = false;
notifyListeners(); notifyListeners();

@ -1,7 +1,11 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/validator/validator.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/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_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/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/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.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 { class SignUpScreen extends StatefulWidget {
static const String routeName = "/signup_screen"; static const String routeName = "/signup_screen";
@ -401,16 +407,16 @@ class _SignUpScreenState extends State<SignUpScreen> {
if (employee != null) { if (employee != null) {
// Check if the error message indicates duplicate account // Check if the error message indicates duplicate account
if (_signUpProvider.errorMessage != null && _signUpProvider.errorMessage!.toLowerCase().contains('already')) { // if (_signUpProvider.errorMessage != null && _signUpProvider.errorMessage!.toLowerCase().contains('already')) {
// Show duplicate account popup // // Show duplicate account popup
_showDuplicateAccountDialog(); // _showDuplicateAccountDialog();
setState(() { // setState(() {
_employeeFetched = false; // _employeeFetched = false;
_employeeERPData = null; // _employeeERPData = null;
_employeeIdController.clear(); // _employeeIdController.clear();
}); // });
return; // return;
} // }
setState(() { setState(() {
_employeeFetched = true; _employeeFetched = true;
@ -423,28 +429,28 @@ class _SignUpScreenState extends State<SignUpScreen> {
_siteController.text = employee.branchCode ?? ''; _siteController.text = employee.branchCode ?? '';
}); });
} else { } else {
setState(() {
_employeeFetched = false;
_employeeERPData = null;
// _employeeIdController.clear();
});
// Check if it's a duplicate account error // Check if it's a duplicate account error
if (_signUpProvider.errorMessage != null && // if (_signUpProvider.errorMessage != null &&
(_signUpProvider.errorMessage!.toLowerCase().contains('already') || // (_signUpProvider.errorMessage!.toLowerCase().contains('already') ||
_signUpProvider.errorMessage!.toLowerCase().contains('exists') || // _signUpProvider.errorMessage!.toLowerCase().contains('exists') ||
_signUpProvider.errorMessage!.toLowerCase().contains('account'))) { // _signUpProvider.errorMessage!.toLowerCase().contains('account'))) {
_showDuplicateAccountDialog(); // _showDuplicateAccountDialog();
setState(() { // setState(() {
_employeeFetched = false; // _employeeFetched = false;
_employeeERPData = null; // _employeeERPData = null;
_employeeIdController.clear(); // _employeeIdController.clear();
}); // });
} else { // } else {
setState(() { // setState(() {
_employeeFetched = false; // _employeeFetched = false;
_employeeERPData = null; // _employeeERPData = null;
}); // });
if (_signUpProvider.errorMessage != null) { // }
Fluttertoast.showToast(
msg: _signUpProvider.errorMessage!,
);
}
}
} }
} }
@ -638,69 +644,70 @@ class _SignUpScreenState extends State<SignUpScreen> {
} }
} else { } else {
if (_signUpProvider.errorMessage != null) { if (_signUpProvider.errorMessage != null) {
Fluttertoast.showToast( context.showSingleBtnDialog(_signUpProvider.errorMessage!);
msg: _signUpProvider.errorMessage!,
);
} }
} }
} }
void _showSuccessDialog() { void _showSuccessDialog() {
final successMessage = _signUpProvider.successMessage ?? 'Your signup request has been submitted successfully'; final successMessage = _signUpProvider.successMessage ?? 'Your signup request has been submitted';
context.showSingleBtnDialog(successMessage, title: 'Success', onTap: () {
showDialog( Navigator.pop(context); // Close dialog
context: context, Navigator.pop(context);
builder: (context) => Dialog( });
backgroundColor: Colors.white, // showDialog(
shape: const RoundedRectangleBorder(), // context: context,
insetPadding: const EdgeInsets.only(left: 21, right: 21), // builder: (context) => Dialog(
child: Padding( // backgroundColor: Colors.white,
padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28), // shape: const RoundedRectangleBorder(),
child: Column( // insetPadding: const EdgeInsets.only(left: 21, right: 21),
crossAxisAlignment: CrossAxisAlignment.start, // child: Padding(
mainAxisSize: MainAxisSize.min, // padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28),
children: [ // child: Column(
Row( // crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, // mainAxisSize: MainAxisSize.min,
children: [ // children: [
Expanded( // Row(
child: Text( // crossAxisAlignment: CrossAxisAlignment.start,
"Success", // children: [
style: const TextStyle( // Expanded(
fontSize: 24, // child: Text(
fontWeight: FontWeight.w600, // "Success",
color: Colors.black87, // style: const TextStyle(
height: 35 / 24, // fontSize: 24,
letterSpacing: -0.96, // fontWeight: FontWeight.w600,
), // color: Colors.black87,
).paddingOnly(top: 16), // height: 35 / 24,
), // letterSpacing: -0.96,
IconButton( // ),
padding: EdgeInsets.zero, // ).paddingOnly(top: 16),
icon: const Icon(Icons.close), // ),
color: Colors.black87, // IconButton(
constraints: const BoxConstraints(), // padding: EdgeInsets.zero,
onPressed: () { // icon: const Icon(Icons.close),
Navigator.pop(context); // Close dialog // color: Colors.black87,
Navigator.pop(context); // Go back to login // constraints: const BoxConstraints(),
}, // onPressed: () {
) // Navigator.pop(context); // Close dialog
], // Navigator.pop(context); // Go back to login
), // },
successMessage.bodyText(context), // )
28.height, // ],
AppFilledButton( // ),
label: "OK", // successMessage.bodyText(context),
onPressed: () { // 28.height,
Navigator.pop(context); // Close dialog // AppFilledButton(
Navigator.pop(context); // Go back to login // label: "OK",
}, // onPressed: () {
textColor: Colors.white, // Navigator.pop(context); // Close dialog
), // Navigator.pop(context); // Go back to login
], // },
), // textColor: Colors.white,
), // ),
), // ],
); // ),
// ),
// ),
// );
} }
} }

Loading…
Cancel
Save