Merge branch 'master' into majd_development

# Conflicts:
#	lib/controllers/providers/api/devices_provider.dart
#	lib/views/widgets/equipment/auto_complete_devices_field.dart
merge-requests/16/head
nextwo 3 years ago
commit 7e808e5bf4

@ -0,0 +1,52 @@
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:test_sa/models/device/device.dart';
import '../controllers/api_routes/urls.dart';
import 'api_client.dart';
class DevicesApiClient {
static final DevicesApiClient _instance = DevicesApiClient._internal();
final List<Device> devices = [];
DevicesApiClient._internal();
factory DevicesApiClient() => _instance;
/// Fetch devices by [hospitalId] and insert the result into [devices] list
Future getEquipment(String hospitalId) async {
final response = await ApiClient().getJsonForResponse(URLs.host1 + URLs.getEquipment, queryParameters: {'client': hospitalId});
List equipmentListJson = json.decode(utf8.decode(response.bodyBytes));
devices.clear();
devices.addAll(equipmentListJson.map((device) => Device.fromJson(device)).toList());
debugPrint("devices : ${devices.length}");
}
/// Returns a list of devices by [hospitalId] and [serialNumber] (or | and) [number]
Future<List<Device>> getDevicesList({required String hospitalId, String? serialNumber, String? number}) async {
final response = await ApiClient().getJsonForResponse(
URLs.host1 + URLs.getEquipment,
queryParameters: {
'client': hospitalId,
if (serialNumber?.isEmpty == false) 'name': serialNumber,
if (number?.isEmpty == false) 'number': number,
},
);
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
return categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
/// Returns a list of devices by [hospitalId] (and optionally) [serialNumber]
Future<List<Device>> getDevicesListBySN({required String hospitalId, required String serialNumber}) async {
final response = await ApiClient().getJsonForResponse(
URLs.host1 + URLs.getEquipment,
queryParameters: {
'client': hospitalId,
if (serialNumber.isNotEmpty) 'serial_qr': serialNumber,
},
);
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
return categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
}

@ -0,0 +1,41 @@
import 'dart:convert';
import 'package:test_sa/api/api_client.dart';
import 'package:test_sa/api/user_api_client.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import '../controllers/api_routes/urls.dart';
class ServiceRequestApiClient {
static final ServiceRequestApiClient _instance = ServiceRequestApiClient._internal();
final List<ServiceRequest> serviceRequests = [];
ServiceRequestApiClient._internal();
factory ServiceRequestApiClient() => _instance;
/// ### The result will be added to [serviceRequests]
Future createRequest(ServiceRequest serviceRequest) async {
final user = UserApiClient().user;
await ApiClient().postJsonForObject(
(json) {
// ServiceRequest.fromJson(json.decode(utf8.decode(response.bodyBytes))[0])
serviceRequests.insert(0, ServiceRequest.fromJson(json[0]));
},
'${URLs.host1}${URLs.createRequest}',
{
"uid": user?.id,
"token": user?.token ?? "",
"sn_id": serviceRequest.deviceId ?? "",
"date": (DateTime.now().millisecondsSinceEpoch).toString(),
"client": user?.hospital?.id ?? '',
"complaint": serviceRequest.maintenanceIssue,
"image": json.encode(serviceRequest.devicePhotos),
"priority": (serviceRequest.priority?.id).toString(),
"defect_types": (serviceRequest.defectType?.id).toString(),
"audio": serviceRequest.audio,
},
isFormData: true,
);
}
}

@ -41,6 +41,7 @@ class UserApiClient {
}, },
"${URLs.host1}${URLs.register}", "${URLs.host1}${URLs.register}",
await newUser.toRegisterJson(), //body await newUser.toRegisterJson(), //body
isFormData: true,
); );
} }
@ -56,6 +57,7 @@ class UserApiClient {
}, },
"${URLs.host1}${URLs.updateProfile}", "${URLs.host1}${URLs.updateProfile}",
updatedUser.toUpdateProfileJson(), //body updatedUser.toUpdateProfileJson(), //body
isFormData: true,
); );
// Map<String, dynamic> jsonObject = {}; // Map<String, dynamic> jsonObject = {};
// jsonObject["uid"] = user.id; // jsonObject["uid"] = user.id;

