add pagination for invoice and update ui for material 3

This commit is contained in:
tzw
2024-01-26 16:56:20 +06:30
parent 93a5fe071a
commit 8d0f712bf4
32 changed files with 351 additions and 635 deletions

View File

@@ -14,8 +14,8 @@ class CustomDuty {
factory CustomDuty.fromMap(Map<String, dynamic> map, String id) { factory CustomDuty.fromMap(Map<String, dynamic> map, String id) {
return CustomDuty( return CustomDuty(
id: id, id: id,
productType: map['product_type'], productType: map['product_type'] ?? "",
desc: map['desc'], desc: map['desc'] ?? "",
fee: (map['fee'] ?? 0).toDouble(), fee: (map['fee'] ?? 0).toDouble(),
); );
} }

View File

@@ -133,8 +133,9 @@ class Invoice {
cargoTypesMaps.map((e) => CargoType.fromMap(e, e["id"])).toList(); cargoTypesMaps.map((e) => CargoType.fromMap(e, e["id"])).toList();
var customDutiesMap = var customDutiesMap =
List<Map<String, dynamic>>.from(map['custom_duties'] ?? []); List<Map<String, dynamic>>.from(map['custom_duties'] ?? []);
var customDuties = var customDuties = customDutiesMap
customDutiesMap.map((e) => CustomDuty.fromMap(e, e["id"])).toList(); .map((e) => CustomDuty.fromMap(e, e["id"] ?? ""))
.toList();
var handlingShipmentsMap = var handlingShipmentsMap =
List<Map<String, dynamic>>.from(map['handling_fee_shipments'] ?? []); List<Map<String, dynamic>>.from(map['handling_fee_shipments'] ?? []);
var handingShipments = var handingShipments =
@@ -149,22 +150,23 @@ class Invoice {
var discount = Discount.fromMap(discountMap, discountMap['id']); var discount = Discount.fromMap(discountMap, discountMap['id']);
var paymentMaps = List<Map<String, dynamic>>.from(map['payments'] ?? []); var paymentMaps = List<Map<String, dynamic>>.from(map['payments'] ?? []);
var payments = paymentMaps.map((e) => Payment.fromMap(e, e["id"])).toList(); var payments = paymentMaps.map((e) => Payment.fromMap(e, e["id"])).toList();
return Invoice( return Invoice(
id: docID, id: docID,
invoiceNumber: map['invoice_number'], invoiceNumber: map['invoice_number'] ?? "",
invoiceDate: invd.toDate(), invoiceDate: invd.toDate(),
userName: map['user_name'], userName: map['user_name'] ?? "",
fcsID: map['fcs_id'], fcsID: map['fcs_id'] ?? "",
phoneNumber: map['phone_number'], phoneNumber: map['phone_number'] ?? "",
amount: map['amount'], amount: map['amount'] ?? 0,
paidAmount: double.tryParse(map['paid_amount'].toString()) ?? 0, paidAmount: double.tryParse(map['paid_amount'].toString()) ?? 0,
status: map['status'], status: map['status'] ?? "",
cartons: cartons, cartons: cartons,
cargoTypes: cargoTypes, cargoTypes: cargoTypes,
shipments: handingShipments, shipments: handingShipments,
customDuties: customDuties, customDuties: customDuties,
deliveryFee: map['delivery_fee'], deliveryFee: map['delivery_fee'] ?? 0,
invoiceURL: map['invoice_url'], invoiceURL: map['invoice_url'] ?? "",
paymentMethod: paymentMethod, paymentMethod: paymentMethod,
discount: discount, discount: discount,
payments: payments, payments: payments,

View File

@@ -109,8 +109,8 @@ class User {
fcsID: map['fcs_id'], fcsID: map['fcs_id'],
privileges: _privileges, privileges: _privileges,
lastMessage: map['last_message'], lastMessage: map['last_message'],
userUnseenCount: map['user_unseen_count'], userUnseenCount: map['user_unseen_count'] ?? 0,
fcsUnseenCount: map['fcs_unseen_count'], fcsUnseenCount: map['fcs_unseen_count'] ?? 0,
preferCurrency: map['preferred_currency'], preferCurrency: map['preferred_currency'],
lastMessageTime: _date == null ? null : _date.toDate()); lastMessageTime: _date == null ? null : _date.toDate());
} }

View File

@@ -2,10 +2,9 @@ import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_title.dart'; import 'package:fcs/pages/widgets/local_title.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -99,21 +98,11 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'cargo.form.title',
leading: new IconButton(
icon:
new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
onPressed: () => Navigator.of(context).pop(),
),
shadowColor: Colors.transparent,
backgroundColor: Colors.white, backgroundColor: Colors.white,
title: LocalText( labelColor: primaryColor,
context, arrowColor: primaryColor),
"cargo.form.title",
fontSize: 20,
color: primaryColor,
)),
body: Container( body: Container(
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
child: ListView( child: ListView(

View File

@@ -3,9 +3,8 @@ import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/length_picker.dart'; import 'package:fcs/pages/widgets/length_picker.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -135,12 +134,12 @@ class _CartonSizeEditorState extends State<CartonSizeEditor> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: "box.carton_size",
leading: new IconButton( backgroundColor: Colors.white,
icon: labelColor: primaryColor,
new Icon(CupertinoIcons.back, color: primaryColor, size: 30), arrowColor: primaryColor,
onPressed: () { onBack: () {
if (isDataChanged()) { if (isDataChanged()) {
showConfirmDialog(context, "back.button_confirm", () { showConfirmDialog(context, "back.button_confirm", () {
Navigator.of(context).pop(); Navigator.of(context).pop();
@@ -150,14 +149,6 @@ class _CartonSizeEditorState extends State<CartonSizeEditor> {
} }
}, },
), ),
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
title: LocalText(
context,
"box.carton_size",
fontSize: 20,
color: primaryColor,
)),
body: Container( body: Container(
padding: EdgeInsets.all(18), padding: EdgeInsets.all(18),
child: ListView( child: ListView(

View File

@@ -1,7 +1,7 @@
import 'package:fcs/domain/entities/carton_size.dart'; import 'package:fcs/domain/entities/carton_size.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -72,22 +72,11 @@ class _CartonSizeListState extends State<CartonSizeList> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'box.carton_size.title',
leading: new IconButton(
icon:
new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
onPressed: () => Navigator.of(context).pop(),
),
shadowColor: Colors.transparent,
backgroundColor: Colors.white, backgroundColor: Colors.white,
title: LocalText( labelColor: primaryColor,
context, arrowColor: primaryColor),
"box.carton_size.title",
fontSize: 20,
color: primaryColor,
),
),
body: Padding( body: Padding(
padding: const EdgeInsets.only(left: 12.0, right: 12), padding: const EdgeInsets.only(left: 12.0, right: 12),
child: ListView( child: ListView(

View File

@@ -76,23 +76,14 @@ class Bubble extends StatelessWidget {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0), borderRadius: BorderRadius.circular(10.0),
)), )),
onPressed: () {}, onPressed: () {
_viewDetail();
},
child: Text( child: Text(
getLocalString(context, "message.view.detail"), getLocalString(context, "message.view.detail"),
style: TextStyle( style: TextStyle(
color: primaryColor, color: primaryColor,
fontWeight: FontWeight.bold))) fontWeight: FontWeight.bold)))
// FlatButton(
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10.0),
// ),
// color: Colors.blue[50],
// onPressed: () => _viewDetail(),
// child: Text(
// getLocalString(context, "message.view.detail"),
// style: TextStyle(
// color: primaryColor,
// fontWeight: FontWeight.bold)))
] ]
: [ : [
Text(isCustomer ? "FCS Team" : sender ?? "", Text(isCustomer ? "FCS Team" : sender ?? "",

View File

@@ -82,7 +82,7 @@ class DiscountModel extends BaseModel {
var snaps = await q.get(const GetOptions(source: Source.server)); var snaps = await q.get(const GetOptions(source: Source.server));
var discounts = snaps.docs.map((snap) { var discounts = snaps.docs.map((snap) {
if (snap.exists) { if (snap.exists) {
var s = Discount.fromMap(snap.data as Map<String, dynamic>, snap.id); var s = Discount.fromMap(snap.data(), snap.id);
return s; return s;
} }
}).toList(); }).toList();

View File

@@ -3,7 +3,6 @@ import 'package:fcs/domain/entities/rate.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/local_title.dart'; import 'package:fcs/pages/widgets/local_title.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef OnSelect = Function(Carton carton, bool checked); typedef OnSelect = Function(Carton carton, bool checked);

View File

@@ -1,7 +1,7 @@
import 'package:fcs/domain/entities/discount.dart'; import 'package:fcs/domain/entities/discount.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class InvoiceDiscountList extends StatelessWidget { class InvoiceDiscountList extends StatelessWidget {
@@ -15,24 +15,9 @@ class InvoiceDiscountList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: LocalAppBar(labelKey: 'invoice.shipment.discount.title'),
centerTitle: true, body:
leading: new IconButton( Padding(padding: const EdgeInsets.all(8.0), child: table(context)));
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context),
),
backgroundColor: primaryColor,
title: LocalText(
context,
"invoice.shipment.discount.title",
fontSize: 20,
color: Colors.white,
),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: table(context),
));
} }
Widget table(BuildContext context) { Widget table(BuildContext context) {

View File

@@ -25,11 +25,11 @@ import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/shipment/model/shipment_model.dart'; import 'package:fcs/pages/shipment/model/shipment_model.dart';
import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_icons.dart'; import 'package:fcs/pages/widgets/fcs_icons.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_dropdown.dart'; import 'package:fcs/pages/widgets/local_dropdown.dart';
import 'package:fcs/pages/widgets/local_popup_menu_button.dart'; import 'package:fcs/pages/widgets/local_popup_menu_button.dart';
import 'package:fcs/pages/widgets/local_popupmenu.dart'; import 'package:fcs/pages/widgets/local_popupmenu.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -249,22 +249,23 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
], ],
popupMenuCallback: (p) async { popupMenuCallback: (p) async {
if (p.id == 1) { if (p.id == 1) {
CustomDuty customDuty = await Navigator.of(context).push( CargoType? customDuty = await Navigator.of(context).push(
CupertinoPageRoute( CupertinoPageRoute(
builder: (context) => CustomList(selected: true))); builder: (context) => CustomList(selected: true)));
_addCustom(customDuty); if (customDuty == null) return;
// _addCustom(customDuty);
} else if (p.id == 2) { } else if (p.id == 2) {
Shipment shipment = await Navigator.of(context).push( Shipment? shipment = await Navigator.of(context).push(
CupertinoPageRoute( CupertinoPageRoute(
builder: (context) => builder: (context) =>
InvoiceHandlingFeeList(shipments: _invoice!.shipments))); InvoiceHandlingFeeList(shipments: _invoice!.shipments)));
if (shipment == null) return;
_addShipment(shipment); _addShipment(shipment);
} else if (p.id == 3) { } else if (p.id == 3) {
Discount? discount = Discount? discount = await Navigator.of(context).push(
await Navigator.of(context).push(CupertinoPageRoute( CupertinoPageRoute(
builder: (context) => InvoiceDiscountList( builder: (context) =>
discounts: discounts, InvoiceDiscountList(discounts: discounts)));
)));
if (discount != null) { if (discount != null) {
setState(() { setState(() {
_invoice!.discount = discount; _invoice!.discount = discount;
@@ -314,19 +315,11 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'invoice.form.title',
leading: new IconButton(
icon: new Icon(CupertinoIcons.back, color: primaryColor),
onPressed: () {
Navigator.of(context).pop();
},
),
backgroundColor: Colors.white, backgroundColor: Colors.white,
shadowColor: Colors.transparent, labelColor: primaryColor,
title: LocalText(context, 'invoice.form.title', arrowColor: primaryColor),
color: primaryColor, fontSize: 20),
),
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: ListView( child: ListView(
@@ -336,10 +329,7 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
_isNew ? Container() : statusBox, _isNew ? Container() : statusBox,
_showCartons ? cartonTable : Container(), _showCartons ? cartonTable : Container(),
_showCartons _showCartons
? Divider( ? Divider(color: primaryColor, thickness: 2)
color: primaryColor,
thickness: 2,
)
: Container(), : Container(),
invoiceTableBox, invoiceTableBox,
SizedBox( SizedBox(

View File

@@ -1,5 +1,6 @@
import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/domain/entities/shipment.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -19,20 +20,7 @@ class InvoiceHandlingFeeList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: LocalAppBar(labelKey: 'invoice.shipment.handling.fee.title'),
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.pop(context),
),
backgroundColor: primaryColor,
title: LocalText(
context,
"invoice.shipment.handling.fee.title",
fontSize: 20,
color: Colors.white,
),
),
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: table(context), child: table(context),

View File

@@ -3,7 +3,7 @@ import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/customer/model/customer_model.dart'; import 'package:fcs/pages/customer/model/customer_model.dart';
import 'package:fcs/pages/invoice/editor/invoice_editor.dart'; import 'package:fcs/pages/invoice/editor/invoice_editor.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -44,20 +44,7 @@ class _InvoiceCustomerListState extends State<InvoiceCustomerList> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(labelKey: 'customer.list.title'),
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
title: LocalText(
context,
"customer.list.title",
fontSize: 20,
color: Colors.white,
),
),
body: Column( body: Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
@@ -83,12 +70,10 @@ class _InvoiceCustomerListState extends State<InvoiceCustomerList> {
Widget _item(User customer) { Widget _item(User customer) {
return InkWell( return InkWell(
onTap: () async { onTap: () async {
bool created = await Navigator.of(context).push(CupertinoPageRoute( bool? created = await Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => InvoiceEditor( builder: (context) => InvoiceEditor(
customer: customer, customer: customer, fcsShipment: widget.fcsShipment)));
fcsShipment: widget.fcsShipment, if (created ?? false) {
)));
if (created) {
_load(); _load();
} }
}, },

View File

@@ -11,10 +11,9 @@ import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_icons.dart'; import 'package:fcs/pages/widgets/fcs_icons.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -151,17 +150,11 @@ class _InvoiceInfoState extends State<InvoiceInfo> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'invoice.form.title',
leading: new IconButton(
icon: new Icon(CupertinoIcons.back, color: primaryColor),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: Colors.white, backgroundColor: Colors.white,
shadowColor: Colors.transparent, labelColor: primaryColor,
title: LocalText(context, 'invoice.form.title', arrowColor: primaryColor),
color: primaryColor, fontSize: 20),
),
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: ListView( child: ListView(

View File

@@ -1,6 +1,7 @@
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/invoice/invoice_shipment_list.dart'; import 'package:fcs/pages/invoice/invoice_shipment_list.dart';
import 'package:fcs/pages/invoice/model/invoice_model.dart'; import 'package:fcs/pages/invoice/model/invoice_model.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_popup_menu_button.dart'; import 'package:fcs/pages/widgets/local_popup_menu_button.dart';
import 'package:fcs/pages/widgets/local_popupmenu.dart'; import 'package:fcs/pages/widgets/local_popupmenu.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
@@ -9,38 +10,35 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../domain/entities/invoice.dart';
import '../../pagination/paginator_listview.dart';
import 'invoice_list_row.dart'; import 'invoice_list_row.dart';
class InvoiceList extends StatefulWidget { class InvoiceList extends StatefulWidget {
final bool? forCustomer; final bool forCustomer;
const InvoiceList({Key? key, this.forCustomer}) : super(key: key); const InvoiceList({Key? key, required this.forCustomer}) : super(key: key);
@override @override
_InvoiceListState createState() => _InvoiceListState(); _InvoiceListState createState() => _InvoiceListState();
} }
class _InvoiceListState extends State<InvoiceList> { class _InvoiceListState extends State<InvoiceList> {
bool _isLoading = false; bool _isLoading = false;
var _controller = ScrollController(); int _selectedIndex = 1;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_controller.addListener(() async { _init();
if (_controller.position.pixels == _controller.position.maxScrollExtent) {
Provider.of<InvoiceModel>(context, listen: false)
.loadMore(isCustomer: widget.forCustomer!);
}
});
InvoiceModel invoiceModel =
Provider.of<InvoiceModel>(context, listen: false);
invoiceModel.initData(widget.forCustomer!, true, false);
} }
@override _init() {
void dispose() { var model = context.read<InvoiceModel>();
super.dispose(); _selectedIndex = model.selectedIndex;
model.loadPaginationInvoices(_selectedIndex, widget.forCustomer);
if (mounted) {
setState(() {});
}
} }
@override @override
@@ -62,38 +60,21 @@ class _InvoiceListState extends State<InvoiceList> {
textKey: "invoice.popupmenu.cancel", textKey: "invoice.popupmenu.cancel",
selected: invoiceModel.selectedIndex == 3) selected: invoiceModel.selectedIndex == 3)
], ],
popupMenuCallback: (p) => this.setState(() { popupMenuCallback: (p) {
invoiceModel.selectedIndex = p.id; this.setState(() {
if (p.id == 2) { _selectedIndex = p.id;
Provider.of<InvoiceModel>(context, listen: false) });
.initData(widget.forCustomer!, false, true); context
} else if (p.id == 3) { .read<InvoiceModel>()
Provider.of<InvoiceModel>(context, listen: false) .onChanged(_selectedIndex, widget.forCustomer);
.initData(widget.forCustomer!, true, false); });
} else {
Provider.of<InvoiceModel>(context, listen: false)
.initData(widget.forCustomer!, true, false);
}
}),
);
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: DefaultTabController(
length: 2,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'invoices.title', actions: <Widget>[popupMenu]),
leading: new IconButton( floatingActionButton: (widget.forCustomer)
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
title: LocalText(context, 'invoices.title',
color: Colors.white, fontSize: 20),
actions: <Widget>[popupMenu],
),
floatingActionButton: widget.forCustomer!
? null ? null
: FloatingActionButton.extended( : FloatingActionButton.extended(
onPressed: () { onPressed: () {
@@ -104,46 +85,11 @@ class _InvoiceListState extends State<InvoiceList> {
LocalText(context, 'invoices.add', color: Colors.white), LocalText(context, 'invoices.add', color: Colors.white),
backgroundColor: primaryColor, backgroundColor: primaryColor,
), ),
body: Column( body: PaginatorListView<Invoice>(
children: <Widget>[ paginatorListener: invoiceModel.getInvoices!,
Expanded( rowBuilder: (p) =>
child: RefreshIndicator( InvoiceListRow(invoice: p, isCustomer: widget.forCustomer),
child: ListView.separated( color: primaryColor)),
physics: AlwaysScrollableScrollPhysics(),
controller: _controller,
separatorBuilder: (context, index) => Divider(
color: Colors.black,
height: 1,
),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: invoiceModel.invoices.length,
itemBuilder: (BuildContext context, int index) {
return InvoiceListRow(
key: ValueKey(invoiceModel.invoices[index].id),
invoice: invoiceModel.invoices[index],
forCustomer: widget.forCustomer,
);
}),
onRefresh: () => invoiceModel.refresh(),
),
),
invoiceModel.isLoading
? Container(
padding: EdgeInsets.all(8),
color: primaryColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Loading...",
style: TextStyle(color: Colors.white)),
],
),
)
: Container(),
],
)),
),
); );
} }

View File

@@ -13,8 +13,9 @@ import '../widgets/pdf_screen.dart';
class InvoiceListRow extends StatelessWidget { class InvoiceListRow extends StatelessWidget {
final dateFormatter = new DateFormat('dd MMM yyyy'); final dateFormatter = new DateFormat('dd MMM yyyy');
final Invoice? invoice; final Invoice? invoice;
final bool? forCustomer; final bool isCustomer;
InvoiceListRow({Key? key, this.invoice, this.forCustomer}) : super(key: key); InvoiceListRow({Key? key, this.invoice, required this.isCustomer})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -22,9 +23,7 @@ class InvoiceListRow extends StatelessWidget {
onTap: () { onTap: () {
Navigator.of(context).push(CupertinoPageRoute( Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => PDFScreen( builder: (context) => PDFScreen(
title: invoice!.invoiceNumber, title: invoice!.invoiceNumber, url: invoice!.invoiceURL)));
url: invoice!.invoiceURL,
)));
}, },
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
@@ -55,7 +54,7 @@ class InvoiceListRow extends StatelessWidget {
new Text( new Text(
invoice!.status ?? "", invoice!.status ?? "",
style: new TextStyle( style: new TextStyle(
fontSize: 13.0, color: primaryColor), fontSize: 15.0, color: primaryColor),
), ),
new Text( new Text(
invoice!.invoiceDate != null invoice!.invoiceDate != null
@@ -76,28 +75,25 @@ class InvoiceListRow extends StatelessWidget {
? Padding( ? Padding(
padding: const EdgeInsets.only(left: 10.0), padding: const EdgeInsets.only(left: 10.0),
child: InkWell( child: InkWell(
child: ElevatedButton( child: ElevatedButton.icon(
child: Row( style: ElevatedButton.styleFrom(
children: <Widget>[ // shape: RoundedRectangleBorder(
Icon( // borderRadius: BorderRadius.all(Radius.circular(5))),
elevation: 0,
backgroundColor: Colors.grey.shade300),
icon: Icon(
Icons.payment, Icons.payment,
color: primaryColor, color: primaryColor,
), ),
Padding( label: Padding(
padding: const EdgeInsets.only(left: 3.0), padding: const EdgeInsets.only(left: 3.0),
child: Text( child: Text("Payment",
"Payment", style:
style: TextStyle(fontSize: 12, color: Colors.black), TextStyle(fontSize: 12, color: Colors.black))),
),
)
],
),
onPressed: () { onPressed: () {
Navigator.of(context).push(CupertinoPageRoute( Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => PaymentPage( builder: (context) => PaymentPage(
invoice: invoice, invoice: invoice, forCustomer: isCustomer)));
forCustomer: forCustomer,
)));
}, },
)), )),
) )
@@ -141,7 +137,7 @@ class InvoiceListRow extends StatelessWidget {
Navigator.pop(context); Navigator.pop(context);
Navigator.of(context).push(CupertinoPageRoute( Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => builder: (context) =>
InvoiceInfo(invoice: invoice, forCustomer: forCustomer))); InvoiceInfo(invoice: invoice, forCustomer: isCustomer)));
}, },
), ),
CupertinoActionSheetAction( CupertinoActionSheetAction(
@@ -162,7 +158,7 @@ class InvoiceListRow extends StatelessWidget {
Navigator.of(context).push(CupertinoPageRoute( Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => PaymentPage( builder: (context) => PaymentPage(
invoice: invoice, invoice: invoice,
forCustomer: forCustomer, forCustomer: isCustomer,
))); )));
}, },
) )

