From 32e6be2abd49b06ecbf572b4cf33b8182c6d9c10 Mon Sep 17 00:00:00 2001 From: Sai Naw Wun Date: Sun, 11 Oct 2020 02:17:23 +0630 Subject: [PATCH] fix profile --- assets/local/localization_en.json | 7 +- assets/local/localization_mu.json | 9 +- lib/data/provider/auth_fb.dart | 7 +- .../delivery_address_data_provider.dart | 6 + lib/data/provider/package_data_provider.dart | 7 +- lib/data/services/auth_imp.dart | 9 +- lib/data/services/auth_service.dart | 3 +- lib/data/services/delivery_address_imp.dart | 6 + .../services/delivery_address_service.dart | 1 + lib/data/services/package_imp.dart | 5 + lib/data/services/package_service.dart | 1 + lib/domain/constants.dart | 21 + lib/domain/entities/role.dart | 67 ---- lib/domain/entities/user.dart | 5 +- lib/domain/vo/delivery_address.dart | 9 +- lib/domain/vo/privilege.dart | 54 +++ lib/pages/box/box_editor.dart | 4 +- .../delivery_address_editor.dart | 122 +++--- .../delivery_address_list.dart | 112 ++++-- .../delivery_address_row.dart | 188 +++------ .../model/delivery_address_model.dart | 8 + lib/pages/main/home_page.dart | 6 +- lib/pages/main/model/main_model.dart | 9 +- lib/pages/package/model/package_model.dart | 20 +- lib/pages/package/package_info.dart | 8 +- lib/pages/package/tracking_id_page.dart | 8 +- lib/pages/package_search/package_serach.dart | 8 +- lib/pages/profile/profile_currency_edit.dart | 129 ++++++ lib/pages/profile/profile_edit.dart | 2 +- lib/pages/profile/profile_page.dart | 370 ++++++------------ lib/pages/receiving/receiving_info.dart | 162 ++++++++ lib/pages/receiving/receiving_list.dart | 10 +- lib/pages/receiving/receiving_list_row.dart | 5 +- lib/pages/receiving/receiving_new.dart | 33 +- lib/pages/shipment/pickup_box_editor.dart | 2 +- lib/pages/shipment/shipment_editor.dart | 4 +- lib/pages/staff/model/staff_model.dart | 4 +- lib/pages/staff/staff_editor.dart | 33 +- lib/pages/staff/staff_list.dart | 6 +- lib/pages/widgets/barcode_scanner.dart | 18 + lib/pages/widgets/display_text.dart | 10 +- lib/pages/widgets/status_tree.dart | 66 ++++ 42 files changed, 938 insertions(+), 626 deletions(-) delete mode 100644 lib/domain/entities/role.dart create mode 100644 lib/domain/vo/privilege.dart create mode 100644 lib/pages/profile/profile_currency_edit.dart create mode 100644 lib/pages/receiving/receiving_info.dart create mode 100644 lib/pages/widgets/barcode_scanner.dart create mode 100644 lib/pages/widgets/status_tree.dart diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index cad7714..af2569e 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -109,7 +109,6 @@ "user.fcs_id":"MY FCS_ID", "user.shipping_address":"USA SHIPPING ADDRESS", "user.deliveryAddress":"My delivery address", - "user.form.shipping_address":"ADDRESS", "User End ================================================================":"", "Customer Start ================================================================":"", @@ -142,15 +141,17 @@ "Profile Start ================================================================":"", "profile.title": "My Profile", "profile.edit_title": "Edit My Profile", + "profile.edit.currency.title":"Preferred Currency", "profile.name": "Name", "profile.phone": "Phone", "profile.language": "Languages", "profile.logout": "logout", + "profile.currency":"Preferred Currency", "profile.usa.shipping.address": "USA Shipping Address", "profile.logout.confirm":"Are you sure want to logout?", "profile.devices":"Devices", "profile.email":"Email", - "profile.privilege":"Privilege", + "profile.privileges":"Privileges", "Profile End ================================================================":"", "Package Start ================================================================":"", @@ -375,6 +376,7 @@ "delivery_address.update": "Update Delivery Address", "delivery_address.new_address":"Add New\nAddress", "delivery_address.change_address": "Change Address", + "delivery_address.delete.confirm":"Delete this Delivery Address?", "delivery_addresses End ================================================================":"", "Receiving Start ================================================================":"", @@ -386,6 +388,7 @@ "receiving.name":"Customer Name", "receiving.phone":"Phone Number", "receiving.create_btn":"Complete receiving", + "receiving.delete.confirm":"Delete this receiving?", "Receiving End ================================================================":"", "Processing Start ================================================================":"", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index 0fd1a9d..e43679f 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -109,7 +109,6 @@ "user.fcs_id":"My FCS_ID", "user.shipping_address":"My USA shipping address", "user.deliveryAddress":"My delivery address", - "user.form.shipping_address":"ကုန်ပစ္စည်းပို့ဆောင်ရမည့်လိပ်စာ", "User End ================================================================":"", "Customer Start ================================================================":"", @@ -142,15 +141,17 @@ "Profile Start ================================================================":"", "profile.title":"ကျွန်ုပ် ပရိုဖိုင်", "profile.edit_title":"ကျွန်ုပ် ပရိုဖိုင်ကိုပြုပြင်ရန်", + "profile.edit.currency.title":"နှစ်သက်သော ငွေအမျိုးအစား", "profile.name":"နာမည်", "profile.phone": "ဖုန်းနံပါတ်", "profile.language": "ဘာသာစကားများ", "profile.logout": "အကောင့်ထွက်ရန်", - "profile.usa.shipping.address": "အမေရိကား ပစည်းပို့ရန်လိပ်စာ", + "profile.currency":"နှစ်သက်သော ငွေအမျိုးအစား", + "profile.usa.shipping.address": "အမေရိကား ပစ္စည်းပို့ရန်လိပ်စာ", "profile.logout.confirm":"အကောင့်ထွက်ရန်သေချာပြီလား?", "profile.devices":"ဖုန်းမော်ဒယ်အမျိုးအစားများ", "profile.email":"အီးမေးလ်", - "profile.privilege":"လုပ်ပိုင်ခွင့်", + "profile.privileges":"လုပ်ပိုင်ခွင့်များ", "Profile End ================================================================":"", "Package Start ================================================================":"", @@ -375,6 +376,7 @@ "delivery_address.update": "ပြုပြင်ရန်", "delivery_address.new_address":"လိပ်စာအသစ်", "delivery_address.change_address": "လိပ်စာပြောင်းပါ", + "delivery_address.delete.confirm":"ပို့ဆောင်ရမည့်လိပ်စာကို ဖျက်မလား?", "delivery_addresses End ================================================================":"", "Receiving Start ================================================================":"", @@ -386,6 +388,7 @@ "receiving.name":"နာမည်", "receiving.phone":"ဖုန်းနံပါတ်", "receiving.create_btn":"လက်ခံမည်", + "receiving.delete.confirm":"လက်ခံခြင်းကို ဖျက်မလား?", "Receiving End ================================================================":"", "Processing Start ================================================================":"", diff --git a/lib/data/provider/auth_fb.dart b/lib/data/provider/auth_fb.dart index 11a4d14..bea0d16 100644 --- a/lib/data/provider/auth_fb.dart +++ b/lib/data/provider/auth_fb.dart @@ -182,11 +182,16 @@ class AuthFb { return invited["invited"]; } - Future updateProfile(String newUserName) async { + Future updateProfileName(String newUserName) async { return await requestAPI("/profile", "PUT", payload: {"user_name": newUserName}, token: await getToken()); } + Future updatePreferredCurrency(String currency) async { + return await requestAPI("/currency", "PUT", + payload: {"preferred_currency": currency}, token: await getToken()); + } + Future getToken() async { FirebaseUser firebaseUser = await _fb.currentUser(); IdTokenResult token = await firebaseUser.getIdToken(); diff --git a/lib/data/provider/delivery_address_data_provider.dart b/lib/data/provider/delivery_address_data_provider.dart index 94fa841..70e620b 100644 --- a/lib/data/provider/delivery_address_data_provider.dart +++ b/lib/data/provider/delivery_address_data_provider.dart @@ -21,4 +21,10 @@ class DeliveryAddressDataProvider { return await requestAPI("/delivery_address", "DELETE", payload: deliveryAddress.toMap(), token: await getToken()); } + + Future selectDefalutDeliveryAddress( + DeliveryAddress deliveryAddress) async { + return await requestAPI("/delivery_address/defalut", "PUT", + payload: deliveryAddress.toMap(), token: await getToken()); + } } diff --git a/lib/data/provider/package_data_provider.dart b/lib/data/provider/package_data_provider.dart index a89ea54..9eec0c7 100644 --- a/lib/data/provider/package_data_provider.dart +++ b/lib/data/provider/package_data_provider.dart @@ -16,8 +16,13 @@ class PackageDataProvider { payload: {"packages": json, "fcs_id": fcsID}, token: await getToken()); } + Future createPackage(Package package) async { + return await requestAPI("/package", "POST", + payload: package.toJson(), token: await getToken()); + } + Future deletePackage(Package package) async { - return await requestAPI("/packages", "DELETE", + return await requestAPI("/package", "DELETE", payload: {"id": package.id}, token: await getToken()); } diff --git a/lib/data/services/auth_imp.dart b/lib/data/services/auth_imp.dart index cb33ec9..27d0376 100644 --- a/lib/data/services/auth_imp.dart +++ b/lib/data/services/auth_imp.dart @@ -62,7 +62,12 @@ class AuthServiceImp implements AuthService { } @override - Future updateProfile(String newUserName) { - return authFb.updateProfile(newUserName); + Future updateProfileName(String newUserName) { + return authFb.updateProfileName(newUserName); + } + + @override + Future updatePreferredCurrency(String currency) { + return authFb.updatePreferredCurrency(currency); } } diff --git a/lib/data/services/auth_service.dart b/lib/data/services/auth_service.dart index 3c2797a..412c498 100644 --- a/lib/data/services/auth_service.dart +++ b/lib/data/services/auth_service.dart @@ -8,7 +8,8 @@ abstract class AuthService { Future signout(); Future signup(String userName); Future joinInvite(String userName); - Future updateProfile(String newUserName); + Future updateProfileName(String newUserName); + Future updatePreferredCurrency(String currency); Future hasInvite(); Stream getUserStream(); Stream getSetting(); diff --git a/lib/data/services/delivery_address_imp.dart b/lib/data/services/delivery_address_imp.dart index fe74fd2..96d8a36 100644 --- a/lib/data/services/delivery_address_imp.dart +++ b/lib/data/services/delivery_address_imp.dart @@ -28,4 +28,10 @@ class DeliveryAddressImp implements DeliveryAddressService { Future deleteDeliveryAddress(DeliveryAddress deliveryAddress) { return deliveryAddressDataProvider.deleteDeliveryAddress(deliveryAddress); } + + @override + Future selectDefalutDeliveryAddress(DeliveryAddress deliveryAddress) { + return deliveryAddressDataProvider + .selectDefalutDeliveryAddress(deliveryAddress); + } } diff --git a/lib/data/services/delivery_address_service.dart b/lib/data/services/delivery_address_service.dart index 3630390..e638daf 100644 --- a/lib/data/services/delivery_address_service.dart +++ b/lib/data/services/delivery_address_service.dart @@ -4,4 +4,5 @@ abstract class DeliveryAddressService { Future createDeliveryAddress(DeliveryAddress deliveryAddress); Future updateDeliveryAddress(DeliveryAddress deliveryAddress); Future deleteDeliveryAddress(DeliveryAddress deliveryAddress); + Future selectDefalutDeliveryAddress(DeliveryAddress deliveryAddress); } diff --git a/lib/data/services/package_imp.dart b/lib/data/services/package_imp.dart index a0614a8..9e33dff 100644 --- a/lib/data/services/package_imp.dart +++ b/lib/data/services/package_imp.dart @@ -19,6 +19,11 @@ class PackageServiceImp implements PackageService { return packageDataProvider.createPackages(packages, fcsID); } + @override + Future createPackage(Package package) { + return packageDataProvider.createPackage(package); + } + @override Future> searchPackage(String term) { return packageDataProvider.searchPackage(term); diff --git a/lib/data/services/package_service.dart b/lib/data/services/package_service.dart index cd79eb2..93ac51d 100644 --- a/lib/data/services/package_service.dart +++ b/lib/data/services/package_service.dart @@ -2,6 +2,7 @@ import 'package:fcs/domain/entities/package.dart'; abstract class PackageService { Future createPackages(List packages, String fcsID); + Future createPackage(Package package); Future deletePackage(Package package); Future> searchPackage(String term); } diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index 80a7990..690fa9b 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -26,3 +26,24 @@ const message_type_profile = "t_profile"; const fcs_shipment_confirmed_status = "confirmed"; const fcs_shipment_shipped_status = "shipped"; const fcs_shipment_delivered_status = "delivered"; + +// Package status +const package_received_status = "received"; +const package_processed_status = "processed"; +const package_packed_status = "packed"; +const package_shipped_status = "shipped"; +const package_delivered_status = "delivered"; + +// Privileges +const privilege_admin = "admin"; +const privilege_support = "sp"; +const privilege_package = "pkg"; +const privilege_shipment = "sh"; +const privilege_fcs_shipment = "fsh"; +const privilege_staff = "st"; +const privilege_carton = "ca"; +const privilege_customer = "cu"; +const privilege_delivery = "deli"; +const privilege_invoice = "inv"; +const privilege_processing = "pr"; +const privilege_receiving = "rc"; diff --git a/lib/domain/entities/role.dart b/lib/domain/entities/role.dart deleted file mode 100644 index d0e5aae..0000000 --- a/lib/domain/entities/role.dart +++ /dev/null @@ -1,67 +0,0 @@ -class Role { - String roleID; - String roleName; - String privileges; - Role({this.roleName, this.roleID, this.privileges}); - - Role.fromJson(Map json) { - roleName = json['role_name']; - roleID = json['role_id']; - privileges = json['privileges']; - } -} - -class Parser { - String status; - String message; - Role data; - Parser({this.status, this.message, this.data}); - - Parser.fromJson(Map json) { - status = json['status']; - message = json['message']; - if (json['status'] == 'Ok') { - data = Role.fromJson(json['data']); - } - } -} - -class StatusParser { - String status; - String message; - StatusParser(this.status, this.message); - - StatusParser.fromJson(Map json) { - status = json['status']; - message = json['message']; - } -} - -class Privilege { - String id; - String name; - String desc; - bool sysAdminOnly = true; - bool isChecked = false; - - Privilege({this.id, this.name, this.desc, this.isChecked, this.sysAdminOnly}); - - factory Privilege.fromMap(Map map, String docID) { - return Privilege( - id: docID, - name: map['name'], - desc: map['desc'], - sysAdminOnly: map['sys_admin_only']); - } -} - -class UserLevel { - String id; - String name; - int level; - UserLevel({this.id, this.name, this.level}); - - factory UserLevel.fromMap(Map map, String docID) { - return UserLevel(id: docID, name: map['name'], level: map['level']); - } -} diff --git a/lib/domain/entities/user.dart b/lib/domain/entities/user.dart index 6dbc119..2c43357 100644 --- a/lib/domain/entities/user.dart +++ b/lib/domain/entities/user.dart @@ -17,6 +17,7 @@ class User { String lastMessage; int userUnseenCount; int fcsUnseenCount; + String preferCurrency; String get initial => name != null && name != "" ? name.substring(0, 1) : "?"; @@ -64,7 +65,8 @@ class User { this.lastMessage, this.lastMessageTime, this.userUnseenCount, - this.fcsUnseenCount}); + this.fcsUnseenCount, + this.preferCurrency}); factory User.fromJson(Map json) { return User( @@ -106,6 +108,7 @@ class User { lastMessage: map['last_message'], userUnseenCount: map['user_unseen_count'], fcsUnseenCount: map['fcs_unseen_count'], + preferCurrency: map['preferred_currency'], lastMessageTime: _date == null ? null : _date.toDate()); } diff --git a/lib/domain/vo/delivery_address.dart b/lib/domain/vo/delivery_address.dart index ab98533..b7157bb 100644 --- a/lib/domain/vo/delivery_address.dart +++ b/lib/domain/vo/delivery_address.dart @@ -5,8 +5,8 @@ class DeliveryAddress { String addressLine2; String city; String state; - String country; String phoneNumber; + bool isDefault; DeliveryAddress( {this.id, this.fullName, @@ -14,8 +14,8 @@ class DeliveryAddress { this.addressLine2, this.city, this.state, - this.country, - this.phoneNumber}); + this.phoneNumber, + this.isDefault = false}); factory DeliveryAddress.fromMap(Map map, String docID) { return DeliveryAddress( @@ -25,8 +25,8 @@ class DeliveryAddress { addressLine2: map['address_line2'], city: map['city'], state: map['state'], - country: map['country'], phoneNumber: map['phone_number'], + isDefault: map['is_defalut'] ?? false, ); } @@ -39,7 +39,6 @@ class DeliveryAddress { 'city': city, 'state': state, 'phone_number': phoneNumber, - 'country': country, }; } } diff --git a/lib/domain/vo/privilege.dart b/lib/domain/vo/privilege.dart new file mode 100644 index 0000000..5b913b2 --- /dev/null +++ b/lib/domain/vo/privilege.dart @@ -0,0 +1,54 @@ +import 'package:fcs/domain/constants.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_icons/flutter_icons.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class Privilege { + String id; + String name; + String desc; + bool sysAdminOnly = true; + bool isChecked = false; + + IconData iconData; + + Privilege( + {this.id, this.name, this.desc, this.isChecked, this.sysAdminOnly}) { + if (this.id == privilege_admin) { + iconData = MaterialCommunityIcons.account_tie; + } else if (this.id == privilege_support) { + iconData = SimpleLineIcons.support; + } else if (this.id == privilege_package) { + iconData = Octicons.package; + } else if (this.id == privilege_shipment) { + iconData = SimpleLineIcons.direction; + } else if (this.id == privilege_fcs_shipment) { + iconData = Ionicons.ios_airplane; + } else if (this.id == privilege_staff) { + iconData = MaterialCommunityIcons.worker; + } else if (this.id == privilege_carton) { + iconData = MaterialCommunityIcons.package; + } else if (this.id == privilege_customer) { + iconData = Feather.users; + } else if (this.id == privilege_delivery) { + iconData = MaterialCommunityIcons.truck_fast; + } else if (this.id == privilege_invoice) { + iconData = FontAwesomeIcons.fileInvoice; + } else if (this.id == privilege_processing) { + iconData = FontAwesome.dropbox; + } else if (this.id == privilege_receiving) { + iconData = MaterialCommunityIcons.inbox_arrow_down; + } else { + iconData = MaterialCommunityIcons.account_question; + } + } + + factory Privilege.fromMap(Map map, String docID) { + return Privilege( + id: docID, + name: map['name'], + desc: map['desc'], + sysAdminOnly: map['sys_admin_only']); + } +} diff --git a/lib/pages/box/box_editor.dart b/lib/pages/box/box_editor.dart index 4458c8c..8d48fff 100644 --- a/lib/pages/box/box_editor.dart +++ b/lib/pages/box/box_editor.dart @@ -570,7 +570,7 @@ class _BoxEditorState extends State { ), Column( children: [ - DeliveryAddressRow(shippingAddress: _deliveryAddress), + DeliveryAddressRow(deliveryAddress: _deliveryAddress), Container( padding: EdgeInsets.only(top: 20, bottom: 15, right: 15), child: Align( @@ -659,7 +659,7 @@ class _BoxEditorState extends State { return addresses.asMap().entries.map((s) { return InkWell( onTap: () {}, - child: DeliveryAddressRow(shippingAddress: s.value, index: s.key), + child: DeliveryAddressRow(deliveryAddress: s.value), ); }).toList(); } diff --git a/lib/pages/delivery_address/delivery_address_editor.dart b/lib/pages/delivery_address/delivery_address_editor.dart index 2bf7338..7c29891 100644 --- a/lib/pages/delivery_address/delivery_address_editor.dart +++ b/lib/pages/delivery_address/delivery_address_editor.dart @@ -23,25 +23,28 @@ class _DeliveryAddressEditorState extends State { TextEditingController _address2Controller = new TextEditingController(); TextEditingController _cityController = new TextEditingController(); TextEditingController _stateController = new TextEditingController(); - TextEditingController _countryController = new TextEditingController(); TextEditingController _phoneController = new TextEditingController(); DeliveryAddress _deliveryAddress = new DeliveryAddress(); bool _isLoading = false; + bool _isNew = true; @override void initState() { super.initState(); if (widget.deliveryAddress != null) { + _isNew = false; _deliveryAddress = widget.deliveryAddress; _nameController.text = _deliveryAddress.fullName; _address1Controller.text = _deliveryAddress.addressLine1; _address2Controller.text = _deliveryAddress.addressLine2; _cityController.text = _deliveryAddress.city; _stateController.text = _deliveryAddress.state; - _countryController.text = _deliveryAddress.country; _phoneController.text = _deliveryAddress.phoneNumber; + } else { + _cityController.text = "Yangon"; + _stateController.text = "Yangon"; } } @@ -52,9 +55,9 @@ class _DeliveryAddressEditorState extends State { @override Widget build(BuildContext context) { - final usaAddress = InputText( + final fullName = InputText( labelTextKey: 'delivery_address.full_name', - iconData: Icons.text_format, + iconData: MaterialCommunityIcons.account_arrow_left, controller: _nameController); final addressLine1 = InputText( @@ -77,14 +80,10 @@ class _DeliveryAddressEditorState extends State { iconData: Entypo.location, controller: _stateController); - final countryBox = InputText( - labelTextKey: 'delivery_address.country', - iconData: Entypo.flag, - controller: _countryController); - final phoneNumberBox = InputText( labelTextKey: 'delivery_address.phonenumber', iconData: Icons.phone, + textInputType: TextInputType.phone, controller: _phoneController); final createBtn = fcsButton( @@ -100,52 +99,43 @@ class _DeliveryAddressEditorState extends State { ); return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon(Icons.close), - onPressed: () => Navigator.of(context).pop(), + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + title: LocalText( + context, + 'delivery_address', + color: Colors.white, + fontSize: 20, + ), + actions: [IconButton(icon: Icon(Icons.delete), onPressed: _delete)], ), - backgroundColor: primaryColor, - title: LocalText( - context, - 'user.form.shipping_address', - color: Colors.white, - fontSize: 20, - ), - ), - body: Card( - child: Column( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 10.0, right: 10), - child: ListView(children: [ - usaAddress, - SizedBox(height: 5), - addressLine1, - SizedBox(height: 5), - addressLine2, - SizedBox(height: 5), - cityBox, - SizedBox(height: 5), - regionBox, - SizedBox(height: 5), - countryBox, - SizedBox(height: 5), - phoneNumberBox, - SizedBox(height: 10), - ]), - )), - widget.deliveryAddress == null ? createBtn : updateBtn, + body: Padding( + padding: const EdgeInsets.only(left: 10.0, right: 10), + child: ListView(children: [ + fullName, + SizedBox(height: 5), + phoneNumberBox, + SizedBox(height: 10), + addressLine1, + SizedBox(height: 5), + addressLine2, + SizedBox(height: 5), + cityBox, + SizedBox(height: 5), + regionBox, + SizedBox(height: 5), + _isNew ? createBtn : updateBtn, SizedBox(height: 10) - ], + ]), ), - ), - ), - ); + )); } DeliveryAddress _getPayload() { @@ -158,7 +148,6 @@ class _DeliveryAddressEditorState extends State { deliveryAddress.addressLine2 = _address2Controller.text; deliveryAddress.city = _cityController.text; deliveryAddress.state = _stateController.text; - deliveryAddress.country = _countryController.text; deliveryAddress.phoneNumber = _phoneController.text; } catch (e) { showMsgDialog(context, "Error", e.toString()); // shold never happen @@ -180,10 +169,6 @@ class _DeliveryAddressEditorState extends State { await showMsgDialog(context, "Error", "Invalid state!"); return false; } - if (deliveryAddress.country == null) { - await showMsgDialog(context, "Error", "Invalid country!"); - return false; - } if (deliveryAddress.phoneNumber == null) { await showMsgDialog(context, "Error", "Invalid phone number!"); return false; @@ -216,7 +201,6 @@ class _DeliveryAddressEditorState extends State { Future _update() async { DeliveryAddress deliveryAddress = _getPayload(); - print('deliveryAddress => ${deliveryAddress.country}'); bool valid = await _validate(deliveryAddress); if (!valid) { return; @@ -237,4 +221,26 @@ class _DeliveryAddressEditorState extends State { }); } } + + _delete() { + showConfirmDialog(context, "delivery_address.delete.confirm", _deleteDA); + } + + _deleteDA() async { + setState(() { + _isLoading = true; + }); + try { + DeliveryAddressModel deliveryAddressModel = + Provider.of(context, listen: false); + await deliveryAddressModel.deleteDeliveryAddress(_deliveryAddress); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } + } } diff --git a/lib/pages/delivery_address/delivery_address_list.dart b/lib/pages/delivery_address/delivery_address_list.dart index bcd94df..b2c967d 100644 --- a/lib/pages/delivery_address/delivery_address_list.dart +++ b/lib/pages/delivery_address/delivery_address_list.dart @@ -53,53 +53,79 @@ class _DeliveryAddressListState extends State { color: Colors.white, ), ), - body: Column( - children: [ - Expanded( - child: Column( - children: - getAddressList(context, shipmentModel.deliveryAddresses), - ), - ), - Container( - padding: EdgeInsets.only(top: 20, bottom: 15, right: 15), - child: Align( - alignment: Alignment.bottomRight, - child: Container( - width: 130, - height: 40, - child: FloatingActionButton.extended( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () { - Navigator.push( - context, - BottomUpPageRoute(DeliveryAddressEditor()), - ); - }, - icon: Icon(Icons.add), - label: Text( - getLocalString(context, 'delivery_address.new_address'), - style: TextStyle(fontSize: 12), - ), - backgroundColor: primaryColor, + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + Navigator.of(context) + .push(BottomUpPageRoute(DeliveryAddressEditor())); + }, + icon: Icon(Icons.add), + label: LocalText(context, "delivery_address.new_address", + color: Colors.white), + backgroundColor: primaryColor, + ), + body: Padding( + padding: const EdgeInsets.all(8.0), + child: ListView.separated( + separatorBuilder: (c, i) => Divider( + color: primaryColor, ), - ), - ), - ), - ], + itemCount: shipmentModel.deliveryAddresses.length, + itemBuilder: (context, index) { + return _row(context, shipmentModel.deliveryAddresses[index]); + }), )), ); } - List getAddressList( - BuildContext context, List addresses) { - return addresses.asMap().entries.map((s) { - return InkWell( - onTap: () { - // Navigator.pop(context, s.value); - }, - child: DeliveryAddressRow(shippingAddress: s.value, index: s.key), - ); - }).toList(); + _row(BuildContext context, DeliveryAddress deliveryAddress) { + return Row( + children: [ + InkWell( + onTap: () => _select(deliveryAddress), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Icon(Icons.check, + color: + deliveryAddress.isDefault ? primaryColor : Colors.black26), + ), + ), + Expanded( + child: DeliveryAddressRow( + key: ValueKey(deliveryAddress.id), + deliveryAddress: deliveryAddress, + selectionCallback: (d) => _edit(context, deliveryAddress)), + ), + ], + ); + } + + _edit(BuildContext context, DeliveryAddress deliveryAddress) { + Navigator.push( + context, + BottomUpPageRoute( + DeliveryAddressEditor(deliveryAddress: deliveryAddress)), + ); + } + + Future _select(DeliveryAddress deliveryAddress) async { + if (deliveryAddress.isDefault) { + Navigator.pop(context); + return; + } + setState(() { + _isLoading = true; + }); + var deliveryAddressModel = + Provider.of(context, listen: false); + try { + await deliveryAddressModel.selectDefalutDeliveryAddress(deliveryAddress); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } } } diff --git a/lib/pages/delivery_address/delivery_address_row.dart b/lib/pages/delivery_address/delivery_address_row.dart index 2fd254b..b601d0b 100644 --- a/lib/pages/delivery_address/delivery_address_row.dart +++ b/lib/pages/delivery_address/delivery_address_row.dart @@ -1,146 +1,78 @@ import 'package:fcs/domain/vo/delivery_address.dart'; -import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; -import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/widgets/local_text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; +import 'package:flutter_icons/flutter_icons.dart'; -import 'delivery_address_editor.dart'; +typedef SelectionCallback(DeliveryAddress deliveryAddress); class DeliveryAddressRow extends StatelessWidget { - final DeliveryAddress shippingAddress; - final int index; - - const DeliveryAddressRow({Key key, this.shippingAddress, this.index}) + final DeliveryAddress deliveryAddress; + final SelectionCallback selectionCallback; + const DeliveryAddressRow( + {Key key, this.deliveryAddress, this.selectionCallback}) : super(key: key); @override Widget build(BuildContext context) { - var deliveryAddressModel = Provider.of(context); - return Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: Column( + return InkWell( + onTap: selectionCallback == null + ? null + : () => this.selectionCallback(deliveryAddress), + child: Row( children: [ - Row( - children: [ - Expanded( - child: new Padding( - padding: const EdgeInsets.symmetric(vertical: 10.0), - child: Row( - children: [ - InkWell( - onTap: () { - Navigator.pop(context, shippingAddress); - }, - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.fullName == null - ? '' - : shippingAddress.fullName, - style: new TextStyle( - fontSize: 15.0, - color: Colors.black, - fontWeight: FontWeight.bold), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.addressLine1 == null - ? '' - : shippingAddress.addressLine1, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.addressLine2 == null - ? '' - : shippingAddress.addressLine2, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.city == null - ? '' - : shippingAddress.city, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.state == null - ? '' - : shippingAddress.state, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.country == null - ? '' - : shippingAddress.country, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - shippingAddress.phoneNumber == null - ? '' - : "Phone:${shippingAddress.phoneNumber}", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - ], - ), - ), - ], - ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + line(context, deliveryAddress.fullName, + iconData: MaterialCommunityIcons.account_arrow_left, + color: primaryColor, + fontSize: 16), + line(context, deliveryAddress.phoneNumber, + iconData: Icons.phone, color: primaryColor, fontSize: 16), + SizedBox( + height: 5, ), - ), - IconButton( - padding: EdgeInsets.only(right: 30), - icon: Icon(Icons.edit, color: Colors.black45), - onPressed: () { - Navigator.push( - context, - BottomUpPageRoute(DeliveryAddressEditor( - deliveryAddress: shippingAddress)), - ); - }), - IconButton( - padding: EdgeInsets.only(right: 30), - icon: Icon(Icons.delete, color: Colors.black45), - onPressed: () async { - await deliveryAddressModel - .deleteDeliveryAddress(shippingAddress); - }) - ], + line(context, deliveryAddress.addressLine1, + iconData: Icons.location_on), + line( + context, + deliveryAddress.addressLine2, + ), + line( + context, + deliveryAddress.city, + ), + line(context, deliveryAddress.state), + ], + ), ), - index == null - ? Container() - : index == deliveryAddressModel.deliveryAddresses.length - 1 - ? Container() - : Divider(color: Colors.black) ], ), ); } + + Widget line(BuildContext context, String text, + {IconData iconData, Color color, double fontSize}) { + return Row( + children: [ + iconData == null + ? SizedBox(width: 40) + : Padding( + padding: const EdgeInsets.only(left: 8.0, right: 8), + child: Icon(iconData, color: Colors.black38), + ), + Flexible( + child: TextLocalStyle( + context, + text ?? "", + fontSize: fontSize ?? 14, + color: color, + ), + ), + ], + ); + } } diff --git a/lib/pages/delivery_address/model/delivery_address_model.dart b/lib/pages/delivery_address/model/delivery_address_model.dart index 99f472c..73df666 100644 --- a/lib/pages/delivery_address/model/delivery_address_model.dart +++ b/lib/pages/delivery_address/model/delivery_address_model.dart @@ -12,6 +12,9 @@ class DeliveryAddressModel extends BaseModel { StreamSubscription listener; + DeliveryAddress get defalutAddress => + deliveryAddresses.firstWhere((e) => e.isDefault, orElse: () => null); + @override void privilegeChanged() { super.privilegeChanged(); @@ -61,4 +64,9 @@ class DeliveryAddressModel extends BaseModel { return Services.instance.deliveryAddressService .deleteDeliveryAddress(deliveryAddress); } + + Future selectDefalutDeliveryAddress(DeliveryAddress deliveryAddress) { + return Services.instance.deliveryAddressService + .selectDefalutDeliveryAddress(deliveryAddress); + } } diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index 39fd1ae..c7d4b8a 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -206,12 +206,12 @@ class _HomePageState extends State { CupertinoPageRoute(builder: (context) => PackageList()))); final receivingBtn = TaskButton("receiving.title", - icon: Octicons.package, + icon: MaterialCommunityIcons.inbox_arrow_down, btnCallback: () => Navigator.of(context).push( CupertinoPageRoute(builder: (context) => ReceivingList()))); final processingBtn = TaskButton("processing.title", - icon: Octicons.package, + icon: FontAwesome.dropbox, btnCallback: () => Navigator.of(context).push( CupertinoPageRoute(builder: (context) => ProcessingList()))); final boxesBtn = TaskButton("boxes.name", @@ -287,7 +287,7 @@ class _HomePageState extends State { List widgets = []; if (user != null) { - // true ? widgets.add(pickUpBtn) : ""; + true ? widgets.add(pickUpBtn) : ""; !customer ? widgets.add(fcsShipmentBtn) : ""; customer ? widgets.add(notiBtn) : ""; user.hasStaffs() ? widgets.add(staffBtn) : ""; diff --git a/lib/pages/main/model/main_model.dart b/lib/pages/main/model/main_model.dart index fc219d4..14a7846 100644 --- a/lib/pages/main/model/main_model.dart +++ b/lib/pages/main/model/main_model.dart @@ -162,8 +162,13 @@ class MainModel extends ChangeNotifier { notifyListeners(); } - Future updateProfile(String newUserName) async { - await Services.instance.authService.updateProfile(newUserName); + Future updateProfileName(String newUserName) async { + await Services.instance.authService.updateProfileName(newUserName); + notifyListeners(); + } + + Future updatePreferredCurrency(String currency) async { + await Services.instance.authService.updatePreferredCurrency(currency); notifyListeners(); } } diff --git a/lib/pages/package/model/package_model.dart b/lib/pages/package/model/package_model.dart index 9c2f9e0..4633a5a 100644 --- a/lib/pages/package/model/package_model.dart +++ b/lib/pages/package/model/package_model.dart @@ -93,6 +93,24 @@ class PackageModel extends BaseModel { .createPackages(packages, user.fcsID); } + Future createPackage(User user, Package package, List files, + List deletedUrls) async { + if (user != null) { + package.fcsID = user.fcsID; + } + if (files != null) { + if (files.length > 5) throw Exception("Exceed number of file upload"); + package.photoUrls = package.photoUrls == null ? [] : package.photoUrls; + for (File f in files) { + String path = Path.join(pkg_files_path); + String url = await uploadStorage(path, f); + package.photoUrls.add(url); + } + package.photoUrls.removeWhere((e) => deletedUrls.contains(e)); + } + return Services.instance.packageService.createPackage(package); + } + Future completeProcessing( Package package, List files, List deletedUrls) async { if (files != null) { @@ -105,7 +123,7 @@ class PackageModel extends BaseModel { } package.photoUrls.removeWhere((e) => deletedUrls.contains(e)); } - await request("/packages", "PUT", + await request("/package", "PUT", payload: package.toJson(), token: await getToken()); } diff --git a/lib/pages/package/package_info.dart b/lib/pages/package/package_info.dart index 1a0ec6c..0e635ff 100644 --- a/lib/pages/package/package_info.dart +++ b/lib/pages/package/package_info.dart @@ -185,9 +185,11 @@ class _PackageInfoState extends State { ? Ionicons.ios_airplane : e.status == "delivered" ? MaterialCommunityIcons.truck_fast - : e.status == "processed" - ? MaterialIcons.check - : Octicons.package, + : e.status == "packed" + ? MaterialCommunityIcons.package + : e.status == "processed" + ? FontAwesome.dropbox + : MaterialCommunityIcons.inbox_arrow_down, color: Colors.white, ))) .toList(); diff --git a/lib/pages/package/tracking_id_page.dart b/lib/pages/package/tracking_id_page.dart index 182fc2b..2918b5e 100644 --- a/lib/pages/package/tracking_id_page.dart +++ b/lib/pages/package/tracking_id_page.dart @@ -5,6 +5,7 @@ import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/market/market_editor.dart'; import 'package:fcs/pages/market/model/market_model.dart'; import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/widgets/barcode_scanner.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_text.dart'; @@ -163,13 +164,8 @@ class _TrackingIDPageState extends State { } try { - String barcode = await BarcodeScanner.scan(); + String barcode = await scanBarcode(); if (barcode != null) { - String gs = String.fromCharCode(29); - if (barcode.contains(gs)) { - var codes = barcode.split(gs); - barcode = codes.length >= 2 ? codes[1] : barcode; - } setState(() { _transcationIDCtl.text = barcode; }); diff --git a/lib/pages/package_search/package_serach.dart b/lib/pages/package_search/package_serach.dart index ac9804e..2ee5ccf 100644 --- a/lib/pages/package_search/package_serach.dart +++ b/lib/pages/package_search/package_serach.dart @@ -4,6 +4,7 @@ import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/package/package_list_row.dart'; +import 'package:fcs/pages/widgets/barcode_scanner.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:permission_handler/permission_handler.dart'; @@ -147,13 +148,8 @@ class PackageSearchDelegate extends SearchDelegate { // Barcode bc = barcodes.firstWhere((element) => true); // String barcode; // if (bc != null) barcode = bc.rawValue; - String barcode = await BarcodeScanner.scan(); + String barcode = await scanBarcode(); if (barcode != null) { - String gs = String.fromCharCode(29); - if (barcode.contains(gs)) { - var codes = barcode.split(gs); - barcode = codes.length >= 2 ? codes[1] : barcode; - } query = barcode; showResults(context); } diff --git a/lib/pages/profile/profile_currency_edit.dart b/lib/pages/profile/profile_currency_edit.dart new file mode 100644 index 0000000..6d91664 --- /dev/null +++ b/lib/pages/profile/profile_currency_edit.dart @@ -0,0 +1,129 @@ +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/localization/app_translations.dart'; +import 'package:fcs/pages/main/model/language_model.dart'; +import 'package:fcs/pages/main/model/main_model.dart'; +import 'package:fcs/pages/widgets/local_text.dart'; +import 'package:fcs/pages/widgets/progress.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:fcs/pages/main/util.dart'; + +typedef void ProfileCallback(); + +enum Currency { USD, MMK } + +class ProfileCurrencyEdit extends StatefulWidget { + @override + _ProfileCurrencyEditState createState() => _ProfileCurrencyEditState(); +} + +class _ProfileCurrencyEditState extends State { + final TextEditingController nameController = new TextEditingController(); + bool _loading = false; + + @override + void initState() { + super.initState(); + MainModel mainModel = Provider.of(context, listen: false); + if (mainModel.user.preferCurrency == "MMK") { + _currency = Currency.MMK; + } else { + _currency = Currency.USD; + } + } + + Currency _currency = Currency.USD; + + @override + Widget build(BuildContext context) { + final saveBtn = + fcsButton(context, getLocalString(context, "btn.save"), callack: _save); + + return LocalProgress( + inAsyncCall: _loading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: LocalText( + context, + "profile.edit.currency.title", + fontSize: 20, + color: primaryColor, + ), + backgroundColor: Colors.white, + shadowColor: Colors.transparent, + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 35, + color: primaryColor, + ), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: Column( + children: [ + InkWell( + onTap: () => setState(() { + _currency = Currency.USD; + }), + child: ListTile( + title: Text('USD'), + leading: Radio( + activeColor: primaryColor, + value: Currency.USD, + groupValue: _currency, + onChanged: (Currency value) { + setState(() { + _currency = value; + }); + }, + ), + ), + ), + InkWell( + onTap: () => setState(() { + _currency = Currency.MMK; + }), + child: ListTile( + title: const Text('MMK'), + leading: Radio( + activeColor: primaryColor, + value: Currency.MMK, + groupValue: _currency, + onChanged: (Currency value) { + setState(() { + _currency = value; + }); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(18.0), + child: saveBtn, + ), + ], + ), + ), + ); + } + + _save() async { + setState(() { + _loading = true; + }); + try { + await Provider.of(context, listen: false) + .updatePreferredCurrency(_currency.toString().split(".").last); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _loading = false; + }); + } + } +} diff --git a/lib/pages/profile/profile_edit.dart b/lib/pages/profile/profile_edit.dart index 58f1ed5..23f4a37 100644 --- a/lib/pages/profile/profile_edit.dart +++ b/lib/pages/profile/profile_edit.dart @@ -96,7 +96,7 @@ class _ProfileEditState extends State { }); try { await Provider.of(context, listen: false) - .updateProfile(nameController.text); + .updateProfileName(nameController.text); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index b08ed79..5b9b454 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -1,21 +1,25 @@ -import 'package:fcs/domain/entities/role.dart'; +import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/vo/delivery_address.dart'; -import 'package:fcs/localization/app_translations.dart'; +import 'package:fcs/domain/vo/privilege.dart'; import 'package:fcs/localization/transalation.dart'; import 'package:fcs/pages/delivery_address/delivery_address_list.dart'; +import 'package:fcs/pages/delivery_address/delivery_address_row.dart'; import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/model/main_model.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/profile/profile_currency_edit.dart'; import 'package:fcs/pages/profile/profile_edit.dart'; +import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/progress.dart'; -import 'package:fcs/pages/main/util.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_icons/flutter_icons.dart'; import 'package:provider/provider.dart'; import '../../helpers/theme.dart'; @@ -33,8 +37,6 @@ class _ProfileState extends State { String selectedLanguage; TextEditingController bizNameController = new TextEditingController(); - DeliveryAddress _deliveryAddress = new DeliveryAddress(); - static final List languagesList = Translation().supportedLanguages; static final List languageCodesList = Translation().supportedLanguagesCodes; @@ -56,12 +58,6 @@ class _ProfileState extends State { @override void initState() { super.initState(); - var shipmentModel = - Provider.of(context, listen: false); - - if (shipmentModel.deliveryAddresses.length != 0) { - _deliveryAddress = shipmentModel.deliveryAddresses[0]; - } } @override @@ -70,11 +66,19 @@ class _ProfileState extends State { if (mainModel.user == null) { return Container(); } + DeliveryAddressModel deliveryAddressModel = + Provider.of(context); + final namebox = DisplayText( - text: mainModel.user.name, + text: mainModel.user.name + " (${mainModel.user.status})", labelTextKey: "profile.name", iconData: Icons.person, ); + final currencyBox = DisplayText( + text: mainModel.user.preferCurrency, + labelTextKey: "profile.currency", + iconData: FontAwesome5.money_bill_alt, + ); final phonenumberbox = DisplayText( text: mainModel.user.phone, @@ -142,42 +146,40 @@ class _ProfileState extends State { ), shadowColor: Colors.transparent, backgroundColor: Colors.white, - actions: [], ), body: Padding( padding: const EdgeInsets.all(8.0), - child: Column( + child: ListView( children: [ - Expanded( - child: ListView( - shrinkWrap: true, - children: [ - Row( - children: [ - Expanded(child: namebox), - Padding( - padding: const EdgeInsets.only(right: 0), - child: IconButton( - icon: Icon(Icons.edit, color: Colors.grey), - onPressed: _editName), - ) - ], - ), - mainModel.isCustomer() - ? Container() - : getPrivilegeBox(context), - getShippingAddressList(context), - phonenumberbox, - fcsIDBox, - usaShippingAddressBox, - DisplayText( - text: mainModel.user.status, - labelTextKey: "customer.status", - iconData: Icons.add_alarm, - ), - ], - ), + Row( + children: [ + Expanded(child: namebox), + Padding( + padding: const EdgeInsets.only(right: 0), + child: IconButton( + icon: Icon(Icons.edit, color: Colors.grey), + onPressed: _editName), + ) + ], ), + phonenumberbox, + fcsIDBox, + usaShippingAddressBox, + Row( + children: [ + Expanded(child: currencyBox), + Padding( + padding: const EdgeInsets.only(right: 0), + child: IconButton( + icon: Icon(Icons.edit, color: Colors.grey), + onPressed: _editCurrency), + ) + ], + ), + defalutDeliveryAddress( + context, deliveryAddressModel.defalutAddress), + getPrivilegeBox(context), + SizedBox(height: 15), logoutbutton, SizedBox(height: 25) ], @@ -187,221 +189,104 @@ class _ProfileState extends State { ); } - Widget getShippingAddressList(BuildContext context) { - var languageModel = Provider.of(context); - return ListTileTheme( - contentPadding: EdgeInsets.all(10), - child: ExpansionTile( - title: Text( - getLocalString(context, 'delivery_addresses'), - style: languageModel.isEng - ? TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - ) - : TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - fontFamily: "Myanmar3"), - ), - children: [ - showDeliveryAddress(_deliveryAddress), - Container( - padding: EdgeInsets.only(top: 20, bottom: 15, right: 15), - child: Align( - alignment: Alignment.bottomRight, - child: Container( - width: 130, - height: 40, - child: FloatingActionButton.extended( - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onPressed: () async { - DeliveryAddress deliveryAddress = await Navigator.push( - context, - BottomUpPageRoute(DeliveryAddressList( - deliveryAddress: _deliveryAddress)), - ); - setState(() { - _deliveryAddress = deliveryAddress; - }); - }, - label: LocalText(context, - 'delivery_address.change_address', - fontSize: 12, - color: Colors.white, - ), - backgroundColor: primaryColor, - ), + Widget defalutDeliveryAddress( + BuildContext context, DeliveryAddress deliveryAddress) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: DisplayText( + labelTextKey: "delivery_address", + iconData: MaterialCommunityIcons.truck_fast, ), ), - ) - ], - ), - ); - } - - Widget showDeliveryAddress(DeliveryAddress deliveryAddress) { - return Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: new Padding( - padding: const EdgeInsets.symmetric(vertical: 10.0), - child: Row( - children: [ - new Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.fullName == null - ? '' - : deliveryAddress.fullName, - style: new TextStyle( - fontSize: 15.0, - color: Colors.black, - fontWeight: FontWeight.bold), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.addressLine1 == null - ? '' - : deliveryAddress.addressLine1, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.addressLine2 == null - ? '' - : deliveryAddress.addressLine2, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.city == null - ? '' - : deliveryAddress.city, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.state == null - ? '' - : deliveryAddress.state, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.country == null - ? '' - : deliveryAddress.country, - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - deliveryAddress.phoneNumber == null - ? '' - : "Phone:${deliveryAddress.phoneNumber}", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - ], - ), - ], - ), - ), + Chip( + label: InkWell( + onTap: () => Navigator.push( + context, + BottomUpPageRoute(DeliveryAddressList()), ), - ], - ), - ], - ), + child: LocalText(context, "delivery_address.change_address", + color: primaryColor), + )) + ], + ), + Padding( + padding: const EdgeInsets.only(left: 28.0), + child: deliveryAddress == null + ? Container() + : DeliveryAddressRow( + key: ValueKey(deliveryAddress.id), + deliveryAddress: deliveryAddress), + ), + ], ); } - List privileges = [ - Privilege(name: 'Manage shipment'), - Privilege(name: 'Manage pickups'), - Privilege(name: 'Manage packages'), - Privilege(name: 'Manage deliveries'), - Privilege(name: 'Admin') - ]; - Widget getPrivilegeBox(BuildContext context) { - var languageModel = Provider.of(context); + User user = Provider.of(context, listen: false).user; + List _privileges = + Provider.of(context, listen: false).privileges; - return ListTileTheme( - contentPadding: EdgeInsets.all(10), - child: ExpansionTile( - title: Text( - AppTranslations.of(context).text("profile.privilege"), - style: languageModel.isEng - ? TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - ) - : TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - fontFamily: "Myanmar3"), + if (user == null || user.isCustomer()) return Container(); + List privileges = []; + user.privileges.forEach((e) { + var p = _privileges.firstWhere((p) => p.id == e, orElse: () => null); + if (p != null) { + privileges.add(p); + } + }); + + return Column( + children: [ + DisplayText( + labelTextKey: "profile.privileges", + iconData: MaterialCommunityIcons.clipboard_check_outline, ), - children: [ - Align( - alignment: Alignment.topLeft, - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: getRowPrivilegeWidget(privileges)), - ), - ) - ], - ), + Padding( + padding: const EdgeInsets.only(left: 30.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: getRowPrivilegeWidget(privileges)), + ) + ], ); } List getRowPrivilegeWidget(List privileges) { return privileges.map((p) { return Container( - padding: EdgeInsets.all(8.0), + padding: EdgeInsets.all(3.0), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(p.name, - style: TextStyle(fontSize: 16.0, fontStyle: FontStyle.normal)), - SizedBox( - width: 30, + Icon( + p.iconData, + color: Colors.black38, ), - Container( - child: Text( - "- ${p.desc}", - style: TextStyle(fontSize: 16.0, fontStyle: FontStyle.normal), + SizedBox( + width: 10, + ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("${p.name}", + style: TextStyle( + fontSize: 16.0, + fontStyle: FontStyle.normal, + color: primaryColor, + )), + Text( + "${p.desc}", + style: TextStyle( + fontSize: 14.0, + fontStyle: FontStyle.normal, + color: Colors.black38), + ), + ], ), ) ], @@ -415,7 +300,7 @@ class _ProfileState extends State { _showToast(title); } - void _showToast(String title) { + _showToast(String title) { final ScaffoldState scaffold = key.currentState; scaffold.showSnackBar( SnackBar( @@ -431,6 +316,11 @@ class _ProfileState extends State { .push(CupertinoPageRoute(builder: (context) => ProfileEdit())); } + _editCurrency() { + Navigator.of(context).push( + CupertinoPageRoute(builder: (context) => ProfileCurrencyEdit())); + } + _logout() { showConfirmDialog(context, "profile.logout.confirm", () async { setState(() { diff --git a/lib/pages/receiving/receiving_info.dart b/lib/pages/receiving/receiving_info.dart new file mode 100644 index 0000000..dbaac71 --- /dev/null +++ b/lib/pages/receiving/receiving_info.dart @@ -0,0 +1,162 @@ +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/main/model/main_model.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/package/model/package_model.dart'; +import 'package:fcs/pages/package/package_editor.dart'; +import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; +import 'package:fcs/pages/widgets/display_text.dart'; +import 'package:fcs/pages/widgets/local_text.dart'; +import 'package:fcs/pages/widgets/multi_img_controller.dart'; +import 'package:fcs/pages/widgets/multi_img_file.dart'; +import 'package:fcs/pages/widgets/progress.dart'; +import 'package:fcs/pages/widgets/status_tree.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_icons/flutter_icons.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:timeline_list/timeline.dart'; +import 'package:timeline_list/timeline_model.dart'; + +final DateFormat dateFormat = DateFormat("d MMM yyyy"); + +class ReceivingInfo extends StatefulWidget { + final Package package; + ReceivingInfo({this.package}); + + @override + _ReceivingInfoState createState() => _ReceivingInfoState(); +} + +class _ReceivingInfoState extends State { + Package _package; + bool _isLoading = false; + MultiImgController multiImgController = MultiImgController(); + + @override + void initState() { + super.initState(); + initPackage(widget.package); + } + + initPackage(Package package) { + setState(() { + _package = package; + multiImgController.setImageUrls = package.photoUrls; + }); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + bool isCustomer = Provider.of(context).isCustomer(); + + final trackingIdBox = DisplayText( + text: _package.trackingID, + labelTextKey: "package.tracking.id", + iconData: MaterialCommunityIcons.barcode_scan, + ); + final customerNameBox = DisplayText( + text: _package.userName, + labelTextKey: "package.create.name", + iconData: Icons.perm_identity, + ); + final remarkBox = DisplayText( + text: _package.remark ?? "-", + labelTextKey: "package.edit.remark", + iconData: Entypo.new_message, + ); + final img = MultiImageFile( + enabled: false, + controller: multiImgController, + title: "Receipt File", + ); + + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(Icons.close, color: primaryColor, size: 30), + onPressed: () => Navigator.of(context).pop(), + ), + shadowColor: Colors.transparent, + backgroundColor: Colors.white, + title: LocalText( + context, + "package.info.title", + fontSize: 20, + color: primaryColor, + ), + actions: [ + isCustomer + ? Container() + : IconButton( + icon: Icon(Icons.delete, color: primaryColor), + onPressed: _delete, + ) + ], + ), + body: Card( + child: Column( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(10.0), + child: ListView(children: [ + trackingIdBox, + _package.userID != null ? customerNameBox : Container(), + _package.photoUrls.length == 0 ? Container() : img, + remarkBox, + ExpansionTile( + initiallyExpanded: true, + title: Text( + 'Status', + style: TextStyle( + color: primaryColor, fontWeight: FontWeight.bold), + ), + children: [ + StatusTree( + shipmentHistory: _package.shipmentHistory, + currentStatus: _package.currentStatus), + ], + ), + SizedBox( + height: 20, + ) + ]), + )), + ], + ), + ), + ), + ); + } + + _delete() { + showConfirmDialog(context, "receiving.delete.confirm", _deleteReceiving); + } + + _deleteReceiving() async { + setState(() { + _isLoading = true; + }); + try { + PackageModel packageModel = + Provider.of(context, listen: false); + await packageModel.deletePackage(_package); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } + } +} diff --git a/lib/pages/receiving/receiving_list.dart b/lib/pages/receiving/receiving_list.dart index 402f10f..e145d9a 100644 --- a/lib/pages/receiving/receiving_list.dart +++ b/lib/pages/receiving/receiving_list.dart @@ -1,10 +1,7 @@ import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/package/model/package_model.dart'; -import 'package:fcs/pages/package/package_info.dart'; -import 'package:fcs/pages/package/package_new.dart'; import 'package:fcs/pages/package_search/package_serach.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/local_text.dart'; @@ -13,6 +10,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'receiving_info.dart'; import 'receiving_list_row.dart'; import 'receiving_new.dart'; @@ -76,8 +74,8 @@ class _ReceivingListState extends State { _newReceiving(); }, icon: Icon(Icons.add), - label: Text( - AppTranslations.of(context).text("receiving.new")), + label: + LocalText(context, "receiving.new", color: Colors.white), backgroundColor: primaryColor, ), body: new ListView.separated( @@ -110,7 +108,7 @@ class _ReceivingListState extends State { if (_package == null) return; Navigator.push( context, - BottomUpPageRoute(PackageInfo(package: _package)), + BottomUpPageRoute(ReceivingInfo(package: _package)), ); } } diff --git a/lib/pages/receiving/receiving_list_row.dart b/lib/pages/receiving/receiving_list_row.dart index 435622d..5f8812c 100644 --- a/lib/pages/receiving/receiving_list_row.dart +++ b/lib/pages/receiving/receiving_list_row.dart @@ -1,10 +1,11 @@ import 'package:fcs/domain/entities/package.dart'; -import 'package:fcs/pages/package/package_info.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; +import 'receiving_info.dart'; + typedef CallbackPackageSelect(Package package); class ReceivingListRow extends StatelessWidget { @@ -28,7 +29,7 @@ class ReceivingListRow extends StatelessWidget { } Navigator.push( context, - BottomUpPageRoute(PackageInfo(package: package)), + BottomUpPageRoute(ReceivingInfo(package: package)), ); }, child: Row( diff --git a/lib/pages/receiving/receiving_new.dart b/lib/pages/receiving/receiving_new.dart index d0b0e5e..0a0af86 100644 --- a/lib/pages/receiving/receiving_new.dart +++ b/lib/pages/receiving/receiving_new.dart @@ -2,8 +2,10 @@ import 'package:barcode_scan/barcode_scan.dart'; import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/user_search/user_serach.dart'; import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/package/model/package_model.dart'; +import 'package:fcs/pages/user_search/user_serach.dart'; +import 'package:fcs/pages/widgets/barcode_scanner.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/input_text.dart'; @@ -29,7 +31,7 @@ class _ReceivingNewState extends State { User user; TextEditingController _transcationIDCtl = new TextEditingController(); TextEditingController _remarkCtl = new TextEditingController(); - MultiImgController multiImgController = MultiImgController(); + MultiImgController _multiImgController = MultiImgController(); @override void initState() { @@ -80,8 +82,8 @@ class _ReceivingNewState extends State { controller: _remarkCtl); final img = MultiImageFile( enabled: true, - controller: multiImgController, - title: "Receipt File", + controller: _multiImgController, + title: "Receiving", ); final namebox = DisplayText( text: user != null ? user.name : "", @@ -161,14 +163,8 @@ class _ReceivingNewState extends State { } try { - String barcode = await BarcodeScanner.scan(); + String barcode = await scanBarcode(); if (barcode != null) { - String gs = String.fromCharCode(29); - if (barcode.contains(gs)) { - var codes = barcode.split(gs); - barcode = codes.length >= 2 ? codes[1] : barcode; - } - setState(() { _transcationIDCtl.text = barcode; }); @@ -179,17 +175,22 @@ class _ReceivingNewState extends State { } _create() async { - if (user == null) { - showMsgDialog(context, "Error", "Invalid user!"); + Package package = Package(); + package.trackingID = _transcationIDCtl.text; + package.remark = _remarkCtl.text; + + if (package.trackingID == null || package.trackingID == "") { + showMsgDialog(context, "Error", "Invalid tracking ID!"); return; } setState(() { _isLoading = true; }); - // PackageModel packageModel = - // Provider.of(context, listen: false); + PackageModel packageModel = + Provider.of(context, listen: false); try { - // await packageModel.createPackages(user, packages); + await packageModel.createPackage(user, package, + _multiImgController.getAddedFile, _multiImgController.getDeletedUrl); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/pages/shipment/pickup_box_editor.dart b/lib/pages/shipment/pickup_box_editor.dart index 8048534..0d53b96 100644 --- a/lib/pages/shipment/pickup_box_editor.dart +++ b/lib/pages/shipment/pickup_box_editor.dart @@ -222,7 +222,7 @@ class _PickupBoxEditorState extends State { color: primaryColor, fontWeight: FontWeight.bold), ), children: [ - DeliveryAddressRow(shippingAddress: _shippingAddress), + DeliveryAddressRow(deliveryAddress: _shippingAddress), Container( padding: EdgeInsets.only(top: 20, bottom: 15, right: 15), diff --git a/lib/pages/shipment/shipment_editor.dart b/lib/pages/shipment/shipment_editor.dart index 768f9f5..bc412b9 100644 --- a/lib/pages/shipment/shipment_editor.dart +++ b/lib/pages/shipment/shipment_editor.dart @@ -304,7 +304,7 @@ class _ShipmentEditorState extends State { _currVal == 3 ? Container( child: DeliveryAddressRow( - shippingAddress: DeliveryAddress( + deliveryAddress: DeliveryAddress( fullName: 'FCS Office', addressLine1: '154-19 64th Ave.', addressLine2: 'Flushing', @@ -412,7 +412,7 @@ class _ShipmentEditorState extends State { Padding( padding: const EdgeInsets.only(left: 10.0), child: DeliveryAddressRow( - shippingAddress: _shippingAddress), + deliveryAddress: _shippingAddress), ), Container( padding: EdgeInsets.only( diff --git a/lib/pages/staff/model/staff_model.dart b/lib/pages/staff/model/staff_model.dart index e7ba735..79f92df 100644 --- a/lib/pages/staff/model/staff_model.dart +++ b/lib/pages/staff/model/staff_model.dart @@ -3,8 +3,8 @@ import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fcs/data/services/services.dart'; import 'package:fcs/domain/constants.dart'; -import 'package:fcs/domain/entities/role.dart'; import 'package:fcs/domain/entities/user.dart'; +import 'package:fcs/domain/vo/privilege.dart'; import 'package:fcs/helpers/firebase_helper.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:logging/logging.dart'; @@ -58,8 +58,6 @@ class StaffModel extends BaseModel { } Future _loadPrivileges() async { - if (user == null || !user.hasStaffs()) return; - try { privilegeListener = Firestore.instance .collection("/$privilege_collection") diff --git a/lib/pages/staff/staff_editor.dart b/lib/pages/staff/staff_editor.dart index 5c2af22..b86baf0 100644 --- a/lib/pages/staff/staff_editor.dart +++ b/lib/pages/staff/staff_editor.dart @@ -1,10 +1,10 @@ -import 'package:fcs/domain/entities/role.dart'; import 'package:fcs/domain/entities/user.dart'; +import 'package:fcs/domain/vo/privilege.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/main/model/language_model.dart'; -import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/progress.dart'; @@ -68,16 +68,22 @@ class _StaffEditorState extends State { p.isChecked = value; }); }), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - new Text( - p.name, - style: TextStyle(fontSize: 15.0, color: primaryColor), - ), - Text(p.desc, - style: TextStyle(fontSize: 13, color: Colors.grey[600])) - ], + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon(p.iconData, size: 50, color: Colors.black38), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + new Text( + p.name, + style: TextStyle(fontSize: 15.0, color: primaryColor), + ), + Text(p.desc, + style: TextStyle(fontSize: 13, color: Colors.grey[600])) + ], + ), ), ], ), @@ -192,6 +198,9 @@ class _StaffEditorState extends State { Column( children: showprivilegeList(context), ), + SizedBox( + height: 10, + ), Container( child: isNew ? addButton : updateButton, ), diff --git a/lib/pages/staff/staff_list.dart b/lib/pages/staff/staff_list.dart index d022236..fbae2b2 100644 --- a/lib/pages/staff/staff_list.dart +++ b/lib/pages/staff/staff_list.dart @@ -1,17 +1,15 @@ import 'package:fcs/domain/entities/user.dart'; -import 'package:fcs/localization/app_translations.dart'; +import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; - import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:intl/intl.dart'; - import 'package:provider/provider.dart'; + import 'staff_editor.dart'; class StaffList extends StatefulWidget { diff --git a/lib/pages/widgets/barcode_scanner.dart b/lib/pages/widgets/barcode_scanner.dart new file mode 100644 index 0000000..3bbed5d --- /dev/null +++ b/lib/pages/widgets/barcode_scanner.dart @@ -0,0 +1,18 @@ +import 'package:barcode_scan/barcode_scan.dart'; + +Future scanBarcode() async { + try { + String barcode = await BarcodeScanner.scan(); + if (barcode == null) return null; + + String gs = String.fromCharCode(29); + if (barcode.contains(gs)) { + var codes = barcode.split(gs); + barcode = codes.length >= 2 ? codes[1] : barcode; + } + return barcode; + } catch (e) { + print('error: $e'); + return null; + } +} diff --git a/lib/pages/widgets/display_text.dart b/lib/pages/widgets/display_text.dart index 8b3bf37..8d36a9f 100644 --- a/lib/pages/widgets/display_text.dart +++ b/lib/pages/widgets/display_text.dart @@ -63,10 +63,12 @@ class DisplayText extends StatelessWidget { AppTranslations.of(context).text(labelTextKey), style: labelStyle, ), - Text( - text, - style: textStyle, - ), + text == null + ? Container() + : Text( + text, + style: textStyle, + ), ], ), ), diff --git a/lib/pages/widgets/status_tree.dart b/lib/pages/widgets/status_tree.dart new file mode 100644 index 0000000..fb89a54 --- /dev/null +++ b/lib/pages/widgets/status_tree.dart @@ -0,0 +1,66 @@ +import 'package:fcs/domain/constants.dart'; +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/vo/shipment_status.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_icons/flutter_icons.dart'; +import 'package:intl/intl.dart'; +import 'package:timeline_list/timeline.dart'; +import 'package:timeline_list/timeline_model.dart'; + +var dateFormatter = new DateFormat('dd MMM yyyy'); + +class StatusTree extends StatelessWidget { + final List shipmentHistory; + final String currentStatus; + + const StatusTree({Key key, this.shipmentHistory, this.currentStatus}) + : super(key: key); + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(left: 20), + height: 400, + child: Timeline(children: _models(), position: TimelinePosition.Left), + ); + } + + List _models() { + if (shipmentHistory == null || currentStatus == null) return []; + bool isPacked = currentStatus != package_received_status && + currentStatus != package_processed_status; + return shipmentHistory + .map((e) => TimelineModel( + Padding( + padding: const EdgeInsets.all(18.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(e.status, + style: TextStyle( + color: e.done ? primaryColor : Colors.grey, + fontSize: 16, + fontWeight: FontWeight.bold)), + e.done || isPacked + ? Text(dateFormatter.format(e.date)) + : Container(), + ], + ), + ), + iconBackground: e.done ? primaryColor : Colors.grey, + icon: Icon( + e.status == "shipped" + ? Ionicons.ios_airplane + : e.status == "delivered" + ? MaterialCommunityIcons.truck_fast + : e.status == "packed" + ? MaterialCommunityIcons.package + : e.status == "processed" + ? FontAwesome.dropbox + : MaterialCommunityIcons.inbox_arrow_down, + color: Colors.white, + ))) + .toList(); + } +}