@ -1,16 +1,16 @@
import 'dart:convert'; import 'package:test_sa/api/devices_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart';
import '../../../models/device/device.dart'; import '../../../models/device/device.dart';
import '../../../models/user.dart';
import '../../api_routes/urls.dart';
class DevicesProvider extends ChangeNotifier { class DevicesProvider extends LoadingNotifier {
final List<Device> _searchableList = [];
List<Device> get searchableList => _searchableList;
//reset provider data //reset provider data
void reset() { void reset() {
_devices = null; DevicesApiClient().devices.clear();
_stateCode = null; _stateCode = null;
} }
@ -21,117 +21,43 @@ class DevicesProvider extends ChangeNotifier {
int? get stateCode => _stateCode; int? get stateCode => _stateCode;
List<Device>? _devices; /// - Fetching Devices From The Server and Inserting them into [DevicesApiClient.devices] List.
/// - [_searchableList] will be filled after the request succeed.
List<Device>? get devices => _devices; ///
/// ### NOTE : if [hospitalId] is [NULL] nothing will happen
// when categories in-process _loading = true Future getEquipment({required String? hospitalId}) async {
// done _loading = true if (hospitalId != null) {
// failed _loading = false _searchableList.clear();
bool? _loading; waitApiRequest(
() async {
bool? get isLoading => _loading; await DevicesApiClient().getEquipment(hospitalId);
_searchableList.addAll(DevicesApiClient().devices);
set isLoading(bool? isLoading) { },
_loading = isLoading; onSuccess: () {
notifyListeners(); /// TODO : this is temporary
} _stateCode = 200;
},
/// return -2 if request in progress onError: (error) {
/// return -1 if error happen when sending request /// TODO : this is temporary
/// return state code if request complete may be 200, 404 or 403 _stateCode = error.error?.errorCode;
/// for more details check http state manager },
/// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getEquipment({required String host, required User user, required String hospitalId}) async {
if (_loading == true) {
return -2;
}
_loading = true;
notifyListeners();
Response response;
try {
response = await get(
Uri.parse("${host + URLs.getEquipment}?client=$hospitalId"),
headers: {"Content-Type": "application/json; charset=utf-8"},
); );
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return -1;
} }
_stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List equipmentListJson = json.decode(utf8.decode(response.bodyBytes));
_devices = equipmentListJson.map((device) => Device.fromJson(device)).toList();
}
_loading = false;
notifyListeners();
return response.statusCode;
} }
/// return -2 if request in progress /// Returns a list of devices by [hospitalId] and [serialNumber] (or | and) [number]
/// return -1 if error happen when sending request ///
/// return state code if request complete may be 200, 404 or 403 /// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
/// for more details check http state manager Future<List<Device>> getDevicesList({required String? hospitalId, String? serialNumber, String? number}) {
/// lib\controllers\http_status_manger\http_status_manger.dart if (hospitalId == null) return Future.value(const []);
Future<List<Device>> getDevicesList({ return DevicesApiClient().getDevicesList(hospitalId: hospitalId, serialNumber: serialNumber, number: number);
required String host,
required User? user,
required String hospitalId,
String? serialNumber,
String? number,
}) async {
Response response;
try {
response = await get(
Uri.parse("$host${URLs.getEquipment}?client=$hospitalId"
"${serialNumber?.isEmpty == false ? "&name=$serialNumber" : ""}"
"${number?.isEmpty == false ? "&number=$number" : ""}"),
);
List<Device> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
return page;
} catch (error) {
return [];
}
} }
/// return -2 if request in progress /// Returns a list of devices by [hospitalId] (and optionally) [serialNumber]
/// return -1 if error happen when sending request ///
/// return state code if request complete may be 200, 404 or 403 /// ### NOTE : if [hospitalId] is [NULL] empty list will be returned
/// for more details check http state manager Future<List<Device>> getDevicesListBySN({required String? hospitalId, required String serialNumber}) {
/// lib\controllers\http_status_manger\http_status_manger.dart if (hospitalId == null) return Future.value(const []);
Future<List<Device>> getDevicesListBySN({ return DevicesApiClient().getDevicesListBySN(hospitalId: hospitalId, serialNumber: serialNumber);
required String host,
required User user,
required String hospitalId,
required String sn,
}) async {
Response response;
try {
response = await get(
Uri.parse("$host${URLs.getEquipment}?client=$hospitalId${sn.isEmpty ? "" : "&serial_qr=$sn"}"),
);
_stateCode = response.statusCode;
List<Device> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
}
return page;
} catch (error) {
_loading = false;
_stateCode = -1;
notifyListeners();
return [];
}
} }
} }

