timer implemented

design_3.0_latest
muhammad.abbasi 1 year ago
parent 6722e19cc5
commit 8b0bf4bedc

@ -35,6 +35,7 @@ class URLs {
static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount';
static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails';
static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject'; static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject';
static get engineerStopTimer=> '$_baseUrl/ServiceRequest/EngineerStopTimer';
static get nurseConfirmUrl=> '$_baseUrl/ServiceRequest/NurseConfirm'; static get nurseConfirmUrl=> '$_baseUrl/ServiceRequest/NurseConfirm';
static get engineerDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerCount'; static get engineerDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerCount';
static get engineerDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerDetails'; static get engineerDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerDetails';

@ -41,7 +41,8 @@ class DashBoardProvider extends ChangeNotifier {
List<CategoryTabs> tabs = []; List<CategoryTabs> tabs = [];
void setTabs(UsersTypes userType, context) { void setTabs({required UsersTypes userType, required BuildContext context}) {
print('user type i got in method is ${userType}');
tabs = CategoryTabs.getTabs(userType: userType, context: context); tabs = CategoryTabs.getTabs(userType: userType, context: context);
} }
@ -78,10 +79,10 @@ class DashBoardProvider extends ChangeNotifier {
isAllCountLoading = true; isAllCountLoading = true;
notifyListeners(); notifyListeners();
String url = ''; String url = '';
if (usersType == UsersTypes.nurse) { if (usersType == UsersTypes.engineer) {
url = URLs.nurseDashboardCountUrl;
} else {
url = URLs.engineerDashboardCountUrl; url = URLs.engineerDashboardCountUrl;
} else {
url = URLs.nurseDashboardCountUrl;
} }
Response response; Response response;
try { try {
@ -159,16 +160,18 @@ class DashBoardProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
print('i am called...${usersType}');
Response response; Response response;
String url = ''; String url = '';
if (usersType == UsersTypes.nurse) { if (usersType == UsersTypes.engineer) {
url = URLs.nurseDashboardDetailsUrl;
} else {
url = URLs.engineerDashboardDetailsUrl; url = URLs.engineerDashboardDetailsUrl;
} else {
url = URLs.nurseDashboardDetailsUrl;
} }
try { try {
Map<String, dynamic> body = {"pageNumber": pageNum, "pageSize": pageItemNumber}; Map<String, dynamic> body = {"pageNumber": pageNum, "pageSize": pageItemNumber};
if (status != null) body["status"] = status; if (status != null) body["statusValue"] = status;
if (isHighPriority) body["isHighPriority"] = true; if (isHighPriority) body["isHighPriority"] = true;
if (isOverdue) body["isOverdue"] = true; if (isOverdue) body["isOverdue"] = true;
response = await ApiManager.instance.post(url, body: body); response = await ApiManager.instance.post(url, body: body);
@ -227,7 +230,7 @@ class CategoryTabs {
tabs.add(CategoryTabs('Open Request', 1)); tabs.add(CategoryTabs('Open Request', 1));
tabs.add(CategoryTabs('In Progress', 2)); tabs.add(CategoryTabs('In Progress', 2));
tabs.add(CategoryTabs('Acknowledged', 3)); tabs.add(CategoryTabs('Acknowledged', 3));
tabs.add(CategoryTabs('Rejected', 4)); tabs.add(CategoryTabs('Rejected', 6));
return tabs; return tabs;
} }
} }

@ -49,6 +49,7 @@ class _DashboardViewState extends State<DashboardView> {
} }
void getRequests() { void getRequests() {
_dashBoardProvider.setTabs(userType:userProvider.user!.type!,context: context);
_dashBoardProvider.getDashBoardCount(usersType: userProvider.user!.type!); _dashBoardProvider.getDashBoardCount(usersType: userProvider.user!.type!);
_dashBoardProvider.resetRequestDataList(); _dashBoardProvider.resetRequestDataList();
_dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: _dashBoardProvider.tabs[_dashBoardProvider.currentListIndex].tag); _dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: _dashBoardProvider.tabs[_dashBoardProvider.currentListIndex].tag);
@ -58,10 +59,8 @@ class _DashboardViewState extends State<DashboardView> {
scheduleMicrotask(() async { scheduleMicrotask(() async {
userProvider = Provider.of<UserProvider>(context, listen: false); userProvider = Provider.of<UserProvider>(context, listen: false);
settingProvider = Provider.of<SettingProvider>(context, listen: false); settingProvider = Provider.of<SettingProvider>(context, listen: false);
RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
//allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
_dashBoardProvider = Provider.of<DashBoardProvider>(context, listen: false); _dashBoardProvider = Provider.of<DashBoardProvider>(context, listen: false);
_dashBoardProvider.setTabs(userProvider.user!.type!, context);
notificationsProvider = Provider.of<NotificationsProvider>(context, listen: false); notificationsProvider = Provider.of<NotificationsProvider>(context, listen: false);
user = userProvider.user!; user = userProvider.user!;
getRequests(); getRequests();

@ -42,7 +42,7 @@ class RequestCategoryFragment extends StatelessWidget {
} }
Widget getTabs({required BuildContext context, required DashBoardProvider requestsProvider, required UsersTypes userType}) { Widget getTabs({required BuildContext context, required DashBoardProvider requestsProvider, required UsersTypes userType}) {
List<CategoryTabs> tabs = CategoryTabs.getTabs(userType: UsersTypes.engineer, context: context); List<CategoryTabs> tabs = CategoryTabs.getTabs(userType: userType, context: context);
return SizedBox( return SizedBox(
height: 44 + 16, height: 44 + 16,
child: ListView.separated( child: ListView.separated(

@ -76,7 +76,7 @@ class ActivityMaintenanceHelperModel {
if(lastSituation!=null){ if(lastSituation!=null){
data['lastSituationId'] = lastSituation?.id; data['lastSituationId'] = lastSituation?.id;
} }
if (assignedEmployee != null&&assignedEmployee?.userId!=null) { if (assistantEmployees != null&&assistantEmployees!.isNotEmpty) {
data['assistantEmployees'] = [modelAssistantEmployees?.toJson()]; data['assistantEmployees'] = [modelAssistantEmployees?.toJson()];
} }
else{ else{

@ -9,8 +9,9 @@ import '../app_style/app_color.dart';
class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
final String? title; final String? title;
final List<Widget>? actions; final List<Widget>? actions;
final VoidCallback ?onBackPress;
const DefaultAppBar({this.title, this.actions, Key? key}) : super(key: key); const DefaultAppBar({this.title,this.onBackPress, this.actions, Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -20,7 +21,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
title: Row( title: Row(
children: [ children: [
const Icon(Icons.arrow_back_ios).onPress(() { const Icon(Icons.arrow_back_ios).onPress(() {
Navigator.of(context).pop(); onBackPress?? Navigator.of(context).pop();
}), }),
10.width, 10.width,
Text( Text(

@ -38,8 +38,13 @@ class RequestDetailProvider extends ChangeNotifier {
} }
void stopTimer() { void stopTimer() {
Timer.periodic(const Duration(seconds: 1), (Timer t) {
timerStartTime = timerStartTime.add(const Duration(seconds: 1));
notifyListeners(); // Notify UI when time is updated
});
timer?.cancel(); timer?.cancel();
isTimerRunning = false; isTimerRunning = false;
engineerStopTimer();
notifyListeners(); // Notify UI when timer stops notifyListeners(); // Notify UI when timer stops
} }
@ -209,6 +214,28 @@ class RequestDetailProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
return -1; return -1;
} }
} //engineerAcceptWorkOrder......
Future<int> engineerStopTimer() async {
Response response;
try {
final body = {"workOrderId": currentWorkOrder?.data?.requestId};
isLoading = true;
notifyListeners();
response = await ApiManager.instance.post(URLs.engineerStopTimer, body: body);
print('response of stop timer is ${response.body}');
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (e) {
log("engineer accept [error] : $e");
isLoading = false;
notifyListeners();
return -1;
}
} }
//engineerRejectWorkOrder...... //engineerRejectWorkOrder......
@ -413,6 +440,8 @@ class RequestDetailProvider extends ChangeNotifier {
} }
} }
//Nurse confirm reopen //Nurse confirm reopen
Future<CommonResponseModel> nurseReject() async { Future<CommonResponseModel> nurseReject() async {
try { try {
@ -421,14 +450,16 @@ class RequestDetailProvider extends ChangeNotifier {
final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: nurseActionHelperModel!.toJson()); final response = await ApiManager.instance.post(URLs.nurseRejectUrl, body: nurseActionHelperModel!.toJson());
stateCode = response.statusCode; stateCode = response.statusCode;
CommonResponseModel commonResponseModel = CommonResponseModel(); CommonResponseModel commonResponseModel = CommonResponseModel();
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body));
} }
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
return commonResponseModel; return commonResponseModel;
} catch (e) { } catch (e) {
log("engineer accept [error] : $e"); log("nurse reject [error] : $e");
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
return CommonResponseModel(); return CommonResponseModel();

@ -42,8 +42,10 @@ class FooterActionButton {
return const SizedBox(); return const SizedBox();
// TODO: Handle this case. // TODO: Handle this case.
case WorkOrderNextStepEnum.markedAsFixed: case WorkOrderNextStepEnum.markedAsFixed:
break;
// TODO: Handle this case. // TODO: Handle this case.
case WorkOrderNextStepEnum.nTakeAction: case WorkOrderNextStepEnum.nTakeAction:
print('i am here take action ..');
// const SizedBox().flushBar(context: context, title: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm, message: ''); // const SizedBox().flushBar(context: context, title: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm, message: '');
return footerContainer( return footerContainer(
child: AppFilledButton( child: AppFilledButton(
@ -177,8 +179,12 @@ class FooterActionButton {
fontSize: 12.toScreenWidth, fontSize: 12.toScreenWidth,
)); ));
} }
} else if (userProvider.user?.type == UsersTypes.nurse) { }
else {
print('value is ${workOrderNextStepStatus}');
if (workOrderNextStepStatus == WorkOrderNextStepEnum.nTakeAction) { if (workOrderNextStepStatus == WorkOrderNextStepEnum.nTakeAction) {
print('i am here take action ..');
return footerContainer( return footerContainer(
child: AppFilledButton( child: AppFilledButton(
label: context.translation.takeAction, label: context.translation.takeAction,

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/app_strings/app_asset.dart'; import 'package:test_sa/app_strings/app_asset.dart';
import 'package:test_sa/dashboard_latest/widgets/request_category_list.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
@ -611,6 +612,62 @@ class ServiceRequestBottomSheet {
); );
})); }));
} }
static Future nurseRejectBackBottomSheet({required BuildContext context}) {
String feedback = '';
return buildBottomSheetParent(
context: context,
childWidget: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox().indicatorWidget(),
8.height,
Align(
alignment: AlignmentDirectional.centerStart,
child: context.translation.rejectionReason.bottomSheetHeadingTextStyle(context),
),
21.height,
AppTextFormField(
labelText: context.translation.comments,
textInputType: TextInputType.multiline,
labelStyle: AppTextStyles.textFieldLabelStyle,
showWithoutDecoration: true,
backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100,
alignLabelWithHint: true,
onChange: (text) {
feedback = text;
},
onSaved: (text) {
feedback = text;
},
),
16.height,
AppFilledButton(
label: context.translation.reject,
maxWidth: true,
buttonColor: Colors.white54,
textColor: AppColor.red30,
showBorder: true,
onPressed: () {
if (feedback.isNotEmpty) {
requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel(
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId,
feedback: feedback,
);
requestDetailProvider.nurseReject();
Navigator.pop(context);
if(requestDetailProvider.currentWorkOrder!.data!.requestId!=null){
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
}
}
// Navigator.pop(context);
// requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback: feedback);
},
),
],
);
}));
}
static Future nurseTakeActionBottomSheet({required BuildContext context}) { static Future nurseTakeActionBottomSheet({required BuildContext context}) {
bool acknowledge = false; bool acknowledge = false;
@ -618,7 +675,7 @@ class ServiceRequestBottomSheet {
String? nurseSignature; String? nurseSignature;
return buildBottomSheetParent( return buildBottomSheetParent(
context: context, context: context,
childWidget: Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) { childWidget: Consumer<RequestDetailProvider>(builder: (context, RequestDetailProvider requestDetailProvider, child) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
@ -629,37 +686,63 @@ class ServiceRequestBottomSheet {
child: context.translation.pleaseConfirmTheIssueHasBeenResolved.bottomSheetHeadingTextStyle(context), child: context.translation.pleaseConfirmTheIssueHasBeenResolved.bottomSheetHeadingTextStyle(context),
), ),
10.height, 10.height,
Row( StatefulBuilder(
children: [ builder: (context, setState) {
InkWell( return Column(
child: acknowledge children: [
? const Icon( Row(
Icons.check_box, children: [
color: AppColor.primary10, InkWell(
) child: acknowledge
: const Icon( ? const Icon(
Icons.check_box_outline_blank, Icons.check_box,
color: AppColor.neutral120, color: AppColor.primary10,
)
: const Icon(
Icons.check_box_outline_blank,
color: AppColor.neutral120,
),
onTap: () {
setState(() {
acknowledge = !acknowledge;
});
},
), ),
onTap: () { 6.width,
acknowledge = !acknowledge; Flexible(
}, child: context.translation.nurseAcknowledge
), .bodyText(context)
6.width, .custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120),
Flexible(child: context.translation.nurseAcknowledge.bodyText(context).custom(color: context.isDark ? AppColor.primary50 : AppColor.neutral120)), ),
], ],
), ),
17.height, 17.height,
ESignature( ESignature(
title: '', title: '',
oldSignature: '', oldSignature: '',
newSignature: newSignature, newSignature: newSignature,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
showShadow: false, showShadow: false,
onSaved: (signature) { onChange:(signature){
if (signature == null || signature.isEmpty) return; setState(() {
newSignature = signature; if (signature == null || signature.isEmpty) return;
nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; newSignature = signature;
nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
print('signature i got is ${newSignature}');
});
},
onSaved: (signature) {
setState(() {
if (signature == null || signature.isEmpty) return;
newSignature = signature;
nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
print('signature i got is ${newSignature}');
});
},
),
],
);
}, },
), ),
36.height, 36.height,
@ -674,14 +757,8 @@ class ServiceRequestBottomSheet {
textColor: AppColor.red30, textColor: AppColor.red30,
showBorder: true, showBorder: true,
onPressed: () async { onPressed: () async {
if (newSignature != null && acknowledge) { Navigator.pop(context);
requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel( nurseRejectBackBottomSheet(context: context);
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId,
signatureNurse: nurseSignature,
);
requestDetailProvider.nurseReject();
Navigator.pop(context);
}
}, },
).expanded, ).expanded,
const SizedBox( const SizedBox(
@ -692,14 +769,18 @@ class ServiceRequestBottomSheet {
maxWidth: true, maxWidth: true,
buttonColor: AppColor.green70, buttonColor: AppColor.green70,
onPressed: () async { onPressed: () async {
if (newSignature != null && acknowledge) { if (newSignature != null) {
//TODO replace provider with new provider and also check workorder id is not correct.
requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel( requestDetailProvider.nurseActionHelperModel = NurseActionHelperModel(
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!,
signatureNurse: nurseSignature, signatureNurse: nurseSignature,
); );
requestDetailProvider.nurseConfirm(); requestDetailProvider.nurseConfirm();
if(requestDetailProvider.currentWorkOrder!.data!.requestId!=null){
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
}
Navigator.pop(context); Navigator.pop(context);
}else{
//show some toast...
} }
}, },
).expanded, ).expanded,

@ -16,6 +16,7 @@ import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/service_request_latest/views/components/initial_visit_card.dart'; import 'package:test_sa/service_request_latest/views/components/initial_visit_card.dart';
import 'package:test_sa/service_request_latest/views/components/timer_widget.dart';
import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart'; import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -29,6 +30,7 @@ class WorkOrderDetailView extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false); UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
return Consumer<RequestDetailProvider>(builder: (pContext, requestProvider, _) { return Consumer<RequestDetailProvider>(builder: (pContext, requestProvider, _) {
return requestProvider.isLoading return requestProvider.isLoading
? const CircularProgressIndicator(color: AppColor.primary10).center ? const CircularProgressIndicator(color: AppColor.primary10).center
: requestProvider.currentWorkOrder == null : requestProvider.currentWorkOrder == null
@ -56,15 +58,16 @@ class WorkOrderDetailView extends StatelessWidget {
context: context), context: context),
], ],
), ),
// const TimerWidget(), if (requestProvider.timer!=null&&requestProvider.timer!.isActive)...[
const TimerWidget(),
]
], ],
); );
}); });
} }
Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) { Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) {
print('callids i got is ${workOrder.requestId}');
print('work order next step value is ${workOrder.nextStep?.toJson()}');
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -391,7 +394,7 @@ class WorkOrderDetailView extends StatelessWidget {
// ), // ),
// ), // ),
// FooterActionButton.requestDetailsFooterWidget(status: 7, context: context), // FooterActionButton.requestDetailsFooterWidget(status: 7, context: context),
// TimerWidget(),
// ], // ],
// ), // ),
// ); // );

@ -22,8 +22,6 @@ class _TimerWidgetState extends State<TimerWidget> {
Offset position = Offset(SizeConfig.screenWidth! - 100, SizeConfig.screenHeight! / 2 - 50); Offset position = Offset(SizeConfig.screenWidth! - 100, SizeConfig.screenHeight! / 2 - 50);
@override @override
void initState() { void initState() {
// TODO: implement initState
Provider.of<RequestDetailProvider>(context,listen: false).startTimer();
super.initState(); super.initState();
} }
@override @override
@ -64,8 +62,6 @@ class _TimerWidgetState extends State<TimerWidget> {
onTap: () { onTap: () {
if (provider.isTimerRunning) { if (provider.isTimerRunning) {
provider.stopTimer(); provider.stopTimer();
} else {
provider.startTimer();
} }
}, },
child: Container( child: Container(

@ -146,18 +146,13 @@ class _VerifyArrivalViewState extends State<VerifyArrivalView> {
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
status = await requestDetailProvider.engineerConfirmArrival( status = await requestDetailProvider.engineerConfirmArrival(
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 1, photoInfo: '', otp: '', assetNo: result);
verificationTypeId: 1,
photoInfo: '',
otp: '',
assetNo: requestDetailProvider.currentWorkOrder!.data!.asset!.assetNumber!);
print('status i got is $status');
if (status == 200) { if (status == 200) {
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
//Navigator.pop(context); //Navigator.pop(context);
requestDetailProvider.startTimer();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!)));
} } else {
else {
// Navigator.pop(context); // Navigator.pop(context);
//show some message. //show some message.
} }
@ -172,41 +167,35 @@ class _VerifyArrivalViewState extends State<VerifyArrivalView> {
break; break;
case 2: case 2:
//TODO add loader. //TODO add loader.
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
//Navigator.pop(context); //Navigator.pop(context);
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute(builder: (context) => const VerifyOtpView()), MaterialPageRoute(builder: (context) => const VerifyOtpView()),
); );
break; break;
case 3: case 3:
File ?pickedFile = await onFilePicker(); File? pickedFile = await onFilePicker();
if(pickedFile!=null){ if (pickedFile != null) {
var fileObj = ("${pickedFile.path.split("/").last}|${base64Encode(File(pickedFile.path).readAsBytesSync())}"); var fileObj = ("${pickedFile.path.split("/").last}|${base64Encode(File(pickedFile.path).readAsBytesSync())}");
int? status; int? status;
try{ try {
//TODO add loader //TODO add loader
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
status = await requestDetailProvider.engineerConfirmArrival( status = await requestDetailProvider.engineerConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 4, photoInfo: fileObj, otp: '');
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!,
verificationTypeId: 1,
photoInfo: fileObj,
otp: '',
assetNo: requestDetailProvider.currentWorkOrder!.data!.asset?.assetNumber);
if (status == 200) { if (status == 200) {
requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
// Navigator.pop(context); // Navigator.pop(context);
requestDetailProvider.startTimer();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!)));
} } else {
else{
//show some message. //show some message.
// Navigator.pop(context); // Navigator.pop(context);
} }
}catch(e){ } catch (e) {
print('error i got is $e'); print('error i got is $e');
// Navigator.pop(context); // Navigator.pop(context);
} }
@ -225,8 +214,8 @@ class _VerifyArrivalViewState extends State<VerifyArrivalView> {
} }
// ScanQr // ScanQr
} }
Future<File?> onFilePicker() async {
Future<File?> onFilePicker() async {
// ImageSource? source = await showModalBottomSheet<ImageSource>( // ImageSource? source = await showModalBottomSheet<ImageSource>(
// context: context, // context: context,
// builder: (BuildContext context) { // builder: (BuildContext context) {
@ -276,12 +265,12 @@ class _VerifyArrivalViewState extends State<VerifyArrivalView> {
// }, // },
// ); // );
// if (source == null) return null; // if (source == null) return null;
File ?fileImage; File? fileImage;
final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 70, maxWidth: 800, maxHeight: 800); final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 70, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) { if (pickedFile != null) {
fileImage = File(pickedFile.path); fileImage = File(pickedFile.path);
} }
return fileImage; return fileImage;
} }
} }

