improvements

design_3.0_task_module_new
Sikander Saleem 4 months ago
parent 116855878b
commit c92aae9048

@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart'; import 'package:test_sa/new_views/swipe_module/dialoge/confirm_dialog.dart';
import '../controllers/providers/settings/setting_provider.dart';
import '../controllers/providers/settings/setting_provider.dart'; import '../controllers/providers/settings/setting_provider.dart';
extension BuildContextExtension on BuildContext { extension BuildContextExtension on BuildContext {
@ -17,6 +17,7 @@ extension BuildContextExtension on BuildContext {
bool get isAr => Provider.of<SettingProvider>(this).language == "ar"; bool get isAr => Provider.of<SettingProvider>(this).language == "ar";
SettingProvider get settingProvider => Provider.of<SettingProvider>(this, listen: false); SettingProvider get settingProvider => Provider.of<SettingProvider>(this, listen: false);
UserProvider get userProvider => Provider.of<UserProvider>(this, listen: false); UserProvider get userProvider => Provider.of<UserProvider>(this, listen: false);
void showConfirmDialog(String message, {String? title, VoidCallback? onTap}) => showDialog( void showConfirmDialog(String message, {String? title, VoidCallback? onTap}) => showDialog(
@ -26,4 +27,13 @@ extension BuildContextExtension on BuildContext {
onTap: onTap, onTap: onTap,
), ),
); );
void showBottomSheet(Widget childWidget, {bool? isDismissible, String? title}) => showModalBottomSheet(
context: this,
useSafeArea: true,
isScrollControlled: true,
isDismissible: true,
backgroundColor: Colors.transparent,
builder: (context) => SingleChildScrollView(padding: const EdgeInsets.all(0), child: childWidget.bottomSafeArea).bottomSheetContainerNew(context, title: title),
);
} }