View File

@@ -1,7 +1,6 @@
import 'package:fcs/domain/entities/fcs_shipment.dart'; import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart'; import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -42,19 +41,8 @@ class _InvoiceShipmentListState extends State<InvoiceShipmentList> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: DefaultTabController(
length: 3,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(labelKey: "invoice.shipment.title"),
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
title: LocalText(context, "invoice.shipment.title",
fontSize: 18, color: Colors.white),
),
body: new ListView.separated( body: new ListView.separated(
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => Divider(
color: Colors.black, color: Colors.black,
@@ -68,14 +56,12 @@ class _InvoiceShipmentListState extends State<InvoiceShipmentList> {
fcsShipment: _fcsShipments[index], fcsShipment: _fcsShipments[index],
onSelect: (f) { onSelect: (f) {
Navigator.of(context).push(CupertinoPageRoute( Navigator.of(context).push(CupertinoPageRoute(
builder: (context) => InvoiceCustomerList( builder: (context) =>
fcsShipment: f, InvoiceCustomerList(fcsShipment: f)));
)));
}, },
); );
}), }),
), ),
),
); );
} }
} }

View File

@@ -115,7 +115,7 @@ class InvoiceTable extends StatelessWidget {
List<Widget> dataRow = tableRows.map((r) { List<Widget> dataRow = tableRows.map((r) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey))), border: Border(bottom: BorderSide(color: Colors.grey.shade300))),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 5.0, right: 5.0, top: 10.0, bottom: 10.0), left: 5.0, right: 5.0, top: 10.0, bottom: 10.0),
child: Row( child: Row(
@@ -164,7 +164,7 @@ class InvoiceTable extends StatelessWidget {
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 5.0, right: 5.0, top: 15.0, bottom: 15.0), left: 5.0, right: 5.0, top: 15.0, bottom: 15.0),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border(bottom: BorderSide(color: Colors.grey))), border: Border(bottom: BorderSide(color: Colors.grey.shade300))),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(

View File

@@ -7,131 +7,65 @@ import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/invoice.dart'; import 'package:fcs/domain/entities/invoice.dart';
import 'package:fcs/domain/entities/payment.dart'; import 'package:fcs/domain/entities/payment.dart';
import 'package:fcs/helpers/firebase_helper.dart'; import 'package:fcs/helpers/firebase_helper.dart';
import 'package:fcs/helpers/paginator.dart';
import 'package:fcs/pages/main/model/base_model.dart'; import 'package:fcs/pages/main/model/base_model.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:path/path.dart' as Path; import 'package:path/path.dart' as Path;
import '../../../pagination/paginator_listener.dart';
class InvoiceModel extends BaseModel { class InvoiceModel extends BaseModel {
final log = Logger('InvoiceModel'); final log = Logger('InvoiceModel');
PaginatorListener<Invoice>? getInvoices;
StreamSubscription<QuerySnapshot<Map<String, dynamic>>>? listener; int selectedIndex = 1;
List<Invoice> _invoices = [];
List<Invoice> get invoices =>
_selectedIndex == 1 ? _invoices : List<Invoice>.from(_paginator!.values);
Paginator? _paginator;
bool endOfPaidInvoices = false;
bool isLoading = false;
int _selectedIndex = 1;
set selectedIndex(int index) {
_selectedIndex = index;
notifyListeners();
}
int get selectedIndex => _selectedIndex;
@override
void privilegeChanged() {
super.privilegeChanged();
}
initData(bool forCustomer, bool isCanceled, bool isPaid) {
_loadInvoices(forCustomer);
if (_paginator != null) _paginator!.close();
_paginator = _getPaginator(forCustomer, isCanceled, isPaid);
_paginator!.load(onFinished: () {
notifyListeners();
});
}
Future<void> _loadInvoices(bool forCustomer) async {
if (user == null) return;
if (!forCustomer && !user!.hasInvoices()) return;
String path = "/$invoices_collection";
if (listener != null) listener!.cancel();
_invoices = [];
try {
var q = FirebaseFirestore.instance
.collection("$path")
.where("status", isEqualTo: invoice_issued_status)
.where("is_deleted", isEqualTo: false);
if (forCustomer) {
q = q.where("user_id", isEqualTo: user!.id);
}
listener = q.snapshots().listen((QuerySnapshot snapshot) {
_invoices.clear();
_invoices = snapshot.docs.map((documentSnapshot) {
var s = Invoice.fromMap(
documentSnapshot.data() as Map<String, dynamic>,
documentSnapshot.id);
return s;
}).toList();
notifyListeners();
});
} catch (e) {
log.warning("Error!! $e");
}
}
Paginator _getPaginator(bool isCustomer, bool isCanceled, bool isPaid) {
if (!isCustomer) {
if (user == null || !(user!.hasInvoices())) throw "No privilege";
}
var pageQuery = FirebaseFirestore.instance
.collection("/$invoices_collection")
.where("is_deleted", isEqualTo: false);
if (isCustomer) {
pageQuery = pageQuery.where("user_id", isEqualTo: user!.id);
}
if (isCanceled) {
pageQuery = pageQuery.where("status", isEqualTo: invoice_cancel_status);
}
if (isPaid) {
pageQuery = pageQuery.where("status", isEqualTo: invoice_paid_status);
}
pageQuery = pageQuery.orderBy("created_at", descending: true);
var paginator = new Paginator(pageQuery, rowPerLoad: 20, toObj: (data, id) {
return Invoice.fromMap(data, id);
});
return paginator;
}
Future<void> loadMore({bool? isCustomer}) async {
if (_paginator!.ended || _selectedIndex == 1)
return; // when paid menu is not selected return
isLoading = true;
notifyListeners();
await _paginator!.load(onFinished: () {
isLoading = false;
notifyListeners();
});
}
Future<void> refresh({bool? isCustomer}) async {
if (_selectedIndex == 1) return; // when paid menu is not selected return
await _paginator!.refresh(onFinished: () {
notifyListeners();
});
}
void initUser(user) { void initUser(user) {
super.initUser(user); super.initUser(user);
} }
logout() async { logout() async {
if (_paginator != null) _paginator!.close(); getInvoices?.close();
if (listener != null) await listener!.cancel(); }
_invoices = [];
onChanged(int index, bool isCustomer) {
selectedIndex = index;
loadPaginationInvoices(index, isCustomer);
notifyListeners();
}
Future<void> loadPaginationInvoices(int index, bool isCustomer) async {
if (user == null) return;
if (!isCustomer && !user!.hasInvoices()) return;
String path = "/$invoices_collection";
Query col = FirebaseFirestore.instance.collection(path);
Query pageQuery = FirebaseFirestore.instance.collection(path);
if (isCustomer) {
col = col.where("user_id", isEqualTo: user!.id);
pageQuery = pageQuery.where("user_id", isEqualTo: user!.id);
}
if (index == 1) {
col = col.where("status", isEqualTo: invoice_issued_status);
pageQuery = pageQuery.where("status", isEqualTo: invoice_issued_status);
}
if (index == 2) {
col = col.where("status", isEqualTo: invoice_paid_status);
pageQuery = pageQuery.where("status", isEqualTo: invoice_paid_status);
}
if (index == 3) {
col = col.where("status", isEqualTo: invoice_cancel_status);
pageQuery = pageQuery.where("status", isEqualTo: invoice_cancel_status);
}
pageQuery = pageQuery.orderBy("created_at", descending: true);
getInvoices?.close();
getInvoices = PaginatorListener<Invoice>(
col, pageQuery, (data, id) => Invoice.fromMap(data, id),
rowPerLoad: 30);
} }
Future<Invoice?> getInvoice(String id) async { Future<Invoice?> getInvoice(String id) async {
@@ -140,7 +74,7 @@ class InvoiceModel extends BaseModel {
var ref = FirebaseFirestore.instance.collection("$path").doc(id); var ref = FirebaseFirestore.instance.collection("$path").doc(id);
var snap = await ref.get(const GetOptions(source: Source.server)); var snap = await ref.get(const GetOptions(source: Source.server));
if (snap.exists) { if (snap.exists) {
var s = Invoice.fromMap(snap.data as Map<String, dynamic>, snap.id); var s = Invoice.fromMap(snap.data() as Map<String, dynamic>, snap.id);
return s; return s;
} }
} catch (e) { } catch (e) {

View File

@@ -4,16 +4,15 @@ import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/invoice.dart'; import 'package:fcs/domain/entities/invoice.dart';
import 'package:fcs/domain/entities/payment.dart'; import 'package:fcs/domain/entities/payment.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/invoice/model/invoice_model.dart'; import 'package:fcs/pages/invoice/model/invoice_model.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/img_picker.dart'; import 'package:fcs/pages/widgets/img_picker.dart';
import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/local_title.dart'; import 'package:fcs/pages/widgets/local_title.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@@ -51,8 +50,9 @@ class _PaymentPageState extends State<PaymentPage> {
InvoiceModel invoiceModel = InvoiceModel invoiceModel =
Provider.of<InvoiceModel>(context, listen: false); Provider.of<InvoiceModel>(context, listen: false);
Invoice? i = await invoiceModel.getInvoice(_invoice.id!); Invoice? i = await invoiceModel.getInvoice(_invoice.id!);
if (i == null) return;
setState(() { setState(() {
_invoice = i!; _invoice = i;
}); });
} }
@@ -90,15 +90,11 @@ class _PaymentPageState extends State<PaymentPage> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true, labelKey: 'pm_.title',
leading: new IconButton( backgroundColor: Colors.white,
icon: new Icon(CupertinoIcons.back), labelColor: primaryColor,
onPressed: () => Navigator.of(context).pop(), arrowColor: primaryColor),
),
backgroundColor: primaryColor,
title: Text(AppTranslations.of(context)!.text("pm_.title")),
),
body: ListView( body: ListView(
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
children: <Widget>[ children: <Widget>[

View File

@@ -17,7 +17,11 @@ Widget getInvoiceStatus(BuildContext context, Invoice invoice) {
), ),
Padding( Padding(
padding: const EdgeInsets.only(left: 8.0), padding: const EdgeInsets.only(left: 8.0),
child: Chip(label: Text(invoice.status ?? "")), child: Chip(
shape: const StadiumBorder(
side: BorderSide(color: Colors.transparent)),
backgroundColor: Colors.grey.withOpacity(0.3),
label: Text(invoice.status ?? "")),
), ),
], ],
); );

View File

@@ -344,16 +344,14 @@ Widget fcsButton(BuildContext context, String text,
return Container( return Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 10), padding: EdgeInsets.only(left: 10, right: 10, top: 10),
child: Container( child: SizedBox(
height: 45.0, height: 45.0,
decoration: BoxDecoration( child: ElevatedButton(
color: primaryColor, style: ElevatedButton.styleFrom(
shape: BoxShape.rectangle, elevation: 0,
), backgroundColor: primaryColor,
child: ButtonTheme( shape: RoundedRectangleBorder(
minWidth: 900.0, borderRadius: BorderRadius.all(Radius.circular(3)))),
height: 100.0,
child: TextButton(
onPressed: callack == null ? null : () => callack(), onPressed: callack == null ? null : () => callack(),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@@ -372,7 +370,6 @@ Widget fcsButton(BuildContext context, String text,
), ),
), ),
), ),
),
); );
} }

