Files
fcs/lib/pages/rates/cargo_editor.dart
2025-03-12 17:49:27 +06:30

288 lines
8.1 KiB
Dart

// ignore_for_file: use_build_context_synchronously
import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:provider/provider.dart';
import '../widgets/local_text.dart';
import 'model/shipment_rate_model.dart';
class CargoEditor extends StatefulWidget {
final CargoType? cargo;
const CargoEditor({super.key, this.cargo});
@override
_CargoEditorState createState() => _CargoEditorState();
}
class _CargoEditorState extends State<CargoEditor> {
TextEditingController descController = TextEditingController();
TextEditingController rateController = TextEditingController();
TextEditingController displayIndexController = TextEditingController();
bool _isLoading = false;
late CargoType _cargo;
bool _isNew = false;
final _cargoFormKey = GlobalKey<FormState>();
bool _isDefault = false;
bool _isMixCargo = false;
@override
void initState() {
super.initState();
if (widget.cargo != null) {
_cargo = widget.cargo!;
descController.text = _cargo.name ?? "";
rateController.text = _cargo.rate.toStringAsFixed(2);
displayIndexController.text = _cargo.displayIndex.toString();
_isDefault = _cargo.isDefault;
_isMixCargo = _cargo.isMixCargo;
} else {
_isNew = true;
}
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
final typeBox = InputText(
labelTextKey: 'cargo.type',
iconData: Ionicons.text,
controller: descController,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return "Please insert cargo type";
}
return null;
},
);
final rateBox = InputText(
labelTextKey: 'cargo.rate',
iconData: Fontisto.dollar,
controller: rateController,
textInputType: TextInputType.number,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value == null || value.isEmpty) {
return "Please insert rate";
}
return null;
},
);
final displayIndexBox = InputText(
labelTextKey: 'cargo.display_index',
iconData: FontAwesome.sort_numeric_asc,
controller: displayIndexController,
textInputType: TextInputType.number,
autovalidateMode: AutovalidateMode.onUserInteraction,
// validator: (value) {
// if (value == null || value.isEmpty) {
// return "Please insert display index";
// }
// return null;
// },
);
final defaultBox = Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocalText(
context,
'cargo.is_default',
color: Colors.black54,
fontSize: 15,
),
],
),
),
Transform.scale(
scale: 0.7,
alignment: Alignment.centerRight,
child: CupertinoSwitch(
activeTrackColor: primaryColor,
value: _isDefault,
onChanged: (v) {
setState(() {
_isDefault = v;
});
}))
]),
);
final mixCargoBox =
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocalText(
context,
'cargo.is_mix',
color: Colors.black54,
fontSize: 15,
),
],
),
),
Transform.scale(
scale: 0.7,
alignment: Alignment.centerRight,
child: CupertinoSwitch(
activeTrackColor: primaryColor,
value: _isMixCargo,
onChanged: (v) {
setState(() {
_isMixCargo = v;
});
}))
]);
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: LocalAppBar(
labelKey: "cargo.form.title",
backgroundColor: Colors.white,
labelColor: primaryColor,
arrowColor: primaryColor,
onBack: () {
if (isDataChanged()) {
showConfirmDialog(context, "back.button_confirm", () {
Navigator.of(context).pop();
});
} else {
Navigator.of(context).pop();
}
},
actions: [
_isNew
? Container()
: IconButton(
icon: Icon(Icons.delete, color: primaryColor),
onPressed: _delete,
)
],
),
body: Form(
key: _cargoFormKey,
child: Container(
padding: EdgeInsets.all(18),
child: Column(
children: <Widget>[
Expanded(
child: ListView(
children: <Widget>[
typeBox,
rateBox,
displayIndexBox,
SizedBox(height: 10),
defaultBox,
mixCargoBox,
SizedBox(height: 30),
],
),
),
fcsButton(context, getLocalString(context, "btn.save"),
callack: _save),
SizedBox(height: 30)
],
),
),
),
),
);
}
_save() async {
if (!_cargoFormKey.currentState!.validate()) {
return;
}
setState(() {
_isLoading = true;
});
try {
var shipmentRateModel =
Provider.of<ShipmentRateModel>(context, listen: false);
CargoType cargo = CargoType(
name: descController.text,
rate: double.parse(rateController.text),
displayIndex: displayIndexController.text == ''
? 0
: int.parse(displayIndexController.text),
isDefault: _isDefault,
isMixCargo: _isMixCargo);
if (_isNew) {
await shipmentRateModel.addCargoType(cargo);
} else {
cargo.id = _cargo.id;
await shipmentRateModel.updateCargoType(cargo);
}
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
_delete() {
showConfirmDialog(context, "cargo.edit.delete.confirm", _deleteCargoType);
}
_deleteCargoType() async {
setState(() {
_isLoading = true;
});
try {
var shipmentRateModel =
Provider.of<ShipmentRateModel>(context, listen: false);
await shipmentRateModel.deleteCargoType(_cargo.id!);
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
isDataChanged() {
if (_isNew) {
return descController.text != "" ||
rateController.text != "" ||
displayIndexController.text != "" ||
_isDefault != false ||
_isMixCargo != false;
} else {
CargoType cargo = CargoType(
name: descController.text,
rate: double.parse(rateController.text),
displayIndex: int.parse(displayIndexController.text),
isDefault: _isDefault,
isMixCargo: _isMixCargo);
return _cargo.isChangedForEdit(cargo);
}
}
}