update carton form and add recent search

This commit is contained in:
tzw
2024-09-23 18:36:23 +06:30
parent 458884bf70
commit 3629a8312c
16 changed files with 292 additions and 96 deletions

View File

@@ -151,6 +151,7 @@ class _CargoWidgetState extends State<CargoWidget> {
);
final userRow = Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: senderBox, flex: 2),
Flexible(child: consigneeBox)
@@ -265,7 +266,7 @@ class _CargoWidgetState extends State<CargoWidget> {
_surchargeControllers.clear();
_surchareItems.asMap().entries.forEach((e) {
var editor = new TextEditingController();
editor.text = e.value.qty == 0 ? "" : e.value.qty.toString();
editor.text = e.value.qty.toString();
_surchargeControllers.add(editor);
});
@@ -314,6 +315,12 @@ class _CargoWidgetState extends State<CargoWidget> {
final continueBtn = ContinueButton(
onTap: () {
if (widget.onContinue != null) {
if(_surchareItems.isNotEmpty && _surchareItems.any((item)=> item.qty == 0)){
showMsgDialog(context, "Error", "Please insert surcharge item quantity");
return;
}
widget.onContinue!(_cargoTypes, _surchareItems);
}
},

View File

@@ -167,27 +167,33 @@ class _CartonFilterState extends State<CartonFilter> {
final _titleWidget = SizedBox(
height: 30,
child: TabBar(
unselectedLabelColor: Colors.grey,
labelColor: primaryColor,
indicatorColor: primaryColor,
indicatorSize: TabBarIndicatorSize.tab,
labelPadding: const EdgeInsets.all(0),
indicatorPadding: const EdgeInsets.all(0),
tabs: [
Tab(
text: AppTranslations.of(context)?.text("box.fcs_shipment_num"),
),
Tab(
text: AppTranslations.of(context)?.text("box.consignee.title"),
),
Tab(
text: AppTranslations.of(context)?.text("box.sender.title"),
),
Tab(
text: AppTranslations.of(context)?.text("box.status"),
),
],
child: Theme(
data: ThemeData(
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
),
child: TabBar(
unselectedLabelColor: Colors.grey,
labelColor: primaryColor,
indicatorColor: primaryColor,
indicatorSize: TabBarIndicatorSize.tab,
labelPadding: const EdgeInsets.all(0),
indicatorPadding: const EdgeInsets.all(0),
tabs: [
Tab(
text: AppTranslations.of(context)?.text("box.fcs_shipment_num"),
),
Tab(
text: AppTranslations.of(context)?.text("box.consignee.title"),
),
Tab(
text: AppTranslations.of(context)?.text("box.sender.title"),
),
Tab(
text: AppTranslations.of(context)?.text("box.status"),
),
],
),
),
);

View File

@@ -16,7 +16,6 @@ import '../widgets/box_size_picker.dart';
import '../widgets/continue_button.dart';
import '../widgets/display_text.dart';
import '../widgets/local_dropdown.dart';
import '../widgets/local_radio_buttons.dart';
import '../widgets/local_text.dart';
import '../widgets/local_title.dart';
import '../widgets/previous_button.dart';
@@ -62,7 +61,7 @@ class CartonSizeWidget extends StatefulWidget {
}
class _CartonSizeWidgetState extends State<CartonSizeWidget> {
List<String> _deliveryTypes = [delivery_caton, pickup_carton];
// List<String> _deliveryTypes = [delivery_caton, pickup_carton];
FcsShipment? _shipment;
String _cartonSizeType = standardCarton;
@@ -132,7 +131,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
text: widget.sender.name,
labelTextKey: "box.sender.title",
iconData: MaterialCommunityIcons.account_arrow_right,
subText: Text(widget.sender.fcsID!,
subText: Text(widget.sender.fcsID ?? "",
style: TextStyle(fontSize: 13, color: labelColor)),
);
@@ -145,6 +144,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
);
final userRow = Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: senderBox,
@@ -154,14 +154,71 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
],
);
final deliveryTypeBox = LocalRadioButtons(
values: _deliveryTypes,
selectedValue: _selectedDeliveryType,
callback: (String? v) {
setState(() {
_selectedDeliveryType = v!;
});
});
final deliveryTypeBox = Container(
child: Row(
children: [
Flexible(
child: InkWell(
onTap: () {
setState(() {
_selectedDeliveryType = delivery_caton;
});
},
child: Row(children: <Widget>[
LocalRadio(
value: delivery_caton,
groupValue: _selectedDeliveryType,
onChanged: (p0) {
setState(() {
_selectedDeliveryType = delivery_caton;
});
},
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.delivery',
fontSize: 15,
color: _selectedDeliveryType == delivery_caton
? primaryColor
: Colors.black),
),
)
]),
)),
Flexible(
child: InkWell(
onTap: () {
setState(() {
_selectedDeliveryType = pickup_carton;
});
},
child: Row(children: <Widget>[
LocalRadio(
value: pickup_carton,
groupValue: _selectedDeliveryType,
onChanged: (p0) {
setState(() {
_selectedDeliveryType = pickup_carton;
});
},
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.pickup',
fontSize: 15,
color: _selectedDeliveryType == pickup_carton
? primaryColor
: Colors.black),
),
)
]),
),
)
],
),
);
final billRadioBox = Container(
child: Row(
@@ -186,7 +243,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.bill_to_sender',
child: LocalText(context, 'box.sender.title',
fontSize: 15,
color: _billToValue == billToSender
? primaryColor
@@ -215,7 +272,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.bill_to.consignee',
child: LocalText(context, 'box.consignee.title',
fontSize: 15,
color: _billToValue == billToConsignee
? primaryColor
@@ -465,12 +522,14 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
children: [
const SizedBox(height: 8),
userRow,
LocalTitle(textKey: "box.bill_to", topPadding: 8),
const SizedBox(height: 5),
billRadioBox,
const SizedBox(height: 8),
LocalTitle(textKey: "box.select.delivery"),
const SizedBox(height: 5),
deliveryTypeBox,
const SizedBox(height: 5),
const SizedBox(height: 8),
LocalTitle(textKey: "box.select_carton_size"),
const SizedBox(height: 8),
cartonSizedBox,

View File

@@ -71,7 +71,8 @@ class CartonSubmit extends StatelessWidget {
child: SubmitTextWidget(
labelKey: 'box.carton.type',
text: carton_from_packages,
subText: boxDimension),
// subText: boxDimension
),
);
final shipmentBox = Padding(
@@ -135,9 +136,9 @@ class CartonSubmit extends StatelessWidget {
],
),
),
billToValue == billToSender
? billWidget(context)
: const SizedBox()
// billToValue == billToSender
// ? billWidget(context)
// : const SizedBox()
],
),
),
@@ -162,9 +163,9 @@ class CartonSubmit extends StatelessWidget {
],
),
),
billToValue == billToConsignee
? billWidget(context)
: const SizedBox()
// billToValue == billToConsignee
// ? billWidget(context)
// : const SizedBox()
],
),
))
@@ -174,14 +175,30 @@ class CartonSubmit extends StatelessWidget {
]),
);
final billToBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.bill_to',
text: billToValue == billToSender ? 'Sender' : 'Consignee',
),
);
final deliveryTypeBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.delivery_type',
labelKey: 'box.select.delivery',
text: deliveryType,
),
);
final cartonSizeBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.carton_size',
text: boxDimension??'',
),
);
final packagesBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
@@ -341,12 +358,16 @@ class CartonSubmit extends StatelessWidget {
children: [
cartonType,
const SizedBox(height: 10),
shipmentBox,
const SizedBox(height: 10),
usersBox,
const SizedBox(height: 10),
billToBox,
const SizedBox(height: 10),
deliveryTypeBox,
const SizedBox(height: 10),
cartonSizeBox,
const SizedBox(height: 10),
shipmentBox,
const SizedBox(height: 10),
packages.isNotEmpty ? packagesBox : const SizedBox(),
const SizedBox(height: 10),
cargosBox,

View File

@@ -3,7 +3,6 @@ import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_title.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -117,9 +116,6 @@ class _CustomDutyAdditionState extends State<CustomDutyAddition> {
child: ListView(
shrinkWrap: true,
children: <Widget>[
LocalTitle(
textKey: "box.select.cargo.title",
),
Column(
children: getCargoRowList(customDuties),
),

View File

@@ -112,7 +112,15 @@ class _MixCartonSubmitState extends State<MixCartonSubmit> {
child: SubmitTextWidget(
labelKey: 'box.carton.type',
text: carton_mix_carton,
subText: boxDimension,
// subText: boxDimension,
),
);
final cartonSizeBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.carton_size',
text: boxDimension ?? '',
),
);
@@ -284,6 +292,8 @@ class _MixCartonSubmitState extends State<MixCartonSubmit> {
children: [
cartonType,
const SizedBox(height: 10),
cartonSizeBox,
const SizedBox(height: 10),
shipmentBox,
const SizedBox(height: 10),
widget.cartons.isNotEmpty ? cartonsBox : const SizedBox(),

View File

@@ -126,6 +126,7 @@ class _PackageSelectionWidgetState extends State<PackageSelectionWidget> {
);
final userRow = Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: senderBox,

View File

@@ -31,7 +31,7 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
bool _isLoading = false;
bool _isNew = true;
final _deliveryFormKey=GlobalKey<FormState>();
final _deliveryFormKey = GlobalKey<FormState>();
@override
void initState() {
@@ -64,8 +64,8 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
controller: _nameController,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if(value==null || value.isEmpty){
return"Please enter full name";
if (value == null || value.isEmpty) {
return "Please enter full name";
}
return null;
});
@@ -74,10 +74,10 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
labelTextKey: 'delivery_address.address_line1',
iconData: Icons.location_on,
controller: _address1Controller,
autovalidateMode: AutovalidateMode.onUserInteraction,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if(value==null || value.isEmpty){
return"Please enter address";
if (value == null || value.isEmpty) {
return "Please enter address";
}
return null;
});
@@ -91,10 +91,10 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
labelTextKey: 'delivery_address.city',
iconData: Icons.location_city,
controller: _cityController,
autovalidateMode: AutovalidateMode.onUserInteraction,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if(value==null || value.isEmpty){
return"Please enter city";
if (value == null || value.isEmpty) {
return "Please enter city";
}
return null;
});
@@ -103,10 +103,10 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
labelTextKey: 'delivery_address.state_region',
iconData: Entypo.location,
controller: _stateController,
autovalidateMode: AutovalidateMode.onUserInteraction,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if(value==null || value.isEmpty){
return"Please enter state/region";
if (value == null || value.isEmpty) {
return "Please enter state/region";
}
return null;
});
@@ -116,10 +116,10 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
iconData: Icons.phone,
textInputType: TextInputType.phone,
controller: _phoneController,
autovalidateMode: AutovalidateMode.onUserInteraction,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if(value==null || value.isEmpty){
return"Please enter phone number";
if (value == null || value.isEmpty) {
return "Please enter phone number";
}
return null;
});
@@ -207,7 +207,7 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
}
Future<bool> _validate(DeliveryAddress deliveryAddress) async {
if(_deliveryFormKey.currentState!.validate()){
if (!_deliveryFormKey.currentState!.validate()) {
return false;
}
// if (deliveryAddress.addressLine1 == "") {
@@ -236,7 +236,7 @@ class _DeliveryAddressEditorState extends State<DeliveryAddressEditor> {
if (!valid) {
return;
}
if (widget.user != null) {
deliveryAddress.userID = widget.user!.id;
}

View File

@@ -87,7 +87,7 @@ class FcsShipmentModel extends BaseModel {
try {
var snaps = await FirebaseFirestore.instance
.collection("/$fcs_shipment_collection")
.where("status", isEqualTo: fcs_shipment_processed_status)
// .where("status", isEqualTo: fcs_shipment_processed_status)
.get(const GetOptions(source: Source.server));
fcsShipments = snaps.docs.map((documentSnapshot) {
var fcs =

View File

@@ -13,6 +13,8 @@ import 'package:fcs/pagination/paginator_listener.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as Path;
import '../../../helpers/shared_pref.dart';
class PackageModel extends BaseModel {
final log = Logger('PackageModel');
@@ -214,7 +216,10 @@ class PackageModel extends BaseModel {
return packages;
}
Future<List<User>> searchUser(String term) {
Future<List<User>> searchUser(String term) async {
if (term != '') {
await SharedPref.saveRecentSearch('account_search', term);
}
return Services.instance.userService.searchUser(term);
}

View File

@@ -7,6 +7,8 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../data/services/services.dart';
import '../../helpers/shared_pref.dart';
import '../widgets/suggest_list.dart';
typedef OnUserSelect(User suer);
typedef OnUserRowSelect(User suer);
@@ -79,7 +81,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
child: Text(
"No result found",
textAlign: TextAlign.center,
style: TextStyle(color:Colors.black),
style: TextStyle(color: Colors.black),
),
),
);
@@ -118,12 +120,26 @@ class UserSearchDelegate extends SearchDelegate<User> {
@override
Widget buildSuggestions(BuildContext context) {
return Container(
child: Center(
child: Opacity(
opacity: 0.2,
child: Icon(Icons.perm_identity, size: 200, color: primaryColor)),
),
return FutureBuilder<List<String>?>(
future: SharedPref.getRecentSearch('account_search', query),
builder: (context, snapshot) {
List<String> _oldFilters = snapshot.data ?? [];
if (_oldFilters.isEmpty) {
return const Center(
child: Opacity(
opacity: 0.2,
child: Icon(Icons.perm_identity, color: primaryColor, size: 200),
),
);
}
return SuggestList(
recentSearchList: _oldFilters,
onTap: (String s) {
query = s;
showResults(context);
},
prefKey: 'account_search');
},
);
}

View File

@@ -0,0 +1,53 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../helpers/theme.dart';
typedef OnTap = Function(String query);
class SuggestList extends StatefulWidget {
final List<String>? recentSearchList;
final String prefKey;
final OnTap? onTap;
const SuggestList(
{Key? key, this.recentSearchList, this.onTap, required this.prefKey})
: super(key: key);
@override
_SuggestListState createState() => _SuggestListState();
}
class _SuggestListState extends State<SuggestList> {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.recentSearchList?.length,
itemBuilder: (context, index) {
return ListTile(
leading: const Icon(Icons.restore, color: labelColor),
title: Text(
widget.recentSearchList?[index] ?? '',
style: const TextStyle(color: primaryColor),
),
onTap: () {
if (widget.onTap != null) {
widget.onTap!(widget.recentSearchList![index]);
}
},
trailing: IconButton(
icon: const Icon(Icons.close, color: labelColor),
onPressed: () async {
setState(() {
widget.recentSearchList
?.remove(widget.recentSearchList?[index]);
});
final prefs = await SharedPreferences.getInstance();
prefs.setStringList(widget.prefKey, widget.recentSearchList!);
setState(() {});
},
),
);
},
);
}
}