@ -21,8 +21,10 @@ extension WidgetExtensions on Widget {
Widget paddingAll(double value) => Padding(padding: EdgeInsets.all(value), child: this); Widget paddingAll(double value) => Padding(padding: EdgeInsets.all(value), child: this);
Widget get bottomSafeArea => SafeArea(bottom: true, top: false, right: false, left: false, child: this);
Widget indicatorWidget({double? height, double? width, Color? color}) => Container( Widget indicatorWidget({double? height, double? width, Color? color}) => Container(
width: height ?? 40.toScreenWidth, width: height ?? 50.toScreenWidth,
height: width ?? 5.toScreenHeight, height: width ?? 5.toScreenHeight,
decoration: BoxDecoration(color: color ?? AppColor.white50, borderRadius: BorderRadius.circular(30)), decoration: BoxDecoration(color: color ?? AppColor.white50, borderRadius: BorderRadius.circular(30)),
child: this, child: this,
@ -55,24 +57,26 @@ extension WidgetExtensions on Widget {
Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this); Widget toExpanded({int flex = 1}) => Expanded(flex: flex, child: this);
Widget handlePopScope({required BuildContext cxt, required VoidCallback onSave, bool? showPopUp =true}) { Widget handlePopScope({required BuildContext cxt, required VoidCallback onSave, bool? showPopUp = true}) {
return showPopUp! ? PopScope( return showPopUp!
canPop: false, ? PopScope(
onPopInvokedWithResult: (didPop, result) { canPop: false,
if (didPop) { onPopInvokedWithResult: (didPop, result) {
return; if (didPop) {
} return;
showDialog( }
context: cxt, showDialog(
builder: (BuildContext cxt) => AcknowledgeWorkDialog( context: cxt,
onSave: () => onSave(), builder: (BuildContext cxt) => AcknowledgeWorkDialog(
onDiscard: () { onSave: () => onSave(),
Navigator.of(cxt).pop(); onDiscard: () {
}, Navigator.of(cxt).pop();
), },
); ),
}, );
child: this): this; },
child: this)
: this;
} }
Widget toShimmer({bool isShow = true, double radius = 20}) => isShow Widget toShimmer({bool isShow = true, double radius = 20}) => isShow
@ -128,6 +132,33 @@ extension WidgetExtensions on Widget {
child: this, child: this,
); );
Widget bottomSheetContainerNew(BuildContext context, {EdgeInsets? padding, String? title}) => Container(
clipBehavior: Clip.antiAlias,
margin: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: const BorderRadius.only(topRight: Radius.circular(30), topLeft: Radius.circular(30)),
),
padding: padding ?? EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 12.toScreenHeight),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 50.toScreenWidth,
height: 6.toScreenHeight,
decoration: BoxDecoration(color: AppColor.white50, borderRadius: BorderRadius.circular(30)),
).center,
16.height,
if (title != null) ...[
title.bottomSheetHeadingTextStyle(context),
16.height,
],
this
],
),
);
Widget toShadowCircleContainer(BuildContext context, {bool showShadow = true, double padding = 16}) => showShadow Widget toShadowCircleContainer(BuildContext context, {bool showShadow = true, double padding = 16}) => showShadow
? Container( ? Container(
padding: EdgeInsets.all(padding), padding: EdgeInsets.all(padding),

@ -24,13 +24,11 @@ import 'package:test_sa/providers/service_request_providers/reject_reason_provid
class FooterActionButton { class FooterActionButton {
static Widget footerContainer({required Widget child}) { static Widget footerContainer({required Widget child}) {
return Align( return Container(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: Container( padding: const EdgeInsets.only(left: 16, right: 16, top: 12,bottom: 8),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 16.toScreenHeight), color: AppColor.white10,
color: AppColor.white10, child: SafeArea(child: child),
child: child,
),
); );
} }

@ -41,7 +41,7 @@ class ServiceRequestBottomSheet {
isDismissible: isDismissible ?? true, isDismissible: isDismissible ?? true,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: (context) => SingleChildScrollView( builder: (context) => SingleChildScrollView(
child: childWidget, child: SafeArea(child: childWidget),
).bottomSheetContainer(context), ).bottomSheetContainer(context),
); );
} }
@ -636,13 +636,8 @@ class ServiceRequestBottomSheet {
{'heading': context.translation.requestSparePart, 'subHeading': context.translation.requestSparePartForYourAsset, 'icon': AppAsset.sparePartIcon}, {'heading': context.translation.requestSparePart, 'subHeading': context.translation.requestSparePartForYourAsset, 'icon': AppAsset.sparePartIcon},
{'heading': context.translation.addNewActivity, 'subHeading': context.translation.addNewActivityToYourWorkOrder, 'icon': AppAsset.maintenanceIcon}, {'heading': context.translation.addNewActivity, 'subHeading': context.translation.addNewActivityToYourWorkOrder, 'icon': AppAsset.maintenanceIcon},
]; ];
Widget customListItem({
required BuildContext context, Widget customListItem({required BuildContext context, required String icon, required String heading, required String subHeading, required VoidCallback onTap}) {
required String icon,
required String heading,
required String subHeading,
required VoidCallback onTap,
}) {
return GestureDetector( return GestureDetector(
onTap: onTap, // Handles the tap onTap: onTap, // Handles the tap
child: Card( child: Card(
@ -654,13 +649,7 @@ class ServiceRequestBottomSheet {
crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top
children: [ children: [
// Icon Section // Icon Section
icon icon.toSvgAsset(width: 26, color: AppColor.neutral120, height: 29).paddingOnly(top: 8),
.toSvgAsset(
width: 26,
color: AppColor.neutral120,
height: 29,
)
.paddingOnly(top: 8),
14.width, 14.width,
Expanded( Expanded(
child: Column( child: Column(
@ -725,6 +714,7 @@ class ServiceRequestBottomSheet {
shrinkWrap: true, shrinkWrap: true,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
itemCount: items.length, itemCount: items.length,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = items[index]; final item = items[index];
return customListItem( return customListItem(

@ -346,8 +346,9 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
files: _userAttachments, files: _userAttachments,
buttonColor: AppColor.primary10, buttonColor: AppColor.primary10,
onlyImages: false, onlyImages: false,
// showAsGrid: true,
buttonIcon: 'quotation_icon'.toSvgAsset(color: AppColor.primary10), buttonIcon: 'quotation_icon'.toSvgAsset(color: AppColor.primary10),
onChange: (attachment) { onChange: () {
requestProvider.addWorkOrderAttachment(woId: workOrder.requestId!, attachments: _userAttachments, otherAttachment: _attachments); requestProvider.addWorkOrderAttachment(woId: workOrder.requestId!, attachments: _userAttachments, otherAttachment: _attachments);
}, },
), ),

@ -58,7 +58,7 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
save(requestDetailProvider); save(requestDetailProvider);
}, },
), ),
body: Stack( body: Column(
children: [ children: [
DefaultTabController( DefaultTabController(
length: 2, length: 2,
@ -99,7 +99,7 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
).expanded, ).expanded,
], ],
), ),
), ).expanded,
if (!requestDetailProvider.isReadOnlyRequest) if (!requestDetailProvider.isReadOnlyRequest)
FooterActionButton.footerContainer( FooterActionButton.footerContainer(
child: AppFilledButton( child: AppFilledButton(

@ -7,6 +7,7 @@ import 'package:test_sa/extensions/string_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/extensions/widget_extensions.dart';
import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart'; import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -60,74 +61,77 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
// ppmProvider!.getPlanPreventiveVisitById(widget.request.id!); // ppmProvider!.getPlanPreventiveVisitById(widget.request.id!);
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance), appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea( body: Consumer<PpmProvider>(builder: (context, ppmProvider, child) {
child: Consumer<PpmProvider>(builder: (context, ppmProvider, child) { PlanPreventiveVisit? planPreventiveVisit = ppmProvider.planPreventiveVisit;
PlanPreventiveVisit? planPreventiveVisit = ppmProvider.planPreventiveVisit; return ppmProvider.isLoading
return ppmProvider.isLoading ? const ALoading()
? const ALoading() : planPreventiveVisit != null
:planPreventiveVisit!=null? Column(children: [ ? Column(children: [
SingleChildScrollView( SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Row(
children: [ children: [
// if (widget.request.priority != null) // if (widget.request.priority != null)
// StatusLabel( // StatusLabel(
// label: widget.request.priority, // label: widget.request.priority,
// textColor: AppColor.getRequestStatusTextColorByName(context, widget.request.priority!), // textColor: AppColor.getRequestStatusTextColorByName(context, widget.request.priority!),
// backgroundColor: AppColor.getRequestStatusColorByName(context, widget.request.priority!), // backgroundColor: AppColor.getRequestStatusColorByName(context, widget.request.priority!),
// ), // ),
// if (planPreventiveVisit?.visitStatus != null) 8.width, // if (planPreventiveVisit?.visitStatus != null) 8.width,
StatusLabel( StatusLabel(
label: planPreventiveVisit?.visitStatus!.name!, label: planPreventiveVisit?.visitStatus!.name!,
id: planPreventiveVisit?.visitStatus?.id??0, id: planPreventiveVisit?.visitStatus?.id ?? 0,
textColor: AppColor.getRequestStatusTextColorByName(context, planPreventiveVisit.visitStatus!.name!), textColor: AppColor.getRequestStatusTextColorByName(context, planPreventiveVisit.visitStatus!.name!),
backgroundColor: AppColor.getRequestStatusColorByName(context, planPreventiveVisit.visitStatus!.name!), backgroundColor: AppColor.getRequestStatusColorByName(context, planPreventiveVisit.visitStatus!.name!),
), ),
// 1.width.expanded, // 1.width.expanded,
], ],
),
8.height,
planPreventiveVisit.assetName!.cleanupWhitespace.capitalizeFirstOfEach.heading5(context),
8.height,
'${context.translation.assetNumber}: ${planPreventiveVisit.asset!.assetNumber}'.bodyText(context),
'${context.translation.assetSN}: ${planPreventiveVisit.asset!.assetSerialNo}'.bodyText(context),
'${context.translation.requestNo}: ${planPreventiveVisit.visitNo}'.bodyText(context),
const Divider().defaultStyle(context),
// '${context.translation.expectDate}: ${planPreventiveVisit.expectedDate?.toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.actualDate}: ${planPreventiveVisit.acutalDateOfVisit?.toIso8601String().toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
const Divider().defaultStyle(context),
'${context.translation.assignedEmployee}: ${planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.site}: ${planPreventiveVisit.siteName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.building}: ${planPreventiveVisit.buildingName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.floor}: ${planPreventiveVisit.floorName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.department}: ${planPreventiveVisit.departmentName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
'${context.translation.room}: ${(planPreventiveVisit.roomName ?? "").cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
],
).toShadowContainer(context).paddingAll(16),
).expanded,
if (userProvider!.user!.type == UsersTypes.engineer && (!ppmProvider.isReadOnly)) ...[
FooterActionButton.footerContainer(
child: AppFilledButton(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit)));
getVisitData();
},
label: context.translation.updateWorkOrder,
), ),
8.height, )
planPreventiveVisit.assetName!.cleanupWhitespace.capitalizeFirstOfEach.heading5(context), ] else ...[
8.height, FooterActionButton.footerContainer(
'${context.translation.assetNumber}: ${planPreventiveVisit.asset!.assetNumber}'.bodyText(context), child: AppFilledButton(
'${context.translation.assetSN}: ${planPreventiveVisit.asset!.assetSerialNo}'.bodyText(context), onPressed: () async {
'${context.translation.requestNo}: ${planPreventiveVisit.visitNo}'.bodyText(context), await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit)));
const Divider().defaultStyle(context), getVisitData();
// '${context.translation.expectDate}: ${planPreventiveVisit.expectedDate?.toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha, },
'${context.translation.actualDate}: ${planPreventiveVisit.acutalDateOfVisit?.toIso8601String().toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha, label: context.translation.viewDetails,
const Divider().defaultStyle(context), ),
'${context.translation.assignedEmployee}: ${planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText(context), //todo @baha, )
'${context.translation.site}: ${planPreventiveVisit.siteName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha, ]
'${context.translation.building}: ${planPreventiveVisit.buildingName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha, ])
'${context.translation.floor}: ${planPreventiveVisit.floorName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha, : const Center(child: NoDataFound());
'${context.translation.department}: ${planPreventiveVisit.departmentName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha, }),
'${context.translation.room}: ${(planPreventiveVisit.roomName ?? "").cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
],
).toShadowContainer(context).paddingAll(16),
).expanded,
if (userProvider!.user!.type == UsersTypes.engineer && (!ppmProvider.isReadOnly))...[
AppFilledButton(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit)));
getVisitData();
},
label: context.translation.updateWorkOrder,
).paddingAll(16)
]
else ...[
AppFilledButton(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit)));
getVisitData();
},
label: context.translation.viewDetails,
).paddingAll(16)
]
]):const Center(child: NoDataFound());
}),
),
); );
} }
} }