@ -62,6 +62,7 @@ class VerifyOtpView extends StatelessWidget {
await requestDetailProvider.engineerConfirmArrival( await requestDetailProvider.engineerConfirmArrival(
workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 3, photoInfo: '', otp: pin, assetNo: ''); workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 3, photoInfo: '', otp: pin, assetNo: '');
// Navigator.pop(context); // Navigator.pop(context);
requestDetailProvider.startTimer();
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!)));
} }
}, },

@ -14,6 +14,7 @@ import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_mo
import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/new_views/app_style/app_color.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/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.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/equipment_status_provider.dart';
@ -82,7 +83,7 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
equipmentStatus: currentWorkOrderData.equipmentStatus, equipmentStatus: currentWorkOrderData.equipmentStatus,
loanAvailability: currentWorkOrderData.loanAvailablity, loanAvailability: currentWorkOrderData.loanAvailablity,
failureReason: currentWorkOrderData.failureReasone, failureReason: currentWorkOrderData.failureReasone,
// faultDescription: currentWorkOrderData.problemDescription, // faultDescription: currentWorkOrderData.fa,
solution: currentWorkOrderData.solution?.name, solution: currentWorkOrderData.solution?.name,
returnToService: currentWorkOrderData.returnToService, returnToService: currentWorkOrderData.returnToService,
serviceType: currentWorkOrderData.serviceType, serviceType: currentWorkOrderData.serviceType,
@ -212,8 +213,11 @@ class _VerifyAssetDetailsState extends State<VerifyAssetDetails> with TickerProv
label: context.translation.verify_asset_details, label: context.translation.verify_asset_details,
buttonColor: AppColor.primary10, buttonColor: AppColor.primary10,
onPressed: () async { onPressed: () async {
//TODO add loader..
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
await requestDetailProvider.engineerUpdateWorkOrder(); await requestDetailProvider.engineerUpdateWorkOrder();
Navigator.pop(context); Navigator.pop(context);
Navigator.pop(context);
}, },
), ),
), ),