@ -1,7 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/api/service_request_api_client.dart';
import 'package:test_sa/controllers/providers/loading_notifier.dart';
import '../../../models/issue.dart'; import '../../../models/issue.dart';
import '../../../models/lookup.dart'; import '../../../models/lookup.dart';
@ -13,14 +17,15 @@ import '../../../models/timer_model.dart';
import '../../../models/user.dart'; import '../../../models/user.dart';
import '../../api_routes/urls.dart'; import '../../api_routes/urls.dart';
import '../../http_status_manger/http_status_manger.dart'; import '../../http_status_manger/http_status_manger.dart';
import '../../localization/localization.dart';
class ServiceRequestsProvider extends ChangeNotifier { class ServiceRequestsProvider extends LoadingNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 50; final pageItemNumber = 50;
//reset provider data //reset provider data
void reset() { void reset() {
serviceRequests = null; ServiceRequestApiClient().serviceRequests.clear();
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -33,9 +38,6 @@ class ServiceRequestsProvider extends ChangeNotifier {
// true if there is next page in product list and false if not // true if there is next page in product list and false if not
bool? nextPage = true; bool? nextPage = true;
// list of user requests
List<ServiceRequest>? serviceRequests;
// when requests in-process _loading = true // when requests in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
@ -61,7 +63,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
try { try {
response = await get( response = await get(
Uri.parse( Uri.parse(
"$host${URLs.getServiceRequests}?uid=${user?.id}${hospitalId == null ? "" : "&client_nid=$hospitalId"}&token=${user?.token}&page=${(serviceRequests?.length ?? 0) ~/ pageItemNumber}${search?.toSearchString()}", "$host${URLs.getServiceRequests}?uid=${user?.id}${hospitalId == null ? "" : "&client_nid=$hospitalId"}&token=${user?.token}&page=${(ServiceRequestApiClient().serviceRequests.length) ~/ pageItemNumber}${search?.toSearchString()}",
), ),
headers: {"Content-Type": "application/json; charset=utf-8"}, headers: {"Content-Type": "application/json; charset=utf-8"},
); );
@ -69,10 +71,9 @@ class ServiceRequestsProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", "")); List requestsListJson = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", ""));
List<ServiceRequest> _serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList(); List<ServiceRequest> serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList();
serviceRequests ??= []; ServiceRequestApiClient().serviceRequests.addAll(serviceRequestsPage);
serviceRequests?.addAll(_serviceRequestsPage); if (serviceRequestsPage.length == pageItemNumber) {
if (_serviceRequestsPage.length == pageItemNumber) {
nextPage = true; nextPage = true;
} else { } else {
nextPage = false; nextPage = false;
@ -115,50 +116,33 @@ class ServiceRequestsProvider extends ChangeNotifier {
List<ServiceRequest> requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList(); List<ServiceRequest> requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList();
return requests[0]; return requests[0];
} else { } else {
throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle) ?? ""); throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle));
} }
} }
Future<int> createRequest({ /// ### Create service request and add the response to [ServiceRequestApiClient.serviceRequests]
required String host, Future createRequest(BuildContext context, {required ServiceRequest serviceRequest, required List<File> deviceImages}) async {
required User user, final subtitle = AppLocalization.of(context)?.subtitle;
required ServiceRequest serviceRequest, serviceRequest.devicePhotos = deviceImages.map((e) => base64Encode(e.readAsBytesSync())).toList();
}) async { if (serviceRequest.audio != null) {
var body = { final file = File(serviceRequest.audio!);
"uid": user.id, serviceRequest.audio = base64Encode(file.readAsBytesSync());
"token": user.token ?? "",
"sn_id": serviceRequest.deviceId ?? "",
"date": (DateTime.now().millisecondsSinceEpoch).toString(),
"client": user.hospital?.id ?? '',
"complaint": serviceRequest.maintenanceIssue,
"image": json.encode(serviceRequest.devicePhotos),
"priority": (serviceRequest.priority?.id).toString(),
"defect_types": (serviceRequest.defectType?.id).toString(),
};
body["audio"] = serviceRequest.audio;
Response response;
try {
response = await post(
Uri.parse(host + URLs.createRequest),
body: body,
);
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
final serviceRequests = this.serviceRequests;
if (serviceRequests != null) {
serviceRequests.insert(
0,
ServiceRequest.fromJson(
json.decode(utf8.decode(response.bodyBytes))[0],
),
);
}
notifyListeners();
}
return response.statusCode;
} catch (error) {
return -1;
} }
waitApiRequest(() async {
await ServiceRequestApiClient().createRequest(serviceRequest);
}, onSuccess: () {
/// TODO : this is temporary
stateCode = 200;
Fluttertoast.showToast(msg: subtitle?.requestCompleteSuccessfully ?? '');
Navigator.of(context).pop();
}, onError: (error) {
/// TODO : this is temporary
stateCode = error.error?.errorCode;
String errorMessage = HttpStatusManger.getStatusMessage(status: error.error?.errorCode, subtitle: subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
});
} }
Future<int> createIssueReport({ Future<int> createIssueReport({

@ -3,14 +3,14 @@ class Validator {
Validator._(); Validator._();
// check if string not empty and has value // check if string not empty and has value
static bool hasValue(String string) { static bool hasValue(String? string) {
if (string == null || string.isEmpty) return false; if (string == null || string.isEmpty) return false;
return true; return true;
} }
// Return true if email is valid. Otherwise, return false // Return true if email is valid. Otherwise, return false
static bool isEmail(String email) { static bool isEmail(String email) {
RegExp exp = new RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+"); RegExp exp = RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+");
if (exp.hasMatch(email)) return true; if (exp.hasMatch(email)) return true;
return false; return false;
} }

@ -1,17 +1,12 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../../api/user_api_client.dart'; import '../../../../api/user_api_client.dart';
import '../../../../controllers/http_status_manger/http_status_manger.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/service_requests_provider.dart'; import '../../../../controllers/providers/api/service_requests_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/providers/user_provider.dart';
import '../../../../controllers/validator/validator.dart'; import '../../../../controllers/validator/validator.dart';
import '../../../../extensions/int_extensions.dart'; import '../../../../extensions/int_extensions.dart';
import '../../../../extensions/widget_extensions.dart'; import '../../../../extensions/widget_extensions.dart';
@ -32,30 +27,29 @@ import '../../../widgets/status/service_request/service_request_priority_mune.da
import '../../../widgets/titles/app_sub_title.dart'; import '../../../widgets/titles/app_sub_title.dart';
class CreateRequestPage extends StatefulWidget { class CreateRequestPage extends StatefulWidget {
static final String id = "/create-request"; static const String id = "/create-request";
const CreateRequestPage({super.key});
@override @override
_CreateRequestPageState createState() => _CreateRequestPageState(); CreateRequestPageState createState() => CreateRequestPageState();
} }
class _CreateRequestPageState extends State<CreateRequestPage> { class CreateRequestPageState extends State<CreateRequestPage> {
late double _height; late double _height;
late UserProvider _userProvider;
late SettingProvider _settingProvider;
late ServiceRequestsProvider _serviceRequestsProvider; late ServiceRequestsProvider _serviceRequestsProvider;
ServiceRequest _serviceRequest = ServiceRequest(); final ServiceRequest _serviceRequest = ServiceRequest();
List<File> _deviceImages = [];
bool _isLoading = false;
Device? _device; Device? _device;
late Subtitle _subtitle; Subtitle? _subtitle;
final List<File> _deviceImages = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
late TextEditingController _controller; late TextEditingController _controller;
@override @override
void initState() { void initState() {
_controller = TextEditingController();
super.initState(); super.initState();
_controller = TextEditingController();
} }
@override @override
@ -67,15 +61,13 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_height = MediaQuery.of(context).size.height; _height = MediaQuery.of(context).size.height;
_userProvider = Provider.of<UserProvider>(context); _subtitle = AppLocalization.of(context)?.subtitle;
_settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_subtitle = AppLocalization.of(context)!.subtitle!;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _isLoading, isLoading: _serviceRequestsProvider.loading,
isFailedLoading: false, isFailedLoading: false,
stateCode: 200, stateCode: 200,
onRefresh: () async {}, onRefresh: () async {},
@ -86,22 +78,22 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
ListView( ListView(
children: [ children: [
//AppNameBar(), //AppNameBar(),
SizedBox( const SizedBox(
height: 16, height: 16,
), ),
Hero( Hero(
tag: "logo", tag: "logo",
child: Image( child: Image(
height: _height / 6, height: _height / 6,
image: AssetImage("assets/images/logo.png"), image: const AssetImage("assets/images/logo.png"),
), ),
), ),
Center( Center(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
_subtitle.newServiceRequest, _subtitle?.newServiceRequest ?? '',
style: Theme.of(context).textTheme.headline5?.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600), style: Theme.of(context).textTheme.headlineSmall?.copyWith(color: AColors.cyan, fontWeight: FontWeight.w600),
), ),
), ),
), ),
@ -110,23 +102,23 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
children: [ children: [
12.height, 12.height,
UserApiClient().user?.hospital == null UserApiClient().user?.hospital == null
? SizedBox.shrink() ? const SizedBox.shrink()
: ATextFormField( : ATextFormField(
enable: false, enable: false,
initialValue: UserApiClient().user?.hospital?.name ?? _subtitle.noHospitalFound, initialValue: UserApiClient().user?.hospital?.name ?? _subtitle?.noHospitalFound,
hintText: _subtitle.hospital, hintText: _subtitle?.hospital,
prefixIconData: FontAwesomeIcons.hospital, prefixIconData: FontAwesomeIcons.hospital,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
), ),
12.height, 12.height,
UserApiClient().user?.department == null UserApiClient().user?.department == null
? SizedBox.shrink() ? const SizedBox.shrink()
: ATextFormField( : ATextFormField(
enable: false, enable: false,
initialValue: UserApiClient().user?.department?.name ?? _subtitle.noUniteFound, initialValue: UserApiClient().user?.department?.name ?? _subtitle?.noUniteFound,
hintText: _subtitle.unite, hintText: _subtitle?.unite,
prefixIconData: FontAwesomeIcons.hospitalUser, prefixIconData: FontAwesomeIcons.hospitalUser,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
), ),
12.height, 12.height,
DeviceButton( DeviceButton(
@ -164,7 +156,7 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
), ),
12.height, 12.height,
MultiImagesPicker( MultiImagesPicker(
label: _subtitle.deviceImages, label: _subtitle?.deviceImages,
images: _deviceImages, images: _deviceImages,
), ),
12.height, 12.height,
@ -173,11 +165,11 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
ATextFormField( ATextFormField(
controller: _controller, controller: _controller,
initialValue: _serviceRequest.maintenanceIssue, initialValue: _serviceRequest.maintenanceIssue,
hintText: _subtitle.maintenanceIssue, hintText: _subtitle?.maintenanceIssue,
prefixIconData: FontAwesomeIcons.triangleExclamation, prefixIconData: FontAwesomeIcons.triangleExclamation,
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
textInputType: TextInputType.multiline, textInputType: TextInputType.multiline,
validator: (value) => Validator.hasValue(value!) ? '' : _subtitle.maintenanceIssueRequired, validator: (value) => Validator.hasValue(value) ? null : _subtitle?.maintenanceIssueRequired,
onSaved: (value) { onSaved: (value) {
_serviceRequest.maintenanceIssue = value; _serviceRequest.maintenanceIssue = value;
}, },
@ -192,42 +184,19 @@ class _CreateRequestPageState extends State<CreateRequestPage> {
Padding( Padding(
padding: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(20.0),
child: AButton( child: AButton(
text: _subtitle.submit, text: _subtitle?.submit ?? '',
onPressed: () async { onPressed: () async {
if (!(_formKey.currentState?.validate() ?? false)) return; if (_formKey.currentState?.validate() ?? false) {
_formKey.currentState?.save(); _formKey.currentState?.save();
_serviceRequest.deviceId = _device?.id ?? ""; _serviceRequest.deviceId = _device?.id ?? "";
_isLoading = true; await _serviceRequestsProvider.createRequest(context, serviceRequest: _serviceRequest, deviceImages: _deviceImages);
setState(() {});
_serviceRequest.devicePhotos = _deviceImages.map((e) => base64Encode(e.readAsBytesSync())).toList();
if (_serviceRequest.audio != null) {
final file = File(_serviceRequest.audio!);
_serviceRequest.audio = base64Encode(file.readAsBytesSync());
}
int status = await _serviceRequestsProvider.createRequest(
user: UserApiClient().user!,
host: _settingProvider.host ?? "",
serviceRequest: _serviceRequest,
);
_isLoading = false;
setState(() {});
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully,
);
Navigator.of(context).pop();
} else {
String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(errorMessage),
));
} }
}, },
), ),
), ),
], ],
), ),
ABackButton(), const ABackButton(),
], ],
), ),
), ),

