From 29e414a70377171ad2d29794c35f408c83ccd89f Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 14 Nov 2023 17:07:37 +0300 Subject: [PATCH 1/3] user profile change added & improvements. --- android/app/src/main/AndroidManifest.xml | 5 + ios/.gitignore | 2 +- lib/controllers/api_routes/urls.dart | 1 + .../providers/api/devices_provider.dart | 16 +- .../api/regular_visits_provider.dart | 1 + .../providers/api/user_provider.dart | 120 +++-- lib/models/hospital.dart | 2 +- lib/models/new_models/building.dart | 12 +- lib/models/new_models/floor.dart | 14 +- lib/models/new_models/gas_refill_model.dart | 6 +- lib/models/new_models/site.dart | 14 +- .../service_request/service_report.dart | 4 +- lib/models/user.dart | 3 + lib/new_views/common_widgets/app_drawer.dart | 57 ++- .../common_widgets/app_filled_button.dart | 2 +- .../pages/land_page/dashboard_page.dart | 33 +- .../land_page/requests/asset_item_view.dart | 22 +- lib/views/pages/user/profile_page.dart | 471 ++++++++++-------- .../equipment/single_device_picker.dart | 3 +- .../auto_complete_devices_field.dart | 1 + pubspec.lock | 24 + pubspec.yaml | 1 + 22 files changed, 491 insertions(+), 323 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 5473353f..6aa2ffd4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -46,6 +46,11 @@ + + "$_baseUrl/MobileAuth/LoginIntegration"; // mobile login static get register => "$_baseUrl/handle/create/user"; // post static get updateProfile => "$_baseUrl/update/user/profile"; // post + static get updateProfileImage => "$_baseUrl/Account/ChangeImageEmployee"; // post static get getSites => "$_baseUrl/Customer/GetCustomers"; // get static get getSitesAutoComplete => "$_baseUrl/Customer/GetCustomersAutoComplete"; // get diff --git a/lib/controllers/providers/api/devices_provider.dart b/lib/controllers/providers/api/devices_provider.dart index 3443a4a8..b45dc5ac 100644 --- a/lib/controllers/providers/api/devices_provider.dart +++ b/lib/controllers/providers/api/devices_provider.dart @@ -113,16 +113,24 @@ class AssetProvider extends ChangeNotifier { @required int hospitalId, String serialNumber, String number, + bool addPagination = true, }) async { Response response; try { - response = await ApiManager.instance.post(URLs.getAssets, body: { - "pageSize": pageItemNumber, - "pageNumber": devices.length ~/ pageItemNumber + 1, + Map body = { + // "pageSize": pageItemNumber, + // "pageNumber": devices.length ~/ pageItemNumber + 1, // "siteId": hospitalId, if (serialNumber?.isEmpty == false) "assetSerialNumber": serialNumber, if (number?.isEmpty == false) "assetNo": number, - }); + }; + + if (addPagination) { + body["pageSize"] = pageItemNumber; + body["pageNumber"] = devices.length ~/ pageItemNumber + 1; + } + + response = await ApiManager.instance.post(URLs.getAssets, body: body); // response = await get( // Uri.parse("$host${URLs.getEquipment}?siteId=$hospitalId" // "${serialNumber?.isEmpty == false ? "&assetSerialNumber=$serialNumber" :""}" diff --git a/lib/controllers/providers/api/regular_visits_provider.dart b/lib/controllers/providers/api/regular_visits_provider.dart index 0c3dcd13..a81e297e 100644 --- a/lib/controllers/providers/api/regular_visits_provider.dart +++ b/lib/controllers/providers/api/regular_visits_provider.dart @@ -186,6 +186,7 @@ class RegularVisitsProvider extends ChangeNotifier { body["id"] = visit.id; body["assetId"] = visit.deviceId; body["ppmScheduleId"] = visit.ppmScheduleId; + body["assignedEmployeeId"] = user.userName; // body["token"] = user.token; // body["vChecklists"]?.addAll({}); // body["vCalibrationTools"]?.addAll({"visitId": visit.id,}); diff --git a/lib/controllers/providers/api/user_provider.dart b/lib/controllers/providers/api/user_provider.dart index 6d0cdac5..cc257942 100644 --- a/lib/controllers/providers/api/user_provider.dart +++ b/lib/controllers/providers/api/user_provider.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; @@ -19,7 +20,11 @@ class UserProvider extends ChangeNotifier { // contain user data // when user not login or register _user = null User _user; + User get user => _user; + + File profileImage; + set user(User user) { _user = user; ApiManager.instance.user = user; @@ -29,7 +34,9 @@ class UserProvider extends ChangeNotifier { // when login or register in-process _login = true // when login or register is done or not start = false bool _loading = false; + bool get isLoading => _loading; + set isLoading(bool isLoading) { _loading = isLoading; notifyListeners(); @@ -53,6 +60,7 @@ class UserProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received _user = User.fromJson(jsonDecode(response.body)); + _user.profilePhotoName = URLs.getFileUrl(_user.profilePhotoName); ApiManager.instance.user = _user; notifyListeners(); return response.statusCode; @@ -106,51 +114,69 @@ class UserProvider extends ChangeNotifier { return response.statusCode; } - /// sign up with User object; - /// return -2 if request in progress - /// return -1 if error happen when sending request - /// return state code if request complete may be 200, 404 or 403 - /// for more details about state codes check http state manager - /// lib\controllers\http_status_manger\http_status_manger.dart - // Future updateProfile({ - // @required String host, - // @required User user, - // }) async { - // if (_loading == true) return -2; - // _loading = true; - // notifyListeners(); - // Response response; - // - // Map jsonObject = {}; - // jsonObject["uid"] = user.id; - // jsonObject["token"] = user.token; - // 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( - // URLs.login, - // body: jsonObject, - // ); - // } catch (error) { - // _loading = false; - // notifyListeners(); - // return -1; - // } - // - // _loading = false; - // notifyListeners(); - // - // if (response.statusCode >= 200 && response.statusCode < 300) { - // // client's request was successfully received - // _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); - // _user.clientId = user.clientId; - // _user.clientName = user.clientName; - // _user.departmentName = user.departmentName; - // _user.departmentId = user.departmentId; - // notifyListeners(); - // return response.statusCode; - // } - // return response.statusCode; - // } + Future uploadProfileImage(String userId, File image) async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + Map body = { + "userId": userId, + "imageEmployee": "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}", + }; + response = await ApiManager.instance.post(URLs.updateProfileImage, body: body); + if (response.statusCode >= 200 && response.statusCode < 300) { + profileImage = image; + } + _loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + _loading = false; + notifyListeners(); + return -1; + } + } + +// Future updateProfile({ +// @required String host, +// @required User user, +// }) async { +// if (_loading == true) return -2; +// _loading = true; +// notifyListeners(); +// Response response; +// +// Map jsonObject = {}; +// jsonObject["uid"] = user.id; +// jsonObject["token"] = user.token; +// 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( +// URLs.login, +// body: jsonObject, +// ); +// } catch (error) { +// _loading = false; +// notifyListeners(); +// return -1; +// } +// +// _loading = false; +// notifyListeners(); +// +// if (response.statusCode >= 200 && response.statusCode < 300) { +// // client's request was successfully received +// _user = User.fromJson(jsonDecode(utf8.decode(response.bodyBytes))[0]); +// _user.clientId = user.clientId; +// _user.clientName = user.clientName; +// _user.departmentName = user.departmentName; +// _user.departmentId = user.departmentId; +// notifyListeners(); +// return response.statusCode; +// } +// return response.statusCode; +// } } diff --git a/lib/models/hospital.dart b/lib/models/hospital.dart index e0bf9506..1357815b 100644 --- a/lib/models/hospital.dart +++ b/lib/models/hospital.dart @@ -29,7 +29,7 @@ class Hospital { } Map toMap() { - return {'id': id, 'customerCode': customerCode, 'custName': name, "buildings": buildings}; + return {'id': id, 'customerCode': customerCode, 'custName': name, "buildings": []}; } } diff --git a/lib/models/new_models/building.dart b/lib/models/new_models/building.dart index cce59efa..facb0463 100644 --- a/lib/models/new_models/building.dart +++ b/lib/models/new_models/building.dart @@ -21,9 +21,11 @@ class Building extends Base { }); } } + num id; num value; List floors; + Building copyWith({ num id, String name, @@ -36,14 +38,18 @@ class Building extends Base { value: value ?? this.value, floors: floors ?? this.floors, ); - Map toJson() { + + Map toJson({bool addFloor = true}) { final map = {}; map['id'] = id; map['name'] = name; map['value'] = value; - if (floors != null) { - map['floors'] = floors.map((v) => v.toJson()).toList(); + if(addFloor) { + if (floors != null) { + map['floors'] = floors.map((v) => v.toJson()).toList(); + } } + return map; } } diff --git a/lib/models/new_models/floor.dart b/lib/models/new_models/floor.dart index a7bd28c9..03b4c79c 100644 --- a/lib/models/new_models/floor.dart +++ b/lib/models/new_models/floor.dart @@ -21,9 +21,11 @@ class Floor extends Base { }); } } + num id; num value; List departments; + Floor copyWith({ num id, String name, @@ -36,14 +38,16 @@ class Floor extends Base { value: value ?? this.value, departments: departments ?? this.departments, ); - Map toJson() { + + Map toJson({bool addDepartments = true}) { final map = {}; map['id'] = id; map['name'] = name; map['value'] = value; - if (departments != null) { - map['departments'] = departments.map((v) => v.toJson()).toList(); - } - return map; + if (addDepartments) + if (departments != null) { + map['departments'] = departments.map((v) => v.toJson()).toList(); + } + return map; } } diff --git a/lib/models/new_models/gas_refill_model.dart b/lib/models/new_models/gas_refill_model.dart index 9f3284ff..75144159 100644 --- a/lib/models/new_models/gas_refill_model.dart +++ b/lib/models/new_models/gas_refill_model.dart @@ -157,13 +157,13 @@ class GasRefillModel { map['nurseSignature'] = nurseSignature; map['workingHours'] = workingHours; if (site != null) { - map['site'] = site.toJson(); + map['site'] = site.toJson(addBuildings: false); } if (building != null) { - map['building'] = building.toJson(); + map['building'] = building.toJson(addFloor: false); } if (floor != null) { - map['floor'] = floor.toJson(); + map['floor'] = floor.toJson(addDepartments: false); } if (department != null) { map['department'] = department.toJson(); diff --git a/lib/models/new_models/site.dart b/lib/models/new_models/site.dart index a591cc7e..dce72651 100644 --- a/lib/models/new_models/site.dart +++ b/lib/models/new_models/site.dart @@ -20,9 +20,11 @@ class Site extends Base { }); } } + num id; String custName; List buildings; + Site copyWith({ num id, String custName, @@ -33,13 +35,19 @@ class Site extends Base { custName: custName ?? this.custName, buildings: buildings ?? this.buildings, ); - Map toJson() { + + Map toJson({bool addBuildings = true}) { final map = {}; map['id'] = id; map['custName'] = custName; - if (buildings != null) { - map['buildings'] = buildings.map((v) => v.toJson()).toList(); + if (addBuildings) { + if (buildings != null) { + map['buildings'] = buildings.map((v) => v.toJson()).toList(); + } + } else { + map['buildings'] = []; } + return map; } } diff --git a/lib/models/service_request/service_report.dart b/lib/models/service_request/service_report.dart index 95b0b4cd..69542229 100644 --- a/lib/models/service_request/service_report.dart +++ b/lib/models/service_request/service_report.dart @@ -283,8 +283,8 @@ class ServiceReport { if (reason != null) { map['reason'] = reason.toJson(); } - map['startofWorkTime'] = startofWorkTime; - map['endofWorkTime'] = endofWorkTime; + map['startofWorkTime'] = timer.startAt.toString(); + map['endofWorkTime'] = timer.endAt.toString(); map['workingHours'] = workingHours; map['travelingHours'] = travelingHours; map['travelingExpenses'] = travelingExpenses; diff --git a/lib/models/user.dart b/lib/models/user.dart index 4b755999..21ac5774 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -27,6 +27,7 @@ class User { String securityStamp; String concurrencyStamp; String phoneNumber; + String extensionNo; bool phoneNumberConfirmed; bool twoFactorEnabled; dynamic lockoutEnd; @@ -139,6 +140,7 @@ class User { map['securityStamp'] = securityStamp; map['concurrencyStamp'] = concurrencyStamp; map['phoneNumber'] = phoneNumber; + map['extensionNo'] = extensionNo; map['phoneNumberConfirmed'] = phoneNumberConfirmed; map['twoFactorEnabled'] = twoFactorEnabled; map['lockoutEnd'] = lockoutEnd; @@ -188,6 +190,7 @@ class User { securityStamp = json['securityStamp']; concurrencyStamp = json['concurrencyStamp']; phoneNumber = json['phoneNumber']; + extensionNo = json['extensionNo']; phoneNumberConfirmed = json['phoneNumberConfirmed']; twoFactorEnabled = json['twoFactorEnabled']; lockoutEnd = json['lockoutEnd']; diff --git a/lib/new_views/common_widgets/app_drawer.dart b/lib/new_views/common_widgets/app_drawer.dart index 1c61ef00..ffee9216 100644 --- a/lib/new_views/common_widgets/app_drawer.dart +++ b/lib/new_views/common_widgets/app_drawer.dart @@ -33,39 +33,44 @@ class AppDrawer extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - width: 90, - height: 90, - decoration: ShapeDecoration( - image: DecorationImage( - image: NetworkImage( - (userProvider.user?.profilePhotoName?.isNotEmpty) ?? false - ? userProvider.user.profilePhotoName - : "https://www.shutterstock.com/shutterstock/photos/1714666150/display_1500/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", + Consumer(builder: (context, snapshot, _) { + return CircleAvatar( + radius: 45, + backgroundColor: const Color(0xFFE4E5E6), + child: Padding( + padding: const EdgeInsets.all(1), // Border radius + child: ClipOval( + child: (snapshot.user.profilePhotoName?.isNotEmpty ?? false) + ? Image.network(snapshot.user.profilePhotoName) + : snapshot.profileImage != null + ? Image.file(snapshot.profileImage) + : const Icon( + Icons.person, + size: 50, + color: Colors.white, + ), ), - fit: BoxFit.cover, ), - shape: const OvalBorder(side: BorderSide(width: 1, color: Color(0xFFE4E5E6))), - ), - ).onPress(() => Navigator.of(context).pushNamed(ProfilePage.id)), + ); + }).onPress(() => Navigator.of(context).pushNamed(ProfilePage.id)), const Icon(Icons.clear).onPress(() => Navigator.of(context).pop()) ], ), 8.height, - (userProvider.user?.username ?? "Eng Mahmoud").heading3(context).custom(fontWeight: FontWeight.w600), - (userProvider.user?.email ?? "context.welcome@gmail.com").heading6(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20), + userProvider.user.username.heading3(context).custom(fontWeight: FontWeight.w600), + if ((userProvider.user?.email ?? "").isNotEmpty) (userProvider.user?.email).heading6(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20), 18.height, 1.divider, ListView( - // "settings" : " Settings", - // "ReportBug " : "Report a bug", - // "whatsNew" : "What's New", - // "logout" : "Logout" + // "settings" : " Settings", + // "ReportBug " : "Report a bug", + // "whatsNew" : "What's New", + // "logout" : "Logout" - // "settings" : " الاعدادات", - // "ReportBug " "ابلاغ عن خطا", - // "whatsNew" : "ماهو الجديد", - // "logout" : "خروج" + // "settings" : " الاعدادات", + // "ReportBug " "ابلاغ عن خطا", + // "whatsNew" : "ماهو الجديد", + // "logout" : "خروج" padding: const EdgeInsets.only(top: 24), children: [ drawerItem("drawer_notification", context.translation.notifications, context).onPress(() => Navigator.of(context).pushNamed(NotificationsPage.id)), @@ -113,7 +118,7 @@ class AppDrawer extends StatelessWidget { ); } - Widget drawerItem(String icon, String title, BuildContext context,{Color color}) { + Widget drawerItem(String icon, String title, BuildContext context, {Color color}) { return Row( children: [ SvgPicture.asset( @@ -125,7 +130,9 @@ class AppDrawer extends StatelessWidget { 16.width, Text( title, - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50,), + style: AppTextStyles.heading6.copyWith( + color: context.isDark ? AppColor.neutral10 : AppColor.neutral50, + ), ), ], ); diff --git a/lib/new_views/common_widgets/app_filled_button.dart b/lib/new_views/common_widgets/app_filled_button.dart index 4d681c9a..23e1dca9 100644 --- a/lib/new_views/common_widgets/app_filled_button.dart +++ b/lib/new_views/common_widgets/app_filled_button.dart @@ -32,7 +32,7 @@ class AppFilledButton extends StatelessWidget { borderRadius: BorderRadius.circular(10), color: buttonColor ?? Theme.of(context).primaryColor, ), - child: loading ? const CircularProgressIndicator(color: Colors.white) : label.heading6(context).custom(color: textColor ?? (context.isDark ? AppColor.neutral60 : Colors.white)), + child: label.heading6(context).custom(color: textColor ?? (context.isDark ? AppColor.neutral60 : Colors.white)), ).onPress(onPressed); } } diff --git a/lib/new_views/pages/land_page/dashboard_page.dart b/lib/new_views/pages/land_page/dashboard_page.dart index 8368265d..442f21ff 100644 --- a/lib/new_views/pages/land_page/dashboard_page.dart +++ b/lib/new_views/pages/land_page/dashboard_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; +import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; @@ -45,20 +46,26 @@ class _DashboardPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - width: 48, - height: 48, - decoration: const ShapeDecoration( - image: DecorationImage( - image: NetworkImage( - "https://www.shutterstock.com/shutterstock/photos/1714666150/display_1500/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg"), - fit: BoxFit.cover, - ), - shape: OvalBorder( - side: BorderSide(width: 1, color: Color(0xFFE4E5E6)), + Consumer(builder: (context, snapshot, _) { + return CircleAvatar( + radius: 24, + backgroundColor: const Color(0xFFE4E5E6), + child: Padding( + padding: const EdgeInsets.all(1), // Border radius + child: ClipOval( + child: (snapshot.user.profilePhotoName?.isNotEmpty ?? false) + ? Image.network(snapshot.user.profilePhotoName) + : snapshot.profileImage != null + ? Image.file(snapshot.profileImage) + : const Icon( + Icons.person, + size: 24, + color: Colors.white, + ), + ), ), - ), - ).onPress(widget.onDrawerPress), + ); + }).onPress(widget.onDrawerPress), Stack( alignment: Alignment.topRight, children: [ diff --git a/lib/new_views/pages/land_page/requests/asset_item_view.dart b/lib/new_views/pages/land_page/requests/asset_item_view.dart index 153c7b33..2c65c57e 100644 --- a/lib/new_views/pages/land_page/requests/asset_item_view.dart +++ b/lib/new_views/pages/land_page/requests/asset_item_view.dart @@ -7,7 +7,9 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/device/asset.dart'; +import 'package:test_sa/models/device/asset_transfer.dart'; import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/pages/device_transfer/device_transfer_details.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; class AssetItemView extends StatelessWidget { @@ -27,11 +29,11 @@ class AssetItemView extends StatelessWidget { children: [ StatusLabel(label: request.priority, textColor: AColors.getRequestStatusTextColorByName(request.priority), backgroundColor: AColors.getRequestStatusColorByName(request.priority)), 8.width, - StatusLabel( - label: request.status, - textColor: AColors.getRequestStatusTextColorByName(request.status), - backgroundColor: AColors.getRequestStatusColorByName(request.status), - ), + // StatusLabel( + // label: request.status, + // textColor: AColors.getRequestStatusTextColorByName(request.status), + // backgroundColor: AColors.getRequestStatusColorByName(request.status), + // ), 1.width.expanded, Text(request.date?.toServiceRequestCardFormat ?? "", textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: const Color(0xFF3B3D4A))), ], @@ -72,6 +74,14 @@ class AssetItemView extends StatelessWidget { ], ), ], - ).toShadowContainer(context,showShadow: showShadow).onPress(() {}); + ).toShadowContainer(context,showShadow: showShadow).onPress(() { + + Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: AssetTransfer( + id:request.id + + )))); + + + }); } } diff --git a/lib/views/pages/user/profile_page.dart b/lib/views/pages/user/profile_page.dart index e0132aeb..fb466f96 100644 --- a/lib/views/pages/user/profile_page.dart +++ b/lib/views/pages/user/profile_page.dart @@ -1,4 +1,10 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; @@ -42,220 +48,269 @@ class _ProfilePageState extends State { _user = User.fromJson(_userProvider.user.toJson()); _firstTime = false; } + Color color = context.isDark ? AppColor.neutral10 : AppColor.neutral50; return Scaffold( key: _scaffoldKey, appBar: DefaultAppBar(title: context.translation.myProfile), - body: LoadingManager( - isLoading: _userProvider.isLoading, - isFailedLoading: false, - stateCode: 200, - onRefresh: () async {}, - child: SafeArea( - child: Card( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: double.infinity, - child: Column( - children: [ - Container( - width: 90, - height: 90, - decoration: ShapeDecoration( - image: DecorationImage( - image: NetworkImage( - (_user.profilePhotoName?.isNotEmpty ?? false) - ? _user.profilePhotoName - : "https://www.shutterstock.com/shutterstock/photos/1714666150/display_1500/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", + body: SafeArea( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: double.infinity, + child: Column( + children: [ + Consumer(builder: (context, snapshot, _) { + return Stack( + alignment: Alignment.bottomRight, + children: [ + CircleAvatar( + radius: 45, + backgroundColor: const Color(0xFFE4E5E6), + child: Padding( + padding: const EdgeInsets.all(1), // Border radius + child: ClipOval( + child: (snapshot.user.profilePhotoName?.isNotEmpty ?? false) + ? Image.network(snapshot.user.profilePhotoName) + : snapshot.profileImage != null + ? Image.file(snapshot.profileImage) + : const Icon( + Icons.person, + size: 50, + color: Colors.white, + ), ), - fit: BoxFit.cover, ), - shape: const OvalBorder(side: BorderSide(width: 1, color: Color(0xFFE4E5E6))), ), - ), - (_user.username ?? "Eng Mahmoud").heading3(context).custom(fontWeight: FontWeight.w600), - (_user.email ?? "context.welcome@gmail.com").heading6(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20), - ], - ), - ), - 24.height, - const Divider().defaultStyle(context), - 8.height, - (_user.phoneNumber ?? "+966 433 443 344").heading5(context), - 8.height, - const Divider().defaultStyle(context), - 8.height, - ("Ext: ${"2212"}").heading5(context), - 8.height, - if ((_user.departmentName?.length ?? 0) > 0) const Divider().defaultStyle(context), - ListView.builder( - physics: const NeverScrollableScrollPhysics(), - itemCount: _user.departmentName?.length ?? 0, - shrinkWrap: true, - itemBuilder: (context, index) { - return (_user.departmentName[index] ?? "N/A").heading5(context).paddingOnly(top: 8, bottom: 8); - }, - ), - ], - ).paddingAll(16), - ).paddingAll(16), - // child: Stack( - // children: [ - // Form( - // key: _formKey, - // child: ListView( - // children: [ - // //AppNameBar(), - // Hero( - // tag: "logo", - // child: Image( - // height: _height / 4, - // image: AssetImage("assets/images/logo.png"), - // ), - // ), - // Container( - // 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), - // ) - // ]), - // child: Column( - // children: [ - // ATextFormField( - // initialValue: _user.userName, - // hintText: context.translation.name, - // enable: false, - // prefixIconData: Icons.account_circle, - // style: Theme.of(context).textTheme.headline6, - // validator: (value) => Validator.hasValue(value) ? null : context.translation.nameValidateMessage, - // onSaved: (value) { - // _user.userName = value; - // }, - // ), - // SizedBox( - // height: 8, - // ), - // ATextFormField( - // initialValue: _user.email, - // hintText: context.translation.email, - // enable: false, - // prefixIconData: Icons.email, - // textInputType: TextInputType.emailAddress, - // style: Theme.of(context).textTheme.headline6, - // validator: (value) => Validator.isEmail(value) ? null : context.translation.emailValidateMessage, - // onSaved: (value) { - // _user.email = value; - // }, - // ), - // SizedBox( - // height: 8, - // ), - // AbsorbPointer( - // child: HospitalButton( - // hospital: Hospital(name: _user.clientName, id: _user.clientId), - // onHospitalPick: (hospital) { - // _user.clientName = hospital.name; - // _user.clientId = hospital.id; - // setState(() {}); - // }, - // ), - // ), - // SizedBox( - // height: 8, - // ), - // // DepartmentButton( - // // department: Department(name: _user.departmentName, id: _user.departmentId), - // // onDepartmentPick: (department) { - // // _user.departmentName = department.name; - // // _user.departmentId = department.id; - // // setState(() {}); - // // }, - // // ), - // SizedBox( - // height: 8, - // ), - // ATextFormField( - // initialValue: _user.phoneNumber, - // hintText: context.translation.phoneNumber, - // style: Theme.of(context).textTheme.headline6, - // prefixIconData: Icons.phone_android, - // validator: (value) => Validator.isPhoneNumber(value) ? null : context.translation.phoneNumberValidateMessage, - // textInputType: TextInputType.phone, - // onSaved: (value) { - // _user.phoneNumber = value; - // }, - // ), - // SizedBox( - // height: 8, - // ), - // // ATextFormField( - // // initialValue: _user.whatsApp, - // // hintText: context.translation.whatsApp, - // // style: Theme.of(context).textTheme.headline6, - // // prefixIconData: FontAwesomeIcons.whatsapp, - // // prefixIconSize: 36, - // // validator: (value) => - // // Validator.isPhoneNumber(value) ? null : context.translation.phoneNumberValidateMessage, - // // textInputType: TextInputType.phone, - // // onSaved: (value){ - // // _user.whatsApp = value; - // // }, - // // ), - // ], - // ), - // ), - // SizedBox( - // height: 16, - // ), - // Center( - // child: SizedBox( - // height: _width / 8, - // width: _width / 1.2, - // child: AButton( - // text: context.translation.update, - // onPressed: () async { - // // if (!_formKey.currentState.validate()) return; - // // _formKey.currentState.save(); - // // if (_user.departmentId == null) { - // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( - // // content: Text(context.translation.unitRequired), - // // )); - // // return; - // // } - // // int status = await _userProvider.updateProfile( - // // user: _user, - // // host: _settingProvider.host, - // // ); - // // if (status >= 200 && status < 300) { - // // _settingProvider.setUser(_userProvider.user); - // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( - // // content: Text(context.translation.requestCompleteSuccessfully), - // // )); - // // } else { - // // String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation); - // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( - // // content: Text(errorMessage), - // // )); - // // } - // }, - // ), - // ), - // ), - // SizedBox( - // height: 32, - // ), - // ], - // ), - // ), - // ABackButton(), - // ], - // ), - ), + CircleAvatar( + radius: 14, + backgroundColor: AppColor.primary70, + child: Padding( + padding: EdgeInsets.all(1), // Border radius + child: snapshot.isLoading + ? const SizedBox(height: 16, width: 16, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2)) + : Icon(Icons.upload, size: 16, color: Colors.white), + ), + ).onPress(snapshot.isLoading + ? null + : () async { + final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery, imageQuality: 70, maxWidth: 800, maxHeight: 800); + + if (pickedFile != null) { + CroppedFile croppedFile = await ImageCropper().cropImage( + sourcePath: pickedFile.path, + aspectRatioPresets: [CropAspectRatioPreset.square], + uiSettings: [ + AndroidUiSettings( + toolbarTitle: 'ATOMS', + toolbarColor: Colors.white, + toolbarWidgetColor: color, + initAspectRatio: CropAspectRatioPreset.square, + lockAspectRatio: false, + ), + IOSUiSettings(title: 'ATOMS'), + ], + ); + + if (croppedFile != null) { + snapshot.uploadProfileImage(_user.userID, File(croppedFile.path)); + } + } + }), + ], + ); + }), + 8.height, + (_user.username).heading3(context).custom(fontWeight: FontWeight.w600, color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + if ((_user.email ?? "").isNotEmpty) (_user.email ?? "").heading6(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20), + ], + ), + ), + 24.height, + if ((_user.phoneNumber ?? "").isNotEmpty) ...[ + const Divider().defaultStyle(context), + 8.height, + _user.phoneNumber.heading5(context), + 8.height, + ], + if ((_user.extensionNo ?? "").isNotEmpty) ...[ + const Divider().defaultStyle(context), + 8.height, + _user.extensionNo.heading5(context), + 8.height, + ], + if ((_user.departmentName?.length ?? 0) > 0) const Divider().defaultStyle(context), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + itemCount: _user.departmentName?.length ?? 0, + shrinkWrap: true, + itemBuilder: (context, index) { + return (_user.departmentName[index] ?? "N/A").heading5(context).paddingOnly(top: 8, bottom: 8); + }, + ), + if ((_user.clientName ?? "").isNotEmpty) ...[ + const Divider().defaultStyle(context), + 8.height, + _user.clientName.heading5(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + 8.height, + ], + ], + ).toShadowContainer(context).paddingAll(16), + // child: Stack( + // children: [ + // Form( + // key: _formKey, + // child: ListView( + // children: [ + // //AppNameBar(), + // Hero( + // tag: "logo", + // child: Image( + // height: _height / 4, + // image: AssetImage("assets/images/logo.png"), + // ), + // ), + // Container( + // 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), + // ) + // ]), + // child: Column( + // children: [ + // ATextFormField( + // initialValue: _user.userName, + // hintText: context.translation.name, + // enable: false, + // prefixIconData: Icons.account_circle, + // style: Theme.of(context).textTheme.headline6, + // validator: (value) => Validator.hasValue(value) ? null : context.translation.nameValidateMessage, + // onSaved: (value) { + // _user.userName = value; + // }, + // ), + // SizedBox( + // height: 8, + // ), + // ATextFormField( + // initialValue: _user.email, + // hintText: context.translation.email, + // enable: false, + // prefixIconData: Icons.email, + // textInputType: TextInputType.emailAddress, + // style: Theme.of(context).textTheme.headline6, + // validator: (value) => Validator.isEmail(value) ? null : context.translation.emailValidateMessage, + // onSaved: (value) { + // _user.email = value; + // }, + // ), + // SizedBox( + // height: 8, + // ), + // AbsorbPointer( + // child: HospitalButton( + // hospital: Hospital(name: _user.clientName, id: _user.clientId), + // onHospitalPick: (hospital) { + // _user.clientName = hospital.name; + // _user.clientId = hospital.id; + // setState(() {}); + // }, + // ), + // ), + // SizedBox( + // height: 8, + // ), + // // DepartmentButton( + // // department: Department(name: _user.departmentName, id: _user.departmentId), + // // onDepartmentPick: (department) { + // // _user.departmentName = department.name; + // // _user.departmentId = department.id; + // // setState(() {}); + // // }, + // // ), + // SizedBox( + // height: 8, + // ), + // ATextFormField( + // initialValue: _user.phoneNumber, + // hintText: context.translation.phoneNumber, + // style: Theme.of(context).textTheme.headline6, + // prefixIconData: Icons.phone_android, + // validator: (value) => Validator.isPhoneNumber(value) ? null : context.translation.phoneNumberValidateMessage, + // textInputType: TextInputType.phone, + // onSaved: (value) { + // _user.phoneNumber = value; + // }, + // ), + // SizedBox( + // height: 8, + // ), + // // ATextFormField( + // // initialValue: _user.whatsApp, + // // hintText: context.translation.whatsApp, + // // style: Theme.of(context).textTheme.headline6, + // // prefixIconData: FontAwesomeIcons.whatsapp, + // // prefixIconSize: 36, + // // validator: (value) => + // // Validator.isPhoneNumber(value) ? null : context.translation.phoneNumberValidateMessage, + // // textInputType: TextInputType.phone, + // // onSaved: (value){ + // // _user.whatsApp = value; + // // }, + // // ), + // ], + // ), + // ), + // SizedBox( + // height: 16, + // ), + // Center( + // child: SizedBox( + // height: _width / 8, + // width: _width / 1.2, + // child: AButton( + // text: context.translation.update, + // onPressed: () async { + // // if (!_formKey.currentState.validate()) return; + // // _formKey.currentState.save(); + // // if (_user.departmentId == null) { + // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // // content: Text(context.translation.unitRequired), + // // )); + // // return; + // // } + // // int status = await _userProvider.updateProfile( + // // user: _user, + // // host: _settingProvider.host, + // // ); + // // if (status >= 200 && status < 300) { + // // _settingProvider.setUser(_userProvider.user); + // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // // content: Text(context.translation.requestCompleteSuccessfully), + // // )); + // // } else { + // // String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation); + // // ScaffoldMessenger.of(context).showSnackBar(SnackBar( + // // content: Text(errorMessage), + // // )); + // // } + // }, + // ), + // ), + // ), + // SizedBox( + // height: 32, + // ), + // ], + // ), + // ), + // ABackButton(), + // ], + // ), ), ); } diff --git a/lib/views/widgets/equipment/single_device_picker.dart b/lib/views/widgets/equipment/single_device_picker.dart index 2649cd5c..360e84ee 100644 --- a/lib/views/widgets/equipment/single_device_picker.dart +++ b/lib/views/widgets/equipment/single_device_picker.dart @@ -170,7 +170,8 @@ class _SingleDevicePickerState extends State { return AssetItemListView( device: _searchableList[itemIndex], onPressed: (device) { - Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.id); + Navigator.of(context).pop(device); + // Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.id); }, ); }, diff --git a/lib/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart b/lib/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart index 8fe86d6c..af35ffc3 100644 --- a/lib/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart +++ b/lib/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart @@ -82,6 +82,7 @@ class _AutoCompleteDeviceNumberFieldState extends State Date: Tue, 14 Nov 2023 17:42:39 +0300 Subject: [PATCH 2/3] asset image fixed. --- lib/models/device/asset.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/models/device/asset.dart b/lib/models/device/asset.dart index 1b3e0344..9b3775ec 100644 --- a/lib/models/device/asset.dart +++ b/lib/models/device/asset.dart @@ -115,7 +115,9 @@ class Asset { } comment = json['comment']; tagCode = json['tagCode']; + assetPhoto = json['assetPhoto']; } + num id; String assetSerialNo; String systemID; @@ -165,6 +167,7 @@ class Asset { String comment; String tagCode; String assetPhoto; + Asset copyWith({ num id, String assetSerialNo, @@ -267,6 +270,7 @@ class Asset { tagCode: tagCode ?? this.tagCode, assetPhoto: assetPhoto ?? this.assetPhoto, ); + Map toJson() { final map = {}; map['id'] = id; From 3f05bd298850794f0454b767b24cbfa379231dca Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Tue, 14 Nov 2023 17:52:15 +0300 Subject: [PATCH 3/3] open request fixed for nurse & enigneer. --- lib/controllers/providers/api/all_requests_provider.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/controllers/providers/api/all_requests_provider.dart b/lib/controllers/providers/api/all_requests_provider.dart index 3bbece0b..71fe7e87 100644 --- a/lib/controllers/providers/api/all_requests_provider.dart +++ b/lib/controllers/providers/api/all_requests_provider.dart @@ -5,6 +5,7 @@ import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; +import 'package:test_sa/models/enums/user_types.dart'; import '../../../models/search_all_requests_model.dart'; @@ -175,9 +176,10 @@ class AllRequestsProvider extends ChangeNotifier { if (openRequests == null) notifyListeners(); Response response; try { + bool isEngineer = ApiManager.instance.user.type == UsersTypes.engineer; Map body = { "typeTransaction": [1, 2, 3, 4], - "statusTransaction": [1], + "statusTransaction": [isEngineer ? 2 : 1], "priority": [], "displayData": [] };