@ -22,12 +22,12 @@ class AssistantEmployeeCard extends StatefulWidget {
} }
class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> { class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
bool status = false; bool status = false;
final TextEditingController _workingHoursController = TextEditingController(text: ''); final TextEditingController _workingHoursController = TextEditingController(text: '');
bool isCurrentUserIsAssistantEmp = false; bool isCurrentUserIsAssistantEmp = false;
bool isExpanded = false; bool isExpanded = false;
@override @override
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
@ -57,147 +57,156 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) { return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column( return Column(
children: [ children: [
SizedBox( GestureDetector(
height: 56.toScreenHeight, onTap: () {
child: Row( setState(() {
mainAxisAlignment: MainAxisAlignment.spaceBetween, isExpanded = !isExpanded;
children: [ });
context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20), },
IconButton(onPressed: (){ child: Container(
setState(() { color: AppColor.white10,
isExpanded=!isExpanded; height: 56.toScreenHeight,
}); child: Row(
}, icon: Icon(isExpanded?Icons.arrow_drop_up_outlined:Icons.arrow_drop_down)), mainAxisAlignment: MainAxisAlignment.spaceBetween,
],),
),
isExpanded? Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ServiceReportAssistantEmployeeMenu(
title: context.translation.select,
backgroundColor: AppColor.neutral100,
assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false)
? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first
: null,
//TODO add check...
// enable: !isCurrentUserIsAssistantEmp,
onSelect: (employee) {
print('on select called...${employee?.toJson()}');
if (employee == null) {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
} else {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user= AssignedEmployee(userId: employee.user?.id,userName:employee.user?.name );
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
ADatePicker( context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20),
label: context.translation.startTime, Padding(
hideShadow: true, padding: const EdgeInsets.all(8.0),
backgroundColor: AppColor.neutral100, child: Icon(isExpanded ? Icons.arrow_drop_up_outlined : Icons.arrow_drop_down),
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, ),
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
], ],
), ),
8.height, ),
AppTextFormField( ),
labelText: context.translation.workingHours, isExpanded
backgroundColor: AppColor.neutral80, ? Column(
controller: _workingHoursController, crossAxisAlignment: CrossAxisAlignment.stretch,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), children: [
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null ServiceReportAssistantEmployeeMenu(
? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString() title: context.translation.select,
: '', showAsBottomSheet: true,
textAlign: TextAlign.center, backgroundColor: AppColor.neutral100,
labelStyle: AppTextStyles.textFieldLabelStyle, assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
enable: false, initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false)
showShadow: false, ? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first
style: Theme.of(context).textTheme.titleMedium, : null,
), //TODO add check...
8.height, // enable: !isCurrentUserIsAssistantEmp,
AppTextFormField( onSelect: (employee) {
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment, print('on select called...${employee?.toJson()}');
labelText: context.translation.technicalComment, if (employee == null) {
backgroundColor: AppColor.neutral100, requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
showShadow: false, } else {
labelStyle: AppTextStyles.textFieldLabelStyle, requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
alignLabelWithHint: true, requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name);
textInputType: TextInputType.multiline, }
onChange: (value) { },
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; ),
}, 8.height,
onSaved: (value) { Row(
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value; mainAxisSize: MainAxisSize.min,
}, children: [
), ADatePicker(
8.height, label: context.translation.startTime,
], hideShadow: true,
):const SizedBox(), backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
],
),
8.height,
AppTextFormField(
labelText: context.translation.workingHours,
backgroundColor: AppColor.neutral80,
controller: _workingHoursController,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null
? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString()
: '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
),
8.height,
],
)
: const SizedBox(),
], ],
); );
}); });
} }
@ -205,7 +214,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
double calculateWorkingHours(DateTime? startTime, DateTime? endTime) { double calculateWorkingHours(DateTime? startTime, DateTime? endTime) {
if (startTime != null && endTime != null) { if (startTime != null && endTime != null) {
Duration difference = endTime.difference(startTime); Duration difference = endTime.difference(startTime);
int hours = difference.inHours ; int hours = difference.inHours;
int minutes = difference.inMinutes % 60; int minutes = difference.inMinutes % 60;
return hours.toDouble(); return hours.toDouble();
} else { } else {

@ -48,11 +48,13 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _workingHoursController = TextEditingController(); final TextEditingController _workingHoursController = TextEditingController();
final TextEditingController _travellingHoursController = TextEditingController(); final TextEditingController _travellingHoursController = TextEditingController();
Lookup statusLookup = Lookup.fromJson({"id": 5619, "name": "New", "value": 1});
@override @override
void initState() { void initState() {
_activityStatusProvider = Provider.of<ActivityStatusProvider>(context, listen: false); _activityStatusProvider = Provider.of<ActivityStatusProvider>(context, listen: false);
_requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false); _requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
_requestDetailProvider?.activityMaintenanceHelperModel?.activityStatus = _requestDetailProvider?.activityMaintenanceHelperModel?.activityStatus ?? statusLookup;
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
_travellingHoursController.text = _travellingHoursController.text =
@ -83,7 +85,6 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) { return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
print('data in consumer is ${requestDetailProvider.activityMaintenanceHelperModel?.activityStatus?.toJson()}');
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
@ -92,29 +93,30 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
SingleItemDropDownMenu<Lookup, LastSituationProvider>( SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
context: context, context: context,
height: 56.toScreenHeight, height: 56.toScreenHeight,
title: context.translation.lastSituationStatus, title: context.translation.activityStatus,
showShadow: false, showShadow: false,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
showAsBottomSheet: true, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.lastSituation,
onSelect: (status) { onSelect: (status) {
requestDetailProvider.activityMaintenanceHelperModel?.lastSituation = status; print('status i got is ${status?.toJson()}');
setState(() {}); requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status;
}, },
), ),
8.height, 8.height,
SingleItemDropDownMenu<Lookup, ActivityStatusProvider>( SingleItemDropDownMenu<Lookup, LastSituationProvider>(
context: context, context: context,
height: 56.toScreenHeight, height: 56.toScreenHeight,
title: context.translation.activityStatus, title: context.translation.lastSituationStatus,
showShadow: false, showShadow: false,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, showAsBottomSheet: true,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.lastSituation,
onSelect: (status) { onSelect: (status) {
requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; requestDetailProvider.activityMaintenanceHelperModel?.lastSituation = status;
setState(() {});
}, },
), ),
8.height, 8.height,

@ -41,45 +41,75 @@ class _RequestDetailMainState extends State<RequestDetailMain> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return WillPopScope(
backgroundColor: AppColor.neutral100, onWillPop: () async {
appBar: DefaultAppBar(title: context.translation.serviceDetails), // Implement custom back button handling logic here
body: DefaultTabController( RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context,listen: false);
length: 2, if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){
child: Column( requestDetailProvider.stopTimer();
mainAxisSize: MainAxisSize.min, }
children: <Widget>[ return true; // Return true if you want to allow popping the screen, false otherwise
Container( },
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), child: Scaffold(
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)), backgroundColor: AppColor.neutral100,
child: TabBar( appBar:AppBar(
//controller: _tabController, automaticallyImplyLeading: false,
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), titleSpacing: 16,
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, title: Row(
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, children: [
unselectedLabelStyle: AppTextStyles.bodyText, const Icon(Icons.arrow_back_ios).onPress(() {
labelStyle: AppTextStyles.bodyText, RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context,listen: false);
indicatorPadding: EdgeInsets.zero, if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){
indicatorSize: TabBarIndicatorSize.tab, requestDetailProvider.stopTimer();
dividerColor: Colors.transparent, }
indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)), Navigator.pop(context);
onTap: (index) {
// setState(() {}); }),
}, 10.width,
tabs: [ Text(
Tab(text: context.translation.requestDetail, height: 57.toScreenHeight), context.translation.serviceDetails ,
Tab(text: context.translation.historyLogs, height: 57.toScreenHeight), style: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
], ).expanded,
],
),
),
body: DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)),
child: TabBar(
//controller: _tabController,
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)),
onTap: (index) {
// setState(() {});
},
tabs: [
Tab(text: context.translation.requestDetail, height: 57.toScreenHeight),
Tab(text: context.translation.historyLogs, height: 57.toScreenHeight),
],
),
), ),
), 12.height,
12.height, TabBarView(
TabBarView( children: [
children: [ WorkOrderDetailView(),
WorkOrderDetailView(), const HistoryLogView(),
const HistoryLogView(), ],
], ).expanded,
).expanded, ],
], ),
), ),
), ),
); );