View File

@@ -6,7 +6,6 @@ import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';

View File

@@ -21,31 +21,22 @@ class PackageModel extends BaseModel {
PaginatorListener<Package>? activePackages; PaginatorListener<Package>? activePackages;
bool isLoading = false; bool isLoading = false;
int _menuSelectedIndex = 1; int selectedIndex = 1;
set menuSelectedIndex(int index) { initData(int index, bool isCustomer) {
_menuSelectedIndex = index; selectedIndex = index;
if (isCustomer) {
_loadPaginationPackages(_menuSelectedIndex == 2); _loadPaginationCustomerPackages(selectedIndex == 2);
_loadPaginationCustomerPackages(_menuSelectedIndex == 2); } else {
_loadPaginationPackages(selectedIndex == 2);
notifyListeners(); }
} }
int get menuSelectedIndex => _menuSelectedIndex;
void privilegeChanged() { void privilegeChanged() {
if (user != null) { if (user != null) {
_initData();
}
}
Future<void> _initData() async {
_menuSelectedIndex = 1;
_loadPaginationPackages(_menuSelectedIndex == 2);
_loadPaginationCustomerPackages(_menuSelectedIndex == 2);
_loadPaginationActivePackages(); _loadPaginationActivePackages();
} }
}
@override @override
logout() async { logout() async {
@@ -54,6 +45,16 @@ class PackageModel extends BaseModel {
if (activePackages != null) activePackages!.close(); if (activePackages != null) activePackages!.close();
} }
onChanged(int index, bool isCustomer) {
selectedIndex = index;
if (isCustomer) {
_loadPaginationCustomerPackages(selectedIndex == 2);
} else {
_loadPaginationPackages(selectedIndex == 2);
}
notifyListeners();
}
_loadPaginationPackages(bool isDelivered) { _loadPaginationPackages(bool isDelivered) {
if (user == null) return; if (user == null) return;
if (!((user!.hasPackages() || if (!((user!.hasPackages() ||
@@ -78,7 +79,6 @@ class PackageModel extends BaseModel {
_loadPaginationCustomerPackages(bool isDelivered) { _loadPaginationCustomerPackages(bool isDelivered) {
if (user == null) return; if (user == null) return;
String path = "/$packages_collection"; String path = "/$packages_collection";
Query col = FirebaseFirestore.instance Query col = FirebaseFirestore.instance
.collection(path) .collection(path)
.where("is_delivered", isEqualTo: isDelivered) .where("is_delivered", isEqualTo: isDelivered)

View File

@@ -23,12 +23,24 @@ class PackageList extends StatefulWidget {
class _PackageListState extends State<PackageList> { class _PackageListState extends State<PackageList> {
bool _isLoading = false; bool _isLoading = false;
int _selectedIndex = 1;
@override @override
void initState() { void initState() {
_init();
super.initState(); super.initState();
} }
_init() {
var model = context.read<PackageModel>();
_selectedIndex = model.selectedIndex;
model.initData(_selectedIndex, widget.forCustomer);
if (mounted) {
setState(() {});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var packageModel = Provider.of<PackageModel>(context); var packageModel = Provider.of<PackageModel>(context);
@@ -41,16 +53,20 @@ class _PackageListState extends State<PackageList> {
LocalPopupMenu( LocalPopupMenu(
id: 1, id: 1,
textKey: "package.popupmenu.active", textKey: "package.popupmenu.active",
selected: packageModel.menuSelectedIndex == 1), selected: packageModel.selectedIndex == 1),
LocalPopupMenu( LocalPopupMenu(
id: 2, id: 2,
textKey: "package.popupmenu.delivered", textKey: "package.popupmenu.delivered",
selected: packageModel.menuSelectedIndex == 2) selected: packageModel.selectedIndex == 2)
], ],
popupMenuCallback: (p) => this.setState(() { popupMenuCallback: (p) {
packageModel.menuSelectedIndex = p.id; this.setState(() {
}), _selectedIndex = p.id;
); });
context
.read<PackageModel>()
.onChanged(_selectedIndex, widget.forCustomer);
});
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,

View File

@@ -1,7 +1,6 @@
import 'package:fcs/domain/entities/custom_duty.dart'; import 'package:fcs/domain/entities/custom_duty.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';

View File

@@ -1,10 +1,9 @@
import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../helpers/theme.dart'; import '../../helpers/theme.dart';
@@ -29,14 +28,7 @@ class _RequestInvitationPageState extends State<RequestInvitationPage> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: new Scaffold( child: new Scaffold(
appBar: AppBar( appBar: LocalAppBar(),
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
),
body: _buildBody(context), body: _buildBody(context),
), ),
); );
@@ -91,6 +83,11 @@ class _RequestInvitationPageState extends State<RequestInvitationPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
ElevatedButton( ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(3))),
backgroundColor: primaryColor),
onPressed: _request, onPressed: _request,
child: Text(getLocalString(context, "invite.request")), child: Text(getLocalString(context, "invite.request")),
) )

View File

@@ -4,7 +4,6 @@ import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/signin/invitation_request_page.dart'; import 'package:fcs/pages/signin/invitation_request_page.dart';
import 'package:fcs/pages/signin/signup_page.dart'; import 'package:fcs/pages/signin/signup_page.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
navigateAfterAuthVerified(BuildContext context) async { navigateAfterAuthVerified(BuildContext context) async {

View File

@@ -3,11 +3,11 @@ import 'package:fcs/domain/entities/auth_result.dart';
import 'package:fcs/domain/entities/auth_status.dart'; import 'package:fcs/domain/entities/auth_status.dart';
import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/signin/signin_logic.dart'; import 'package:fcs/pages/signin/signin_logic.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -40,17 +40,7 @@ class _SigninPageState extends State<SigninPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: new Scaffold( child: new Scaffold(appBar: LocalAppBar(), body: _buildLogin(context)),
appBar: AppBar(
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
),
body: _buildLogin(context),
),
); );
} }

View File

@@ -1,10 +1,9 @@
import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -30,16 +29,7 @@ class _SignupPageState extends State<SignupPage> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: new Scaffold( child: new Scaffold(
appBar: AppBar( appBar: LocalAppBar(),
centerTitle: true,
leading: new IconButton(
icon: new Icon(
CupertinoIcons.back,
),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
),
body: _buildBody(context), body: _buildBody(context),
), ),
); );

View File

@@ -5,9 +5,9 @@ import 'package:fcs/domain/entities/auth_status.dart';
import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/signin/signin_logic.dart'; import 'package:fcs/pages/signin/signin_logic.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:pin_input_text_field/pin_input_text_field.dart'; import 'package:pin_input_text_field/pin_input_text_field.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@@ -67,14 +67,7 @@ class _SmsCodePageState extends State<SmsCodePage> {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(),
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
),
body: ListView( body: ListView(
padding: EdgeInsets.only(top: 5, left: 5, right: 5), padding: EdgeInsets.only(top: 5, left: 5, right: 5),
children: <Widget>[ children: <Widget>[
@@ -139,19 +132,11 @@ class _SmsCodePageState extends State<SmsCodePage> {
? primaryColor ? primaryColor
: Colors.grey.shade400))), : Colors.grey.shade400))),
onPressed: canResend ? _resend : null, onPressed: canResend ? _resend : null,
// color: canResend ? Colors.white : Colors.grey,
child: LocalText(context, 'sms.resend', child: LocalText(context, 'sms.resend',
fontSize: 16, fontSize: 16,
color: canResend color: canResend
? primaryColor ? primaryColor
: Colors.grey.shade400), : Colors.grey.shade400)),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10.0),
// side: BorderSide(
// color: canResend
// ? primaryColor
// : Colors.grey.shade400)),
),
InkWell( InkWell(
onTap: allNumberEntered ? _verify : null, onTap: allNumberEntered ? _verify : null,
child: CircleAvatar( child: CircleAvatar(
@@ -220,19 +205,4 @@ class _SmsCodePageState extends State<SmsCodePage> {
_isLoading = false; _isLoading = false;
}); });
} }
_completeResend() {
setState(() {
_isLoading = false;
_start = resend_count_sec;
canResend = false;
startTimer();
});
}
_completeVerify() {
setState(() {
_isLoading = false;
});
}
} }

View File

@@ -4,8 +4,8 @@ import 'dart:io';
import 'package:fcs/helpers/cache_mgr.dart'; import 'package:fcs/helpers/cache_mgr.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart'; import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:share/share.dart'; import 'package:share/share.dart';
@@ -54,17 +54,12 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: LocalAppBar(
centerTitle: true,
backgroundColor: Colors.white, backgroundColor: Colors.white,
shadowColor: Colors.transparent, arrowColor: primaryColor,
title: titleWidget: Text(widget.title ?? "",
Text(widget.title ?? "", style: TextStyle(color: primaryColor)), style: TextStyle(color: primaryColor, fontSize: 20)),
leading: new IconButton( actions: [
icon: new Icon(CupertinoIcons.back, color: primaryColor),
onPressed: () => Navigator.of(context).pop(),
),
actions: <Widget>[
IconButton( IconButton(
icon: Icon( icon: Icon(
Icons.share, Icons.share,