You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
244 lines
10 KiB
Dart
244 lines
10 KiB
Dart
import 'dart:convert';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:provider/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/modules/cm_module/service_request_detail_provider.dart';
|
|
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
|
|
import 'package:test_sa/new_views/app_style/app_color.dart';
|
|
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
|
|
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
|
|
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
|
|
import 'package:test_sa/views/widgets/qr/scan_qr.dart';
|
|
|
|
import 'bottom_sheets/service_request_bottomsheet.dart';
|
|
import 'verify_otp_view.dart';
|
|
|
|
class VerifyArrivalView extends StatefulWidget {
|
|
const VerifyArrivalView({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<VerifyArrivalView> createState() => _VerifyArrivalViewState();
|
|
}
|
|
|
|
class _VerifyArrivalViewState extends State<VerifyArrivalView> {
|
|
@override
|
|
void initState() {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
getInitialData();
|
|
});
|
|
super.initState();
|
|
}
|
|
|
|
Future<void> getInitialData() async {
|
|
ServiceRequestDetailProvider requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
|
|
await requestDetailProvider.getArrivalVerificationType();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: DefaultAppBar(title: context.translation.verifyArrival),
|
|
//backgroundColor: const Color(0xfff8f9fb),
|
|
body: Consumer<ServiceRequestDetailProvider>(builder: (context, ServiceRequestDetailProvider requestDetailProvider, child) {
|
|
return SafeArea(
|
|
child: requestDetailProvider.isArrivalLoading || requestDetailProvider.isLoading
|
|
? const CircularProgressIndicator(color: AppColor.primary10).center
|
|
: requestDetailProvider.arrivalTypeList.isEmpty
|
|
? const NoDataFound().center
|
|
: ListView.builder(
|
|
padding: EdgeInsets.zero,
|
|
itemCount: requestDetailProvider.arrivalTypeList.length,
|
|
itemBuilder: (builderContext, index) {
|
|
final item = requestDetailProvider.arrivalTypeList[index];
|
|
return customListItem(
|
|
icon: item.verificationTypes!.icon ?? '',
|
|
heading: item.verificationTypes!.name ?? '',
|
|
subHeading: item.description ?? '',
|
|
// isLoading: requestDetailProvider.isLoading,
|
|
onTap: () {
|
|
onItemTap(requestDetailProvider: requestDetailProvider, context: context, verificationTypeId: item.verificationTypes?.value);
|
|
});
|
|
},
|
|
).paddingOnly(start: 16, end: 16, top: 12, bottom: 12),
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
|
|
Widget customListItem({required String icon, required String heading, required String subHeading, required VoidCallback onTap, bool isLoading = false}) {
|
|
return GestureDetector(
|
|
onTap: onTap, // Handles the tap
|
|
child: Card(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(14), // Circular border radius
|
|
),
|
|
color: Colors.white,
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center, // Align items at the top
|
|
children: [
|
|
icon.toSvgAsset(width: 30, color: AppColor.neutral120, height: 30).paddingOnly(top: 0),
|
|
12.width,
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
heading,
|
|
style: AppTextStyles.heading6.copyWith(color: AppColor.neutral50),
|
|
),
|
|
6.height,
|
|
Text(
|
|
subHeading,
|
|
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
12.width,
|
|
SizedBox(width: 24, height: 24, child: isLoading ? const CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 2) : const SizedBox())
|
|
],
|
|
).paddingAll(12),
|
|
),
|
|
);
|
|
}
|
|
|
|
void onItemTap({required ServiceRequestDetailProvider requestDetailProvider, required BuildContext context, int? verificationTypeId}) async {
|
|
switch (verificationTypeId) {
|
|
case 1:
|
|
int? status;
|
|
String? result = await Navigator.of(context).push(
|
|
MaterialPageRoute(builder: (_) => const ScanQr()),
|
|
) as String?;
|
|
if (result != null) {
|
|
try {
|
|
//TODO show loader.
|
|
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
|
status = await requestDetailProvider.engineerConfirmArrival(
|
|
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 1, photoInfo: '', otp: '', assetNo: result);
|
|
if (status == 200) {
|
|
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
|
|
Navigator.pop(context);
|
|
requestDetailProvider.startTimer();
|
|
Navigator.pop(context);
|
|
} else {
|
|
Navigator.pop(context);
|
|
//show some message.
|
|
}
|
|
} catch (e) {
|
|
Navigator.pop(context);
|
|
print('error i got is $e');
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
try {
|
|
showWaitingBottomSheet(requestDetailProvider: requestDetailProvider, verificationTypeId: verificationTypeId);
|
|
} catch (e) {
|
|
"Requester not confirmed you arrival".showToast;
|
|
}
|
|
break;
|
|
case 3:
|
|
await requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => const VerifyOtpView()),
|
|
);
|
|
break;
|
|
case 4:
|
|
File? pickedFile = await onFilePicker();
|
|
if (pickedFile != null) {
|
|
var fileObj = ("${pickedFile.path.split("/").last}|${base64Encode(File(pickedFile.path).readAsBytesSync())}");
|
|
int? status;
|
|
try {
|
|
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
|
status = await requestDetailProvider.engineerConfirmArrival(
|
|
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 4, photoInfo: fileObj, otp: '');
|
|
if (status == 200) {
|
|
Navigator.pop(context);
|
|
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
|
|
Navigator.pop(context);
|
|
requestDetailProvider.startTimer();
|
|
} else {
|
|
Navigator.pop(context);
|
|
}
|
|
} catch (e) {
|
|
Navigator.pop(context);
|
|
}
|
|
}
|
|
break;
|
|
case 5:
|
|
int? status;
|
|
String? result = await Navigator.of(context).push(
|
|
MaterialPageRoute(builder: (_) => const ScanQr()),
|
|
) as String?;
|
|
if (result != null) {
|
|
try {
|
|
Map<String, dynamic> resultJson = jsonDecode(result);
|
|
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
|
status = await requestDetailProvider.engineerConfirmArrival(
|
|
workOrderId: resultJson['WorkOrderId'], verificationTypeId: verificationTypeId ?? 5, workOrderCreatedById: resultJson['WorkOrderCreatedById']);
|
|
if (status == 200) {
|
|
requestDetailProvider.getWorkOrderById(id: resultJson['WorkOrderId']);
|
|
Navigator.pop(context);
|
|
requestDetailProvider.startTimer();
|
|
Navigator.pop(context);
|
|
} else {
|
|
Navigator.pop(context);
|
|
//show some message.
|
|
}
|
|
} catch (e) {
|
|
Navigator.pop(context);
|
|
print('error i got is $e');
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
// ScanQr
|
|
}
|
|
|
|
Future<File?> onFilePicker() async {
|
|
File? fileImage;
|
|
final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 70, maxWidth: 800, maxHeight: 800);
|
|
if (pickedFile != null) {
|
|
fileImage = File(pickedFile.path);
|
|
}
|
|
return fileImage;
|
|
}
|
|
|
|
void showWaitingBottomSheet({required ServiceRequestDetailProvider requestDetailProvider, int? verificationTypeId}) async {
|
|
await requestDetailProvider.engineerConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 2, photoInfo: '', otp: '');
|
|
requestDetailProvider.isVerifyArrivalBottomSheetOpen = true;
|
|
ServiceRequestBottomSheet.waitingForApprovalBottomSheet(context: context).then((value) {
|
|
requestDetailProvider.isVerifyArrivalBottomSheetOpen = false;
|
|
});
|
|
bool? isArrived = await ServiceRequestUtils.listenForApproval();
|
|
if (requestDetailProvider.isVerifyArrivalBottomSheetOpen) {
|
|
if (isArrived == null) {
|
|
"Requester not confirmed you arrival".showToast;
|
|
Navigator.pop(context);
|
|
} else if (isArrived) {
|
|
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
|
|
Navigator.pop(context);
|
|
Navigator.pop(context);
|
|
requestDetailProvider.startTimer();
|
|
} else {
|
|
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
|
|
"Requester not confirmed you arrival".showToast;
|
|
Navigator.pop(context);
|
|
Navigator.pop(context);
|
|
}
|
|
} else {
|
|
log('bottomsheet closed ...');
|
|
}
|
|
}
|
|
}
|