@ -1,131 +1,164 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/views/widgets/bottom_sheets/selection_bottom_sheet.dart';
import '../../../models/new_models/assistant_employee.dart'; import '../../../models/new_models/assistant_employee.dart';
import '../../../new_views/app_style/app_color.dart'; import '../../../new_views/app_style/app_color.dart';
class AssistantEmployeeMenu extends StatefulWidget { class AssistantEmployeeMenu extends StatefulWidget {
final List<AssistantEmployees> statuses; final List<AssistantEmployees> statuses;
Color? backgroundColor; Color? backgroundColor;
final AssistantEmployees? initialStatus; // Now nullable final AssistantEmployees? initialStatus; // Now nullable
final Function(AssistantEmployees?) onSelect; // Now accepts nullable values final Function(AssistantEmployees?) onSelect; // Now accepts nullable values
final String? title; // Now nullable final String? title; // Now nullable
final bool enable; final bool enable;
bool? showAsBottomSheet = false;
AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus,this.backgroundColor, this.enable = true}) : super(key: key); AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus, this.showAsBottomSheet = false, this.backgroundColor, this.enable = true})
: super(key: key);
@override @override
_SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState(); _SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState();
} }
class _SingleAssistantEmployeeMenuState extends State<AssistantEmployeeMenu> {AssistantEmployees? _selectedStatus; // Now nullable class _SingleAssistantEmployeeMenuState extends State<AssistantEmployeeMenu> {
AssistantEmployees? _selectedStatus; // Now nullable
@override @override
void setState(VoidCallback fn) { void setState(VoidCallback fn) {
if (mounted) super.setState(fn); if (mounted) super.setState(fn);
} }
@override @override
void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) { void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id);
if (result.isNotEmpty) { if (result.isNotEmpty) {
_selectedStatus = result.first; _selectedStatus = result.first;
} else {
_selectedStatus = null;
}
if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) {
widget.onSelect(_selectedStatus);
}
} else { } else {
_selectedStatus = null; _selectedStatus = null;
} }
if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { super.didUpdateWidget(oldWidget);
widget.onSelect(_selectedStatus);
}
} else {
_selectedStatus = null;
} }
super.didUpdateWidget(oldWidget);
}
@override @override
void initState() { void initState() {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id); final result = widget.statuses.where((element) => element.user?.id == widget.initialStatus?.user?.id);
if (result.isNotEmpty) { if (result.isNotEmpty) {
_selectedStatus = result.first; _selectedStatus = result.first;
} }
if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) {
widget.onSelect(_selectedStatus); widget.onSelect(_selectedStatus);
}
} }
super.initState();
} }
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
height: 60.toScreenHeight, height: 60.toScreenHeight,
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
decoration: BoxDecoration( decoration: BoxDecoration(
color:widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120), color: widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
), ),
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
PositionedDirectional( PositionedDirectional(
end: 0, end: 0,
child: Icon( child: Icon(
Icons.keyboard_arrow_down_rounded, Icons.keyboard_arrow_down_rounded,
color: widget.enable ? null : Colors.grey, color: widget.enable ? null : Colors.grey,
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (widget.title != null)
Text(
widget.title!, // Non-null assertion after null check
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
),
DropdownButton<AssistantEmployees>(
value: _selectedStatus,
dropdownColor: AppColor.white10,
iconSize: 24,
isDense: true,
icon: const SizedBox.shrink(),
elevation: 0,
isExpanded: true,
hint: Text(
context.translation.select,
style: Theme.of(context).textTheme.bodyLarge,
),
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20),
underline: const SizedBox.shrink(),
onChanged: widget.enable
? (AssistantEmployees? newValue) { // Now accepts nullable values
setState(() {
_selectedStatus = newValue;
});
widget.onSelect(newValue);
}
:null,
items: widget.statuses.map<DropdownMenuItem<AssistantEmployees>>(
(AssistantEmployees value) {
return DropdownMenuItem<AssistantEmployees>(
value: value,
child: Text(
value.user?.name ?? "NULL", // Use null-aware operator for user.name
style: AppTextStyles.bodyText.copyWith(color: AppColor.black20),
),
);
},
).toList(),
), ),
], ),
), Column(
], crossAxisAlignment: CrossAxisAlignment.start,
), mainAxisAlignment: MainAxisAlignment.center,
); children: [
if (widget.title != null)
Text(
widget.title!, // Non-null assertion after null check
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
),
DropdownButton<AssistantEmployees>(
value: _selectedStatus,
dropdownColor: AppColor.white10,
iconSize: 24,
isDense: true,
icon: const SizedBox.shrink(),
elevation: 0,
isExpanded: true,
hint: Text(
context.translation.select,
style: Theme.of(context).textTheme.bodyLarge,
),
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20),
underline: const SizedBox.shrink(),
onChanged: widget.enable
? (AssistantEmployees? newValue) {
// Now accepts nullable values
setState(() {
_selectedStatus = newValue;
});
widget.onSelect(newValue);
}
: null,
items: widget.statuses.map<DropdownMenuItem<AssistantEmployees>>(
(AssistantEmployees value) {
return DropdownMenuItem<AssistantEmployees>(
value: value,
child: Text(
value.user?.name ?? "NULL", // Use null-aware operator for user.name
style: AppTextStyles.bodyText.copyWith(color: AppColor.black20),
),
);
},
).toList(),
).onPress(widget.showAsBottomSheet!
? () async {
final selectedT = await showModalBottomSheet<AssistantEmployees?>(
// Specify return type
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
builder: (BuildContext context) => SelectionBottomSheet<AssistantEmployees>(
// Specify generic type
items:
(Provider.of<ServiceReportAssistantsEmployeeProvider>(context, listen: false).assistantEmployees as List<AssistantEmployees>) ?? [], // Provide default empty list if null
selectedItem: _selectedStatus,
// title: widget.title,
builderString: (emp) => emp?.name ?? "", // Null-aware operator for emp.name
),
);
if (selectedT != null) {
widget.onSelect!(selectedT); // Non-null assertion after null check
}
}
: null),
],
),
],
),
);
}
} }
}

@ -13,8 +13,9 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
final String title; final String title;
final num assetId; final num assetId;
final bool enable; final bool enable;
bool showAsBottomSheet;
ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue, required this.assetId, this.backgroundColor, this.enable = true}) ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue,this.showAsBottomSheet=false, required this.assetId, this.backgroundColor, this.enable = true})
: super(key: key); : super(key: key);
@override @override
@ -32,6 +33,7 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
title: title, title: title,
statuses: menuProvider.assistantEmployees ?? [], statuses: menuProvider.assistantEmployees ?? [],
backgroundColor: backgroundColor, backgroundColor: backgroundColor,
showAsBottomSheet: showAsBottomSheet,
// Provide an empty list if null // Provide an empty list if null
onSelect: onSelect, onSelect: onSelect,
// Pass onSelect directly // Pass onSelect directly

Loading…
Cancel
Save