First Action Bottom Sheet Done

main_design2.0
zaid_daoud 2 years ago
parent 32e54d6853
commit 402f7513bd

@ -233,12 +233,12 @@ class ServiceRequestsProvider extends ChangeNotifier {
}
}
Future<int> updateDate({
@required String host,
Future<int> updateRequest({
@required User user,
@required ServiceRequest request,
DateTime date,
}) async {
isLoading = true;
notifyListeners();
Map<String, dynamic> serviceRequest = await getServiceRequestById(requestId: request.id) ?? "";
final List callSiteContacts = (serviceRequest['callSiteContactPerson'] as List);
final Map<String, dynamic> callSiteContactPerson = callSiteContacts.isEmpty ? {} : callSiteContacts[0];
@ -285,8 +285,8 @@ class ServiceRequestsProvider extends ChangeNotifier {
"firstAction": request.firstAction?.toJson(),
"loanAvailablity": request.loanAvailability?.toJson(),
"comments": request.reviewComment,
"firstActionDate": date?.toIso8601String(),
"visitDate": date?.toIso8601String() ?? "",
"firstActionDate": request.visitDate,
"visitDate": request.visitDate,
"callReview": null,
"reviewComment": null,
};
@ -300,8 +300,12 @@ class ServiceRequestsProvider extends ChangeNotifier {
// request.engineerName = employee.name;
notifyListeners();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
notifyListeners();
return -1;
}
}

@ -255,7 +255,7 @@
"pickAsset" : "إختر جهاز",
"filter" : "تصنيف",
"pickAsset" : "إختر جهاز",
"firstAction" : "First Action",
"firstAction" : "الإجراء الأول",
"priority" : "الأولوية",
"equipmentStatus" : "حالة المعدات",
"attachImage" : "إرفاق صورة",
@ -283,5 +283,9 @@
"bySite" : "حسب الموقع",
"applyFilter" : "تصفية",
"pmDateRange" : "النطاق الزمني للصيانة الوقائية",
"pickDate" : "إختر تاريخ"
"pickDate" : "إختر تاريخ",
"pickADate" : "إختر تاريخ",
"firstActionStatus" : "حالة الإجراء الأول",
"loanAvailability" : "توافر القرض",
"save" : "حفظ"
}

@ -288,5 +288,9 @@
"bySite" : "By Site",
"applyFilter" : "Apply Filter",
"pmDateRange" : "PM Date Range",
"pickDate" : "Pick Date"
"pickDate" : "Pick Date",
"pickADate" : "Pick a date",
"firstActionStatus" : "First Action Status",
"loanAvailability" : "Loan Availability",
"save" : "Save"
}