@ -12,10 +12,12 @@ import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart'; import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart';
import 'package:test_sa/models/ppm/ppm.dart'; import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart'; import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.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/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'ppm_calibration_tools_form.dart'; import 'ppm_calibration_tools_form.dart';
import 'ppm_external_details_form.dart'; import 'ppm_external_details_form.dart';
import 'ppm_pm_check_list_form.dart'; import 'ppm_pm_check_list_form.dart';
@ -132,74 +134,74 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
}, },
), ),
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: Column(
child: Column( children: [
children: [ DefaultTabController(
DefaultTabController( length: 2,
length: 2, child: Column(
child: Column( mainAxisSize: MainAxisSize.min,
mainAxisSize: MainAxisSize.min, children: <Widget>[
children: <Widget>[ Container(
Container( margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 16.toScreenHeight, bottom: 8),
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 16.toScreenHeight, bottom: 8), decoration: BoxDecoration(
decoration: BoxDecoration( color: context.isDark ? AppColor.neutral50 : AppColor.white10,
color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10),
borderRadius: BorderRadius.circular(10), ),
), child: TabBar(
child: TabBar( padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, unselectedLabelStyle: AppTextStyles.bodyText,
unselectedLabelStyle: AppTextStyles.bodyText, labelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText, indicatorPadding: EdgeInsets.zero,
indicatorPadding: EdgeInsets.zero, indicatorSize: TabBarIndicatorSize.tab,
indicatorSize: TabBarIndicatorSize.tab, dividerColor: Colors.transparent,
dividerColor: Colors.transparent, indicator: BoxDecoration(
indicator: BoxDecoration( color: context.isDark ? AppColor.neutral60 : AppColor.neutral110,
color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7),
borderRadius: BorderRadius.circular(7),
),
onTap: (index) {
tabIndex = index;
if (tabIndex == 0) {
_tabController?.animateTo(0);
}
setState(() {});
},
tabs: [
Tab(text: "WO Info".addTranslation, height: 57.toScreenHeight),
Tab(text: "WO Inspection".addTranslation, height: 57.toScreenHeight),
],
), ),
onTap: (index) {
tabIndex = index;
if (tabIndex == 0) {
_tabController?.animateTo(0);
}
setState(() {});
},
tabs: [
Tab(text: "WO Info".addTranslation, height: 57.toScreenHeight),
Tab(text: "WO Inspection".addTranslation, height: 57.toScreenHeight),
],
), ),
TabBarView( ),
physics: const NeverScrollableScrollPhysics(), TabBarView(
children: [ physics: const NeverScrollableScrollPhysics(),
WoInfoForm( children: [
planPreventiveVisit: _planPreventiveVisit, WoInfoForm(
onTypeOfServiceChange: (selectedTypeOfService) { planPreventiveVisit: _planPreventiveVisit,
initTabs(selectedTypeOfService); onTypeOfServiceChange: (selectedTypeOfService) {
}), initTabs(selectedTypeOfService);
TabBarView( }),
physics: const NeverScrollableScrollPhysics(), TabBarView(
controller: _tabController, physics: const NeverScrollableScrollPhysics(),
children: [ controller: _tabController,
if (ppmProvider.totalTabs == 4) ...[ children: [
PpmExternalDetailsForm( if (ppmProvider.totalTabs == 4) ...[
models: _planPreventiveVisit.preventiveVisitSuppliers, PpmExternalDetailsForm(
), models: _planPreventiveVisit.preventiveVisitSuppliers,
], ),
PpmCalibrationToolsForm(models: _planPreventiveVisit.preventiveVisitCalibrations),
PpmPMKitsForm(models: _planPreventiveVisit.preventiveVisitKits, assetId: _planPreventiveVisit.asset?.id),
PpmPmChecklistForm(checkList: _planPreventiveVisit.preventiveVisitChecklists),
], ],
) PpmCalibrationToolsForm(models: _planPreventiveVisit.preventiveVisitCalibrations),
], PpmPMKitsForm(models: _planPreventiveVisit.preventiveVisitKits, assetId: _planPreventiveVisit.asset?.id),
).expanded, PpmPmChecklistForm(checkList: _planPreventiveVisit.preventiveVisitChecklists),
], ],
), )
).expanded, ],
Row( ).expanded,
],
),
).expanded,
FooterActionButton.footerContainer(
child: Row(
children: [ children: [
if (tabIndex == 1) ...[ if (tabIndex == 1) ...[
AppFilledButton( AppFilledButton(
@ -261,9 +263,9 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
), ),
] ]
], ],
).toShadowContainer(context, showShadow: false, borderRadius: 0), ),
], ),
), ],
), ),
).handlePopScope( ).handlePopScope(
cxt: context, cxt: context,

@ -26,6 +26,7 @@ class _RoomTabsWidgetState extends State<RoomTabsWidget> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
Container( Container(
padding: EdgeInsets.all(8.toScreenHeight), padding: EdgeInsets.all(8.toScreenHeight),

@ -58,9 +58,10 @@ class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
body: allRequestsProvider!.isLoading body: allRequestsProvider!.isLoading
? const ALoading() ? const ALoading()
: requestProvider.recurrentWoData != null : requestProvider.recurrentWoData != null
? Stack( ? Column(
children: [ children: [
SingleChildScrollView( SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -75,8 +76,8 @@ class _RecurrentWorkOrderViewState extends State<RecurrentWorkOrderView> {
) )
: const SizedBox(), : const SizedBox(),
], ],
).paddingAll(12), ),
).paddingOnly(bottom: 85), ).expanded,
if (requestProvider.recurrentWoData?.status?.value != 1) ...[ if (requestProvider.recurrentWoData?.status?.value != 1) ...[
FooterActionButton.footerContainer( FooterActionButton.footerContainer(
child: Row( child: Row(

@ -8,6 +8,7 @@ import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/new_models/task_request/task_request_model.dart'; import 'package:test_sa/models/new_models/task_request/task_request_model.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/providers/task_request_provider/task_request_provider.dart'; import 'package:test_sa/providers/task_request_provider/task_request_provider.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
@ -61,90 +62,90 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
userProvider ??= Provider.of<UserProvider>(context, listen: false); userProvider ??= Provider.of<UserProvider>(context, listen: false);
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.taskRequest), appBar: DefaultAppBar(title: context.translation.taskRequest),
body: SafeArea( body: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) {
child: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) { TaskData? taskModel = taskProvider.taskRequestModel;
TaskData? taskModel = taskProvider.taskRequestModel; return taskProvider.isLoading
return taskProvider.isLoading ? const ALoading()
? const ALoading() : Column(children: [
: Column(children: [ SingleChildScrollView(
SingleChildScrollView( child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ Row(
Row( crossAxisAlignment: CrossAxisAlignment.start,
children: [
StatusLabel(
label: widget.requestDetails?.priority!,
textColor: AppColor.getRequestStatusTextColorByName(context, widget.requestDetails?.priority!),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.requestDetails?.priority!),
),
8.width,
StatusLabel(
label: widget.requestDetails?.status!,
textColor: AppColor.getRequestStatusTextColorByName(context, widget.requestDetails?.status!),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.requestDetails?.status!),
),
1.width.expanded,
Text(
widget.requestDetails?.date?.toServiceRequestCardFormat ?? "-",
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
],
),
8.height,
if (taskProvider.taskRequestModel?.taskType?.relatedTo?.value == 1) ...[
assetDetails(taskModel: taskProvider.taskRequestModel!),
],
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)],
if (taskProvider.taskRequestModel?.taskType?.relatedTo?.value == 2) ...[
linkWithLocationWidget(taskModel: taskProvider.taskRequestModel!),
],
const Divider().defaultStyle(context),
Text(
"Task Details".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
'${context.translation.taskType}: ${taskModel?.taskType?.typeName ?? "-"}'.bodyText(context),
'${context.translation.taskNo}: ${taskModel?.taskJobNo ?? "-"}'.bodyText(context),
'${context.translation.createdBy}: ${taskModel?.userCreated?.userName ?? "-"}'.bodyText(context),
if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[
recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!),
Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
StatusLabel( 'Type of alert: ${taskProvider.taskRequestModel?.typeOfAlert?.name ?? '-'}'.bodyText(context),
label: widget.requestDetails?.priority!, 'Risk Level: ${taskProvider.taskRequestModel?.riskLevel?.name ?? '-'}'.bodyText(context),
textColor: AppColor.getRequestStatusTextColorByName(context, widget.requestDetails?.priority!), 'Resource: ${taskProvider.taskRequestModel?.resource?.name ?? '-'}'.bodyText(context),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.requestDetails?.priority!), 'Evaluator User: ${taskProvider.taskRequestModel?.evaluatorUser?.userName ?? '-'}'.bodyText(context)
),
8.width,
StatusLabel(
label: widget.requestDetails?.status!,
textColor: AppColor.getRequestStatusTextColorByName(context, widget.requestDetails?.status!),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.requestDetails?.status!),
),
1.width.expanded,
Text(
widget.requestDetails?.date?.toServiceRequestCardFormat ?? "-",
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
], ],
), ),
],
if (taskProvider.taskRequestModel?.callComment != null) ...[
const Divider().defaultStyle(context),
Text(
context.translation.comment,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
2.height,
taskProvider.taskRequestModel!.callComment!.bodyText(context),
],
if (taskProvider.taskRequestModel?.taskJobAttachments?.isNotEmpty ?? false) ...[
8.height, 8.height,
if (taskProvider.taskRequestModel?.taskType?.relatedTo?.value == 1) ...[
assetDetails(taskModel: taskProvider.taskRequestModel!),
],
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)],
if (taskProvider.taskRequestModel?.taskType?.relatedTo?.value == 2) ...[
linkWithLocationWidget(taskModel: taskProvider.taskRequestModel!),
],
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
Text( Text(
"Task Details".addTranslation, "Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
), ),
'${context.translation.taskType}: ${taskModel?.taskType?.typeName ?? "-"}'.bodyText(context), FilesList(images: taskProvider.taskRequestModel!.taskJobAttachments!.map((toElement) => URLs.getFileUrl(toElement.name ?? '') ?? '').toList()),
'${context.translation.taskNo}: ${taskModel?.taskJobNo ?? "-"}'.bodyText(context),
'${context.translation.createdBy}: ${taskModel?.userCreated?.userName ?? "-"}'.bodyText(context),
if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[
recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
'Type of alert: ${taskProvider.taskRequestModel?.typeOfAlert?.name ?? '-'}'.bodyText(context),
'Risk Level: ${taskProvider.taskRequestModel?.riskLevel?.name ?? '-'}'.bodyText(context),
'Resource: ${taskProvider.taskRequestModel?.resource?.name ?? '-'}'.bodyText(context),
'Evaluator User: ${taskProvider.taskRequestModel?.evaluatorUser?.userName ?? '-'}'.bodyText(context)
],
),
],
if (taskProvider.taskRequestModel?.callComment != null) ...[
const Divider().defaultStyle(context),
Text(
context.translation.comment,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
2.height,
taskProvider.taskRequestModel!.callComment!.bodyText(context),
],
if (taskProvider.taskRequestModel?.taskJobAttachments?.isNotEmpty ?? false) ...[
8.height,
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
FilesList(images: taskProvider.taskRequestModel!.taskJobAttachments!.map((toElement) => URLs.getFileUrl(toElement.name ?? '') ?? '').toList()),
],
buildTechnicalComments(taskModel: taskModel),
], ],
).toShadowContainer(context).paddingAll(16), buildTechnicalComments(taskModel: taskModel),
).expanded, ],
if (userProvider!.user!.type == UsersTypes.engineer && (taskModel?.taskJobStatus?.value != 4 && taskModel?.taskJobStatus?.value != 3)) ).toShadowContainer(context).paddingAll(16),
AppFilledButton( ).expanded,
if (userProvider!.user!.type == UsersTypes.engineer && (taskModel?.taskJobStatus?.value != 4 && taskModel?.taskJobStatus?.value != 3))
FooterActionButton.footerContainer(
child: AppFilledButton(
onPressed: () async { onPressed: () async {
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) { if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) {
taskProvider.getSiteData(siteId: taskProvider.taskRequestModel?.asset?.siteId); taskProvider.getSiteData(siteId: taskProvider.taskRequestModel?.asset?.siteId);
@ -152,10 +153,10 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateTaskRequest(taskId: widget.taskId))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateTaskRequest(taskId: widget.taskId)));
}, },
label: context.translation.updateRequest, label: context.translation.updateRequest,
).paddingAll(16) ),
]); )
}), ]);
), }),
); );
} }

