diff --git a/lib/extensions/text_extensions.dart b/lib/extensions/text_extensions.dart index e58043ea..5a81bc5c 100644 --- a/lib/extensions/text_extensions.dart +++ b/lib/extensions/text_extensions.dart @@ -27,7 +27,7 @@ extension TextStyles on String { Text bodyText2(BuildContext context) => getTextWithStyle(this, AppTextStyles.bodyText2, context.isDark ? AppColor.neutral10 : AppColor.neutral20); - Text tinyFont(BuildContext context) => getTextWithStyle(this, AppTextStyles.tinyFont, context.isDark ? AppColor.neutral10 : AppColor.neutral20); + Text tinyFont(BuildContext context) => getTextWithStyle(this, AppTextStyles.tinyFont, context.isDark ? AppColor.neutral10 : AppColor.neutral120); Text overline(BuildContext context) => getTextWithStyle(this, AppTextStyles.overline, context.isDark ? AppColor.neutral10 : AppColor.neutral20); diff --git a/lib/new_views/common_widgets/app_filled_button.dart b/lib/new_views/common_widgets/app_filled_button.dart index 3d99c4d9..0835c413 100644 --- a/lib/new_views/common_widgets/app_filled_button.dart +++ b/lib/new_views/common_widgets/app_filled_button.dart @@ -14,6 +14,7 @@ class AppFilledButton extends StatelessWidget { final Color? buttonColor; final Color? textColor; final bool showBorder; + final double radius; const AppFilledButton( {this.onPressed, @@ -26,6 +27,7 @@ class AppFilledButton extends StatelessWidget { this.showBorder = false, this.buttonColor, this.textColor, + this.radius = 10, Key? key}) : super(key: key); diff --git a/lib/new_views/common_widgets/app_text_form_field.dart b/lib/new_views/common_widgets/app_text_form_field.dart index 9f11bf6d..d9570aba 100644 --- a/lib/new_views/common_widgets/app_text_form_field.dart +++ b/lib/new_views/common_widgets/app_text_form_field.dart @@ -42,6 +42,7 @@ class AppTextFormField extends StatefulWidget { final bool showWithoutDecoration; final VoidCallback? onTap; final bool showSpeechToText; + final Color? enableColor; const AppTextFormField({ Key? key, @@ -74,6 +75,7 @@ class AppTextFormField extends StatefulWidget { this.showWithoutDecoration = false, this.alignLabelWithHint = false, // Provide default value this.onTap, + this.enableColor, }) : super(key: key); @override @@ -93,7 +95,7 @@ class _AppTextFormFieldState extends State { widget.controller?.text = widget.initialValue!; } _focusNode = widget.node ?? FocusNode(); - if(widget.showSpeechToText) { + if (widget.showSpeechToText) { _initSpeech(); } super.initState(); @@ -132,7 +134,6 @@ class _AppTextFormFieldState extends State { await _speechToText.stop(); _focusNode.unfocus(); setState(() {}); - } @override @@ -183,7 +184,7 @@ class _AppTextFormFieldState extends State { controller: widget.controller, textInputAction: widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next, onEditingComplete: widget.onAction ?? () => FocusScope.of(context).nextFocus(), - style:widget.style?? AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500), + style: widget.style ?? AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500,color: AppColor.black10), onTap: widget.onTap, decoration: InputDecoration( alignLabelWithHint: widget.alignLabelWithHint, @@ -194,15 +195,13 @@ class _AppTextFormFieldState extends State { errorBorder: border, contentPadding: widget.contentPadding ?? EdgeInsets.symmetric(vertical: 12.toScreenHeight, horizontal: 16.toScreenWidth), constraints: const BoxConstraints(), - suffixIconConstraints: const BoxConstraints( - minWidth: 0, - ), + suffixIconConstraints: const BoxConstraints(minWidth: 0), filled: true, fillColor: widget.backgroundColor ?? (context.isDark && !widget.enable ? AppColor.neutral50 : !widget.enable - ? AppColor.neutral40 + ? (widget.enableColor ?? AppColor.neutral40) : AppColor.background(context)), errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60), floatingLabelStyle: AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20), @@ -227,7 +226,7 @@ class _AppTextFormFieldState extends State { Icons.fiber_manual_record, color: Colors.red, )).onPress(() { - // _focusNode.unfocus(); + // _focusNode.unfocus(); _stopListening(); }) : speechToTextWidget) @@ -236,16 +235,11 @@ class _AppTextFormFieldState extends State { ), ); - // - // Widget myWidget = Row( - // children: [textField.expanded, if (widget.showSpeechToText) speechToTextWidget], - // ); - if (widget.showWithoutDecoration) return textField; return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), - border: widget.showBorder?Border.all(color: AppColor.white10,width: 1):null, + border: widget.showBorder ? Border.all(color: AppColor.white10, width: 1) : null, boxShadow: widget.showShadow ? [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)] : null, ), child: textField); diff --git a/lib/new_views/common_widgets/single_item_drop_down_menu.dart b/lib/new_views/common_widgets/single_item_drop_down_menu.dart index a5a462f9..9896beb9 100644 --- a/lib/new_views/common_widgets/single_item_drop_down_menu.dart +++ b/lib/new_views/common_widgets/single_item_drop_down_menu.dart @@ -153,7 +153,7 @@ class _SingleItemDropDownMenuState { AppFilledButton( onPressed: () async { //TODO remove after testing.. - await Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView( request: widget.request))); - // setState(() {}); + // await Navigator.of(context).push(MaterialPageRoute(builder: (_) => RecurrentWorkOrderView( request: widget.request))); + await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: ppm, details: widget.request))); + setState(() {}); }, label: context.translation.updateRequest, ).paddingAll(16) diff --git a/lib/views/pages/user/ppm/update_ppm/edit_ppm.dart b/lib/views/pages/user/ppm/update_ppm/edit_ppm.dart deleted file mode 100644 index ee5273a0..00000000 --- a/lib/views/pages/user/ppm/update_ppm/edit_ppm.dart +++ /dev/null @@ -1,128 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/ppm_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/widget_extensions.dart'; -import 'package:test_sa/models/all_requests_and_count_model.dart'; -import 'package:test_sa/models/ppm/ppm.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; -import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; -import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; - -import '../../../../../extensions/text_extensions.dart'; -import '../../../../widgets/pentry/pentry_calibration_tool_form.dart'; -import '../../../../widgets/pentry/pentry_pm_kit_form.dart'; -import '../../../../widgets/pentry/pentry_ppm_check_list_form.dart'; -import '../../../../widgets/pentry/pentry_tbs_form.dart'; - -class EditPpm extends StatefulWidget { - final Ppm ppm; - final RequestsDetails? details; - - const EditPpm({Key? key, required this.ppm, this.details}) : super(key: key); - - @override - State createState() => _EditPpmState(); -} - -class _EditPpmState extends State with SingleTickerProviderStateMixin { - late UserProvider _userProvider; - late PpmProvider _regularVisitsProvider; - late Ppm _ppm; - final GlobalKey _scaffoldKey = GlobalKey(); - - late TabController _tabController; - - _onSubmit() async { - if (!(await _ppm.validate(context))) { - setState(() {}); - return; - } - _ppm.removeEmptyObjects(); - await _regularVisitsProvider.updatePentry(context, user: _userProvider.user!, ppm: widget.ppm); - } - - @override - void initState() { - _ppm = widget.ppm; - _tabController = TabController(length: 4, vsync: this); - super.initState(); - } - - @override - void dispose() { - _tabController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - _userProvider = Provider.of(context, listen: false); - _regularVisitsProvider = Provider.of(context, listen: false); - return Scaffold( - appBar: DefaultAppBar(title: context.translation.preventiveMaintenance), - key: _scaffoldKey, - body: SafeArea( - child: LoadingManager( - isLoading: false, - isFailedLoading: false, - stateCode: 200, - onRefresh: () async {}, - child: Column( - children: [ - Container( - decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)), - child: TabBar( - controller: _tabController, - isScrollable: true, - padding: EdgeInsets.zero, - labelColor: context.isDark ? AppColor.neutral30 : AppColor.neutral60, - unselectedLabelColor: context.isDark ? AppColor.neutral10 : AppColor.neutral20, - unselectedLabelStyle: AppTextStyles.bodyText, - labelStyle: AppTextStyles.bodyText, - dividerColor: Colors.transparent, - indicatorPadding: const EdgeInsets.all(4), - indicatorSize: TabBarIndicatorSize.tab, - indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : Theme.of(context).cardColor, borderRadius: BorderRadius.circular(13)), - onTap: (index) { - setState(() {}); - }, - tabs: [ - Tab(text: "TBS", height: 57.toScreenHeight), - Tab(text: "Calibration Tool", height: 57.toScreenHeight), - Tab(text: "PM Kit", height: 57.toScreenHeight), - Tab(text: "PPM Checklist", height: 57.toScreenHeight), - ], - ), - ), - TabBarView( - physics: const NeverScrollableScrollPhysics(), - controller: _tabController, - children: [ - PentryTBSForm(model: _ppm), - PentryCalibrationToolForm(models: _ppm.vCalibrationTools), - PentryPMKitForm(models: _ppm.vKits, assetId: widget.ppm.assetId), - PentryPMChecklistForm(models: _ppm.vChecklists), - ], - ).expanded, - AppFilledButton( - onPressed: () { - if (_tabController.index == 3) { - _onSubmit(); - } else { - _tabController.animateTo(_tabController.index + 1); - setState(() {}); - } - }, - label: _tabController.index == 3 ? context.translation.submit : context.translation.next, - ).paddingOnly(top: 16), - ], - ).paddingAll(16), - ), - ), - ); - } -} diff --git a/lib/views/pages/user/ppm/update_ppm/ppm_calibration_tools_form.dart b/lib/views/pages/user/ppm/update_ppm/ppm_calibration_tools_form.dart new file mode 100644 index 00000000..0a8f92ec --- /dev/null +++ b/lib/views/pages/user/ppm/update_ppm/ppm_calibration_tools_form.dart @@ -0,0 +1,117 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.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/models/lookup.dart'; +import 'package:test_sa/models/ppm/ppm_calibration_tools.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/views/widgets/pentry/calibration_tool_asset_picker.dart'; + +import '../../../../../new_views/app_style/app_color.dart'; +import '../../../../widgets/date_and_time/date_picker.dart'; + +class PpmCalibrationToolsForm extends StatefulWidget { + final List? models; + + const PpmCalibrationToolsForm({Key? key, this.models = const []}) : super(key: key); + + @override + State createState() => _PpmCalibrationToolsFormState(); +} + +class _PpmCalibrationToolsFormState extends State { + @override + Widget build(BuildContext context) { + final userProvider = Provider.of(context); + return ListView.separated( + itemCount: widget.models!.length + 1, + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), + separatorBuilder: (cxt, index) => 16.height, + itemBuilder: (context, index) { + if (index == widget.models!.length) { + return AppFilledButton( + label: "Add More Calibration Tools".addTranslation, + maxWidth: true, + textColor: AppColor.black10, + buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, + icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), + showIcon: true, + onPressed: () async { + if (widget.models?.isNotEmpty ?? false) { + if (widget.models!.last.assetId == null) { + await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.assetNumber}"); + return; + } + if (widget.models!.last.calibrationDateOfTesters == null) { + await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.date}"); + return; + } + } + widget.models!.add(PpmCalibrationTools(id: 0)); + setState(() {}); + }, + ); + } + final PpmCalibrationTools model = widget.models![index]; + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.background(context), + borderRadius: BorderRadius.circular(20), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + (index == 0 ? "2 /4 . Calibration Tools" : "").heading5(context), + "trash".toSvgAsset(height: 20, width: 15).onPress(() { + widget.models!.remove(model); + setState(() {}); + }), + ], + ), + 16.height, + CalibrationToolAssetPicker( + initialValue: model.assetId == null ? null : Lookup(id: model.assetId?.toInt(), name: model.assetNumber ?? ""), + hospitalId: userProvider.user!.clientId, + onPick: (asset) { + model.assetNumber = asset.assetNumber; + model.assetId = asset.id; + model.assetSerialNo = asset.assetSerialNo; + model.assetName = asset.modelDefinition?.assetName; + setState(() {}); + }, + ), + 12.height, + if (model.assetNumber != null) Text("Asset Number: ${model.assetNumber?.cleanupWhitespace.capitalizeFirstOfEach}", style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120)), + if (model.assetName != null) Text("Asset Name: ${model.assetName?.cleanupWhitespace.capitalizeFirstOfEach}", style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120)), + if (model.assetSerialNo != null) + Text("Asset Serial No: ${model.assetSerialNo?.cleanupWhitespace.capitalizeFirstOfEach}", style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120)), + 12.height, + ADatePicker( + label: context.translation.calibrationDate, + date: DateTime.tryParse(model.calibrationDateOfTesters ?? ""), + from: DateTime.now().subtract(const Duration(days: 90)), + backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.neutral100, + withBorder: false, + hideShadow: true, + onDatePicker: (date) { + model.calibrationDateOfTesters = date.toIso8601String(); + setState(() {}); + }, + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart b/lib/views/pages/user/ppm/update_ppm/ppm_external_details_form.dart similarity index 79% rename from lib/views/widgets/pentry/pentry_calibration_tool_form.dart rename to lib/views/pages/user/ppm/update_ppm/ppm_external_details_form.dart index 1324607f..ea6bfa50 100644 --- a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart +++ b/lib/views/pages/user/ppm/update_ppm/ppm_external_details_form.dart @@ -4,6 +4,7 @@ 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/models/lookup.dart'; @@ -11,32 +12,34 @@ import 'package:test_sa/models/ppm/ppm_calibration_tools.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/views/widgets/pentry/calibration_tool_asset_picker.dart'; -import '../../../new_views/app_style/app_color.dart'; -import '../date_and_time/date_picker.dart'; +import '../../../../../new_views/app_style/app_color.dart'; +import '../../../../widgets/date_and_time/date_picker.dart'; -class PentryCalibrationToolForm extends StatefulWidget { +class PpmExternalDetailsForm extends StatefulWidget { final List? models; - const PentryCalibrationToolForm({Key? key, this.models = const []}) : super(key: key); + const PpmExternalDetailsForm({Key? key, this.models = const []}) : super(key: key); @override - State createState() => _PentryCalibrationToolFormState(); + State createState() => _PpmExternalDetailsFormState(); } -class _PentryCalibrationToolFormState extends State { +class _PpmExternalDetailsFormState extends State { @override Widget build(BuildContext context) { final userProvider = Provider.of(context); return ListView.builder( itemCount: widget.models!.length + 1, - padding: EdgeInsets.only(top: 16.toScreenHeight), + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), itemBuilder: (context, index) { if (index == widget.models!.length) { return AppFilledButton( - label: context.translation.addAsset, + label: "Add More External Details".addTranslation, maxWidth: true, - textColor: Colors.white, - buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50, + textColor: AppColor.black10, + buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, + icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), + showIcon: true, onPressed: () async { if (widget.models?.isNotEmpty ?? false) { if (widget.models!.last.assetId == null) { @@ -68,7 +71,7 @@ class _PentryCalibrationToolFormState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "${context.translation.asset} ${index + 1}".heading5(context), + (index == 0 ? "1 /4 . External Details" : "").heading5(context), "trash".toSvgAsset(height: 20, width: 15).onPress(() { widget.models!.remove(model); setState(() {}); @@ -80,7 +83,7 @@ class _PentryCalibrationToolFormState extends State { initialValue: model.assetId == null ? null : Lookup(id: model.assetId?.toInt(), name: model.assetNumber ?? ""), hospitalId: userProvider.user!.clientId, onPick: (number) { - model.assetNumber = number.name; + model.assetNumber = number.assetNumber; model.assetId = number.id; setState(() {}); }, diff --git a/lib/views/pages/user/ppm/update_ppm/ppm_pm_check_list_form.dart b/lib/views/pages/user/ppm/update_ppm/ppm_pm_check_list_form.dart new file mode 100644 index 00000000..a496f2a9 --- /dev/null +++ b/lib/views/pages/user/ppm/update_ppm/ppm_pm_check_list_form.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/ppm/ppm_check_list.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +import 'package:test_sa/providers/ppm_checklist_status_provider.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; + +class PpmPmChecklistForm extends StatefulWidget { + final List? models; + + const PpmPmChecklistForm({Key? key, this.models}) : super(key: key); + + @override + State createState() => _PpmPmChecklistFormState(); +} + +class _PpmPmChecklistFormState extends State { + PpmChecklists item = PpmChecklists(); + List showLabel = []; + + @override + Widget build(BuildContext context) { + SettingProvider settingProvider = Provider.of(context, listen: false); + List? list = widget.models ?? []; + return (list.isEmpty) + ? const NoDataFound().center + : ListView.builder( + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), + itemCount: list.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (index == 0) ...[ + "4 /4 . PM Checklist".heading5(context), + 16.height, + ], + AppTextFormField( + labelText: "Task".addTranslation, + labelStyle: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, fontWeight: FontWeight.w500), + initialValue: (list[index].instructionTextId == null ? (list[index].task ?? "") : (list[index].text ?? "")), + enable: false, + showShadow: false, + enableColor: AppColor.neutral100, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + // backgroundColor: context.isDark ? AppColor.neutral50 : null, + onChange: (text) { + list[index].taskComment = text; + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + showShadow: false, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + initialValue: list[index].taskStatusId == null ? null : Lookup(id: list[index].taskStatusId!.toInt(), name: list[index].taskStatusName), + title: context.translation.taskStatus, + onSelect: (value) { + if (value != null) { + list[index].taskStatusId = value.id; + list[index].taskStatusName = value.name; + } + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.measuredValue, + labelStyle: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, fontWeight: FontWeight.w500), + initialValue: list[index].measuredValue ?? "", + // enable: false, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + showShadow: false, + onChange: (text) { + list[index].measuredValue = text; + }, + ), + 8.height, + AppTextFormField( + labelText: "Task Comment".addTranslation, + labelStyle: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120, fontWeight: FontWeight.w500), + initialValue: list[index].taskComment ?? "", + // enable: false, + backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, + showShadow: false, + onChange: (text) { + list[index].taskComment = text; + }, + ), + ], + ).toShadowContainer(context, showShadow: false, borderRadius: 20); + }, + ); + } +} diff --git a/lib/views/widgets/pentry/pentry_pm_kit_form.dart b/lib/views/pages/user/ppm/update_ppm/ppm_pm_kits_form.dart similarity index 79% rename from lib/views/widgets/pentry/pentry_pm_kit_form.dart rename to lib/views/pages/user/ppm/update_ppm/ppm_pm_kits_form.dart index e36f9be0..2e2ec24d 100644 --- a/lib/views/widgets/pentry/pentry_pm_kit_form.dart +++ b/lib/views/pages/user/ppm/update_ppm/ppm_pm_kits_form.dart @@ -2,38 +2,41 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/ppm/ppm_kit.dart'; -import '../../../new_views/app_style/app_color.dart'; -import '../../../new_views/common_widgets/app_filled_button.dart'; -import '../parts/auto_complete_parts_field.dart'; +import '../../../../../new_views/app_style/app_color.dart'; +import '../../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../widgets/parts/auto_complete_parts_field.dart'; -class PentryPMKitForm extends StatefulWidget { +class PpmPMKitsForm extends StatefulWidget { final List? models; final num? assetId; - const PentryPMKitForm({Key? key, this.models = const [], this.assetId}) : super(key: key); + const PpmPMKitsForm({Key? key, this.models = const [], this.assetId}) : super(key: key); @override - State createState() => _PentryPMKitFormState(); + State createState() => _PpmPMKitsFormState(); } -class _PentryPMKitFormState extends State { +class _PpmPMKitsFormState extends State { @override Widget build(BuildContext context) { return ListView.builder( itemCount: widget.models!.length + 1, shrinkWrap: true, - padding: EdgeInsets.only(top: 16.toScreenHeight), + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), itemBuilder: (context, index) { if (index == widget.models!.length) { return AppFilledButton( - label: context.translation.addItem, + label: "Add More PM Kits".addTranslation, maxWidth: true, - textColor: Colors.white, - buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50, + textColor: AppColor.black10, + buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, + icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), + showIcon: true, onPressed: () async { if (widget.models?.isNotEmpty ?? false) { if (widget.models!.last.partNumber == null) { @@ -65,7 +68,7 @@ class _PentryPMKitFormState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - "${context.translation.item} ${index + 1}".heading5(context), + (index == 0 ? "3 /4 . PM Kits" : "").heading5(context), "trash".toSvgAsset(width: 15, height: 20).onPress(() { widget.models!.remove(model); setState(() {}); diff --git a/lib/views/pages/user/ppm/update_ppm/update_ppm.dart b/lib/views/pages/user/ppm/update_ppm/update_ppm.dart new file mode 100644 index 00000000..6f92287b --- /dev/null +++ b/lib/views/pages/user/ppm/update_ppm/update_ppm.dart @@ -0,0 +1,162 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/ppm_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/widget_extensions.dart'; +import 'package:test_sa/models/all_requests_and_count_model.dart'; +import 'package:test_sa/models/ppm/ppm.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; +import 'package:test_sa/views/pages/user/ppm/update_ppm/ppm_external_details_form.dart'; + +import '../../../../../extensions/text_extensions.dart'; +import 'ppm_calibration_tools_form.dart'; +import 'ppm_pm_check_list_form.dart'; +import 'ppm_pm_kits_form.dart'; +import 'wo_info_form.dart'; + +class UpdatePpm extends StatefulWidget { + final Ppm ppm; + final RequestsDetails? details; + + const UpdatePpm({Key? key, required this.ppm, this.details}) : super(key: key); + + @override + State createState() => _UpdatePpmState(); +} + +class _UpdatePpmState extends State with SingleTickerProviderStateMixin { + late UserProvider _userProvider; + late PpmProvider _regularVisitsProvider; + late Ppm _ppm; + final GlobalKey _scaffoldKey = GlobalKey(); + + late TabController _tabController; + + _onSubmit() async { + if (!(await _ppm.validate(context))) { + setState(() {}); + return; + } + _ppm.removeEmptyObjects(); + await _regularVisitsProvider.updatePentry(context, user: _userProvider.user!, ppm: widget.ppm); + } + + @override + void initState() { + _ppm = widget.ppm; + _tabController = TabController(length: 4, vsync: this); + super.initState(); + } + + int tabIndex = 0; + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + _userProvider = Provider.of(context, listen: false); + _regularVisitsProvider = Provider.of(context, listen: false); + return Scaffold( + backgroundColor: AppColor.neutral110, + appBar: DefaultAppBar(title: context.translation.preventiveMaintenance), + key: _scaffoldKey, + body: SafeArea( + child: Column( + children: [ + DefaultTabController( + length: 2, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 16.toScreenHeight, bottom: 8), + decoration: BoxDecoration( + color: context.isDark ? AppColor.neutral50 : AppColor.white10, + borderRadius: BorderRadius.circular(10), + ), + child: TabBar( + 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) { + 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( + children: [ + WoInfoForm(model: _ppm), + TabBarView( + physics: const NeverScrollableScrollPhysics(), + controller: _tabController, + children: [ + PpmExternalDetailsForm(models: _ppm.vCalibrationTools), + PpmCalibrationToolsForm(models: _ppm.vCalibrationTools), + PpmPMKitsForm(models: _ppm.vKits, assetId: widget.ppm.assetId), + PpmPmChecklistForm(models: _ppm.vChecklists), + ], + ) + ], + ).expanded, + ], + ), + ).expanded, + Row( + children: [ + AppFilledButton( + buttonColor: AppColor.white60, + textColor: AppColor.neutral50, + onPressed: () { + _onSubmit(); + }, + label: context.translation.save, + ).expanded, + 16.width, + AppFilledButton( + onPressed: () { + if (tabIndex == 0) { + return; + } + if (_tabController.index == 3) { + _onSubmit(); + } else { + _tabController.animateTo(_tabController.index + 1); + setState(() {}); + } + }, + label: tabIndex == 0 ? "Complete".addTranslation : (_tabController.index == 3 ? "Complete".addTranslation : context.translation.next), + ).expanded, + ], + ).toShadowContainer(context, showShadow: false, borderRadius: 0), + ], + ), + ), + ); + } +} diff --git a/lib/views/pages/user/ppm/update_ppm/wo_info_form.dart b/lib/views/pages/user/ppm/update_ppm/wo_info_form.dart new file mode 100644 index 00000000..790a328e --- /dev/null +++ b/lib/views/pages/user/ppm/update_ppm/wo_info_form.dart @@ -0,0 +1,359 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.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/models/ppm/ppm.dart'; +import 'package:test_sa/models/ppm/ppm_attachment.dart'; +import 'package:test_sa/models/service_request/supplier_details.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; +import 'package:test_sa/providers/ppm_asset_availability_provider.dart'; +import 'package:test_sa/providers/ppm_electrical_safety_provider.dart'; +import 'package:test_sa/providers/ppm_service_provider.dart'; +import 'package:test_sa/providers/ppm_task_status_provider.dart'; +import 'package:test_sa/providers/work_order/vendor_provider.dart'; + +import '../../../../../models/lookup.dart'; +import '../../../../../new_views/common_widgets/app_text_form_field.dart'; +import '../../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; +import '../../../../../providers/ppm_device_status_provider.dart'; +import '../../../../../providers/ppm_visit_status_provider.dart'; +import '../../../../widgets/date_and_time/date_picker.dart'; +import '../../../../widgets/e_signature/e_signature.dart'; +import '../../../../widgets/images/multi_image_picker.dart'; +import '../../../../widgets/timer/app_timer.dart'; + +class WoInfoForm extends StatefulWidget { + final Ppm model; + + const WoInfoForm({Key? key, required this.model}) : super(key: key); + + @override + State createState() => _WoInfoFormState(); +} + +class _WoInfoFormState extends State { + SupplierDetails? initialSupplier; + SuppPersons? _suppPerson; + + @override + Widget build(BuildContext context) { + widget.model.files ??= []; + widget.model.files = (widget.model.files ?? []).where((element) => element.attachmentName?.isNotEmpty ?? false).toList(); + + double totalWorkingHours = widget.model.visitTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endDateTime!).difference(DateTime.parse(item.startDateTime!)).inSeconds) ?? 0; + + totalWorkingHours = totalWorkingHours; + + return ListView( + padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16), + children: [ + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.visitStatusId == null ? null : Lookup(name: widget.model.visitStatusName ?? "", id: widget.model.visitStatusId?.toInt()), + title: context.translation.ppmVisit, + onSelect: (value) { + if (value?.value == 4) { + "Status cannot be change to ${value?.name}.".addTranslation.showToast; + setState(() {}); + return; + } + + if (value != null) { + widget.model.visitStatusName = value.name; + widget.model.visitStatusId = value.id; + } + }, + ), + 8.height, + if (totalWorkingHours > 0.0) ...[ + Container( + height: 56.toScreenHeight, + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: context.isDark ? AppColor.neutral40 : AppColor.background(context), + borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Total Working Time", + style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), + ), + Text( + " ${formatDuration(totalWorkingHours.round())}", + style: Theme.of(context).textTheme.bodyMedium, + ), + ], + ), + ), + 8.height, + ], + AppTimer( + label: context.translation.timer, + timer: widget.model.tbsTimer, + enabled: widget.model.tbsTimer?.endAt == null, + timerProgress: (isRunning) { + print("timerProgress:$isRunning"); + }, + onChange: (timer) async { + widget.model.tbsTimer = timer; + return true; + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.deviceStatusId == null ? null : Lookup(name: widget.model.deviceStatusName ?? "", id: widget.model.deviceStatusId?.toInt()), + title: context.translation.deviceStatus, + onSelect: (value) { + if (value != null) { + widget.model.deviceStatusId = value.id; + widget.model.deviceStatusName = value.name; + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.taskStatusId == null ? null : Lookup(name: widget.model.taskStatusName ?? "", id: widget.model.taskStatusId?.toInt()), + title: context.translation.taskStatus, + onSelect: (value) { + if (value != null) { + widget.model.taskStatusId = value.id; + widget.model.taskStatusName = value.name; + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.assetAvailabilityId == null ? null : Lookup(name: widget.model.assetAvailabilityName ?? "", id: widget.model.assetAvailabilityId?.toInt()), + title: "Asset Availability", + onSelect: (value) { + if (value != null) { + widget.model.assetAvailabilityId = value.id; + widget.model.assetAvailabilityName = value.name; + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.safetyId == null ? null : Lookup(name: widget.model.safetyName ?? "", id: widget.model.safetyId?.toInt()), + title: "Electrical Safety", + onSelect: (value) { + if (value != null) { + widget.model.safetyId = value.id; + widget.model.safetyName = value.name; + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + initialValue: widget.model.typeOfServiceId == null ? null : Lookup(name: widget.model.typeOfServiceName ?? "", id: widget.model.typeOfServiceId?.toInt()), + title: context.translation.serviceType, + onSelect: (value) { + if (value != null) { + widget.model.typeOfServiceId = value.id; + widget.model.typeOfServiceName = value.name; + + widget.model.supplierId = null; + widget.model.supplierName = null; + initialSupplier = null; + _suppPerson = null; + widget.model.suppPersonId = null; + widget.model.suppPerson = null; + + setState(() {}); + } + }, + ), + 8.height, + if (widget.model.typeOfServiceId == 66) ...[ + SingleItemDropDownMenu( + context: context, + title: context.translation.supplier, + initialValue: initialSupplier, + showAsBottomSheet: true, + onSelect: (supplier) { + if (supplier != null) { + widget.model.supplierId = supplier.id; + widget.model.supplierName = supplier.name; + initialSupplier = supplier; + _suppPerson = null; + widget.model.suppPersonId = null; + widget.model.suppPerson = null; + setState(() {}); + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.supplierEngineer, + enabled: initialSupplier?.suppPersons?.isNotEmpty ?? false, + initialValue: _suppPerson, + staticData: initialSupplier?.suppPersons, + showAsBottomSheet: true, + onSelect: (suppPerson) { + if (suppPerson != null) { + _suppPerson = suppPerson; + widget.model.suppPersonId = suppPerson.id; + widget.model.suppPerson = suppPerson.name; + setState(() {}); + } + }, + ), + 8.height, + AppTextFormField( + labelText: "Telephone", + initialValue: (widget.model.telephone ?? "").toString(), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.number, + onChange: (value) { + widget.model.telephone = value; + }, + ), + 8.height, + AppTimer( + label: "External Supplier Timer", + timer: widget.model.externalEngineerTimer, + enabled: widget.model.externalEngineerTimer?.endAt == null, + timerProgress: (isRunning) { + print("timerProgress:$isRunning"); + }, + onChange: (timer) async { + widget.model.externalEngineerTimer = timer; + return true; + }, + ), + 8.height, + ], + ADatePicker( + label: context.translation.actualVisitDate, + date: DateTime.tryParse(widget.model.actualDate ?? ""), + from: DateTime.now().subtract(const Duration(days: 30)), + onDatePicker: (date) { + if (date.isBefore(DateTime.parse(widget.model.expectedDate!))) { + "Actual visit date must be greater then expected date".showToast; + return; + } + + widget.model.actualDate = date.toIso8601String(); + setState(() {}); + }, + ), + 8.height, + ADatePicker( + label: context.translation.expectedVisitDate, + date: DateTime.tryParse(widget.model.nextDate ?? ""), + from: DateTime.now().subtract(const Duration(days: 30)), + enable: false, + onDatePicker: (date) { + widget.model.nextDate = date.toIso8601String(); + setState(() {}); + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.travelingHours, + initialValue: (widget.model.travelingHours ?? "").toString(), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.number, + onChange: (value) { + widget.model.travelingHours = value; + }, + ), + 8.height, + MultiFilesPicker( + label: context.translation.attachImage, + files: widget.model.files!.map((e) => File(e.attachmentName!)).toList(), + onChange: (files) { + widget.model.files = files.map((e) => PpmAttachments(attachmentName: e.path)).toList(); + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.comments, + initialValue: (widget.model.comments ?? "").toString(), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + onChange: (value) { + widget.model.comments = value; + }, + ), + 8.height, + ESignature( + title: context.translation.nurseSignature, + oldSignature: widget.model.nurseSignature, + newSignature: widget.model.localNurseSignature, + onChange: (signature) { + widget.model.localNurseSignature = signature; + widget.model.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + 8.height, + ESignature( + title: context.translation.engSign, + oldSignature: widget.model.engSignature, + newSignature: widget.model.localEngineerSignature, + onChange: (signature) { + widget.model.localEngineerSignature = signature; + widget.model.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + ], + ); + } + + String formatDuration1(int seconds) { + int hours = seconds ~/ 3600; + int minutes = (seconds % 3600) ~/ 60; + + String formattedDuration = ''; + if (hours > 0) { + formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; + } + if (minutes > 0) { + formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; + } + if (formattedDuration.isEmpty) { + formattedDuration = 'Less than a minute'; + } + + return formattedDuration.trim(); + } + + String formatDuration(int seconds) { + int hours = seconds ~/ 3600; + int minutes = (seconds % 3600) ~/ 60; + int remainingSeconds = seconds % 60; + + String formattedDuration = ''; + if (hours > 0) { + formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; + } + if (minutes > 0) { + formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; + } + if (remainingSeconds > 0) { + formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} '; + } + if (formattedDuration.isEmpty) { + formattedDuration = 'Less than a second'; + } + + return formattedDuration.trim(); + } +} diff --git a/lib/views/widgets/date_and_time/date_picker.dart b/lib/views/widgets/date_and_time/date_picker.dart index 2d2f2abf..10997b6f 100644 --- a/lib/views/widgets/date_and_time/date_picker.dart +++ b/lib/views/widgets/date_and_time/date_picker.dart @@ -47,8 +47,8 @@ class ADatePicker extends StatelessWidget { (context.isDark && !enable ? AppColor.neutral50 : !enable - ? AppColor.neutral40 - : AppColor.background(context)), + ? AppColor.neutral40 + : AppColor.background(context)), borderRadius: BorderRadius.circular(10), border: withBorder ? Border.all(width: 1, color: Theme.of(context).scaffoldBackgroundColor) : const Border(), boxShadow: hideShadow ? null : [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], @@ -62,10 +62,10 @@ class ADatePicker extends StatelessWidget { children: [ label.tinyFont(context), (date == null - ? hint ?? context.translation.pickADate - : (formatDateWithTime - ? date?.toIso8601String().toFirstActionFormat // Use null-aware operator - : (date?.toIso8601String().split("T").first ?? context.translation.pickADate)))! + ? hint ?? context.translation.pickADate + : (formatDateWithTime + ? date?.toIso8601String().toFirstActionFormat // Use null-aware operator + : (date?.toIso8601String().split("T").first ?? context.translation.pickADate)))! .bodyText(context) .custom(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ], @@ -76,17 +76,17 @@ class ADatePicker extends StatelessWidget { ), ).onPress(enable ? () async { - final DateTime? picked = await showDatePicker( - // Nullable DateTime - context: context, - initialDate: DateTime.now(), - firstDate: from ?? DateTime.now(), - lastDate: to ?? DateTime.now().add(const Duration(days: 365)), - ); - if (picked != null && onDatePicker != null) { - onDatePicker!(picked); // Use null-aware operator - } - } + final DateTime? picked = await showDatePicker( + // Nullable DateTime + context: context, + initialDate: DateTime.now(), + firstDate: from ?? DateTime.now(), + lastDate: to ?? DateTime.now().add(const Duration(days: 365)), + ); + if (picked != null && onDatePicker != null) { + onDatePicker!(picked); // Use null-aware operator + } + } : null); } } diff --git a/lib/views/widgets/equipment/pick_asset.dart b/lib/views/widgets/equipment/pick_asset.dart index 73335a3d..f5d0f4ff 100644 --- a/lib/views/widgets/equipment/pick_asset.dart +++ b/lib/views/widgets/equipment/pick_asset.dart @@ -14,10 +14,10 @@ class PickAsset extends StatelessWidget { final Asset? device; // Now nullable final bool editable; final bool showAssetInfo; - final Color?cardColor; + final Color? cardColor; final bool forPPM; - const PickAsset({Key? key, this.editable = true, this.device, required this.onPickAsset,this.cardColor, this.showAssetInfo = true, this.forPPM = false}) : super(key: key); + const PickAsset({Key? key, this.editable = true, this.device, required this.onPickAsset, this.cardColor, this.showAssetInfo = true, this.forPPM = false}) : super(key: key); @override Widget build(BuildContext context) { @@ -26,9 +26,8 @@ class PickAsset extends StatelessWidget { if (editable) Container( decoration: BoxDecoration( - color:cardColor?? Theme.of(context).cardColor, + color: cardColor ?? Theme.of(context).cardColor, borderRadius: BorderRadius.circular(10), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], ), padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), child: Row( @@ -38,7 +37,7 @@ class PickAsset extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - context.translation.device.tinyFont(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50), + context.translation.device.tinyFont(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral120), if (device != null) device!.assetNumber!.bodyText(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50) else diff --git a/lib/views/widgets/parts/auto_complete_parts_field.dart b/lib/views/widgets/parts/auto_complete_parts_field.dart index b7e21466..cff4c7fe 100644 --- a/lib/views/widgets/parts/auto_complete_parts_field.dart +++ b/lib/views/widgets/parts/auto_complete_parts_field.dart @@ -61,7 +61,7 @@ class _AutoCompletePartsFieldState extends State { decoration: BoxDecoration( color: AppColor.background(context), borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + // boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], ), child: Autocomplete( optionsBuilder: (TextEditingValue textEditingValue) async { @@ -77,7 +77,7 @@ class _AutoCompletePartsFieldState extends State { return TextField( controller: fieldTextEditingController, focusNode: fieldFocusNode, - style: AppTextStyles.bodyText, + style: AppTextStyles.bodyText.copyWith(color: AppColor.black10), textAlign: TextAlign.start, decoration: InputDecoration( border: border, @@ -89,10 +89,11 @@ class _AutoCompletePartsFieldState extends State { constraints: const BoxConstraints(), suffixIconConstraints: const BoxConstraints(minWidth: 0), filled: true, - fillColor: (context.isDark ? AppColor.neutral50 : AppColor.background(context)), + fillColor: (context.isDark ? AppColor.neutral50 : AppColor.neutral100), errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60), floatingLabelStyle: AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20), labelText: widget.byName ? context.translation.partName : context.translation.partNumber, + labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120), ), textInputAction: TextInputAction.search, onSubmitted: (String value) { diff --git a/lib/views/widgets/pentry/calibration_tool_asset_picker.dart b/lib/views/widgets/pentry/calibration_tool_asset_picker.dart index eb0ea85a..bad35478 100644 --- a/lib/views/widgets/pentry/calibration_tool_asset_picker.dart +++ b/lib/views/widgets/pentry/calibration_tool_asset_picker.dart @@ -13,7 +13,7 @@ import '../../../../new_views/app_style/app_color.dart'; class CalibrationToolAssetPicker extends StatefulWidget { final Lookup? initialValue; final int? hospitalId; - final Function(Lookup) onPick; + final Function(Asset) onPick; const CalibrationToolAssetPicker({Key? key, this.initialValue, required this.onPick, this.hospitalId}) : super(key: key); @@ -57,7 +57,6 @@ class _CalibrationToolAssetPickerState extends State decoration: BoxDecoration( color: AppColor.background(context), borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -65,6 +64,7 @@ class _CalibrationToolAssetPickerState extends State PickAsset( showAssetInfo: false, forPPM: true, + cardColor: AppColor.neutral100, device: widget.initialValue == null ? null : Asset( @@ -72,7 +72,7 @@ class _CalibrationToolAssetPickerState extends State assetNumber: widget.initialValue!.name, ), onPickAsset: (device) { - widget.onPick(Lookup(id: device.id?.toInt(), name: device.assetNumber)); + widget.onPick(device); }, ), ], diff --git a/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart b/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart deleted file mode 100644 index 000b74a6..00000000 --- a/lib/views/widgets/pentry/pentry_ppm_check_list_form.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/int_extensions.dart'; -import 'package:test_sa/extensions/text_extensions.dart'; -import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/models/ppm/ppm_check_list.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; -import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/ppm_checklist_status_provider.dart'; -import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; - -class PentryPMChecklistForm extends StatefulWidget { - final List? models; - - const PentryPMChecklistForm({Key? key, this.models}) : super(key: key); - - @override - State createState() => _PentryPMChecklistFormState(); -} - -class _PentryPMChecklistFormState extends State { - PpmChecklists item = PpmChecklists(); - List showLabel = []; - - @override - Widget build(BuildContext context) { - SettingProvider settingProvider = Provider.of(context,listen:false); - print('value of asset group is ${settingProvider.assetGroup?.toJson()}'); - // List? list = widget.models?.where((element) => element.task != null).toList(); - List? list = widget.models??[]; - return (list.isEmpty) - ? const NoDataFound().center - : ListView.builder( - padding: EdgeInsets.only(top: 16.toScreenHeight), - itemCount: list.length , - shrinkWrap: true, - itemBuilder: (context, index) { - return Card( - child: ExpansionTile( - shape: const Border(), - title: (list[index].instructionTextId == null ? (list[index].task ?? "") : (list[index].text ?? "")).heading5(context), - onExpansionChanged: (value) { - if (!value) { - showLabel.remove(index); - } else { - showLabel.add(index); - } - setState(() {}); - }, - subtitle: showLabel.isNotEmpty && showLabel.contains(index) ? null : "${context.translation.status} ${list[index].taskStatusName}".bodyText(context), - iconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50, - collapsedIconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50, - childrenPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), - children: [ - if (showLabel.isNotEmpty && showLabel.contains(index)) - SingleItemDropDownMenu( - context: context, - backgroundColor: context.isDark ? AppColor.neutral50 : null, - initialValue: list[index].taskStatusId == null ? null : Lookup(id: list[index].taskStatusId!.toInt(), name: list[index].taskStatusName), - title: context.translation.status, - onSelect: (value) { - if (value != null) { - list[index].taskStatusId = value.id; - list[index].taskStatusName = value.name; - } - }, - ), - if (showLabel.isNotEmpty && showLabel.contains(index)) 8.height, - AppTextFormField( - labelText: context.translation.measuredValue, - initialValue: list[index].measuredValue ?? "", - // enable: false, - backgroundColor: context.isDark ? AppColor.neutral20 : null, - // backgroundColor: context.isDark ? AppColor.neutral50 : null, - onChange: (text) { - list[index].measuredValue = text; - }, - ), - 8.height, - AppTextFormField( - labelText: context.translation.comment, - initialValue: list[index].taskComment ?? "", - // enable: false, - backgroundColor: context.isDark ? AppColor.neutral20 : null, - // backgroundColor: context.isDark ? AppColor.neutral50 : null, - onChange: (text) { - list[index].taskComment = text; - }, - ), - 8.height, - ], - ), - ); - }, - ); - } -} diff --git a/lib/views/widgets/pentry/pentry_tbs_form.dart b/lib/views/widgets/pentry/pentry_tbs_form.dart deleted file mode 100644 index c78f0008..00000000 --- a/lib/views/widgets/pentry/pentry_tbs_form.dart +++ /dev/null @@ -1,363 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:flutter/material.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/models/ppm/ppm.dart'; -import 'package:test_sa/models/ppm/ppm_attachment.dart'; -import 'package:test_sa/models/service_request/supplier_details.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/providers/loading_list_notifier.dart'; -import 'package:test_sa/providers/ppm_asset_availability_provider.dart'; -import 'package:test_sa/providers/ppm_electrical_safety_provider.dart'; -import 'package:test_sa/providers/ppm_service_provider.dart'; -import 'package:test_sa/providers/ppm_task_status_provider.dart'; -import 'package:test_sa/providers/work_order/vendor_provider.dart'; - -import '../../../models/lookup.dart'; -import '../../../new_views/common_widgets/app_text_form_field.dart'; -import '../../../new_views/common_widgets/single_item_drop_down_menu.dart'; -import '../../../providers/ppm_device_status_provider.dart'; -import '../../../providers/ppm_visit_status_provider.dart'; -import '../date_and_time/date_picker.dart'; -import '../e_signature/e_signature.dart'; -import '../images/multi_image_picker.dart'; -import '../timer/app_timer.dart'; - -class PentryTBSForm extends StatefulWidget { - final Ppm model; - - const PentryTBSForm({Key? key, required this.model}) : super(key: key); - - @override - State createState() => _PentryTBSFormState(); -} - -class _PentryTBSFormState extends State { - SupplierDetails? initialSupplier; - SuppPersons? _suppPerson; - - @override - Widget build(BuildContext context) { - widget.model.files ??= []; - widget.model.files = (widget.model.files ?? []).where((element) => element.attachmentName?.isNotEmpty ?? false).toList(); - - double totalWorkingHours = widget.model.visitTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endDateTime!).difference(DateTime.parse(item.startDateTime!)).inSeconds) ?? 0; - - totalWorkingHours = totalWorkingHours; - - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.visitStatusId == null ? null : Lookup(name: widget.model.visitStatusName ?? "", id: widget.model.visitStatusId?.toInt()), - title: context.translation.ppmVisit, - onSelect: (value) { - if (value?.value == 4) { - "Status cannot be change to ${value?.name}.".addTranslation.showToast; - setState(() {}); - return; - } - - if (value != null) { - widget.model.visitStatusName = value.name; - widget.model.visitStatusId = value.id; - } - }, - ), - 8.height, - if (totalWorkingHours > 0.0) ...[ - Container( - height: 56.toScreenHeight, - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: context.isDark ? AppColor.neutral40 : AppColor.background(context), - borderRadius: BorderRadius.circular(10), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Total Working Time", - style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500), - ), - Text( - " ${formatDuration(totalWorkingHours.round())}", - style: Theme.of(context).textTheme.bodyMedium, - ), - ], - ), - ), - 8.height, - ], - AppTimer( - label: context.translation.timer, - timer: widget.model.tbsTimer, - enabled: widget.model.tbsTimer?.endAt == null, - timerProgress: (isRunning) { - print("timerProgress:$isRunning"); - }, - onChange: (timer) async { - widget.model.tbsTimer = timer; - return true; - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.deviceStatusId == null ? null : Lookup(name: widget.model.deviceStatusName ?? "", id: widget.model.deviceStatusId?.toInt()), - title: context.translation.deviceStatus, - onSelect: (value) { - if (value != null) { - widget.model.deviceStatusId = value.id; - widget.model.deviceStatusName = value.name; - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.taskStatusId == null ? null : Lookup(name: widget.model.taskStatusName ?? "", id: widget.model.taskStatusId?.toInt()), - title: context.translation.taskStatus, - onSelect: (value) { - if (value != null) { - widget.model.taskStatusId = value.id; - widget.model.taskStatusName = value.name; - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.assetAvailabilityId == null ? null : Lookup(name: widget.model.assetAvailabilityName ?? "", id: widget.model.assetAvailabilityId?.toInt()), - title: "Asset Availability", - onSelect: (value) { - if (value != null) { - widget.model.assetAvailabilityId = value.id; - widget.model.assetAvailabilityName = value.name; - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.safetyId == null ? null : Lookup(name: widget.model.safetyName ?? "", id: widget.model.safetyId?.toInt()), - title: "Electrical Safety", - onSelect: (value) { - if (value != null) { - widget.model.safetyId = value.id; - widget.model.safetyName = value.name; - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - initialValue: widget.model.typeOfServiceId == null ? null : Lookup(name: widget.model.typeOfServiceName ?? "", id: widget.model.typeOfServiceId?.toInt()), - title: context.translation.serviceType, - onSelect: (value) { - if (value != null) { - widget.model.typeOfServiceId = value.id; - widget.model.typeOfServiceName = value.name; - - widget.model.supplierId = null; - widget.model.supplierName = null; - initialSupplier = null; - _suppPerson = null; - widget.model.suppPersonId = null; - widget.model.suppPerson = null; - - setState(() {}); - } - }, - ), - 8.height, - if (widget.model.typeOfServiceId == 66) ...[ - SingleItemDropDownMenu( - context: context, - title: context.translation.supplier, - initialValue: initialSupplier, - showAsBottomSheet: true, - onSelect: (supplier) { - if (supplier != null) { - widget.model.supplierId = supplier.id; - widget.model.supplierName = supplier.name; - initialSupplier = supplier; - _suppPerson = null; - widget.model.suppPersonId = null; - widget.model.suppPerson = null; - setState(() {}); - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - title: context.translation.supplierEngineer, - enabled: initialSupplier?.suppPersons?.isNotEmpty ?? false, - initialValue: _suppPerson, - staticData: initialSupplier?.suppPersons, - showAsBottomSheet: true, - onSelect: (suppPerson) { - if (suppPerson != null) { - _suppPerson = suppPerson; - widget.model.suppPersonId = suppPerson.id; - widget.model.suppPerson = suppPerson.name; - setState(() {}); - } - }, - ), - 8.height, - AppTextFormField( - labelText: "Telephone", - initialValue: (widget.model.telephone ?? "").toString(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.number, - onChange: (value) { - widget.model.telephone = value; - }, - ), - 8.height, - AppTimer( - label: "External Supplier Timer", - timer: widget.model.externalEngineerTimer, - enabled: widget.model.externalEngineerTimer?.endAt == null, - timerProgress: (isRunning) { - print("timerProgress:$isRunning"); - }, - onChange: (timer) async { - widget.model.externalEngineerTimer = timer; - return true; - }, - ), - 8.height, - ], - ADatePicker( - label: context.translation.actualVisitDate, - date: DateTime.tryParse(widget.model.actualDate ?? ""), - from: DateTime.now().subtract(const Duration(days: 30)), - onDatePicker: (date) { - if (date.isBefore(DateTime.parse(widget.model.expectedDate!))) { - "Actual visit date must be greater then expected date".showToast; - return; - } - - widget.model.actualDate = date.toIso8601String(); - setState(() {}); - }, - ), - 8.height, - ADatePicker( - label: context.translation.expectedVisitDate, - date: DateTime.tryParse(widget.model.nextDate ?? ""), - from: DateTime.now().subtract(const Duration(days: 30)), - enable: false, - onDatePicker: (date) { - widget.model.nextDate = date.toIso8601String(); - setState(() {}); - }, - ), - 8.height, - AppTextFormField( - labelText: context.translation.travelingHours, - initialValue: (widget.model.travelingHours ?? "").toString(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.number, - onChange: (value) { - widget.model.travelingHours = value; - }, - ), - 8.height, - MultiFilesPicker( - label: context.translation.attachImage, - files: widget.model.files!.map((e) => File(e.attachmentName!)).toList(), - onChange: (files) { - widget.model.files = files.map((e) => PpmAttachments(attachmentName: e.path)).toList(); - }, - ), - 8.height, - AppTextFormField( - labelText: context.translation.comments, - initialValue: (widget.model.comments ?? "").toString(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - onChange: (value) { - widget.model.comments = value; - }, - ), - 8.height, - ESignature( - title: context.translation.nurseSignature, - oldSignature: widget.model.nurseSignature, - newSignature: widget.model.localNurseSignature, - onChange: (signature) { - widget.model.localNurseSignature = signature; - widget.model.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }, - ), - 8.height, - ESignature( - title: context.translation.engSign, - oldSignature: widget.model.engSignature, - newSignature: widget.model.localEngineerSignature, - onChange: (signature) { - widget.model.localEngineerSignature = signature; - widget.model.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }, - ), - 8.height, - ], - ), - ); - } - - String formatDuration1(int seconds) { - int hours = seconds ~/ 3600; - int minutes = (seconds % 3600) ~/ 60; - - String formattedDuration = ''; - if (hours > 0) { - formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; - } - if (minutes > 0) { - formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; - } - if (formattedDuration.isEmpty) { - formattedDuration = 'Less than a minute'; - } - - return formattedDuration.trim(); - } - - String formatDuration(int seconds) { - int hours = seconds ~/ 3600; - int minutes = (seconds % 3600) ~/ 60; - int remainingSeconds = seconds % 60; - - String formattedDuration = ''; - if (hours > 0) { - formattedDuration += '$hours hour${hours > 1 ? 's' : ''} '; - } - if (minutes > 0) { - formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} '; - } - if (remainingSeconds > 0) { - formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} '; - } - if (formattedDuration.isEmpty) { - formattedDuration = 'Less than a second'; - } - - return formattedDuration.trim(); - } -} diff --git a/lib/views/widgets/ppm/ppm_item.dart b/lib/views/widgets/ppm/ppm_item.dart index 81d57678..982e566d 100644 --- a/lib/views/widgets/ppm/ppm_item.dart +++ b/lib/views/widgets/ppm/ppm_item.dart @@ -9,7 +9,7 @@ import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/ppm/ppm.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/views/pages/user/ppm/ppm_details_page.dart'; -import 'package:test_sa/views/pages/user/ppm/update_ppm/edit_ppm.dart'; +import 'package:test_sa/views/pages/user/ppm/update_ppm/update_ppm.dart'; import '../../../controllers/providers/api/user_provider.dart'; import '../../../extensions/text_extensions.dart'; @@ -76,7 +76,7 @@ class PpmItem extends StatelessWidget { children: [ if (userProvider.user!.type == UsersTypes.engineer && (ppm.deviceStatusId != 270 || ppm.deviceStatusId != 269)) "edit".toSvgAsset(height: 48, width: 48).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => EditPpm(ppm: ppm, details: request))); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: ppm, details: request))); }), if (userProvider.user!.type == UsersTypes.engineer && (ppm.deviceStatusId != 270 || ppm.deviceStatusId != 269)) 8.height, Text(