From d0f083ce223da4145bc3bd5c276425e55dd023e5 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Mon, 29 May 2023 14:59:40 +0300 Subject: [PATCH] - Update Login API - Adding Get Service Request By ID API --- lib/controllers/api_routes/urls.dart | 3 +- .../api/service_requests_provider.dart | 34 ++- .../providers/api/user_provider.dart | 13 +- lib/models/user.dart | 261 +++++++++++++----- .../request_device_transfer.dart | 4 +- lib/views/pages/login.dart | 2 +- lib/views/pages/register.dart | 41 +-- lib/views/pages/splash_screen.dart | 33 +-- .../notifications/notifications_page.dart | 27 +- lib/views/pages/user/profile_page.dart | 153 +++++----- .../pages/user/requests/create_request.dart | 8 +- .../pages/user/requests/requests_page.dart | 37 ++- .../auto_complete_devices_field.dart | 102 +++---- .../equipment/single_device_picker.dart | 82 +++--- .../pentry/pentry_calibration_tool_form.dart | 2 +- 15 files changed, 449 insertions(+), 353 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 44645f76..36f430fd 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -14,7 +14,7 @@ class URLs { static String getFileUrl(String file) => file == null || file.isEmpty ? null : "$_host/attachment/$file"; // API Routes - static get login => "$_baseUrl/MobileAuth/Login"; // post + static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // post static get register => "$_baseUrl/handle/create/user"; // post static get updateProfile => "$_baseUrl/update/user/profile"; // post static get getHospitals => "$_baseUrl/Customer/GetCustomers"; // get @@ -23,6 +23,7 @@ class URLs { static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 // 08051 static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get + static get getServiceRequestById => "$_baseUrl/CallRequest/GetCallRequestById"; // get static get getServiceRequestThrough => "$_baseUrl/Lookups/GetLookup?lookupEnum=603"; // get static get getServiceLoanAvailability => "$_baseUrl/Lookups/GetLookup?lookupEnum=4"; // get static get getServiceFirstAction => "$_baseUrl/Lookups/GetLookup?lookupEnum=700"; // get diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index e989a85d..6f853e06 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -138,7 +138,7 @@ class ServiceRequestsProvider extends ChangeNotifier { "assets": serviceRequest.deviceId == null ? [] : [serviceRequest.deviceId], "requestedDate": DateTime.now().toIso8601String(), "requestedTime": DateTime.now().toIso8601String(), - "client": user.hospital?.id ?? '', + "client": user.clientId, "callComments": serviceRequest.maintenanceIssue, if (serviceRequest.devicePhotos.isNotEmpty) "attachmentsCallRequest": serviceRequest.devicePhotos.map((e) => {"name": e}).toList(), "priority": serviceRequest.priority.toMap(), @@ -215,13 +215,14 @@ class ServiceRequestsProvider extends ChangeNotifier { @required ServiceRequest request, DateTime date, }) async { + String callNo = await getServiceRequestCallNoById(requestId: request.id) ?? ""; Response response; var body = { "id": request.id, - "callNo": "", + "callNo": callNo, "callCreatedBy": {"id": user.id, "name": user.userName}, - "requestedDate": date?.toIso8601String(), - "requestedTime": date?.toIso8601String(), + "requestedDate": date?.toIso8601String() ?? "", + "requestedTime": date?.toIso8601String() ?? "", "priority": request.priority?.toMap(), "defectType": request.defectType?.toMap(), "typeofRequest": request.type?.toMap(), @@ -245,8 +246,8 @@ class ServiceRequestsProvider extends ChangeNotifier { "noofFollowup": 0, // "status": null, "callLastSituation": null, - "firstAction": request.firstAction.toMap(), - "loanAvailablity": request.loanAvailability.toMap(), + "firstAction": request.firstAction?.toMap(), + "loanAvailablity": request.loanAvailability?.toMap(), "comments": request.comment, "firstActionDate": null, "visitDate": null, @@ -417,4 +418,25 @@ class ServiceRequestsProvider extends ChangeNotifier { throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle)); } } + + Future getServiceRequestCallNoById({@required String requestId}) async { + Response response; + try { + response = await ApiManager.instance.get( + URLs.getServiceRequestById + "?callRequestId=$requestId", + ); + } catch (error) { + print(error); + return ""; + } + + // If the call to the server was successful, parse the JSON. + if (response.statusCode >= 200 && response.statusCode < 300) { + // If the call to the server was successful, parse the JSON. + print(json.decode(response.body)["data"]); + return json.decode(response.body)["data"]["callNo"] as String; + } else { + return ""; + } + } } diff --git a/lib/controllers/providers/api/user_provider.dart b/lib/controllers/providers/api/user_provider.dart index 918787b0..bce2ce22 100644 --- a/lib/controllers/providers/api/user_provider.dart +++ b/lib/controllers/providers/api/user_provider.dart @@ -98,7 +98,8 @@ class UserProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); - _user.hospital = user.hospital; + _user.clientId = user.clientId; + _user.clientName = user.clientName; notifyListeners(); return response.statusCode; } @@ -123,8 +124,8 @@ class UserProvider extends ChangeNotifier { Map jsonObject = {}; jsonObject["uid"] = user.id; jsonObject["token"] = user.token; - if (user.department.id != _user.department.id) jsonObject["department"] = user.department.id; - if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp; + if (user.departmentId != _user.departmentId) jsonObject["department"] = user.departmentId; + // if (user.whatsApp != _user.whatsApp) jsonObject["whatsapp"] = user.whatsApp; if (user.phoneNumber != _user.phoneNumber) jsonObject["phone"] = user.phoneNumber; try { response = response = await ApiManager.instance.post( @@ -143,8 +144,10 @@ class UserProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); - _user.hospital = user.hospital; - _user.department = user.department; + _user.clientId = user.clientId; + _user.clientName = user.clientName; + _user.departmentName = user.departmentName; + _user.departmentId = user.departmentId; notifyListeners(); return response.statusCode; } diff --git a/lib/models/user.dart b/lib/models/user.dart index 05a1f3cc..89b031a5 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -1,108 +1,219 @@ import 'package:test_sa/controllers/notification/firebase_notification_manger.dart'; -import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/enums/user_types.dart'; -import 'package:test_sa/models/hospital.dart'; class User { + int clientId; + String clientName; + int departmentId; + String departmentName; + String message; + String username; + String userID; + String email; + String password; + String token; + dynamic roles; + List userRoles; + String tokenlife; + bool isAuthenticated; + bool hasError; + String profilePhotoName; String id; String userName; - String password; - String email; - Hospital hospital; - Department department; - UsersTypes type; + String normalizedUserName; + String normalizedEmail; + bool emailConfirmed; + dynamic passwordHash; + String securityStamp; + String concurrencyStamp; String phoneNumber; - String whatsApp; - String token; - bool isActive; - DateTime tokenLife; + bool phoneNumberConfirmed; + bool twoFactorEnabled; + dynamic lockoutEnd; + bool lockoutEnabled; + int accessFailedCount; - User( - {this.id, - this.userName = "", - this.email = "", - this.password = "", - this.phoneNumber = "", - this.hospital, - this.department, - this.type, - this.whatsApp, - this.token, - this.tokenLife, - this.isActive = false}); + User({ + this.clientId, + this.clientName, + this.departmentId, + this.departmentName, + this.message, + this.username, + this.userID, + this.email, + this.password, + this.token, + this.roles, + this.userRoles, + this.tokenlife, + this.isAuthenticated, + this.hasError, + this.profilePhotoName, + this.id, + this.userName, + this.normalizedUserName, + this.normalizedEmail, + this.emailConfirmed, + this.passwordHash, + this.securityStamp, + this.concurrencyStamp, + this.phoneNumber, + this.phoneNumberConfirmed, + this.twoFactorEnabled, + this.lockoutEnd, + this.lockoutEnabled, + this.accessFailedCount, + }); Future> toLoginJson() async { if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); return { "username": userName, "password": password, - "firebase_token": FirebaseNotificationManger?.token ?? "", + "fireBaseToken": FirebaseNotificationManger?.token ?? "", }; } + UsersTypes get type { + switch (userRoles.first.name) { + case "Engineer": + return UsersTypes.engineer; + case "Nurse": + return UsersTypes.normal_user; + default: + return null; + } + } + Map toUpdateProfileJson() { Map jsonObject = {}; - if (department?.id != null) jsonObject["department"] = department.id; - if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp; - if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber; + // if (departmentId != null) jsonObject["department"] = departmentId; + // if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp; + // if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber; return jsonObject; } Future> toRegisterJson() async { - if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); + // if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken(); return { - "username": userName, - "email": email, - "whatsapp": whatsApp, - "client": hospital.id, - "department": department?.id, - "phone": phoneNumber, - "pass": password, - "firebase_token": FirebaseNotificationManger?.token ?? "", + // "username": userName, + // "email": email, + // "whatsapp": whatsApp, + // "client": hospital.id, + // "department": department?.id, + // "phone": phoneNumber, + // "pass": password, + // "firebase_token": FirebaseNotificationManger?.token ?? "", }; } Map toJson() { - return { - "userID": id, - "username": userName, - "email": email, - "token": token, - "phoneNumber": phoneNumber, - "whatsapp": whatsApp, - "client_id": hospital?.id, - "client_name": hospital?.name, - "department_id": department?.id, - "department_name": department?.name, - //"password":password, - "tokenlife": tokenLife.toIso8601String(), - "active": isActive, - "userRoles": type == UsersTypes.engineer ? "value: R-6" : "value: R-5", - // "token":token, pass is token - }; + final map = {}; + map['client_id'] = clientId; + map['client_name'] = clientName; + map['department_id'] = departmentId; + map['department_name'] = departmentName; + map['message'] = message; + map['username'] = username; + map['userID'] = userID; + map['email'] = email; + map['password'] = password; + map['token'] = token; + map['roles'] = roles; + if (userRoles != null) { + map['userRoles'] = userRoles.map((v) => v.toJson()).toList(); + } + map['tokenlife'] = tokenlife; + map['isAuthenticated'] = isAuthenticated; + map['hasError'] = hasError; + map['profilePhotoName'] = profilePhotoName; + map['id'] = id; + map['userName'] = userName; + map['normalizedUserName'] = normalizedUserName; + map['normalizedEmail'] = normalizedEmail; + map['emailConfirmed'] = emailConfirmed; + map['passwordHash'] = passwordHash; + map['securityStamp'] = securityStamp; + map['concurrencyStamp'] = concurrencyStamp; + map['phoneNumber'] = phoneNumber; + map['phoneNumberConfirmed'] = phoneNumberConfirmed; + map['twoFactorEnabled'] = twoFactorEnabled; + map['lockoutEnd'] = lockoutEnd; + map['lockoutEnabled'] = lockoutEnabled; + map['accessFailedCount'] = accessFailedCount; + return map; } - factory User.fromJson(Map parsedJson) { - UsersTypes type; - if (parsedJson["userRoles"].toString().contains("value: R-4") || parsedJson["userRoles"].toString().contains("value: R-5") || parsedJson["userRoles"].toString().contains("value: R-7")) { - type = UsersTypes.normal_user; - } else { - type = UsersTypes.engineer; + User.fromJson(dynamic json) { + clientId = json['client_id']; + clientName = json['client_name']; + departmentId = json['department_id']; + departmentName = json['department_name']; + message = json['message']; + username = json['username']; + userID = json['userID']; + email = json['email']; + password = json['password']; + token = json['token']; + roles = json['roles']; + if (json['userRoles'] != null) { + userRoles = []; + json['userRoles'].forEach((v) { + userRoles.add(UserRoles.fromJson(v)); + }); } - return User( - id: parsedJson["userID"], - userName: parsedJson["username"], - email: parsedJson["email"], - hospital: Hospital(id: parsedJson["client_id"], name: parsedJson["client_name"]), - department: Department( - id: parsedJson["department_id"], - name: parsedJson["department_name"], - ), - phoneNumber: parsedJson["phoneNumber"], - whatsApp: parsedJson["phoneNumber"], - token: parsedJson["token"], - isActive: parsedJson["isAuthenticated"], - tokenLife: DateTime.tryParse(parsedJson["tokenlife"] ?? ""), - type: type); + tokenlife = json['tokenlife']; + isAuthenticated = json['isAuthenticated']; + hasError = json['hasError']; + profilePhotoName = json['profilePhotoName']; + id = json['id']; + userName = json['userName']; + normalizedUserName = json['normalizedUserName']; + normalizedEmail = json['normalizedEmail']; + emailConfirmed = json['emailConfirmed']; + passwordHash = json['passwordHash']; + securityStamp = json['securityStamp']; + concurrencyStamp = json['concurrencyStamp']; + phoneNumber = json['phoneNumber']; + phoneNumberConfirmed = json['phoneNumberConfirmed']; + twoFactorEnabled = json['twoFactorEnabled']; + lockoutEnd = json['lockoutEnd']; + lockoutEnabled = json['lockoutEnabled']; + accessFailedCount = json['accessFailedCount']; + } +} + +class UserRoles { + UserRoles({ + this.id, + this.name, + this.value, + }); + + UserRoles.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + String id; + String name; + String value; + UserRoles copyWith({ + String id, + String name, + String value, + }) => + UserRoles( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id; + map['name'] = name; + map['value'] = value; + return map; } } diff --git a/lib/views/pages/device_transfer/request_device_transfer.dart b/lib/views/pages/device_transfer/request_device_transfer.dart index 6eb86d08..c92c4929 100644 --- a/lib/views/pages/device_transfer/request_device_transfer.dart +++ b/lib/views/pages/device_transfer/request_device_transfer.dart @@ -35,7 +35,7 @@ class _RequestDeviceTransferState extends State { SettingProvider _settingProvider; DeviceTransferProvider _deviceTransferProvider; final TextEditingController _requestedQuantityController = TextEditingController(); - final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo(),sender: DeviceTransferInfo()); + final DeviceTransfer _formModel = DeviceTransfer(receiver: DeviceTransferInfo(), sender: DeviceTransferInfo()); final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); @@ -59,7 +59,7 @@ class _RequestDeviceTransferState extends State { _isLoading = true; setState(() {}); - _formModel.sender?.client?.id = _userProvider.user?.hospital?.id; + _formModel.sender?.client?.id = _userProvider.user?.clientId; int status = await _deviceTransferProvider.createRequest( user: _userProvider.user, host: _settingProvider.host, diff --git a/lib/views/pages/login.dart b/lib/views/pages/login.dart index 3bd061b0..65585b85 100644 --- a/lib/views/pages/login.dart +++ b/lib/views/pages/login.dart @@ -113,7 +113,7 @@ class _LoginState extends State { user: _user, host: _settingProvider.host, ); - if (status >= 200 && status < 300 && _userProvider.user?.userName != null) { + if (status >= 200 && status < 300) { _settingProvider.setUser(_userProvider.user); // if (_userProvider.user.isActive) Navigator.of(context).pushNamed(LandPage.id); diff --git a/lib/views/pages/register.dart b/lib/views/pages/register.dart index 22cd7d91..ab370de9 100644 --- a/lib/views/pages/register.dart +++ b/lib/views/pages/register.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/validator/validator.dart'; +import 'package:test_sa/models/department.dart'; +import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/user.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart'; @@ -123,17 +124,19 @@ class _RegisterState extends State { ), const SizedBox(height: 12), HospitalButton( - hospital: _user.hospital, + hospital: Hospital(id: _user.clientId, name: _user.clientName), onHospitalPick: (hospital) { - _user.hospital = hospital; + _user.clientId = hospital.id; + _user.clientName = hospital.name; setState(() {}); }, ), const SizedBox(height: 12), DepartmentButton( - department: _user.department, + department: Department(id: _user.departmentId, name: _user.departmentName), onDepartmentPick: (department) { - _user.department = department; + _user.departmentId = department.id; + _user.departmentName = department.name; setState(() {}); }, ), @@ -150,31 +153,31 @@ class _RegisterState extends State { }, ), SizedBox(height: 8), - ATextFormField( - initialValue: _user.whatsApp, - hintText: _subtitle.whatsApp, - style: Theme.of(context).textTheme.headline6, - prefixIconData: FontAwesomeIcons.whatsapp, - prefixIconSize: 36, - validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, - textInputType: TextInputType.phone, - onSaved: (value) { - _user.whatsApp = value; - }, - ), + // ATextFormField( + // initialValue: _user.whatsApp, + // hintText: _subtitle.whatsApp, + // style: Theme.of(context).textTheme.headline6, + // prefixIconData: FontAwesomeIcons.whatsapp, + // prefixIconSize: 36, + // validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, + // textInputType: TextInputType.phone, + // onSaved: (value) { + // _user.whatsApp = value; + // }, + // ), const SizedBox(height: 12), AButton( text: _subtitle.signUp, onPressed: () async { if (!_formKey.currentState.validate()) return; _formKey.currentState.save(); - if (_user.hospital == null) { + if (_user.clientId == null) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(_subtitle.hospitalRequired), )); return; } - if (_user.department == null) { + if (_user.departmentId == null) { ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text(_subtitle.unitRequired), )); diff --git a/lib/views/pages/splash_screen.dart b/lib/views/pages/splash_screen.dart index bd7a770f..e28c09de 100644 --- a/lib/views/pages/splash_screen.dart +++ b/lib/views/pages/splash_screen.dart @@ -22,12 +22,11 @@ class SplashScreen extends StatefulWidget { } class _SplashScreenState extends State { - SettingProvider _settingProvider; UserProvider _userProvider; - _goToUserScreen(User user){ - if(user.tokenLife != null && user.tokenLife.isAfter(DateTime.now())){ + _goToUserScreen(User user) { + if (user.tokenlife != null && (DateTime.tryParse(user.tokenlife)?.isAfter(DateTime.now()) ?? false)) { _userProvider.user = user; // Navigator.of(context).pushNamed(Login.id); Navigator.of(context).pushNamed(LandPage.id); @@ -38,38 +37,30 @@ class _SplashScreenState extends State { void initState() { Firebase.initializeApp(); - NotificationManger.initialisation( - (notificationDetails) { - AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload)); - if(notification.path == null || notification.path.isEmpty) - return; - Navigator.pushNamed( - context, - notification.path, - arguments: notification.requestId - ); - } - , (id, title, body, payload) async { - }); + NotificationManger.initialisation((notificationDetails) { + AppNotification notification = AppNotification.fromJson(json.decode(notificationDetails.payload)); + if (notification.path == null || notification.path.isEmpty) return; + Navigator.pushNamed(context, notification.path, arguments: notification.requestId); + }, (id, title, body, payload) async {}); super.initState(); } @override Widget build(BuildContext context) { - _settingProvider = Provider.of(context,listen: false); - _userProvider = Provider.of(context,listen: false); + _settingProvider = Provider.of(context, listen: false); + _userProvider = Provider.of(context, listen: false); return Scaffold( backgroundColor: Colors.white, body: Center( child: SizedBox( - width: MediaQuery.of(context).size.width/1.1, - child: FlareActor( + width: MediaQuery.of(context).size.width / 1.1, + child: FlareActor( "assets/rives/atoms_splash.flr", fit: BoxFit.contain, animation: "splash", callback: (animation) async { Navigator.of(context).pushNamed(Login.id); - if(_settingProvider.isLoaded && _settingProvider.user != null){ + if (_settingProvider.isLoaded && _settingProvider.user != null) { _goToUserScreen(_settingProvider.user); } }, diff --git a/lib/views/pages/user/notifications/notifications_page.dart b/lib/views/pages/user/notifications/notifications_page.dart index a0e85259..bab082e3 100644 --- a/lib/views/pages/user/notifications/notifications_page.dart +++ b/lib/views/pages/user/notifications/notifications_page.dart @@ -9,14 +9,14 @@ import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/pages/user/notifications/notifications_list.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; + class NotificationsPage extends StatefulWidget { static final String id = "/notifications"; @override _NotificationsPageState createState() => _NotificationsPageState(); } -class _NotificationsPageState extends State - with TickerProviderStateMixin{ +class _NotificationsPageState extends State with TickerProviderStateMixin { NotificationsProvider _notificationsProvider; UserProvider _userProvider; SettingProvider _settingProvider; @@ -36,9 +36,9 @@ class _NotificationsPageState extends State onRefresh: () async { _notificationsProvider.reset(); await _notificationsProvider.getNotifications( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital.id, + user: _userProvider.user, + host: _settingProvider.host, + hospitalId: _userProvider.user.clientId, ); }, child: Stack( @@ -46,8 +46,8 @@ class _NotificationsPageState extends State Column( children: [ Container( - color:AColors.primaryColor, - padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), child: Column( children: [ Row( @@ -57,17 +57,15 @@ class _NotificationsPageState extends State child: Center( child: Text( _subtitle.notifications, - style: Theme.of(context).textTheme.headline6.copyWith( - color: AColors.white, - fontStyle: FontStyle.italic - ), + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), ), ), ), - SizedBox(width: 48,) + SizedBox( + width: 48, + ) ], ), - ], ), ), @@ -78,7 +76,7 @@ class _NotificationsPageState extends State await _notificationsProvider.getNotifications( user: _userProvider.user, host: _settingProvider.host, - hospitalId: _userProvider.user.hospital.id, + hospitalId: _userProvider.user.clientId, ); }, notifications: _notificationsProvider.notifications, @@ -86,7 +84,6 @@ class _NotificationsPageState extends State ), ], ), - ], ), ), diff --git a/lib/views/pages/user/profile_page.dart b/lib/views/pages/user/profile_page.dart index 0b3757a0..f5bb5c2c 100644 --- a/lib/views/pages/user/profile_page.dart +++ b/lib/views/pages/user/profile_page.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/validator/validator.dart'; +import 'package:test_sa/models/department.dart'; +import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/user.dart'; import 'package:test_sa/views/app_style/colors.dart'; @@ -16,6 +17,7 @@ import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/departments/department_button.dart'; import 'package:test_sa/views/widgets/hospitals/hospital_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; + class ProfilePage extends StatefulWidget { static final String id = "/user/profile"; @override @@ -38,13 +40,13 @@ class _ProfilePageState extends State { _width = MediaQuery.of(context).size.width; _height = MediaQuery.of(context).size.height; Subtitle _subtitle = AppLocalization.of(context).subtitle; - if(_firstTime){ + if (_firstTime) { _user = User.fromJson(_userProvider.user.toJson()); _firstTime = false; } return Scaffold( key: _scaffoldKey, - body:LoadingManager( + body: LoadingManager( isLoading: _userProvider.isLoading, isFailedLoading: false, stateCode: 200, @@ -60,23 +62,19 @@ class _ProfilePageState extends State { Hero( tag: "logo", child: Image( - height: _height/4, + height: _height / 4, image: AssetImage("assets/images/logo.png"), ), ), Container( - padding: EdgeInsets.symmetric(horizontal: 16,vertical: 16), + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), margin: EdgeInsets.symmetric(horizontal: 16), - decoration: BoxDecoration( - color: AColors.primaryColor, - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), - boxShadow: [ - BoxShadow( - color: AColors.grey, - offset: Offset(0,-1), - ) - ] - ), + decoration: BoxDecoration(color: AColors.primaryColor, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ + BoxShadow( + color: AColors.grey, + offset: Offset(0, -1), + ) + ]), child: Column( children: [ ATextFormField( @@ -85,13 +83,14 @@ class _ProfilePageState extends State { enable: false, prefixIconData: Icons.account_circle, style: Theme.of(context).textTheme.headline6, - validator: (value) => Validator.hasValue(value) - ? null : _subtitle.nameValidateMessage, - onSaved: (value){ + validator: (value) => Validator.hasValue(value) ? null : _subtitle.nameValidateMessage, + onSaved: (value) { _user.userName = value; }, ), - SizedBox(height: 8,), + SizedBox( + height: 8, + ), ATextFormField( initialValue: _user.email, hintText: _subtitle.email, @@ -99,110 +98,108 @@ class _ProfilePageState extends State { prefixIconData: Icons.email, textInputType: TextInputType.emailAddress, style: Theme.of(context).textTheme.headline6, - validator: (value) => Validator.isEmail(value) - ? null : _subtitle.emailValidateMessage, - onSaved: (value){ + validator: (value) => Validator.isEmail(value) ? null : _subtitle.emailValidateMessage, + onSaved: (value) { _user.email = value; }, ), - SizedBox(height: 8,), + SizedBox( + height: 8, + ), AbsorbPointer( child: HospitalButton( - hospital: _user.hospital, - onHospitalPick: (hospital){ - _user.hospital = hospital; + hospital: Hospital(name: _user.clientName, id: _user.clientId), + onHospitalPick: (hospital) { + _user.clientName = hospital.name; + _user.clientId = hospital.id; setState(() {}); }, ), ), - SizedBox(height: 8,), + SizedBox( + height: 8, + ), DepartmentButton( - department: _user.department, - onDepartmentPick: (department){ - _user.department = department; + department: Department(name: _user.departmentName, id: _user.departmentId), + onDepartmentPick: (department) { + _user.departmentName = department.name; + _user.departmentId = department.id; setState(() {}); }, ), - SizedBox(height: 8,), + SizedBox( + height: 8, + ), ATextFormField( initialValue: _user.phoneNumber, hintText: _subtitle.phoneNumber, style: Theme.of(context).textTheme.headline6, prefixIconData: Icons.phone_android, - validator: (value) => - Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, + validator: (value) => Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, textInputType: TextInputType.phone, - onSaved: (value){ + onSaved: (value) { _user.phoneNumber = value; }, ), - SizedBox(height: 8,), - ATextFormField( - initialValue: _user.whatsApp, - hintText: _subtitle.whatsApp, - style: Theme.of(context).textTheme.headline6, - prefixIconData: FontAwesomeIcons.whatsapp, - prefixIconSize: 36, - validator: (value) => - Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, - textInputType: TextInputType.phone, - onSaved: (value){ - _user.whatsApp = value; - }, + SizedBox( + height: 8, ), + // ATextFormField( + // initialValue: _user.whatsApp, + // hintText: _subtitle.whatsApp, + // style: Theme.of(context).textTheme.headline6, + // prefixIconData: FontAwesomeIcons.whatsapp, + // prefixIconSize: 36, + // validator: (value) => + // Validator.isPhoneNumber(value) ? null : _subtitle.phoneNumberValidateMessage, + // textInputType: TextInputType.phone, + // onSaved: (value){ + // _user.whatsApp = value; + // }, + // ), ], ), ), - SizedBox(height: 16,), + SizedBox( + height: 16, + ), Center( child: SizedBox( height: _width / 8, - width: _width/1.2, + width: _width / 1.2, child: AButton( text: _subtitle.update, onPressed: () async { - if(!_formKey.currentState.validate()) - return; + if (!_formKey.currentState.validate()) return; _formKey.currentState.save(); - if(_user.department?.id == null){ - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - _subtitle.unitRequired - ), - ) - ); + if (_user.departmentId == null) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(_subtitle.unitRequired), + )); return; } int status = await _userProvider.updateProfile( user: _user, host: _settingProvider.host, ); - if(status >= 200 && status < 300){ + if (status >= 200 && status < 300) { _settingProvider.setUser(_userProvider.user); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - _subtitle.requestCompleteSuccessfully - ), - ) - ); - }else{ - String errorMessage = HttpStatusManger.getStatusMessage( - status: status, subtitle: _subtitle); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - errorMessage - ), - ) - ); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(_subtitle.requestCompleteSuccessfully), + )); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(errorMessage), + )); } }, ), ), ), - SizedBox(height: 32,), + SizedBox( + height: 32, + ), ], ), ), diff --git a/lib/views/pages/user/requests/create_request.dart b/lib/views/pages/user/requests/create_request.dart index 5e6701f5..c6135982 100644 --- a/lib/views/pages/user/requests/create_request.dart +++ b/lib/views/pages/user/requests/create_request.dart @@ -122,21 +122,21 @@ class CreateRequestPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ 12.height, - _userProvider.user.hospital == null + _userProvider.user.clientId == null ? const SizedBox.shrink() : ATextFormField( enable: false, - initialValue: _userProvider.user.hospital?.name ?? _subtitle.noHospitalFound, + initialValue: _userProvider.user.clientName ?? _subtitle.noHospitalFound, hintText: _subtitle.hospital, prefixIconData: FontAwesomeIcons.hospital, style: Theme.of(context).textTheme.subtitle1, ), 12.height, - _userProvider.user.department == null + _userProvider.user.departmentId == null ? const SizedBox.shrink() : ATextFormField( enable: false, - initialValue: _userProvider.user.department?.name ?? _subtitle.noUniteFound, + initialValue: _userProvider.user.departmentName ?? _subtitle.noUniteFound, hintText: _subtitle.unite, prefixIconData: FontAwesomeIcons.hospitalUser, style: Theme.of(context).textTheme.subtitle1, diff --git a/lib/views/pages/user/requests/requests_page.dart b/lib/views/pages/user/requests/requests_page.dart index 6c04d822..06160333 100644 --- a/lib/views/pages/user/requests/requests_page.dart +++ b/lib/views/pages/user/requests/requests_page.dart @@ -12,14 +12,14 @@ import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/requests/service_request_list.dart'; import 'package:test_sa/views/widgets/search/service_request_search_bar.dart'; + class ServiceRequestsPage extends StatefulWidget { static final String id = "/service-requests"; @override _ServiceRequestsPageState createState() => _ServiceRequestsPageState(); } -class _ServiceRequestsPageState extends State - with TickerProviderStateMixin{ +class _ServiceRequestsPageState extends State with TickerProviderStateMixin { ServiceRequestsProvider _serviceRequestsProvider; UserProvider _userProvider; SettingProvider _settingProvider; @@ -31,7 +31,7 @@ class _ServiceRequestsPageState extends State _userProvider = Provider.of(context); _settingProvider = Provider.of(context); Subtitle _subtitle = AppLocalization.of(context).subtitle; - if(_firstTime){ + if (_firstTime) { _serviceRequestsProvider.reset(); _firstTime = false; } @@ -45,9 +45,9 @@ class _ServiceRequestsPageState extends State onRefresh: () async { _serviceRequestsProvider.reset(); await _serviceRequestsProvider.getRequests( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital?.id, + user: _userProvider.user, + host: _settingProvider.host, + hospitalId: _userProvider.user.clientId, ); }, child: Stack( @@ -55,8 +55,8 @@ class _ServiceRequestsPageState extends State Column( children: [ Container( - color:AColors.primaryColor, - padding: const EdgeInsets.symmetric(horizontal: 0,vertical: 4), + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), child: Column( children: [ Row( @@ -66,10 +66,7 @@ class _ServiceRequestsPageState extends State child: Center( child: Text( _subtitle.serviceRequests, - style: Theme.of(context).textTheme.headline6.copyWith( - color: AColors.white, - fontStyle: FontStyle.italic - ), + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), ), ), ), @@ -83,22 +80,23 @@ class _ServiceRequestsPageState extends State ServiceRequestSearch _temp = await showModalBottomSheet( context: context, isScrollControlled: true, - builder: (context){ + builder: (context) { return ServiceRequestsSearchDialog( initialSearchValue: _serviceRequestsProvider.search, ); }); - if(_temp != null){ + if (_temp != null) { _serviceRequestsProvider.search = _temp; _serviceRequestsProvider.reset(); setState(() {}); } }, ), - SizedBox(width: 16,) + SizedBox( + width: 16, + ) ], ), - ], ), ), @@ -107,9 +105,9 @@ class _ServiceRequestsPageState extends State nextPage: _serviceRequestsProvider.nextPage, onLazyLoad: () async { await _serviceRequestsProvider.getRequests( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital.id, + user: _userProvider.user, + host: _settingProvider.host, + hospitalId: _userProvider.user.clientId, ); }, requests: _serviceRequestsProvider.serviceRequests, @@ -117,7 +115,6 @@ class _ServiceRequestsPageState extends State ), ], ), - ], ), ), diff --git a/lib/views/widgets/equipment/auto_complete_devices_field.dart b/lib/views/widgets/equipment/auto_complete_devices_field.dart index 3c6fbc99..0d45aa6e 100644 --- a/lib/views/widgets/equipment/auto_complete_devices_field.dart +++ b/lib/views/widgets/equipment/auto_complete_devices_field.dart @@ -8,6 +8,7 @@ import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; + class AutoCompleteDeviceField extends StatefulWidget { final Device initialValue; final int hospitalId; @@ -20,7 +21,6 @@ class AutoCompleteDeviceField extends StatefulWidget { } class _AutoCompleteDeviceFieldState extends State { - SettingProvider _settingProvider; DevicesProvider _devicesProvider; UserProvider _userProvider; @@ -37,6 +37,7 @@ class _AutoCompleteDeviceFieldState extends State { _controller.dispose(); super.dispose(); } + @override Widget build(BuildContext context) { _settingProvider = Provider.of(context); @@ -44,64 +45,53 @@ class _AutoCompleteDeviceFieldState extends State { _devicesProvider = Provider.of(context); //Subtitle _subtitle = AppLocalization.of(context).subtitle; return LoadingManager( - isLoading: _devicesProvider.isLoading, - isFailedLoading: _devicesProvider.devices == null, - stateCode: _devicesProvider.stateCode, - onRefresh: () async { - _devicesProvider.reset(); - await _devicesProvider.getEquipment( - host: _settingProvider.host, - user: _userProvider.user, - hospitalId: widget.hospitalId - ); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16 - ), - decoration: BoxDecoration( - color: Colors.white, - border: Border.all(color:AColors.black), - borderRadius: BorderRadius.circular( - AppStyle.borderRadius * AppStyle.getScaleFactor(context) - ), - boxShadow: [ - AppStyle.boxShadow - ] - ), - child: TypeAheadField( - textFieldConfiguration: TextFieldConfiguration( - style: Theme.of(context).textTheme.headline6, - controller: _controller, - textAlign: TextAlign.center, - decoration: const InputDecoration( - border: InputBorder.none, - disabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - enabledBorder: InputBorder.none, - ), - textInputAction: TextInputAction.search, + isLoading: _devicesProvider.isLoading, + isFailedLoading: _devicesProvider.devices == null, + stateCode: _devicesProvider.stateCode, + onRefresh: () async { + _devicesProvider.reset(); + await _devicesProvider.getEquipment(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId); + }, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: Colors.white, + border: Border.all(color: AColors.black), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + boxShadow: [AppStyle.boxShadow]), + child: TypeAheadField( + textFieldConfiguration: TextFieldConfiguration( + style: Theme.of(context).textTheme.headline6, + controller: _controller, + textAlign: TextAlign.center, + decoration: const InputDecoration( + border: InputBorder.none, + disabledBorder: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, ), - suggestionsCallback: (value) async { - return await _devicesProvider.getDevicesList( - host: _settingProvider.host, - user: _userProvider.user, - hospitalId: widget.hospitalId ?? _userProvider.user.hospital.id, - serialNumber: value, - ); - }, - itemBuilder: (context, device) { - return ListTile( - title: Text(device.serialNumber), - subtitle: Text("${device.modelDefinition.modelName}/${device.modelDefinition.manufacturerName}"), - ); - }, - onSuggestionSelected: (device) { - _controller.text = device.serialNumber; - widget.onPick(device.id); - }, + textInputAction: TextInputAction.search, ), + suggestionsCallback: (value) async { + return await _devicesProvider.getDevicesList( + host: _settingProvider.host, + user: _userProvider.user, + hospitalId: widget.hospitalId ?? _userProvider.user.clientId, + serialNumber: value, + ); + }, + itemBuilder: (context, device) { + return ListTile( + title: Text(device.serialNumber), + subtitle: Text("${device.modelDefinition.modelName}/${device.modelDefinition.manufacturerName}"), + ); + }, + onSuggestionSelected: (device) { + _controller.text = device.serialNumber; + widget.onPick(device.id); + }, ), + ), ); } } diff --git a/lib/views/widgets/equipment/single_device_picker.dart b/lib/views/widgets/equipment/single_device_picker.dart index a31be4df..3af9e58e 100644 --- a/lib/views/widgets/equipment/single_device_picker.dart +++ b/lib/views/widgets/equipment/single_device_picker.dart @@ -10,9 +10,9 @@ import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/views/widgets/equipment/device_item.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/no_item_found.dart'; -import 'package:test_sa/views/widgets/qr/scan_qr.dart'; import '../app_text_form_field.dart'; + class SingleDevicePicker extends StatefulWidget { static final String id = "/single-device-Picker"; final bool sandraChoice = true; @@ -31,22 +31,16 @@ class _SingleDevicePickerState extends State { TextEditingController numberController = TextEditingController(); TextEditingController snController = TextEditingController(); _getDevice(String result) async { - if(result == null) return; + if (result == null) return; showDialog( barrierDismissible: false, context: context, - builder: (dialogContext){ + builder: (dialogContext) { return const Center(child: CircularProgressIndicator()); - } - ); - List devices = await _devicesProvider.getDevicesListBySN( - host: _settingProvider.host, - user: _userProvider.user, - hospitalId: _userProvider.user.hospital.id, - sn: result - ); + }); + List devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); Navigator.of(context).pop(); - if(devices.isEmpty){ + if (devices.isEmpty) { Fluttertoast.showToast(msg: _subtitle.noDeviceFound); return; } @@ -71,7 +65,7 @@ class _SingleDevicePickerState extends State { _userProvider = Provider.of(context); _settingProvider = Provider.of(context); - if(_firstTime && _devicesProvider.devices != null){ + if (_firstTime && _devicesProvider.devices != null) { _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); _firstTime = false; @@ -85,54 +79,42 @@ class _SingleDevicePickerState extends State { isFailedLoading: _devicesProvider.devices == null, onRefresh: () async { _devicesProvider.reset(); - await _devicesProvider.getEquipment( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital?.id - ); + await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId); }, child: Column( children: [ const SizedBox(height: 48), Padding( - padding: const EdgeInsets.symmetric(vertical: 8,horizontal: 16), + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Column( children: [ ATextFormField( hintText: _subtitle.searchBySn, controller: snController, - style: Theme.of(context).textTheme.subtitle1, + style: Theme.of(context).textTheme.subtitle1, suffixIcon: const Icon(Icons.search_rounded), textInputAction: TextInputAction.search, onAction: () async { _devicesProvider.reset(); await _devicesProvider.getEquipment( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital?.id, - serialNumber: snController.text, - number: numberController.text - ); + user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), ATextFormField( hintText: "Search by Number", controller: numberController, - style: Theme.of(context).textTheme.subtitle1, + style: Theme.of(context).textTheme.subtitle1, suffixIcon: const Icon(Icons.search_rounded), textInputAction: TextInputAction.search, onAction: () async { _devicesProvider.reset(); await _devicesProvider.getEquipment( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.hospital?.id, - serialNumber: snController.text, - number: numberController.text - ); + user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); }, @@ -141,21 +123,23 @@ class _SingleDevicePickerState extends State { ), ), Expanded( - child: _searchableList.isEmpty ? - NoItemFound(message: _subtitle.noDeviceFound,): - ListView.builder( - padding: EdgeInsets.zero, - shrinkWrap: true, - itemCount: _searchableList.length, - itemBuilder: (listContext,itemIndex){ - return DeviceItem( - device: _searchableList[itemIndex], - onPressed: (device){ - Navigator.of(context).pop(device); - }, - ); - }, - ), + child: _searchableList.isEmpty + ? NoItemFound( + message: _subtitle.noDeviceFound, + ) + : ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: _searchableList.length, + itemBuilder: (listContext, itemIndex) { + return DeviceItem( + device: _searchableList[itemIndex], + onPressed: (device) { + Navigator.of(context).pop(device); + }, + ); + }, + ), ), ], ), diff --git a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart b/lib/views/widgets/pentry/pentry_calibration_tool_form.dart index 7ecdaed6..048e113c 100644 --- a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart +++ b/lib/views/widgets/pentry/pentry_calibration_tool_form.dart @@ -71,7 +71,7 @@ class _PentryCalibrationToolFormState extends State { ), AutoCompleteDeviceNumberField( initialValue: model.assetsNumber, - hospitalId: userProvider.user.hospital?.id, + hospitalId: userProvider.user.clientId, onPick: (number) { model.assetsNumber = number; },