From c77874d72ca1d8eb51ccd53e3a4fa1bc3e30d30c Mon Sep 17 00:00:00 2001 From: tzw Date: Wed, 21 Feb 2024 17:05:20 +0630 Subject: [PATCH] update pin editor --- assets/local/localization_en.json | 6 +- .../provider/fcs_shipment_data_provider.dart | 30 +++- lib/data/services/fcs_shipment_imp.dart | 30 +++- lib/data/services/fcs_shipment_service.dart | 6 +- .../fcs_shipment/fcs_shipment_editor.dart | 3 + lib/pages/fcs_shipment/fcs_shipment_info.dart | 12 +- .../model/fcs_shipment_model.dart | 16 ++- lib/pages/staff/model/staff_model.dart | 13 ++ lib/pages/staff/staff_pin_editor.dart | 134 ++++++++++++++---- 9 files changed, 199 insertions(+), 51 deletions(-) diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 23ed0e6..e531f33 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -392,9 +392,9 @@ "FCSshipment.create":"Create new shipment", "FCSshipment.update":"Update shipment", "FCSshipment.ship.btn":"Ship this shipment", - "FCSshipment.process.btn":"Processed this shipment", - "FCSshipment.arrive.btn":"Arrived this shipment", - "FCSshipment.invoiced.btn":"Invoiced this shipment", + "FCSshipment.process.btn":"Process this shipment", + "FCSshipment.arrive.btn":"Arrive this shipment", + "FCSshipment.invoiced.btn":"Invoice this shipment", "FCSshipment.ship.confirm":"Confirm ship?", "FCSshipment.cancel.btn":"Cancel this shipment", "FCSshipment.cancel.confirm":"Cancel this shipment?", diff --git a/lib/data/provider/fcs_shipment_data_provider.dart b/lib/data/provider/fcs_shipment_data_provider.dart index 9fbf375..34a0dc2 100644 --- a/lib/data/provider/fcs_shipment_data_provider.dart +++ b/lib/data/provider/fcs_shipment_data_provider.dart @@ -21,14 +21,34 @@ class FcsShipmentDataProvider { payload: fcsShipment.toMap(), token: await getToken()); } - Future ship(FcsShipment fcsShipment) async { - return await requestAPI("/fcs_shipments/ship", "PUT", - payload: fcsShipment.toMap(), token: await getToken()); - } - Future reportFcsShipment(FcsShipment fcsShipment) async { dynamic data = await requestAPI("/fcs_shipments/report", "POST", payload: fcsShipment.toMap(), token: await getToken()); return data["url"]; } + + Future processFcsShipment(String id) async { + return await requestAPI("/shipments/process", "PUT", + payload: {"id": id}, token: await getToken()); + } + + Future cancelFcsShipment(String id) async { + return await requestAPI("/shipments/cancel", "PUT", + payload: {"id": id}, token: await getToken()); + } + + Future shipFcsShipment(String id) async { + return await requestAPI("/shipments/ship", "PUT", + payload: {"id": id}, token: await getToken()); + } + + Future arriveFcsShipment(String id) async { + return await requestAPI("/shipments/arrive", "PUT", + payload: {"id": id}, token: await getToken()); + } + + Future invoiceFcsShipment(String id) async { + return await requestAPI("/shipments/invoice", "PUT", + payload: {"id": id}, token: await getToken()); + } } diff --git a/lib/data/services/fcs_shipment_imp.dart b/lib/data/services/fcs_shipment_imp.dart index 35e5071..6e5b4bc 100644 --- a/lib/data/services/fcs_shipment_imp.dart +++ b/lib/data/services/fcs_shipment_imp.dart @@ -28,13 +28,33 @@ class FcsShipmentServiceImp implements FcsShipmentService { return shipmentDataProvider.deleteFcsShipment(fcsShipment); } - @override - Future ship(FcsShipment fcsShipment) { - return shipmentDataProvider.ship(fcsShipment); - } - @override Future report(FcsShipment fcsShipment) { return shipmentDataProvider.reportFcsShipment(fcsShipment); } + + @override + Future arriveFcsShipment(String id) { + return shipmentDataProvider.arriveFcsShipment(id); + } + + @override + Future cancelFcsShipment(String id) { + return shipmentDataProvider.cancelFcsShipment(id); + } + + @override + Future invoiceFcsShipment(String id) { + return shipmentDataProvider.invoiceFcsShipment(id); + } + + @override + Future processFcsShipment(String id) { + return shipmentDataProvider.processFcsShipment(id); + } + + @override + Future shipFcsShipment(String id) { + return shipmentDataProvider.shipFcsShipment(id); + } } diff --git a/lib/data/services/fcs_shipment_service.dart b/lib/data/services/fcs_shipment_service.dart index 2284122..4805783 100644 --- a/lib/data/services/fcs_shipment_service.dart +++ b/lib/data/services/fcs_shipment_service.dart @@ -4,6 +4,10 @@ abstract class FcsShipmentService { Future createFcsShipment(FcsShipment fcsShipment); Future updateFcsShipment(FcsShipment fcsShipment); Future deleteFcsShipment(FcsShipment fcsShipment); - Future ship(FcsShipment fcsShipment); Future report(FcsShipment fcsShipment); + Future processFcsShipment(String id); + Future cancelFcsShipment(String id); + Future shipFcsShipment(String id); + Future arriveFcsShipment(String id); + Future invoiceFcsShipment(String id); } diff --git a/lib/pages/fcs_shipment/fcs_shipment_editor.dart b/lib/pages/fcs_shipment/fcs_shipment_editor.dart index 70eb196..a5f3448 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_editor.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_editor.dart @@ -150,10 +150,12 @@ class _FcsShipmentEditorState extends State { return null; }, ), + const SizedBox(height: 20), DropdownButtonFormField( value: _currentShipmentType == "" ? null : _currentShipmentType, decoration: InputDecoration( + contentPadding: EdgeInsets.zero, enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: primaryColor)), focusedBorder: UnderlineInputBorder( @@ -175,6 +177,7 @@ class _FcsShipmentEditorState extends State { }) }, ), + const SizedBox(height: 5), InputText( labelTextKey: 'FCSshipment.consignee', iconData: Icons.work, diff --git a/lib/pages/fcs_shipment/fcs_shipment_info.dart b/lib/pages/fcs_shipment/fcs_shipment_info.dart index 1ae5354..13effdd 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_info.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_info.dart @@ -135,21 +135,21 @@ class _FcsShipmentInfoState extends State { padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( textKey: "FCSshipment.process.btn", - callBack: _ship, + callBack: () {}, ), ); final arriveBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( textKey: "FCSshipment.arrive.btn", - callBack: _ship, + callBack: () {}, ), ); final invoiceBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( textKey: "FCSshipment.invoice.btn", - callBack: _ship, + callBack: () {}, ), ); @@ -226,9 +226,7 @@ class _FcsShipmentInfoState extends State { _fcsShipment?.status == fcs_shipment_arrived_status ? invoiceBtn : Container(), - SizedBox( - height: 20, - ) + SizedBox(height: 20) ]), ), ), @@ -296,7 +294,7 @@ class _FcsShipmentInfoState extends State { try { FcsShipmentModel fcsShipmentModel = Provider.of(context, listen: false); - await fcsShipmentModel.ship(_fcsShipment!); + await fcsShipmentModel.ship(_fcsShipment!.id!); Navigator.pop(context, true); } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart index c921bd3..efdd301 100644 --- a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart +++ b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart @@ -147,8 +147,20 @@ class FcsShipmentModel extends BaseModel { return Services.instance.fcsShipmentService.updateFcsShipment(fcsShipment); } - Future ship(FcsShipment fcsShipment) { - return Services.instance.fcsShipmentService.ship(fcsShipment); + Future process(String id) { + return Services.instance.fcsShipmentService.processFcsShipment(id); + } + + Future ship(String id) { + return Services.instance.fcsShipmentService.shipFcsShipment(id); + } + + Future arrive(String id) { + return Services.instance.fcsShipmentService.arriveFcsShipment(id); + } + + Future invoice(String id) { + return Services.instance.fcsShipmentService.invoiceFcsShipment(id); } Future report(FcsShipment fcsShipment) { diff --git a/lib/pages/staff/model/staff_model.dart b/lib/pages/staff/model/staff_model.dart index 705737a..0db5bfe 100644 --- a/lib/pages/staff/model/staff_model.dart +++ b/lib/pages/staff/model/staff_model.dart @@ -78,6 +78,19 @@ class StaffModel extends BaseModel { token: await getToken()); } + Future updatePin( + {required String userID, + required bool enablePin, + required int pin}) async { + // await request("/employee/pin", "PUT", + // payload: { + // "id": userID, + // "enable_pin_login": enablePin, + // "new_pin": pin + // }, + // token: await getToken()); + } + Future findUser(String phoneNumber) { return Services.instance.userService.findUser(phoneNumber); } diff --git a/lib/pages/staff/staff_pin_editor.dart b/lib/pages/staff/staff_pin_editor.dart index 0f08e9e..ab2ceef 100644 --- a/lib/pages/staff/staff_pin_editor.dart +++ b/lib/pages/staff/staff_pin_editor.dart @@ -4,9 +4,11 @@ import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; import 'package:pin_input_text_field/pin_input_text_field.dart'; +import 'package:provider/provider.dart'; import '../main/util.dart'; import '../widgets/local_text.dart'; +import 'model/staff_model.dart'; class StaffPinEditor extends StatefulWidget { final User staff; @@ -22,38 +24,69 @@ class _StaffPinEditorState extends State { bool _enablePinLogin = false; String _newPin = ""; String _confirmPin = ""; + FocusNode _newPinFocus = FocusNode(); + FocusNode _confirmPinFocus = FocusNode(); + TextEditingController _newPinCtl = TextEditingController(); + TextEditingController _confirmPinCtl = TextEditingController(); @override void initState() { + _init(); + super.initState(); + } + + _init() { _staff = widget.staff; _enablePinLogin = _staff.enablePinLogin; _newPin = _staff.pinDigit ?? ""; _confirmPin = _staff.confirmPinDigit ?? ""; - super.initState(); + _newPinCtl.text = _newPin; + _confirmPinCtl.text = _confirmPin; + _checkFocusNode(); + + if (mounted) { + setState(() {}); + } + } + + @override + void dispose() { + _newPinFocus.dispose(); + _confirmPinFocus.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { - final enablePinBox = Row( - children: [ - Checkbox( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - visualDensity: const VisualDensity( + final enablePinBox = InkWell( + onTap: () { + setState(() { + _enablePinLogin = !_enablePinLogin; + }); + _checkFocusNode(); + }, + child: Row( + children: [ + Checkbox( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + visualDensity: const VisualDensity( horizontal: VisualDensity.minimumDensity, - vertical: VisualDensity.minimumDensity), - activeColor: primaryColor, - side: BorderSide(color: Colors.black38, width: 2), - value: _enablePinLogin, - onChanged: (value) { - setState(() { - _enablePinLogin = value ?? false; - }); - }, - ), - const SizedBox(width: 15), - LocalText(context, 'staff.enable_pin', - fontSize: 15, color: Colors.black) - ], + ), + activeColor: primaryColor, + side: BorderSide(color: Colors.black38, width: 2), + value: _enablePinLogin, + onChanged: (value) { + setState(() { + _enablePinLogin = value ?? false; + }); + _checkFocusNode(); + }, + ), + const SizedBox(width: 15), + LocalText(context, 'staff.enable_pin', + fontSize: 15, color: Colors.black) + ], + ), ); final newPinBox = Column( @@ -63,14 +96,17 @@ class _StaffPinEditorState extends State { color: Colors.black54, fontSize: 15), const SizedBox(height: 8), PinInputTextField( + controller: _newPinCtl, + enabled: _enablePinLogin, cursor: Cursor( color: primaryColor, enabled: true, width: 2, height: 23), pinLength: 6, decoration: BoxLooseDecoration( - strokeColorBuilder: - PinListenColorBuilder(primaryColor, Colors.grey.shade400)), + strokeColorBuilder: PinListenColorBuilder( + _enablePinLogin ? primaryColor : Colors.grey.shade400, + Colors.grey.shade400)), textInputAction: TextInputAction.done, - autoFocus: true, + focusNode: _newPinFocus, onChanged: _newPinChange), ], ); @@ -82,14 +118,17 @@ class _StaffPinEditorState extends State { color: Colors.black54, fontSize: 15), const SizedBox(height: 8), PinInputTextField( + controller: _confirmPinCtl, + enabled: _enablePinLogin, pinLength: 6, cursor: Cursor( color: primaryColor, enabled: true, width: 2, height: 23), decoration: BoxLooseDecoration( - strokeColorBuilder: - PinListenColorBuilder(primaryColor, Colors.grey.shade400)), + strokeColorBuilder: PinListenColorBuilder( + _enablePinLogin ? primaryColor : Colors.grey.shade400, + Colors.grey.shade400)), textInputAction: TextInputAction.done, - autoFocus: false, + focusNode: _confirmPinFocus, onChanged: _confirmPinChange), ], ); @@ -125,9 +164,9 @@ class _StaffPinEditorState extends State { style: TextStyle(color: Colors.black, fontSize: 15)), ], ), - const SizedBox(height: 20), + const SizedBox(height: 10), enablePinBox, - const SizedBox(height: 30), + const SizedBox(height: 20), FormField( builder: (FormFieldState state) { return Column( @@ -211,9 +250,44 @@ class _StaffPinEditorState extends State { )); } + _checkFocusNode() { + if (_enablePinLogin) { + _onChangeFocusNode(); + } else { + _cancelFoucsNode(); + } + if (mounted) { + setState(() {}); + } + } + + _onChangeFocusNode() { + if (this._newPin.length == 6) { + _newPinFocus.unfocus(); + Future.delayed(const Duration(milliseconds: 300), () { + _confirmPinFocus.requestFocus(); + }); + } else { + _confirmPinFocus.unfocus(); + Future.delayed(const Duration(milliseconds: 300), () { + _newPinFocus.requestFocus(); + }); + } + } + + _cancelFoucsNode() { + _newPinFocus.unfocus(); + Future.delayed(const Duration(milliseconds: 300), () { + _confirmPinFocus.unfocus(); + }); + } + _newPinChange(pin) { setState(() { this._newPin = pin; + if (this._newPin.length == 6) { + _confirmPinFocus.requestFocus(); + } }); } @@ -231,6 +305,10 @@ class _StaffPinEditorState extends State { }); try { + await context.read().updatePin( + userID: _staff.id!, + enablePin: _enablePinLogin, + pin: int.parse(_confirmPin)); Navigator.pop(context, true); } catch (e) { showMsgDialog(context, "Error", e.toString());