@ -98,81 +98,79 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
body: taskProvider.isLoading body: taskProvider.isLoading
? const ALoading() ? const ALoading()
: taskProvider.taskRequestModel != null : taskProvider.taskRequestModel != null
? SafeArea( ? Form(
child: Form( key: _formKey,
key: _formKey, child: Column(
child: Stack( children: [
children: [ SingleChildScrollView(
SingleChildScrollView( padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)),
padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), child: Column(
child: Column( children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( _timerWidget(context, true, taskProvider),
crossAxisAlignment: CrossAxisAlignment.start, 8.height,
children: [ if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)],
_timerWidget(context, true, taskProvider), if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[
8.height, recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!),
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)], ],
if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[ // if (previousComments.isNotEmpty) ...[
recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!), // 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50),
], // 8.height,
// if (previousComments.isNotEmpty) ...[ buildPreviousComments(taskProvider: taskProvider),
// 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50), // 8.height,
// 8.height, // ],
buildPreviousComments(taskProvider: taskProvider), AppTextFormField(
// 8.height, initialValue: "",
// ], labelText: context.translation.technicalComment,
AppTextFormField( textInputType: TextInputType.multiline,
initialValue: "", backgroundColor: AppColor.neutral90,
labelText: context.translation.technicalComment, showShadow: false,
textInputType: TextInputType.multiline, alignLabelWithHint: true,
backgroundColor: AppColor.neutral90, onChange: (value) {
showShadow: false, comments = value;
alignLabelWithHint: true, setState(() {});
onChange: (value) { },
comments = value; onSaved: (value) {},
setState(() {}); ),
}, 20.height,
onSaved: (value) {}, MultiFilesPicker(
), label: context.translation.attachFiles,
20.height, files: _files,
MultiFilesPicker( buttonColor: AppColor.black10,
label: context.translation.attachFiles, onlyImages: false,
files: _files, buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
buttonColor: AppColor.black10, ),
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
],
).toShadowContainer(context),
16.height,
const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
], ],
), ).toShadowContainer(context),
).paddingOnly(bottom: 85), 16.height,
FooterActionButton.footerContainer( const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
child: Row( ],
mainAxisAlignment: MainAxisAlignment.spaceAround, ),
children: [ ).expanded,
AppFilledButton( FooterActionButton.footerContainer(
label: context.translation.save, child: Row(
buttonColor: AppColor.white60, mainAxisAlignment: MainAxisAlignment.spaceAround,
textColor: AppColor.black10, children: [
onPressed: () => _updateTask(context: context, status: 0), AppFilledButton(
).expanded, label: context.translation.save,
12.width, buttonColor: AppColor.white60,
AppFilledButton( textColor: AppColor.black10,
label: context.translation.complete, onPressed: () => _updateTask(context: context, status: 0),
buttonColor: AppColor.primary10, ).expanded,
onPressed: () => _updateTask(context: context, status: 1), 12.width,
).expanded, AppFilledButton(
], label: context.translation.complete,
), buttonColor: AppColor.primary10,
), onPressed: () => _updateTask(context: context, status: 1),
], ).expanded,
],
),
), ),
), ],
) ),
)
: NoDataFound(message: context.translation.noDataFound).center, : NoDataFound(message: context.translation.noDataFound).center,
).handlePopScope( ).handlePopScope(
cxt: context, cxt: context,

@ -209,88 +209,86 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
}, },
), ),
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: LoadingManager(
child: LoadingManager( isLoading: _isLoading,
isLoading: _isLoading, isFailedLoading: false,
isFailedLoading: false, stateCode: 200,
stateCode: 200, onRefresh: () async {},
onRefresh: () async {}, child: Form(
child: Form( key: _formKey,
key: _formKey, child: Column(
child: Column( children: [
children: [ SingleChildScrollView(
SingleChildScrollView( padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)),
padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), child: Column(
child: Column( children: [
children: [ Column(
Column( crossAxisAlignment: CrossAxisAlignment.stretch,
crossAxisAlignment: CrossAxisAlignment.stretch, children: [
children: [ _timerWidget(context, totalWorkingHours, isTimerEnable),
_timerWidget(context, totalWorkingHours, isTimerEnable), 8.height,
8.height, AppTextFormField(
AppTextFormField( initialValue: widget.isSender ? _formModel.senderComment ?? "" : _formModel.receiverComment ?? "",
initialValue: widget.isSender ? _formModel.senderComment ?? "" : _formModel.receiverComment ?? "", labelText: context.translation.technicalComment,
labelText: context.translation.technicalComment, labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral20),
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral20), textInputType: TextInputType.multiline,
textInputType: TextInputType.multiline, backgroundColor: AppColor.neutral100,
backgroundColor: AppColor.neutral100, showShadow: false,
showShadow: false, alignLabelWithHint: true,
alignLabelWithHint: true, onSaved: (value) {
onSaved: (value) { widget.isSender ? _formModel.senderComment = value : _formModel.receiverComment = value;
widget.isSender ? _formModel.senderComment = value : _formModel.receiverComment = value; },
}, ),
), 8.height,
8.height, MultiFilesPicker(
MultiFilesPicker( label: context.translation.attachFiles,
label: context.translation.attachFiles, files: _files,
files: _files, buttonColor: AppColor.black10,
buttonColor: AppColor.black10, onlyImages: false,
onlyImages: false, buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120), ),
), 8.height,
8.height, ],
], ).toShadowContainer(context),
).toShadowContainer(context), 16.height,
16.height, AssistantEmployeeCard(
AssistantEmployeeCard( isSender: widget.isSender,
isSender: widget.isSender, formModel: _formModel,
formModel: _formModel, ).toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
).toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)), ],
], ),
), ).expanded,
).expanded, FooterActionButton.footerContainer(
FooterActionButton.footerContainer( child: Row(
child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
children: [ AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () => _update(status: 0),
).expanded,
12.width,
if (!widget.isSender && _formModel.senderMachineStatusValue == 3) ...[
AppFilledButton( AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () => _update(status: 0),
).expanded,
12.width,
if (!widget.isSender && _formModel.senderMachineStatusValue == 3) ...[
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () {
_update(status: 1);
}).expanded,
] else if (widget.isSender) ...[
AppFilledButton(
label: context.translation.complete, label: context.translation.complete,
buttonColor: AppColor.primary10, buttonColor: AppColor.primary10,
onPressed: () { onPressed: () {
_update(status: 1); _update(status: 1);
}, }).expanded,
).expanded, ] else if (widget.isSender) ...[
], AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () {
_update(status: 1);
},
).expanded,
], ],
), ],
), ),
], ),
), ],
), ),
), ),
), ),