@ -54,6 +54,8 @@ import 'package:test_sa/providers/gas_request_providers/gas_types_provider.dart'
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
import 'package:test_sa/providers/service_request_providers/first_action_provider.dart';
import 'package:test_sa/providers/service_request_providers/loan_availability_provider.dart';
import 'package:test_sa/providers/service_request_providers/priority_provider.dart';
import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart';
import 'package:test_sa/providers/service_request_providers/type_of_request_provider.dart';
@ -166,6 +168,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => EquipmentStatusProvider()),
ChangeNotifierProvider(create: (_) => RequestedThroughProvider()),
ChangeNotifierProvider(create: (_) => TypeOfRequestProvider()),
ChangeNotifierProvider(create: (_) => FirstActionStatusProvider()),
ChangeNotifierProvider(create: (_) => LoanAvailabilityProvider()),
],
child: GestureDetector(
onTap: () {

@ -3,13 +3,12 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
class AppFilledButton extends StatelessWidget {
final VoidCallback onPressed;
final String label;
final bool maxWidth;
final bool maxWidth, loading;
final Color buttonColor;
final Color textColor;
@ -17,6 +16,7 @@ class AppFilledButton extends StatelessWidget {
@required this.onPressed,
@required this.label,
this.maxWidth = false,
this.loading = false,
this.buttonColor,
this.textColor,
Key key,
@ -32,7 +32,7 @@ class AppFilledButton extends StatelessWidget {
borderRadius: BorderRadius.circular(10),
color: buttonColor ?? Theme.of(context).primaryColor,
),
child: label.heading6(context).custom(color: textColor ?? (context.isDark ? AppColor.neutral60 : Colors.white)),
child: loading ? const CircularProgressIndicator(color: Colors.white) : label.heading6(context).custom(color: textColor ?? (context.isDark ? AppColor.neutral60 : Colors.white)),
).onPress(onPressed);
}
}

@ -0,0 +1,36 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import '../../controllers/api_routes/api_manager.dart';
import '../../controllers/api_routes/urls.dart';
import '../../models/lookup.dart';
class FirstActionStatusProvider extends LoadingListNotifier<Lookup> {
@override
Future getDate() async {
if (loading == true) return -2;
loading = true;
notifyListeners();
loading = true;
notifyListeners();
try {
Response 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"];
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -0,0 +1,36 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import '../../controllers/api_routes/api_manager.dart';
import '../../controllers/api_routes/urls.dart';
import '../../models/lookup.dart';
class LoanAvailabilityProvider extends LoadingListNotifier<Lookup> {
@override
Future getDate() async {
if (loading == true) return -2;
loading = true;
notifyListeners();
loading = true;
notifyListeners();
try {
Response 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"];
items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
}
}

@ -158,7 +158,7 @@ class CreateServiceRequestPageState extends State<CreateServiceRequestPage> {
context: context,
enabled: false,
title: context.translation.requestedThrough,
initialValue: snapshot.items?.firstWhere((element) => element.id == 375, orElse: () => null),
initialValue: snapshot.items?.firstWhere((element) => element.value == 3, orElse: () => null),
);
}),
8.height,
@ -211,7 +211,7 @@ class CreateServiceRequestPageState extends State<CreateServiceRequestPage> {
}
Future<void> _submit() async {
_serviceRequest?.requestedThrough = Provider.of<RequestedThroughProvider>(context, listen: false).items?.firstWhere((element) => element.id == 375, orElse: () => null);
_serviceRequest?.requestedThrough = Provider.of<RequestedThroughProvider>(context, listen: false).items?.firstWhere((element) => element.value == 3, orElse: () => null);
if (_formKey.currentState.validate() && await _serviceRequest.validateNewRequest(context)) {
_formKey.currentState.save();
_serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList();

@ -0,0 +1,122 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import '../../../../controllers/providers/api/service_requests_provider.dart';
import '../../../../models/lookup.dart';
import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/common_widgets/app_filled_button.dart';
import '../../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../../providers/service_request_providers/first_action_provider.dart';
import '../../../../providers/service_request_providers/loan_availability_provider.dart';
import '../../../widgets/date_and_time/date_picker.dart';
class FirstActionBottomSheet extends StatefulWidget {
final ServiceRequest request;
const FirstActionBottomSheet({Key key, @required this.request}) : super(key: key);
@override
State<FirstActionBottomSheet> createState() => _FirstActionBottomSheetState();
}
class _FirstActionBottomSheetState extends State<FirstActionBottomSheet> {
ServiceRequest _serviceRequest;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
_serviceRequest = widget.request;
}
@override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context, listen: false);
return Container(
height: MediaQuery.of(context).size.height * 0.55,
clipBehavior: Clip.antiAlias,
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
child: Form(
key: _formKey,
child: Column(
children: [
Container(
width: 40.toScreenWidth,
height: 5.toScreenHeight,
decoration: BoxDecoration(color: AppColor.neutral40, borderRadius: BorderRadius.circular(30)),
),
Align(
alignment: AlignmentDirectional.centerStart,
child: context.translation.firstAction.heading3(context).custom(fontWeight: FontWeight.w600).paddingOnly(top: 16, bottom: 16),
),
SingleItemDropDownMenu<Lookup, FirstActionStatusProvider>(
context: context,
title: context.translation.firstActionStatus,
initialValue: _serviceRequest.firstAction,
onSelect: (value) {
setState(() {
_serviceRequest.firstAction = value;
if (_serviceRequest?.firstAction?.value != 2) {
_serviceRequest.visitDate = null;
}
});
},
),
if (_serviceRequest?.firstAction?.value == 2) 8.height,
if (_serviceRequest?.firstAction?.value == 2)
ADatePicker(
label: context.translation.visitDate,
date: DateTime.tryParse(_serviceRequest.visitDate ?? ""),
onDatePicker: (date) {
setState(() {
_serviceRequest.visitDate = date?.toIso8601String();
});
},
),
8.height,
SingleItemDropDownMenu<Lookup, LoanAvailabilityProvider>(
context: context,
title: context.translation.loanAvailability,
initialValue: _serviceRequest.loanAvailability,
onSelect: (value) {
_serviceRequest.loanAvailability = value;
},
),
8.height,
AppTextFormField(
labelText: context.translation.comments,
textInputType: TextInputType.multiline,
alignLabelWithHint: true,
onSaved: (text) {
_serviceRequest.comments = text;
},
),
16.height,
Consumer<ServiceRequestsProvider>(
builder: (context, snapshot, _) => AppFilledButton(
label: context.translation.save,
loading: snapshot.isLoading,
onPressed: () async {
_formKey.currentState.save();
await snapshot.updateRequest(user: userProvider.user, request: _serviceRequest);
Navigator.pop(context);
},
),
),
16.height,
],
),
),
);
}
}

@ -1,39 +1,27 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/service_requests_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/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/enums/translation_keys.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart';
import 'package:test_sa/views/pages/user/requests/work_order/create_service_report.dart';
import 'package:test_sa/views/pages/user/requests/work_order/future_service_report.dart';
import 'package:test_sa/views/pages/user/requests/work_order/work_orders_list_page.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_icon_button.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/requests/info_row.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
import 'package:test_sa/views/widgets/sound/sound_player.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../models/service_request/search_work_order.dart';
import 'first_action_bottom_sheet.dart';
class ServiceRequestDetailsPage extends StatelessWidget {
static const String id = "/call-details";
@ -176,8 +164,17 @@ class ServiceRequestDetailsPage extends StatelessWidget {
),
],
).paddingOnly(bottom: 16, start: 16, end: 16))
.onPress(() {
.onPress(() async {
// todo 'sikander' add comment bottom sheet
// await showModalBottomSheet(
// context: context,
// useSafeArea: true,
// isScrollControlled: true,
// backgroundColor: Colors.transparent,
// builder: (context) => FirstActionBottomSheet(
// onPressed: () {},
// ),
// );
}),
],
),
@ -185,44 +182,56 @@ class ServiceRequestDetailsPage extends StatelessWidget {
}
return Scaffold(
appBar: DefaultAppBar(title: context.translation.serviceDetails),
backgroundColor: const Color(0xfff8f9fb),
body: SafeArea(
child: FutureBuilder(
future: _serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return const ALoading();
} else if (snap.hasData) {
serviceRequest = snap.data;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: informationCard(),
).expanded,
if (_userProvider.user.type != UsersTypes.engineer || (serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3))
(serviceRequest.firstAction == null
? AppFilledButton(
label: context.translation.firstAction,
maxWidth: true,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => CreateServiceRequestPage(serviceRequest: serviceRequest)),
);
})
: AppFilledButton(
label: context.translation.viewWorkOrder,
maxWidth: true,
onPressed: () {
Navigator.of(context).pushNamed(WorkOrderListPage.id, arguments: serviceRequest);
}))
.paddingOnly(start: 16, end: 16, bottom: 24),
],
);
}
return const SizedBox();
})));
appBar: DefaultAppBar(title: context.translation.serviceDetails),
backgroundColor: const Color(0xfff8f9fb),
body: SafeArea(
child: FutureBuilder(
future: _serviceRequestsProvider.getServiceRequestObjectById(requestId: serviceRequest.id),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return const ALoading();
} else if (snap.hasData) {
serviceRequest = snap.data;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: informationCard(),
).expanded,
if (_userProvider.user.type != UsersTypes.engineer || (serviceRequest.statusValue == 5 || serviceRequest.statusValue == 3))
(serviceRequest.firstAction == null
? AppFilledButton(
label: context.translation.firstAction,
maxWidth: true,
onPressed: () async {
// Navigator.of(context).push(
// MaterialPageRoute(builder: (_) => CreateServiceRequestPage(serviceRequest: serviceRequest)),
// );
await showModalBottomSheet(
context: context,
useSafeArea: true,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => FirstActionBottomSheet(request: serviceRequest),
);
},
)
: AppFilledButton(
label: context.translation.viewWorkOrder,
maxWidth: true,
onPressed: () {
Navigator.of(context).pushNamed(WorkOrderListPage.id, arguments: serviceRequest);
},
))
.paddingOnly(start: 16, end: 16, bottom: 24),
],
);
}
return const SizedBox();
},
),
),
);
}
}

@ -32,7 +32,7 @@ class ADatePicker extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
label.tinyFont(context),
(date?.toIso8601String() ?? context.translation.pickDate).bodyText(context).custom(color: AppColor.neutral50),
((date?.toIso8601String()?.split("T")?.first) ?? context.translation.pickADate).bodyText(context).custom(color: AppColor.neutral50),
],
).expanded,
16.width,

@ -3,14 +3,12 @@ import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.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/service_requests_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/extensions/context_extension.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
@ -55,7 +53,7 @@ class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialo
);
},
);
int status = await _serviceRequestsProvider.updateDate(user: _userProvider.user, host: _settingProvider.host, request: widget.request);
int status = await _serviceRequestsProvider.updateRequest(user: _userProvider.user, request: widget.request);
if (status == 200) Navigator.of(context).pop();
Navigator.of(context).pop();
Fluttertoast.showToast(
@ -70,7 +68,6 @@ class _ServiceRequestsUpdateDialogState extends State<ServiceRequestsUpdateDialo
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context, listen: false);
_settingProvider = Provider.of<SettingProvider>(context, listen: false);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context, listen: false);

Loading…
Cancel
Save