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/string_extensions.dart ' ;
import ' package:test_sa/extensions/text_extensions.dart ' ;
import ' package:test_sa/extensions/widget_extensions.dart ' ;
import ' package:test_sa/helper/utils.dart ' ;
import ' package:test_sa/models/enums/user_types.dart ' ;
import ' package:test_sa/models/enums/work_order_next_step.dart ' ;
import ' package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart ' ;
import ' package:test_sa/modules/cm_module/cm_detail_provider.dart ' ;
import ' package:test_sa/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart ' ;
import ' package:test_sa/modules/cx_module/chat/chat_provider.dart ' ;
import ' package:test_sa/modules/cx_module/chat/chat_widget.dart ' ;
import ' package:test_sa/modules/export_module/provider/export_provider.dart ' ;
import ' package:test_sa/modules/export_module/widgets/file_success_dialog.dart ' ;
import ' package:test_sa/modules/loan_module/pages/create_loan_request_page.dart ' ;
import ' package:test_sa/modules/loan_module/pages/loan_equipment_detail_page.dart ' ;
import ' package:test_sa/modules/loan_module/provider/loan_provider.dart ' ;
import ' package:test_sa/new_views/app_style/app_color.dart ' ;
import ' package:test_sa/new_views/common_widgets/default_app_bar.dart ' ;
import ' views/components/history_log_view.dart ' ;
import ' views/components/service_request_detail_view.dart ' ;
class CMDetailPage extends StatefulWidget {
final int requestId ;
final int moduleId ;
CMDetailPage ( { Key ? key , required this . requestId , required this . moduleId } ) : super ( key: key ) ;
@ override
_CMDetailPageState createState ( ) {
return _CMDetailPageState ( ) ;
}
}
class _CMDetailPageState extends State < CMDetailPage > {
late CMDetailProvider _requestProvider ;
static const int moduleId = 1 ;
@ override
void initState ( ) {
super . initState ( ) ;
_requestProvider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
WidgetsBinding . instance . addPostFrameCallback ( ( _ ) {
Provider . of < ChatProvider > ( context , listen: false ) . reset ( ) ;
getInitialData ( ) ;
} ) ;
}
Future < void > getInitialData ( ) async {
bool isNurse = ( Provider . of < UserProvider > ( context , listen: false ) . user ? . type ) = = UsersTypes . normal_user ;
_requestProvider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
await _requestProvider . getWorkOrderById ( id: widget . requestId ) ;
if ( isNurse & & ( _requestProvider . currentWorkOrder ? . data ? . nextStep ? . workOrderNextStepEnum = = WorkOrderNextStepEnum . waitingForRequesterToConfirm ) ) {
ServiceRequestBottomSheet . nurseVerifyArrivalBottomSheet ( context: context ) ;
}
_requestProvider . needVisitHelperModel = NeedVisitHelperModel (
workOrderId: _requestProvider . currentWorkOrder ? . data ? . requestId ,
visitDate: _requestProvider . currentWorkOrder ? . data ? . needAVisitDateTime ,
comment: _requestProvider . currentWorkOrder ? . data ? . needAVisitComment ,
) ;
}
@ override
void dispose ( ) {
super . dispose ( ) ;
}
Future < void > stopTimer ( ) async {
CMDetailProvider requestDetailProvider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
if ( requestDetailProvider . timer ! = null & & requestDetailProvider . timer ! . isActive ) {
requestDetailProvider . stopTimer ( ) ;
}
}
@ override
Widget build ( BuildContext context ) {
bool isNurse = ( Provider . of < UserProvider > ( context , listen: false ) . user ? . type ) = = UsersTypes . normal_user ;
return WillPopScope (
onWillPop: ( ) async {
stopTimer ( ) ;
return true ;
} ,
child: Scaffold (
backgroundColor: Theme . of ( context ) . scaffoldBackgroundColor ,
appBar: DefaultAppBar (
title: context . translation . cmDetails ,
onBackPress: ( ) {
stopTimer ( ) ;
Navigator . pop ( context ) ;
} ,
actions: [
Selector < CMDetailProvider , bool > (
selector: ( _ , myModel ) = > myModel . isLoading , // Selects only the userName
builder: ( _ , isLoading , __ ) {
if ( isLoading ) {
return const SizedBox ( ) ;
} else {
CMDetailProvider provider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
if ( ( context . userProvider . isEngineer | | context . userProvider . isNurse ) & &
provider . currentWorkOrder ? . data ? . assignedEmployee ! = null & &
( provider . currentWorkOrder ? . data ? . workOrderContactPerson ? . isNotEmpty ? ? false ) ) {
return ChatWidget (
moduleId: widget . moduleId ,
isShow: context . settingProvider . isUserFlowMedical & &
( context . userProvider . isEngineer | | context . userProvider . isNurse ) & &
provider . currentWorkOrder ? . data ? . assignedEmployee ! = null ,
isReadOnly: _requestProvider . isReadOnlyRequest ,
requestId: widget . requestId . toInt ( ) ,
assigneeEmployeeNumber: provider . currentWorkOrder ? . data ? . assignedEmployee ! . employeeId ! ,
myLoginUserID: context . userProvider . user ! . employeeId ? ? context . userProvider . user ! . username ! ,
contactEmployeeINumber: provider . currentWorkOrder ? . data ? . workOrderContactPerson . first . employeeId ,
) ;
}
return const SizedBox ( ) ;
}
} ) ,
if ( isNurse )
IconButton (
icon: ' qr ' . toSvgAsset ( height: 24 , width: 24 ) ,
onPressed: ( ) {
ServiceRequestBottomSheet . getQRCodeBottomSheet ( context: context ) ;
} ,
)
else . . . [
Selector < CMDetailProvider , bool > (
selector: ( _ , myModel ) = > myModel . isLoading , // Selects only the userName
builder: ( _ , isLoading , __ ) {
if ( isLoading ) {
return const SizedBox ( ) ;
} else {
CMDetailProvider provider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
//TODO need to verify the check with backend workOrderNextStepEnum
int ? statusValue = provider . currentWorkOrder ? . data ? . status ? . value ;
WorkOrderNextStepEnum ? workOrderNextStepEnum = provider . currentWorkOrder ? . data ? . nextStep ? . workOrderNextStepEnum ;
if ( statusValue = = 2 & & workOrderNextStepEnum = = WorkOrderNextStepEnum . activity ) {
return Container (
padding: const EdgeInsets . symmetric ( vertical: 4 , horizontal: 6 ) ,
margin: const EdgeInsets . only ( left: 2 ) ,
decoration: BoxDecoration ( color: AppColor . background ( context ) , border: Border . all ( color: AppColor . border2Color ( context ) ) , borderRadius: BorderRadius . circular ( 16 ) ) ,
child: Row (
mainAxisSize: MainAxisSize . min ,
children: [
Icon ( Icons . add , size: 20 , color: AppColor . textStyleColor ( context ) ) ,
Text (
" Loan " ,
style: AppTextStyles . bodyText2 . copyWith ( color: AppColor . textStyleColor ( context ) ) ,
) ,
4. width ,
] ,
) ,
) . onPress ( ( ) async {
LoanProvider loanProvider = Provider . of < LoanProvider > ( context , listen: false ) ;
Utils . showLoading ( context ) ;
var data = await loanProvider . getLoanByWorkOrderId ( widget . requestId ) ;
Utils . hideLoading ( context ) ;
if ( data = = null ) {
CMDetailProvider cmProvider = Provider . of < CMDetailProvider > ( context , listen: false ) ;
Navigator . push ( context , MaterialPageRoute ( builder: ( context ) = > CreateLoanRequestPage ( workOrderId: widget . requestId , workOrder: cmProvider . currentWorkOrder ! . data ) ) ) ;
} else {
Navigator . push ( context , MaterialPageRoute ( builder: ( context ) = > LoanEquipmentDetailPage ( loanId: data . id ! ) ) ) ;
}
} ) ;
}
return const SizedBox ( ) ;
}
} ) ,
// Print Button
IconButton (
icon: " download " . toSvgAsset ( height: 24 , width: 24 , color: AppColor . icon2Color ( context ) ) ,
padding: EdgeInsets . zero ,
onPressed: _handlePrint ,
) ,
IconButton (
icon: const Icon ( Icons . home ) ,
onPressed: ( ) {
// stopTimer();
Navigator . pop ( context ) ;
} ,
)
] ,
] ,
) ,
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: AppColor . tabBarBackground ( context ) ,
border: Border . all ( color: AppColor . tabBarBorder ( context ) ) ,
borderRadius: BorderRadius . circular ( 20 ) ,
) ,
child: TabBar (
//controller: _tabController,
padding: EdgeInsets . symmetric ( vertical: 6. toScreenHeight , horizontal: 6. 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 ,
overlayColor: WidgetStateProperty . all ( Colors . transparent ) ,
indicator: BoxDecoration (
color: AppColor . background ( context ) ,
borderRadius: BorderRadius . circular ( 15 ) ,
boxShadow: [ BoxShadow ( color: Colors . black . withOpacity ( 0.03 ) , blurRadius: 5 , offset: const Offset ( 0 , 0 ) , spreadRadius: 0 ) ] ) ,
onTap: ( index ) {
// setState(() {});
} ,
tabs: [
Tab ( text: context . translation . details , height: 57. toScreenHeight ) ,
Tab ( text: context . translation . historyLogs , height: 57. toScreenHeight ) ,
] ,
) ,
) ,
12. height ,
TabBarView (
children: [
ServiceRequestDetailView ( ) ,
const HistoryLogView ( ) ,
] ,
) . expanded ,
] ,
) ,
) ) ,
) ;
}
void getChatToken ( int moduleId , String title ) {
ChatProvider cProvider = Provider . of < ChatProvider > ( context , listen: false ) ;
if ( cProvider . chatLoginResponse ! = null & & cProvider . referenceID = = widget . requestId ) return ;
String assigneeEmployeeNumber = Provider . of < CMDetailProvider > ( context , listen: false ) . currentWorkOrder ? . data ? . assignedEmployee ? . employeeId ? ? " " ;
String myEmployeeId = context . userProvider . user ! . username ! ;
String receiver = context . userProvider . isNurse
? assigneeEmployeeNumber
: ( context . userProvider . isEngineer
? ( Provider . of < CMDetailProvider > ( context , listen: false ) . currentWorkOrder ! . data ! . workOrderContactPerson . isEmpty
? Provider . of < CMDetailProvider > ( context , listen: false ) . currentWorkOrder ! . data ! . workOrderCreatedBy ! . employeeId !
: Provider . of < CMDetailProvider > ( context , listen: false ) . currentWorkOrder ! . data ! . workOrderContactPerson . first . employeeId ! )
: " " ) ;
cProvider . getUserAutoLoginTokenSilent ( moduleId , widget . requestId , title , myEmployeeId , receiver ) ;
}
/// Handle print button press
Future < void > _handlePrint ( ) async {
try {
final exportProvider = Provider . of < ExportApiProvider > ( context , listen: false ) ;
final filePath = await exportProvider . printWorkOrder (
widget . requestId ,
widget . moduleId ,
context ,
) ;
if ( filePath ! = null ) {
// Show success dialog using the reusable FileSuccessDialog widget
await FileSuccessDialog . show ( context: context , filePath: filePath , title: ' Export Successful ' , message: ' Your PDF has been generated successfully ' , logPrefix: ' printed ' ) ;
} else if ( exportProvider . errorMessage ! = null ) {
if ( mounted ) {
exportProvider . errorMessage ? . showToast ;
}
}
} catch ( error ) {
if ( mounted ) {
' Print Failed ' . showToast ;
}
}
}
}