@ -10,6 +10,7 @@ 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';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.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/views/pages/user/gas_refill/update_gas_refill_request.dart'; import 'package:test_sa/views/pages/user/gas_refill/update_gas_refill_request.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
@ -56,52 +57,52 @@ class _GasRefillDetailsPageState extends State<GasRefillDetailsPage> {
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.gasRefillDetails), appBar: DefaultAppBar(title: context.translation.gasRefillDetails),
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: FutureBuilder(
child: FutureBuilder( future: gasRefillProvider.getGasRefillObjectById(widget.model.id!),
future: gasRefillProvider.getGasRefillObjectById(widget.model.id!), builder: (context, snap) {
builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) {
if (snap.connectionState == ConnectionState.waiting) { return const ALoading();
return const ALoading(); } else if (snap.hasData) {
} else if (snap.hasData) { _model = snap.data as GasRefillModel;
_model = snap.data as GasRefillModel; _attachments = _model.gasRefillAttachments?.map((e) => File(e.attachmentName ?? '')).toList() ?? [];
_attachments = _model.gasRefillAttachments?.map((e) => File(e.attachmentName ?? '')).toList() ?? [];
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SingleChildScrollView( SingleChildScrollView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: informationCard(_model), child: informationCard(_model),
).expanded, ).expanded,
if (_userProvider.user!.type == UsersTypes.engineer && (_model.status!.value! != 2)) ...[ if (_userProvider.user!.type == UsersTypes.engineer && (_model.status!.value! != 2)) ...[
AppFilledButton( FooterActionButton.footerContainer(
child: AppFilledButton(
onPressed: () async { onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateGasRefillRequest(gasRefillModel: _model))); await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateGasRefillRequest(gasRefillModel: _model)));
// getVisitData(); // getVisitData();
}, },
label: context.translation.updateRequest, label: context.translation.updateRequest,
).paddingAll(16) ),
] )
//TODO need to uncomment this to enable nurse edit gas refill request. ]
// else if (_model.status!.value! == 0) ...[ //TODO need to uncomment this to enable nurse edit gas refill request.
// AppFilledButton( // else if (_model.status!.value! == 0) ...[
// onPressed: () async { // AppFilledButton(
// await Navigator.of(context).push(MaterialPageRoute( // onPressed: () async {
// builder: (_) => GasRefillRequestForm( // await Navigator.of(context).push(MaterialPageRoute(
// gasModel: _model, // builder: (_) => GasRefillRequestForm(
// gasRefillDetails: _model.gasRefillDetails?[0], // gasModel: _model,
// ))); // gasRefillDetails: _model.gasRefillDetails?[0],
// // getVisitData(); // )));
// }, // // getVisitData();
// label: context.translation.updateRequest, // },
// ).paddingAll(16) // label: context.translation.updateRequest,
// ], // ).paddingAll(16)
], // ],
); ],
} );
return NoDataFound(message: context.translation.noDataFound).center; }
}, return NoDataFound(message: context.translation.noDataFound).center;
), },
), ),
); );
} }