@ -1,11 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/api/service_request_api_client.dart';
import '../../../../api/user_api_client.dart'; import '../../../../api/user_api_client.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/service_requests_provider.dart'; import '../../../../controllers/providers/api/service_requests_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart'; import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/providers/user_provider.dart';
import '../../../../models/service_request/service_request_search.dart'; import '../../../../models/service_request/service_request_search.dart';
import '../../../../models/subtitle.dart'; import '../../../../models/subtitle.dart';
import '../../../app_style/colors.dart'; import '../../../app_style/colors.dart';
@ -16,23 +16,23 @@ import '../../../widgets/requests/service_request_list.dart';
import '../../../widgets/search/service_request_search_bar.dart'; import '../../../widgets/search/service_request_search_bar.dart';
class ServiceRequestsPage extends StatefulWidget { class ServiceRequestsPage extends StatefulWidget {
static final String id = "/service-requests"; static const String id = "/service-requests";
const ServiceRequestsPage({super.key});
@override @override
_ServiceRequestsPageState createState() => _ServiceRequestsPageState(); ServiceRequestsPageState createState() => ServiceRequestsPageState();
} }
class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerProviderStateMixin { class ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerProviderStateMixin {
late ServiceRequestsProvider _serviceRequestsProvider; late ServiceRequestsProvider _serviceRequestsProvider;
late UserProvider _userProvider;
late SettingProvider _settingProvider; late SettingProvider _settingProvider;
bool _expandedSearch = false; final bool _expandedSearch = false;
bool _firstTime = true; bool _firstTime = true;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
Subtitle? subtitle = AppLocalization.of(context)?.subtitle; Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
if (_firstTime) { if (_firstTime) {
@ -44,7 +44,6 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerPr
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _serviceRequestsProvider.isLoading, isLoading: _serviceRequestsProvider.isLoading,
isFailedLoading: _serviceRequestsProvider.serviceRequests == null,
stateCode: _serviceRequestsProvider.stateCode, stateCode: _serviceRequestsProvider.stateCode,
onRefresh: () async { onRefresh: () async {
_serviceRequestsProvider.reset(); _serviceRequestsProvider.reset();
@ -116,7 +115,7 @@ class _ServiceRequestsPageState extends State<ServiceRequestsPage> with TickerPr
hospitalId: UserApiClient().user?.hospital?.id, hospitalId: UserApiClient().user?.hospital?.id,
); );
}, },
requests: _serviceRequestsProvider.serviceRequests ?? [], requests: ServiceRequestApiClient().serviceRequests,
), ),
), ),
], ],

