import 'package:fcs/domain/entities/fcs_shipment.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; import 'package:provider/provider.dart'; import '../../domain/entities/package.dart'; import '../../domain/entities/user.dart'; import '../main/util.dart'; import '../widgets/continue_button.dart'; import '../widgets/local_text.dart'; import '../widgets/local_title.dart'; import '../widgets/previous_button.dart'; import 'model/package_selection_model.dart'; import 'package_selection_result.dart'; typedef OnPrevious = Function(List packages); typedef OnContinue = Function(List packages); class PackagesWidget extends StatefulWidget { final User sender; final User consignee; final FcsShipment shipment; final OnPrevious? onPrevious; final OnContinue? onContinue; const PackagesWidget({ super.key, this.onPrevious, this.onContinue, required this.shipment, required this.sender, required this.consignee, }); @override State createState() => _PackagesWidgetState(); } class _PackagesWidgetState extends State { final _scrollController = ScrollController(); bool _down = true; List _packages = []; bool _isLoading = false; @override void initState() { _init(); super.initState(); _scrollController.addListener(() { setState(() { _down = _scrollController.position.userScrollDirection == ScrollDirection.forward; }); }); } _init() async { _packages.clear(); _isLoading = true; var packageModel = context.read(); var list = await packageModel.getActivePackages( shipmentId: widget.shipment.id!, senderId: widget.sender.id!, consigneeId: widget.consignee.id!); _packages = List.from(list); _isLoading = false; if (mounted) { setState(() {}); } } @override Widget build(BuildContext context) { final senderBox = userDisplayBox(context, lableKey: "box.sender.title", icon: MaterialCommunityIcons.account_arrow_right, showLink: false, name: widget.sender.name ?? "", fcsID: widget.sender.fcsID ?? ""); final consigneeBox = userDisplayBox(context, showLink: false, lableKey: "box.consignee.title", icon: MaterialCommunityIcons.account_arrow_left, name: widget.consignee.name, fcsID: widget.consignee.fcsID); final userRow = Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(flex: 2, child: consigneeBox), Flexible(child: senderBox) ], ); final continueBtn = ContinueButton( onTap: () { if (_packages.isEmpty) { showMsgDialog(context, 'Error', "Please add the packages"); return false; } if (widget.onContinue != null) { widget.onContinue!(_packages); } }, ); final previousBtn = PreviousButton(onTap: () { if (widget.onPrevious != null) { widget.onPrevious!(_packages); } }); return Column( children: [ Expanded( child: Padding( padding: EdgeInsets.only(left: 10, right: 10), child: Column( children: [ AnimatedSwitcher( duration: const Duration(milliseconds: 300), transitionBuilder: (Widget child, Animation animation) => FadeTransition( opacity: animation, child: SizeTransition( sizeFactor: animation, axis: Axis.vertical, child: child, ), ), child: _down ? Column(children: [ const SizedBox(height: 8), userRow, LocalTitle( textKey: "box.select.package", topPadding: 5), const SizedBox(height: 10), ]) : const SizedBox(), ), Expanded( child: _packages.isEmpty && !_isLoading ? Center( child: LocalText(context, 'box.no_package', color: Colors.black, fontSize: 15)) : RefreshIndicator( color: primaryColor, onRefresh: () async { _init(); }, child: ListView.builder( padding: const EdgeInsets.only(top: 10), controller: _scrollController, shrinkWrap: true, physics: const AlwaysScrollableScrollPhysics(), itemBuilder: (context, index) { Package package = _packages[index]; return packageRow(context, package); }, itemCount: _packages.length)), ), ], ), ), ), widget.onContinue != null ? Padding( padding: const EdgeInsets.only(left: 15, right: 15, top: 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ previousBtn, continueBtn, ], ), ) : const SizedBox(), const SizedBox(height: 20) ], ); } Widget packageRow(BuildContext context, Package package) { return Padding( padding: const EdgeInsets.only(top: 5, bottom: 5), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(5)), border: Border.all(color: Colors.grey.shade300)), padding: EdgeInsets.only(left: 10, right: 10), child: Row( children: [ Expanded( child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(package.trackingID ?? "", style: TextStyle(fontSize: 15.0, color: Colors.black)), Text( package.cartonIds.isEmpty ? "-" : "${numberFormatter.format(package.cartonIds.length)} Boxes", style: TextStyle(fontSize: 15.0, color: Colors.grey), ), ], ), ), ), package.isChecked ? Icon(Icons.check, color: primaryColor) : const SizedBox() ], ), ), ); } }