@ -211,83 +211,81 @@ class _UpdateGasRefillRequestState extends State<UpdateGasRefillRequest> {
key: _scaffoldKey, key: _scaffoldKey,
body: Form( body: Form(
key: _formKey, key: _formKey,
child: SafeArea( child: LoadingManager(
child: LoadingManager( isLoading: _isLoading,
isLoading: _isLoading, isFailedLoading: false,
isFailedLoading: false, stateCode: 200,
stateCode: 200, onRefresh: () async {},
onRefresh: () async {}, child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.stretch,
crossAxisAlignment: CrossAxisAlignment.stretch, children: [
children: [ SingleChildScrollView(
SingleChildScrollView( padding: const EdgeInsets.all(16),
padding: const EdgeInsets.all(16), child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.stretch,
crossAxisAlignment: CrossAxisAlignment.stretch, children: [
children: [ 8.height,
8.height, SingleItemDropDownMenu<Lookup, NullableLoadingProvider>(
SingleItemDropDownMenu<Lookup, NullableLoadingProvider>( context: context,
context: context, title: context.translation.quantity,
title: context.translation.quantity, backgroundColor: AppColor.neutral100,
backgroundColor: AppColor.neutral100, showShadow: false,
showShadow: false, showAsBottomSheet: true,
showAsBottomSheet: true, initialValue: _deliveredQuantity,
initialValue: _deliveredQuantity, staticData: deliveredQuantity,
staticData: deliveredQuantity, onSelect: (value) {
onSelect: (value) { _deliveredQuantity = value;
_deliveredQuantity = value; _currentDetails.deliverdQty = value!.value;
_currentDetails.deliverdQty = value!.value; },
}, ),
), 8.height,
8.height, _timerWidget(context, totalWorkingHours),
_timerWidget(context, totalWorkingHours), 8.height,
8.height, AppTextFormField(
AppTextFormField( labelText: context.translation.technicalComment,
labelText: context.translation.technicalComment, textInputType: TextInputType.multiline,
textInputType: TextInputType.multiline, alignLabelWithHint: true,
alignLabelWithHint: true, backgroundColor: AppColor.neutral100,
backgroundColor: AppColor.neutral100, showShadow: false,
showShadow: false, controller: _commentController,
controller: _commentController, onChange: (value) {
onChange: (value) { _formModel.techComment = value;
_formModel.techComment = value; },
}, onSaved: (value) {},
onSaved: (value) {}, ),
), 16.height,
16.height, MultiFilesPicker(
MultiFilesPicker( label: context.translation.attachFiles,
label: context.translation.attachFiles, files: _attachments,
files: _attachments, buttonColor: AppColor.black10,
buttonColor: AppColor.black10, onlyImages: false,
onlyImages: false, buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120), ),
), 8.height,
8.height, ],
], ).toShadowContainer(context),
).toShadowContainer(context), ).expanded,
).expanded, FooterActionButton.footerContainer(
FooterActionButton.footerContainer( child: Row(
child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround,
mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
children: [ AppFilledButton(
AppFilledButton( label: context.translation.save,
label: context.translation.save, buttonColor: AppColor.white60,
buttonColor: AppColor.white60, textColor: AppColor.black10,
textColor: AppColor.black10, onPressed: () => _onSubmit(context, 0),
onPressed: () => _onSubmit(context, 0), ).expanded,
).expanded, 12.width,
12.width, AppFilledButton(
AppFilledButton( label: context.translation.complete,
label: context.translation.complete, buttonColor: AppColor.primary10,
buttonColor: AppColor.primary10, onPressed: () => _onSubmit(context, 1),
onPressed: () => _onSubmit(context, 1), ).expanded,
).expanded, ],
],
),
), ),
], ),
)), ],
), )),
), ),
).handlePopScope( ).handlePopScope(
cxt: context, cxt: context,

@ -177,15 +177,8 @@ class _ProfilePageState extends State<ProfilePage> {
label: "Update Information", label: "Update Information",
buttonColor: AppColor.neutral50, buttonColor: AppColor.neutral50,
onPressed: () { onPressed: () {
showModalBottomSheet( context.showBottomSheet(
context: context, UpdateUserContactInfoBottomSheet(
useSafeArea: true,
isScrollControlled: true,
isDismissible: true,
backgroundColor: Colors.transparent,
builder: (context) => SingleChildScrollView(
padding: const EdgeInsets.all(0),
child: UpdateUserContactInfoBottomSheet(
_userProvider.user!.userID!, _userProvider.user!.userID!,
uEmail: _user.email, uEmail: _user.email,
uPhoneNo: _user.phoneNumber, uPhoneNo: _user.phoneNumber,
@ -198,8 +191,7 @@ class _ProfilePageState extends State<ProfilePage> {
Provider.of<SettingProvider>(context, listen: false).setUser(_userProvider.user!); Provider.of<SettingProvider>(context, listen: false).setUser(_userProvider.user!);
}, },
), ),
).bottomSheetContainer(context), title: "Update Information");
);
}, },
) )
], ],

@ -48,12 +48,6 @@ class _UpdateUserContactInfoBottomSheetState extends State<UpdateUserContactInfo
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
8.height,
Align(
alignment: AlignmentDirectional.centerStart,
child: "Update Information".bottomSheetHeadingTextStyle(context),
),
16.height,
AppTextFormField( AppTextFormField(
labelText: "Email", labelText: "Email",
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,

@ -3,6 +3,7 @@ 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/extensions/widget_extensions.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.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';
@ -96,28 +97,6 @@ class _SelectionBottomSheetState<T> extends State<SelectionFullScreenDialog<T>>
setState(() {}); setState(() {});
}, },
).paddingOnly(top: 16, start: 16, end: 16, bottom: 8), ).paddingOnly(top: 16, start: 16, end: 16, bottom: 8),
// TextField(
// onChanged: (queryString) {
// query = queryString;
// setState(() {});
// },
// style: const TextStyle(fontSize: 14),
// focusNode: searchFocusNode,
// decoration: InputDecoration(
// hintText: 'Search by name',
// labelText: 'Search',
// hintStyle: const TextStyle(fontSize: 14),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: AppColor.blueStatus(context), width: 2.0),
// borderRadius: const BorderRadius.all(Radius.circular(12.0)),
// ),
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(color: AppColor.blueStatus(context), width: 1.0),
// borderRadius: const BorderRadius.all(Radius.circular(12.0)),
// ),
// contentPadding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
// ),
// ),
8.height, 8.height,
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
@ -145,14 +124,16 @@ class _SelectionBottomSheetState<T> extends State<SelectionFullScreenDialog<T>>
), ),
8.height, 8.height,
if (_selectedValue != null) if (_selectedValue != null)
AppFilledButton( FooterActionButton.footerContainer(
label: context.translation.select, child: AppFilledButton(
maxWidth: true, label: context.translation.select,
onPressed: () { maxWidth: true,
Navigator.pop(context); onPressed: () {
widget.onSelect(_selectedValue); Navigator.pop(context);
}, widget.onSelect(_selectedValue);
).paddingAll(16), },
),
),
], ],
), ),
); );

