- Update Login API

- Adding Get Service Request By ID API
merge-requests/27/head
zaid_daoud 2 years ago
parent a219d81ccc
commit d0f083ce22

@ -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

@ -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<String> 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 "";
}
}
}

@ -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<String, dynamic> 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;
}

@ -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> 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<Map<String, dynamic>> 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<String, dynamic> toUpdateProfileJson() {
Map<String, dynamic> 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<Map<String, dynamic>> 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<String, dynamic> 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 = <String, dynamic>{};
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<String, dynamic> 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<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['name'] = name;
map['value'] = value;
return map;
}
}

@ -35,7 +35,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
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<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@ -59,7 +59,7 @@ class _RequestDeviceTransferState extends State<RequestDeviceTransfer> {
_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,

@ -113,7 +113,7 @@ class _LoginState extends State<Login> {
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);

@ -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<Register> {
),
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<Register> {
},
),
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),
));

@ -22,12 +22,11 @@ class SplashScreen extends StatefulWidget {
}
class _SplashScreenState extends State<SplashScreen> {
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<SplashScreen> {
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<SettingProvider>(context,listen: false);
_userProvider = Provider.of<UserProvider>(context,listen: false);
_settingProvider = Provider.of<SettingProvider>(context, listen: false);
_userProvider = Provider.of<UserProvider>(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);
}
},

@ -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<NotificationsPage>
with TickerProviderStateMixin{
class _NotificationsPageState extends State<NotificationsPage> with TickerProviderStateMixin {
NotificationsProvider _notificationsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
@ -36,9 +36,9 @@ class _NotificationsPageState extends State<NotificationsPage>
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<NotificationsPage>
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<NotificationsPage>
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<NotificationsPage>
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<NotificationsPage>
),
],
),
],
),
),

@ -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<ProfilePage> {
_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<ProfilePage> {
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<ProfilePage> {
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<ProfilePage> {
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,
),
],
),
),

@ -122,21 +122,21 @@ class CreateRequestPageState extends State<CreateRequestPage> {
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,

@ -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<ServiceRequestsPage>
with TickerProviderStateMixin{
class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerProviderStateMixin {
ServiceRequestsProvider _serviceRequestsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
@ -31,7 +31,7 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle;
if(_firstTime){
if (_firstTime) {
_serviceRequestsProvider.reset();
_firstTime = false;
}
@ -45,9 +45,9 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage>
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<ServiceRequestsPage>
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<ServiceRequestsPage>
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<ServiceRequestsPage>
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<ServiceRequestsPage>
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<ServiceRequestsPage>
),
],
),
],
),
),

@ -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<AutoCompleteDeviceField> {
SettingProvider _settingProvider;
DevicesProvider _devicesProvider;
UserProvider _userProvider;
@ -37,6 +37,7 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
@ -44,64 +45,53 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_devicesProvider = Provider.of<DevicesProvider>(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<Device>(
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<Device>(
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);
},
),
),
);
}
}

@ -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<SingleDevicePicker> {
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<Device> devices = await _devicesProvider.getDevicesListBySN(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: _userProvider.user.hospital.id,
sn: result
);
});
List<Device> 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<SingleDevicePicker> {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(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<SingleDevicePicker> {
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<SingleDevicePicker> {
),
),
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);
},
);
},
),
),
],
),

@ -71,7 +71,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
),
AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber,
hospitalId: userProvider.user.hospital?.id,
hospitalId: userProvider.user.clientId,
onPick: (number) {
model.assetsNumber = number;
},

Loading…
Cancel
Save