@ -1,13 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/api/user_api_client.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart'; import '../../../controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/user_provider.dart';
import '../../../models/device/device.dart'; import '../../../models/device/device.dart';
import '../../../models/user.dart';
import '../../app_style/colors.dart'; import '../../app_style/colors.dart';
import '../../app_style/sizing.dart'; import '../../app_style/sizing.dart';
@ -19,14 +15,11 @@ class AutoCompleteDeviceField extends StatefulWidget {
const AutoCompleteDeviceField({Key? key, required this.initialValue, this.onPick, this.hospitalId}) : super(key: key); const AutoCompleteDeviceField({Key? key, required this.initialValue, this.onPick, this.hospitalId}) : super(key: key);
@override @override
_AutoCompleteDeviceFieldState createState() => _AutoCompleteDeviceFieldState(); AutoCompleteDeviceFieldState createState() => AutoCompleteDeviceFieldState();
} }
class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> { class AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
SettingProvider? _settingProvider;
DevicesProvider? _devicesProvider; DevicesProvider? _devicesProvider;
UserProvider? _userProvider;
TextEditingController? _controller; TextEditingController? _controller;
@override @override
@ -40,56 +33,42 @@ class _AutoCompleteDeviceFieldState extends State<AutoCompleteDeviceField> {
_controller?.dispose(); _controller?.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<DevicesProvider>(context); _devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Container( return Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 16),
horizontal: 16
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
border: Border.all(color:AColors.black), border: Border.all(color: AColors.black),
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
AppStyle.borderRadius * AppStyle.getScaleFactor(context) boxShadow: const [AppStyle.boxShadow]),
),
boxShadow: [
AppStyle.boxShadow
]
),
child: TypeAheadField<Device>( child: TypeAheadField<Device>(
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
controller: _controller, controller: _controller,
textAlign: TextAlign.center, textAlign: TextAlign.center,
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
disabledBorder: InputBorder.none, disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none, focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none, enabledBorder: InputBorder.none,
), ),
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (value) async { suggestionsCallback: (value) async {
return await _devicesProvider!.getDevicesList( return await _devicesProvider!.getDevicesList(hospitalId: widget.hospitalId, serialNumber: value);
host: _settingProvider?.host??"",
user: UserApiClient().user,
hospitalId: widget.hospitalId??"",
serialNumber: value,
);
}, },
itemBuilder: (context, device) { itemBuilder: (context, device) {
return ListTile( return ListTile(
title: Text(device.serialNumber??""), title: Text(device.serialNumber ?? ""),
subtitle: Text("${device.model??""}/${device.brand??""}"), subtitle: Text("${device.model ?? ""}/${device.brand ?? ""}"),
); );
}, },
onSuggestionSelected: (device) { onSuggestionSelected: (device) {
_controller?.text = device.serialNumber??""; _controller?.text = device.serialNumber ?? "";
widget.onPick!(device.id??""); widget.onPick!(device.id ?? "");
}, },
), ),
); );

@ -15,7 +15,7 @@ class DeviceButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Subtitle? _subtitle = AppLocalization.of(context)?.subtitle; Subtitle? subtitle = AppLocalization.of(context)?.subtitle;
return ElevatedButton( return ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
elevation: 0, elevation: 0,
@ -33,8 +33,8 @@ class DeviceButton extends StatelessWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 6), padding: const EdgeInsets.symmetric(horizontal: 6),
child: Text( child: Text(
_subtitle?.pickDevice ?? "", subtitle?.pickDevice ?? "",
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
textAlign: TextAlign.left, textAlign: TextAlign.left,
@ -43,27 +43,27 @@ class DeviceButton extends StatelessWidget {
) )
: Expanded( : Expanded(
child: ListTile( child: ListTile(
contentPadding: EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
title: Text( title: Text(
"${_subtitle?.sn ?? ""} : ${device?.serialNumber ?? ""}", "${subtitle?.sn ?? ""} : ${device?.serialNumber ?? ""}",
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
), ),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider( Divider(
color: Theme.of(context).textTheme.subtitle1?.color, color: Theme.of(context).textTheme.titleMedium?.color,
), ),
Text( Text(
"${_subtitle?.brand} : ${device?.brand}", "${subtitle?.brand} : ${device?.brand}",
style: Theme.of(context).textTheme.subtitle2, style: Theme.of(context).textTheme.titleSmall,
), ),
Divider( Divider(
color: Theme.of(context).textTheme.subtitle1?.color, color: Theme.of(context).textTheme.titleMedium?.color,
), ),
Text( Text(
"${_subtitle?.model} : ${device?.model}", "${subtitle?.model} : ${device?.model}",
style: Theme.of(context).textTheme.subtitle2, style: Theme.of(context).textTheme.titleSmall,
), ),
], ],
), ),

@ -1,15 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/api/devices_api_client.dart';
import 'package:test_sa/api/user_api_client.dart'; import 'package:test_sa/api/user_api_client.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/devices_provider.dart'; import '../../../controllers/providers/api/devices_provider.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
import '../../../controllers/providers/user_provider.dart';
import '../../../models/device/device.dart'; import '../../../models/device/device.dart';
import '../../../models/subtitle.dart'; import '../../../models/subtitle.dart';
import '../../../models/user.dart';
import '../app_text_form_field.dart'; import '../app_text_form_field.dart';
import '../loaders/loading_manager.dart'; import '../loaders/loading_manager.dart';
import '../loaders/no_item_found.dart'; import '../loaders/no_item_found.dart';
@ -27,10 +25,7 @@ class SingleDevicePicker extends StatefulWidget {
} }
class SingleDevicePickerState extends State<SingleDevicePicker> { class SingleDevicePickerState extends State<SingleDevicePicker> {
DevicesProvider? _devicesProvider; late DevicesProvider _devicesProvider;
UserProvider? _userProvider;
SettingProvider? _settingProvider;
final List<Device> _searchableList = [];
Subtitle? _subtitle; Subtitle? _subtitle;
_getDevice(String? result) async { _getDevice(String? result) async {
@ -41,8 +36,7 @@ class SingleDevicePickerState extends State<SingleDevicePicker> {
builder: (dialogContext) { builder: (dialogContext) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
}); });
List<Device> devices = List<Device> devices = await _devicesProvider.getDevicesListBySN(hospitalId: UserApiClient().user?.hospital?.id ?? "", serialNumber: result);
await _devicesProvider!.getDevicesListBySN(host: _settingProvider?.host ?? "", user: UserApiClient().user ?? User(), hospitalId: UserApiClient().user?.hospital?.id ?? "", sn: result);
Navigator.of(context).pop(); Navigator.of(context).pop();
if (devices.isEmpty) { if (devices.isEmpty) {
Fluttertoast.showToast(msg: _subtitle?.noDeviceFound ?? ""); Fluttertoast.showToast(msg: _subtitle?.noDeviceFound ?? "");
@ -58,28 +52,22 @@ class SingleDevicePickerState extends State<SingleDevicePicker> {
@override @override
void dispose() { void dispose() {
_devicesProvider?.reset(); _devicesProvider.reset();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_devicesProvider = Provider.of<DevicesProvider>(context); _devicesProvider = Provider.of<DevicesProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_subtitle = AppLocalization.of(context)?.subtitle; _subtitle = AppLocalization.of(context)?.subtitle;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
body: LoadingManager( body: LoadingManager(
isLoading: _devicesProvider?.isLoading, isLoading: _devicesProvider.loading,
stateCode: _devicesProvider?.stateCode, stateCode: _devicesProvider.stateCode,
isFailedLoading: _devicesProvider?.devices == null,
onRefresh: () async { onRefresh: () async {
_devicesProvider?.reset(); _devicesProvider.reset();
_searchableList.clear(); await _devicesProvider.getEquipment(hospitalId: UserApiClient().user?.hospital?.id);
await _devicesProvider?.getEquipment(user: UserApiClient().user ?? User(), host: _settingProvider?.host ?? "", hospitalId: UserApiClient().user?.hospital?.id ?? "");
_searchableList.addAll(_devicesProvider?.devices ?? []);
}, },
child: Column( child: Column(
children: [ children: [
@ -90,24 +78,22 @@ class SingleDevicePickerState extends State<SingleDevicePicker> {
children: [ children: [
ATextFormField( ATextFormField(
hintText: _subtitle?.searchBySn ?? "", hintText: _subtitle?.searchBySn ?? "",
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
suffixIcon: const Icon(Icons.search_rounded), suffixIcon: const Icon(Icons.search_rounded),
onChange: (value) { onChange: (value) {
_searchableList.clear(); _devicesProvider.searchableList.clear();
_searchableList.addAll(_devicesProvider!.devices!.where((element) => element.serialNumber!.toLowerCase().contains(value.toLowerCase())).toList()); _devicesProvider.searchableList.addAll(DevicesApiClient().devices.where((element) => element.serialNumber!.toLowerCase().contains(value.toLowerCase())).toList());
setState(() {}); setState(() {});
}, },
), ),
const SizedBox( const SizedBox(height: 8),
height: 8,
),
ATextFormField( ATextFormField(
hintText: "Search by Number", hintText: "Search by Number",
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
suffixIcon: const Icon(Icons.search_rounded), suffixIcon: const Icon(Icons.search_rounded),
onChange: (value) { onChange: (value) {
_searchableList.clear(); _devicesProvider.searchableList.clear();
_searchableList.addAll(_devicesProvider!.devices!.where((element) => element.number!.toLowerCase().contains(value.toLowerCase())).toList()); _devicesProvider.searchableList.addAll(DevicesApiClient().devices.where((element) => element.number!.toLowerCase().contains(value.toLowerCase())).toList());
setState(() {}); setState(() {});
}, },
), ),
@ -115,17 +101,15 @@ class SingleDevicePickerState extends State<SingleDevicePicker> {
), ),
), ),
Expanded( Expanded(
child: _searchableList.isEmpty child: _devicesProvider.searchableList.isEmpty
? NoItemFound( ? NoItemFound(message: _subtitle?.noDeviceFound ?? "")
message: _subtitle?.noDeviceFound ?? "",
)
: ListView.builder( : ListView.builder(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
shrinkWrap: true, shrinkWrap: true,
itemCount: _searchableList.length, itemCount: _devicesProvider.searchableList.length,
itemBuilder: (listContext, itemIndex) { itemBuilder: (listContext, itemIndex) {
return DeviceItem( return DeviceItem(
device: _searchableList[itemIndex], device: _devicesProvider.searchableList[itemIndex],
onPressed: (device) { onPressed: (device) {
Navigator.of(context).pop(device); Navigator.of(context).pop(device);
}, },
@ -140,9 +124,7 @@ class SingleDevicePickerState extends State<SingleDevicePicker> {
heroTag: "some tag 2", heroTag: "some tag 2",
child: const Icon(Icons.qr_code_scanner), child: const Icon(Icons.qr_code_scanner),
onPressed: () async { onPressed: () async {
String result = await Navigator.of(context).push( String result = await Navigator.of(context).push(MaterialPageRoute(builder: (_) => const ScanQr())) as String;
MaterialPageRoute(builder: (_) => ScanQr()),
) as String;
_getDevice(result); _getDevice(result);
}, },
), ),

@ -2,13 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../../../api/user_api_client.dart';
import '../../../../controllers/providers/api/devices_provider.dart'; import '../../../../controllers/providers/api/devices_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/providers/user_provider.dart';
import '../../../../models/device/device.dart'; import '../../../../models/device/device.dart';
import '../../../../models/lookup.dart'; import '../../../../models/lookup.dart';
import '../../../../models/user.dart';
import '../../../app_style/colors.dart'; import '../../../app_style/colors.dart';
import '../../../app_style/sizing.dart'; import '../../../app_style/sizing.dart';
@ -24,9 +20,7 @@ class AutoCompleteDeviceNumberField extends StatefulWidget {
} }
class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumberField> { class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumberField> {
late SettingProvider _settingProvider;
late DevicesProvider _devicesProvider; late DevicesProvider _devicesProvider;
late UserProvider _userProvider;
late TextEditingController _controller; late TextEditingController _controller;
@override @override
@ -43,10 +37,7 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<DevicesProvider>(context); _devicesProvider = Provider.of<DevicesProvider>(context);
//Subtitle _subtitle = AppLocalization.of(context).subtitle;
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
@ -56,7 +47,7 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
boxShadow: const [AppStyle.boxShadow]), boxShadow: const [AppStyle.boxShadow]),
child: TypeAheadField<Device>( child: TypeAheadField<Device>(
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: Theme.of(context).textTheme.headline6, style: Theme.of(context).textTheme.titleLarge,
controller: _controller, controller: _controller,
textAlign: TextAlign.center, textAlign: TextAlign.center,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -68,12 +59,7 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (vale) async { suggestionsCallback: (vale) async {
return await _devicesProvider.getDevicesList( return await _devicesProvider.getDevicesList(hospitalId: widget.hospitalId, number: vale);
host: _settingProvider.host ?? "",
user: UserApiClient().user ?? User(),
hospitalId: widget.hospitalId ?? "",
number: vale,
);
}, },
itemBuilder: (context, device) { itemBuilder: (context, device) {
return ListTile( return ListTile(

@ -4,7 +4,6 @@ import 'package:provider/provider.dart';
import '../../../../api/user_api_client.dart'; import '../../../../api/user_api_client.dart';
import '../../../../controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart'; import '../../../../controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart';
import '../../../../controllers/providers/settings/setting_provider.dart'; import '../../../../controllers/providers/settings/setting_provider.dart';
import '../../../../controllers/providers/user_provider.dart';
import '../../../../models/lookup.dart'; import '../../../../models/lookup.dart';
import '../../loaders/loading_manager.dart'; import '../../loaders/loading_manager.dart';
import '../single_status_menu.dart'; import '../single_status_menu.dart';
@ -22,7 +21,6 @@ class ServiceRequestPriorityMenu extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context); final settingProvider = Provider.of<SettingProvider>(context);
final userProvider = Provider.of<UserProvider>(context);
final menuProvider = Provider.of<ServiceRequestPriorityProvider>(context); final menuProvider = Provider.of<ServiceRequestPriorityProvider>(context);
return LoadingManager( return LoadingManager(
isLoading: menuProvider.isLoading, isLoading: menuProvider.isLoading,

Loading…
Cancel
Save