@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@ -18,12 +17,13 @@ class MultiFilesPicker extends StatefulWidget {
final String label; final String label;
final bool error; final bool error;
final List<File> files; final List<File> files;
final List<AttachmentModel> attachment ; final List<AttachmentModel> attachment;
final bool enabled, onlyImages; final bool enabled, onlyImages;
double? buttonHeight; double? buttonHeight;
Widget? buttonIcon; Widget? buttonIcon;
Color? buttonColor; Color? buttonColor;
final Function(List<File>)? onChange; final VoidCallback? onChange;
final bool showAsGrid; final bool showAsGrid;
MultiFilesPicker( MultiFilesPicker(
@ -51,7 +51,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if(widget.enabled)...[ if (widget.enabled) ...[
AppDashedButton( AppDashedButton(
title: widget.label, title: widget.label,
height: widget.buttonHeight, height: widget.buttonHeight,
@ -60,8 +60,8 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
onPressed: (widget.enabled == false) onPressed: (widget.enabled == false)
? () {} ? () {}
: widget.showAsGrid : widget.showAsGrid
? showFileSourceSheet ? showFileSourceSheet
: onFilePicker), : onFilePicker),
16.height, 16.height,
], ],
if (widget.files.isNotEmpty) if (widget.files.isNotEmpty)
@ -80,7 +80,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
} }
widget.files.remove(image); widget.files.remove(image);
if (widget.onChange != null) { if (widget.onChange != null) {
widget.onChange!(widget.files); widget.onChange!();
} }
setState(() {}); setState(() {});
}, },
@ -101,6 +101,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
if (result != null) { if (result != null) {
for (var path in result.paths) { for (var path in result.paths) {
widget.files.add(File(path!)); widget.files.add(File(path!));
widget.onChange!();
} }
setState(() {}); setState(() {});
} }
@ -151,10 +152,10 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
File fileImage = File(pickedFile.path); File fileImage = File(pickedFile.path);
widget.files.add(fileImage); widget.files.add(fileImage);
if (widget.onChange != null) { if (widget.onChange != null) {
widget.onChange!(widget.files); widget.onChange!();
} }
setState(() {}); setState(() {});
} }
} }
Widget gridItem(IconData iconData, String title) { Widget gridItem(IconData iconData, String title) {
@ -187,28 +188,26 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
ImageSource? source = await showModalBottomSheet<ImageSource>( ImageSource? source = await showModalBottomSheet<ImageSource>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
Widget listCard({required String icon, required String label, required VoidCallback onTap}){ Widget listCard({required String icon, required String label, required VoidCallback onTap}) {
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
constraints: BoxConstraints(minWidth: 111.toScreenWidth,minHeight: 111.toScreenHeight), constraints: BoxConstraints(minWidth: 111.toScreenWidth, minHeight: 111.toScreenHeight),
padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth,vertical: 12.toScreenHeight), padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 12.toScreenHeight),
decoration: BoxDecoration( decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(width: 1, color: AppColor.white70)),
borderRadius: BorderRadius.circular(12),
border: Border.all(width: 1,color:AppColor.white70)
),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
icon.toSvgAsset(), icon.toSvgAsset(),
24.height, 24.height,
label.bodyText2(context).custom(color: AppColor.black20), label.bodyText2(context).custom(color: AppColor.black20),
], ],
), ),
), ),
); );
} }
return Container( return Container(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Row( child: Row(
@ -216,7 +215,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
children: <Widget>[ children: <Widget>[
listCard( listCard(
icon: 'camera_icon', icon: 'camera_icon',
label: '${context.translation.open}\n${context.translation.camera}', label: '${context.translation.open}\n${context.translation.camera}',
onTap: () { onTap: () {
Navigator.of(context).pop(ImageSource.camera); Navigator.of(context).pop(ImageSource.camera);
}, },
@ -230,7 +229,7 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
), ),
listCard( listCard(
icon: 'file_icon', icon: 'file_icon',
label: '${context.translation.open}\n${context.translation.files}', label: '${context.translation.open}\n${context.translation.files}',
onTap: () async { onTap: () async {
await fromFilePicker(); await fromFilePicker();
Navigator.pop(context); Navigator.pop(context);
@ -273,49 +272,41 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
if (pickedFile != null) { if (pickedFile != null) {
File fileImage = File(pickedFile.path); File fileImage = File(pickedFile.path);
if (fileImage != null) { widget.files.add(fileImage);
widget.files.add(fileImage); if (widget.onChange != null) {
if (widget.onChange != null) { widget.onChange!();
widget.onChange!(widget.files);
}
setState(() {});
} }
setState(() {});
} }
setState(() {});
} }
} }
class AttachmentModel {
int id = 0;
File? file;
AttachmentModel(this.id, this.file);
class AttachmentModel {
int id =0;
File ? file;
AttachmentModel(this.id,this.file);
factory AttachmentModel.fromJson(Map<String, dynamic> json) { factory AttachmentModel.fromJson(Map<String, dynamic> json) {
return AttachmentModel( return AttachmentModel(
json['id'] ?? 0, json['id'] ?? 0,
json['file'] != null ? File(json['file']) : null, json['file'] != null ? File(json['file']) : null,
); );
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'id': id, 'id': id,
'file': file?.path, 'file': file?.path,
}; };
} }
} }
class AttachmentPicker extends StatefulWidget { class AttachmentPicker extends StatefulWidget {
final String label; final String label;
final bool error; final bool error;
final List<AttachmentModel> attachment ; final List<AttachmentModel> attachment;
final bool enabled, onlyImages; final bool enabled, onlyImages;
double? buttonHeight; double? buttonHeight;
Widget? buttonIcon; Widget? buttonIcon;
@ -325,16 +316,16 @@ class AttachmentPicker extends StatefulWidget {
AttachmentPicker( AttachmentPicker(
{Key? key, {Key? key,
this.attachment = const <AttachmentModel>[], this.attachment = const <AttachmentModel>[],
required this.label, required this.label,
this.error = false, this.error = false,
this.buttonHeight, this.buttonHeight,
this.buttonIcon, this.buttonIcon,
this.enabled = true, this.enabled = true,
this.onlyImages = false, this.onlyImages = false,
this.onChange, this.onChange,
this.showAsGrid = false, this.showAsGrid = false,
this.buttonColor}) this.buttonColor})
: super(key: key); : super(key: key);
@override @override
@ -355,15 +346,15 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
onPressed: (widget.enabled == false) onPressed: (widget.enabled == false)
? () {} ? () {}
: widget.showAsGrid : widget.showAsGrid
? showFileSourceSheet ? showFileSourceSheet
: onFilePicker), : onFilePicker),
16.height, 16.height,
if (widget.attachment.isNotEmpty) if (widget.attachment.isNotEmpty)
Wrap( Wrap(
spacing: 8.toScreenWidth, spacing: 8.toScreenWidth,
children: List.generate( children: List.generate(
widget.attachment.length, widget.attachment.length,
(index) { (index) {
File image = widget.attachment[index].file!; File image = widget.attachment[index].file!;
return MultiFilesPickerItem( return MultiFilesPickerItem(
file: image, file: image,
@ -481,16 +472,13 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
ImageSource? source = await showModalBottomSheet<ImageSource>( ImageSource? source = await showModalBottomSheet<ImageSource>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
Widget listCard({required String icon, required String label, required VoidCallback onTap}){ Widget listCard({required String icon, required String label, required VoidCallback onTap}) {
return GestureDetector( return GestureDetector(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
constraints: BoxConstraints(minWidth: 111.toScreenWidth,minHeight: 111.toScreenHeight), constraints: BoxConstraints(minWidth: 111.toScreenWidth, minHeight: 111.toScreenHeight),
padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth,vertical: 12.toScreenHeight), padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 12.toScreenHeight),
decoration: BoxDecoration( decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(width: 1, color: AppColor.white70)),
borderRadius: BorderRadius.circular(12),
border: Border.all(width: 1,color:AppColor.white70)
),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -503,6 +491,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
), ),
); );
} }
return Container( return Container(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: Row( child: Row(
@ -510,7 +499,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
children: <Widget>[ children: <Widget>[
listCard( listCard(
icon: 'camera_icon', icon: 'camera_icon',
label: '${context.translation.open}\n${context.translation.camera}', label: '${context.translation.open}\n${context.translation.camera}',
onTap: () { onTap: () {
Navigator.of(context).pop(ImageSource.camera); Navigator.of(context).pop(ImageSource.camera);
}, },
@ -524,7 +513,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
), ),
listCard( listCard(
icon: 'file_icon', icon: 'file_icon',
label: '${context.translation.open}\n${context.translation.files}', label: '${context.translation.open}\n${context.translation.files}',
onTap: () async { onTap: () async {
await fromFilePicker(); await fromFilePicker();
Navigator.pop(context); Navigator.pop(context);
@ -572,7 +561,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
widget.onChange!(widget.attachment); widget.onChange!(widget.attachment);
} }
setState(() {}); setState(() {});
} }
setState(() {}); setState(() {});
} }

Loading…
Cancel
Save