Merge branch 'main_latest_merged' into majd_development_new
# Conflicts: # assets/subtitles/ar_subtitle.json # assets/subtitles/en_subtitle.json # lib/main.dart # lib/models/service_request/service_request.dart # lib/views/pages/splash_screen.dart # lib/views/pages/user/notifications/notifications_page.dart # lib/views/pages/user/profile_page.dart # lib/views/pages/user/requests/create_request.dart # lib/views/pages/user/requests/request_details.dart # lib/views/pages/user/requests/requests_page.dart # lib/views/widgets/equipment/auto_complete_devices_field.dart # lib/views/widgets/equipment/single_device_picker.dartmerge-requests/29/head
commit
8b7b40b0af
@ -0,0 +1,69 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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/lookup.dart';
|
||||||
|
import 'package:test_sa/models/user.dart';
|
||||||
|
|
||||||
|
class ServiceFirstActionProvider extends ChangeNotifier {
|
||||||
|
//reset provider data
|
||||||
|
void reset() {
|
||||||
|
_statuses = null;
|
||||||
|
_stateCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state code of current request to defied error message
|
||||||
|
// like 400 customer request failed
|
||||||
|
// 500 service not available
|
||||||
|
int _stateCode;
|
||||||
|
int get stateCode => _stateCode;
|
||||||
|
|
||||||
|
// contain user data
|
||||||
|
// when user not login or register _user = null
|
||||||
|
List<Lookup> _statuses;
|
||||||
|
List<Lookup> get items => _statuses;
|
||||||
|
|
||||||
|
// when categories in-process _loading = true
|
||||||
|
// done _loading = true
|
||||||
|
// failed _loading = false
|
||||||
|
bool _loading;
|
||||||
|
bool get isLoading => _loading;
|
||||||
|
set isLoading(bool isLoading) {
|
||||||
|
_loading = isLoading;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> getData({String host, User user}) async {
|
||||||
|
if (_loading == true) return -2;
|
||||||
|
_loading = true;
|
||||||
|
notifyListeners();
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await ApiManager.instance.get(
|
||||||
|
URLs.getServiceFirstAction,
|
||||||
|
);
|
||||||
|
_stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// client's request was successfully received
|
||||||
|
List categoriesListJson = json.decode(response.body)["data"];
|
||||||
|
_statuses = categoriesListJson.map((e) => Lookup.fromJson(e)).toList();
|
||||||
|
}
|
||||||
|
_loading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
_loading = false;
|
||||||
|
_stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
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/lookup.dart';
|
||||||
|
import 'package:test_sa/models/user.dart';
|
||||||
|
|
||||||
|
class ServiceLoanAvailabilityProvider extends ChangeNotifier {
|
||||||
|
//reset provider data
|
||||||
|
void reset() {
|
||||||
|
_statuses = null;
|
||||||
|
_stateCode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state code of current request to defied error message
|
||||||
|
// like 400 customer request failed
|
||||||
|
// 500 service not available
|
||||||
|
int _stateCode;
|
||||||
|
int get stateCode => _stateCode;
|
||||||
|
|
||||||
|
// contain user data
|
||||||
|
// when user not login or register _user = null
|
||||||
|
List<Lookup> _statuses;
|
||||||
|
List<Lookup> get items => _statuses;
|
||||||
|
|
||||||
|
// when categories in-process _loading = true
|
||||||
|
// done _loading = true
|
||||||
|
// failed _loading = false
|
||||||
|
bool _loading;
|
||||||
|
bool get isLoading => _loading;
|
||||||
|
set isLoading(bool isLoading) {
|
||||||
|
_loading = isLoading;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 check http state manager
|
||||||
|
/// lib\controllers\http_status_manger\http_status_manger.dart
|
||||||
|
Future<int> getData({String host, User user}) async {
|
||||||
|
if (_loading == true) return -2;
|
||||||
|
_loading = true;
|
||||||
|
notifyListeners();
|
||||||
|
Response response;
|
||||||
|
try {
|
||||||
|
response = await ApiManager.instance.get(
|
||||||
|
URLs.getServiceLoanAvailability,
|
||||||
|
);
|
||||||
|
_stateCode = response.statusCode;
|
||||||
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
|
// client's request was successfully received
|
||||||
|
List categoriesListJson = json.decode(response.body)["data"];
|
||||||
|
_statuses = categoriesListJson.map((e) => Lookup.fromJson(e)).toList();
|
||||||
|
}
|
||||||
|
_loading = false;
|
||||||
|
notifyListeners();
|
||||||
|
return response.statusCode;
|
||||||
|
} catch (error) {
|
||||||
|
_loading = false;
|
||||||
|
_stateCode = -1;
|
||||||
|
notifyListeners();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,108 +1,219 @@
|
|||||||
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart';
|
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/enums/user_types.dart';
|
||||||
import 'package:test_sa/models/hospital.dart';
|
|
||||||
|
|
||||||
class User {
|
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 id;
|
||||||
String userName;
|
String userName;
|
||||||
String password;
|
String normalizedUserName;
|
||||||
String email;
|
String normalizedEmail;
|
||||||
Hospital hospital;
|
bool emailConfirmed;
|
||||||
Department department;
|
dynamic passwordHash;
|
||||||
UsersTypes type;
|
String securityStamp;
|
||||||
|
String concurrencyStamp;
|
||||||
String phoneNumber;
|
String phoneNumber;
|
||||||
String whatsApp;
|
bool phoneNumberConfirmed;
|
||||||
String token;
|
bool twoFactorEnabled;
|
||||||
bool isActive;
|
dynamic lockoutEnd;
|
||||||
DateTime tokenLife;
|
bool lockoutEnabled;
|
||||||
|
int accessFailedCount;
|
||||||
|
|
||||||
User(
|
User({
|
||||||
{this.id,
|
this.clientId,
|
||||||
this.userName = "",
|
this.clientName,
|
||||||
this.email = "",
|
this.departmentId,
|
||||||
this.password = "",
|
this.departmentName,
|
||||||
this.phoneNumber = "",
|
this.message,
|
||||||
this.hospital,
|
this.username,
|
||||||
this.department,
|
this.userID,
|
||||||
this.type,
|
this.email,
|
||||||
this.whatsApp,
|
this.password,
|
||||||
this.token,
|
this.token,
|
||||||
this.tokenLife,
|
this.roles,
|
||||||
this.isActive = false});
|
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 {
|
Future<Map<String, dynamic>> toLoginJson() async {
|
||||||
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
|
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
|
||||||
return {
|
return {
|
||||||
"username": userName,
|
"username": userName,
|
||||||
"password": password,
|
"password": password,
|
||||||
"firebase_token": FirebaseNotificationManger?.token ?? "",
|
"fireBaseToken": FirebaseNotificationManger?.token ?? "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UsersTypes get type {
|
||||||
|
switch (userRoles.first.name) {
|
||||||
|
case "Engineer":
|
||||||
|
return UsersTypes.engineer;
|
||||||
|
case "Hospital":
|
||||||
|
return UsersTypes.normal_user;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toUpdateProfileJson() {
|
Map<String, dynamic> toUpdateProfileJson() {
|
||||||
Map<String, dynamic> jsonObject = {};
|
Map<String, dynamic> jsonObject = {};
|
||||||
if (department?.id != null) jsonObject["department"] = department.id;
|
// if (departmentId != null) jsonObject["department"] = departmentId;
|
||||||
if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp;
|
// if (whatsApp != null && whatsApp.isNotEmpty) jsonObject["whatsapp"] = whatsApp;
|
||||||
if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber;
|
// if (phoneNumber != null && phoneNumber.isNotEmpty) jsonObject["phone"] = phoneNumber;
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> toRegisterJson() async {
|
Future<Map<String, dynamic>> toRegisterJson() async {
|
||||||
if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
|
// if (FirebaseNotificationManger.token == null) await FirebaseNotificationManger.getToken();
|
||||||
return {
|
return {
|
||||||
"username": userName,
|
// "username": userName,
|
||||||
"email": email,
|
// "email": email,
|
||||||
"whatsapp": whatsApp,
|
// "whatsapp": whatsApp,
|
||||||
"client": hospital.id,
|
// "client": hospital.id,
|
||||||
"department": department?.id,
|
// "department": department?.id,
|
||||||
"phone": phoneNumber,
|
// "phone": phoneNumber,
|
||||||
"pass": password,
|
// "pass": password,
|
||||||
"firebase_token": FirebaseNotificationManger?.token ?? "",
|
// "firebase_token": FirebaseNotificationManger?.token ?? "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
final map = <String, dynamic>{};
|
||||||
"userID": id,
|
map['client_id'] = clientId;
|
||||||
"username": userName,
|
map['client_name'] = clientName;
|
||||||
"email": email,
|
map['department_id'] = departmentId;
|
||||||
"token": token,
|
map['department_name'] = departmentName;
|
||||||
"phoneNumber": phoneNumber,
|
map['message'] = message;
|
||||||
"whatsapp": whatsApp,
|
map['username'] = username;
|
||||||
"client_id": hospital?.id,
|
map['userID'] = userID;
|
||||||
"client_name": hospital?.name,
|
map['email'] = email;
|
||||||
"department_id": department?.id,
|
map['password'] = password;
|
||||||
"department_name": department?.name,
|
map['token'] = token;
|
||||||
//"password":password,
|
map['roles'] = roles;
|
||||||
"tokenlife": tokenLife.toIso8601String(),
|
if (userRoles != null) {
|
||||||
"active": isActive,
|
map['userRoles'] = userRoles.map((v) => v.toJson()).toList();
|
||||||
"userRoles": type == UsersTypes.engineer ? "value: R-6" : "value: R-5",
|
}
|
||||||
// "token":token, pass is token
|
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) {
|
User.fromJson(dynamic json) {
|
||||||
UsersTypes type;
|
clientId = json['client_id'];
|
||||||
if (parsedJson["userRoles"].toString().contains("value: R-4") || parsedJson["userRoles"].toString().contains("value: R-5") || parsedJson["userRoles"].toString().contains("value: R-7")) {
|
clientName = json['client_name'];
|
||||||
type = UsersTypes.normal_user;
|
departmentId = json['department_id'];
|
||||||
} else {
|
departmentName = json['department_name'];
|
||||||
type = UsersTypes.engineer;
|
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(
|
tokenlife = json['tokenlife'];
|
||||||
id: parsedJson["userID"],
|
isAuthenticated = json['isAuthenticated'];
|
||||||
userName: parsedJson["username"],
|
hasError = json['hasError'];
|
||||||
email: parsedJson["email"],
|
profilePhotoName = json['profilePhotoName'];
|
||||||
hospital: Hospital(id: parsedJson["client_id"], name: parsedJson["client_name"]),
|
id = json['id'];
|
||||||
department: Department(
|
userName = json['userName'];
|
||||||
id: parsedJson["department_id"],
|
normalizedUserName = json['normalizedUserName'];
|
||||||
name: parsedJson["department_name"],
|
normalizedEmail = json['normalizedEmail'];
|
||||||
),
|
emailConfirmed = json['emailConfirmed'];
|
||||||
phoneNumber: parsedJson["phoneNumber"],
|
passwordHash = json['passwordHash'];
|
||||||
whatsApp: parsedJson["phoneNumber"],
|
securityStamp = json['securityStamp'];
|
||||||
token: parsedJson["token"],
|
concurrencyStamp = json['concurrencyStamp'];
|
||||||
isActive: parsedJson["isAuthenticated"],
|
phoneNumber = json['phoneNumber'];
|
||||||
tokenLife: DateTime.tryParse(parsedJson["tokenlife"] ?? ""),
|
phoneNumberConfirmed = json['phoneNumberConfirmed'];
|
||||||
type: type);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
import 'package:flutter/material.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';
|
||||||
|
import 'package:test_sa/models/lookup.dart';
|
||||||
|
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
||||||
|
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
||||||
|
|
||||||
|
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart';
|
||||||
|
|
||||||
|
class ServiceRequestedFirstAction extends StatelessWidget {
|
||||||
|
final Function(Lookup) onSelect;
|
||||||
|
final Lookup initialValue;
|
||||||
|
|
||||||
|
const ServiceRequestedFirstAction({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final settingProvider = Provider.of<SettingProvider>(context);
|
||||||
|
final userProvider = Provider.of<UserProvider>(context);
|
||||||
|
final menuProvider = Provider.of<ServiceFirstActionProvider>(context);
|
||||||
|
return LoadingManager(
|
||||||
|
isLoading: menuProvider.isLoading,
|
||||||
|
isFailedLoading: menuProvider.items == null,
|
||||||
|
stateCode: menuProvider.stateCode,
|
||||||
|
onRefresh: () async {
|
||||||
|
menuProvider.reset();
|
||||||
|
await menuProvider.getData(user: userProvider.user, host: settingProvider.host);
|
||||||
|
},
|
||||||
|
child: SingleStatusMenu(
|
||||||
|
initialStatus: initialValue,
|
||||||
|
statuses: menuProvider.items,
|
||||||
|
onSelect: onSelect,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:flutter/material.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';
|
||||||
|
import 'package:test_sa/models/lookup.dart';
|
||||||
|
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
|
||||||
|
import 'package:test_sa/views/widgets/status/single_status_menu.dart';
|
||||||
|
|
||||||
|
import '../../../../controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart';
|
||||||
|
|
||||||
|
class ServiceRequestedLoanAvailability extends StatelessWidget {
|
||||||
|
final Function(Lookup) onSelect;
|
||||||
|
final Lookup initialValue;
|
||||||
|
|
||||||
|
const ServiceRequestedLoanAvailability({Key key, this.onSelect, this.initialValue}) : super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final settingProvider = Provider.of<SettingProvider>(context);
|
||||||
|
final userProvider = Provider.of<UserProvider>(context);
|
||||||
|
final menuProvider = Provider.of<ServiceLoanAvailabilityProvider>(context);
|
||||||
|
return LoadingManager(
|
||||||
|
isLoading: menuProvider.isLoading,
|
||||||
|
isFailedLoading: menuProvider.items == null,
|
||||||
|
stateCode: menuProvider.stateCode,
|
||||||
|
onRefresh: () async {
|
||||||
|
menuProvider.reset();
|
||||||
|
await menuProvider.getData(user: userProvider.user, host: settingProvider.host);
|
||||||
|
},
|
||||||
|
child: SingleStatusMenu(
|
||||||
|
initialStatus: initialValue,
|
||||||
|
statuses: menuProvider.items,
|
||||||
|
onSelect: onSelect,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue