diff --git a/assets/fonts/Myanmar3_2018.ttf b/assets/fonts/Myanmar3_2018.ttf new file mode 100644 index 0000000..2a6d3c8 Binary files /dev/null and b/assets/fonts/Myanmar3_2018.ttf differ diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 59c7247..b77a0dc 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -41,6 +41,8 @@ "faq.edit.mm":"Myanmar", "faq.edit.question":"Question", "faq.edit.answer":"Answer", + "faq.edit.sn":"S/N", + "faq.edit.delete.confirm":"Delete this FAQ?", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index 20e09f0..f3a074a 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -41,7 +41,8 @@ "faq.edit.mm":"မြန်မာ", "faq.edit.question":"မေးခွန်း", "faq.edit.answer":"အဖြေ", - + "faq.edit.sn":"S/N", + "faq.edit.delete.confirm":"Delete this FAQ?", "btn.save":"သိမ်းဆည်းရန်", "btn.approve":"အတည်ပြုရန်", diff --git a/lib/app.dart b/lib/app.dart index 6c454a2..f3a0443 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -4,6 +4,8 @@ import 'package:fcs/fcs/common/helpers/theme.dart'; import 'package:fcs/fcs/common/localization/app_translations_delegate.dart'; import 'package:fcs/fcs/common/localization/transalation.dart'; import 'package:fcs/fcs/common/pages/contact/model/contact_model.dart'; +import 'package:fcs/fcs/common/pages/customers/model/customer_model.dart'; +import 'package:fcs/fcs/common/pages/faq/model/faq_model.dart'; import 'package:fcs/fcs/common/pages/model/language_model.dart'; import 'package:fcs/fcs/common/pages/term/model/term_model.dart'; import 'package:fcs/fcs/common/services/services.dart'; @@ -31,7 +33,6 @@ import 'package:fcs/fcs/common/pages/model/main_model.dart' as fcs; import 'model/announcement_model.dart'; import 'model/chart_model.dart'; -import 'model/customer_model.dart'; import 'model/device_model.dart'; import 'model/do_model.dart'; import 'model/employee_model.dart'; @@ -60,6 +61,7 @@ class _AppState extends State { final ContactModel contactModel =new ContactModel(); final TermModel termModel=new TermModel(); final MainModel mainModel = new MainModel(); + final FAQModel faqModel = new FAQModel(); final UserModel userModel = new UserModel(); final ProductModel productModel = new ProductModel(); @@ -130,7 +132,6 @@ class _AppState extends State { ..addModel(messageModel) ..addModel(shipmentRateModel) ..addModel(invoiceModel) - ..addModel(customerModel) ..addModel(discountModel); this.mainModel.init(); @@ -249,6 +250,7 @@ class _AppState extends State { ChangeNotifierProvider.value(value: mainModel2), ChangeNotifierProvider.value(value: contactModel), ChangeNotifierProvider.value(value: termModel), + ChangeNotifierProvider.value(value: faqModel), ], child: Consumer( builder: (context, value, child) { diff --git a/lib/fcs/common/data/providers/auth_fb.dart b/lib/fcs/common/data/providers/auth_fb.dart index 281ad5a..8f1eb87 100644 --- a/lib/fcs/common/data/providers/auth_fb.dart +++ b/lib/fcs/common/data/providers/auth_fb.dart @@ -109,6 +109,13 @@ class AuthFb { user.hasSignup = idToken.claims.containsKey("signup") && idToken.claims["signup"]; user.phoneNumber = firebaseUser.phoneNumber; + + // add privileges + String privileges = idToken.claims["privileges"]; + if (privileges != null && privileges != "") { + user.privileges = privileges.split(":").toList(); + } + return user; } diff --git a/lib/fcs/common/domain/entities/customer.dart b/lib/fcs/common/domain/entities/customer.dart new file mode 100644 index 0000000..0fb51e7 --- /dev/null +++ b/lib/fcs/common/domain/entities/customer.dart @@ -0,0 +1,36 @@ + + +class Customer { + String id; + String name; + String phoneNumber; + String status; + + Customer({ + this.id, + this.name, + this.status, + this.phoneNumber, + }); + + factory Customer.fromMap(Map map, String docID) { + return Customer( + id: docID, + name: map['user_name'], + phoneNumber: map['phone_number'], + status: map['status'], + ); + } + + Map toMap() { + return { + 'user_name': name, + 'phone_number': phoneNumber, + }; + } + + @override + String toString() { + return 'Customer{name: $name, phoneNumber: $phoneNumber,statis:$status}'; + } +} diff --git a/lib/fcs/common/domain/entities/faq.dart b/lib/fcs/common/domain/entities/faq.dart index 4c694d7..8782c55 100644 --- a/lib/fcs/common/domain/entities/faq.dart +++ b/lib/fcs/common/domain/entities/faq.dart @@ -1,27 +1,48 @@ class FAQ { String id; + int sn; String questionEng; String questionMm; String answerEng; String answerMm; - String question(bool isEng) => isEng?questionEng:questionMm; - String answer(bool isEng) => isEng?answerEng:answerMm; - - Map images; - FAQ({this.id,this.questionEng,this.questionMm,this.answerEng,this.answerMm,this.images}); + String question(bool isEng) => isEng ? questionEng : questionMm; + String answer(bool isEng) => isEng ? answerEng : answerMm; + Map imageUrls; + FAQ( + {this.id, + this.sn, + this.questionEng, + this.questionMm, + this.answerEng, + this.answerMm, + this.imageUrls}); Map toMap() { return { + 'id': id, + 'sn':sn, 'question_eng': questionEng, 'answer_eng': answerEng, 'question_mm': questionMm, 'answer_mm': answerMm, - 'images': images, + 'images': imageUrls, }; } + factory FAQ.fromMap(Map map, String id) { + return FAQ( + id: id, + sn: map['sn'], + questionEng: map['question_eng'], + answerEng: map['answer_eng'], + questionMm: map['question_mm'], + answerMm: map['answer_mm'], + imageUrls: Map.from(map['images'] ?? Map()), + ); + } + @override String toString() { return 'FAQ{id: $id, questionEng: $questionEng,questionMm:$questionMm}'; diff --git a/lib/fcs/common/domain/entities/role.dart b/lib/fcs/common/domain/entities/role.dart new file mode 100644 index 0000000..6a2b0df --- /dev/null +++ b/lib/fcs/common/domain/entities/role.dart @@ -0,0 +1,72 @@ +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/fcs/common/domain/entities/user.dart b/lib/fcs/common/domain/entities/user.dart index 768d8b1..56309fe 100644 --- a/lib/fcs/common/domain/entities/user.dart +++ b/lib/fcs/common/domain/entities/user.dart @@ -1,283 +1,70 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_auth/firebase_auth.dart'; - class User { String id; String name; String phoneNumber; bool hasSignup; + List privileges = []; String fcsID; - String shippingAddress; - String deliveryAddress; + String get phone => phoneNumber != null && phoneNumber.startsWith("959") ? "0${phoneNumber.substring(2)}" : phoneNumber; - List claimPrivileges = []; - - final String dateofBirth; - final String gender; - final String status; - final bool disable; - bool registeredBuyer; - List privilegeIds; - String roleName; - String roleID; - bool agreeTerms; - String bizID; - String accountID; - String email; - bool isBlock; - int userLevel; - String userLevelID; - - String frontUrl; - String backUrl; - String selfieUrl; - - DateTime lastActiveTime; - String device; - - String primaryDeviceID; - String primaryDeviceName; - - String pin; - - String get getname => this.name; - String get getphonenumber => this.phoneNumber; - String get getdateofBirth => this.dateofBirth; - bool get getdisable => this.disable; - - Future setFirebaseUser(FirebaseUser firebaseUser) async { - IdTokenResult idToken = await firebaseUser.getIdToken(refresh: true); - String privileges = idToken.claims["privileges"]; - if (privileges == null || privileges == "") return; - this.claimPrivileges = privileges.split(":").toList(); - - this.accountID = idToken.claims["account_id"]; - this.bizID = idToken.claims["biz_id"]; - } - - User( - {this.id, - this.name, - this.gender, - this.phoneNumber, - this.fcsID, - this.shippingAddress, - this.deliveryAddress, - this.dateofBirth, - this.roleName, - this.roleID, - this.privilegeIds, - this.email, - this.disable, - this.status, - this.frontUrl, - this.backUrl, - this.selfieUrl, - this.registeredBuyer, - this.agreeTerms, - this.lastActiveTime, - this.device, - this.primaryDeviceID, - this.primaryDeviceName, - this.isBlock, - this.userLevel, - this.userLevelID, - this.pin}); + User({ + this.id, + this.name, + this.phoneNumber, + this.fcsID, + }); factory User.fromJson(Map json) { return User( - id: json['id'], - name: json['user_name'], - phoneNumber: json['phone_number'], - dateofBirth: json['dob'], - gender: json['gender'], - frontUrl: json['front_url'], - backUrl: json['back_url'], - selfieUrl: json['selfie_url'], - status: json['status'], - agreeTerms: json['agree_terms'], - disable: json['disable'], - registeredBuyer: json['registered_buyer'], - privilegeIds: json['privileges'], - email: json['email'], - isBlock: json['black_list'], - userLevel: json['user_level'], - userLevelID: json['user_level_id'], - pin: json['pin']); - } - - factory User.fromUserJson(Map json) { - DateTime parsedDate = DateTime.parse(json['last_active_time']); - - return User( - id: json['id'], - name: json['user_name'], - phoneNumber: json['phone_number'], - dateofBirth: json['dob'], - roleName: json['role_name'], - roleID: json['role_id'], - disable: json['disable'], - gender: json['gender'], - status: json['status'], - lastActiveTime: parsedDate == null ? null : parsedDate, - device: json['last_active_device'], - email: json['email'], - primaryDeviceID: json['primary_device_id'], - primaryDeviceName: json['primary_device_name'], - userLevel: json['user_level'], - userLevelID: json['user_level_id'], - pin: json['pin']); + id: json['id'], + name: json['user_name'], + phoneNumber: json['phone_number'], + ); } Map toJson() => { 'id': id, 'user_name': name, - 'gender': gender, 'phone_number': phoneNumber, - 'dob': dateofBirth, - 'roleName': roleName, - 'roleId': roleID, - 'disable': disable, - 'status': status, - 'registered_buyer': registeredBuyer, - 'agree_terms': agreeTerms, - 'front_url': frontUrl, - 'back_url': backUrl, - 'selfie_url': selfieUrl, - 'email': email, - 'black_list': isBlock, - 'user_level': userLevel, - 'user_level_id': userLevelID, - 'pin': pin, - 'privileges': privilegeIds, }; Map toMap() { return { 'user_name': name, 'phone_number': phoneNumber, - 'dob': dateofBirth, - 'role_name': roleName, - 'role_id': roleID, - 'disable': disable, - 'gender': gender, - 'status': status, - 'email': email, - 'black_list': isBlock, - 'user_level': userLevel, - 'user_level_id': userLevelID, - 'pin': pin }; } factory User.fromMap(Map map, String docID) { - var activeTime = (map['last_active_time'] as Timestamp); return User( - id: docID, - name: map['user_name'], - phoneNumber: map['phone_number'], - privilegeIds: - map['privileges'] == null ? [] : map['privileges'].cast(), - dateofBirth: map['dob'], - roleName: map['role_name'], - roleID: map['role_id'], - disable: map['disable'], - gender: map['gender'], - status: map['status'], - registeredBuyer: map['registered_buyer'], - agreeTerms: map['agree_terms'] == null ? false : map['agree_terms'], - lastActiveTime: activeTime == null ? null : activeTime.toDate(), - device: map['last_active_device'], - email: map['email'], - primaryDeviceID: map['primary_device_id'], - primaryDeviceName: map['primary_device_name'], - isBlock: map['black_list'], - userLevel: map['user_level'], - userLevelID: map['user_level_id'], - pin: map['pin']); + id: docID, + name: map['user_name'], + phoneNumber: map['phone_number'], + ); } - bool isBlockUser() { - return this.isBlock == true; + bool isCustomer() { + return privileges == null || privileges.length == 0; } - bool isPrimaryDevice() { - return this.primaryDeviceID != null && this.primaryDeviceID != ''; - } - - bool isRegisteredBuyer() { - return this.registeredBuyer != null && this.registeredBuyer; - } - - bool isSysAdmin() { - return claimPrivileges != null - ? claimPrivileges.contains('sys_admin') - : false; - } - - bool isSysSupport() { - return claimPrivileges != null - ? claimPrivileges.contains('sys_support') - : false; - } - - bool isBizAdmin() { - return claimPrivileges != null ? claimPrivileges.contains('ba') : false; - } - - bool isBuyer() { - return claimPrivileges == null || claimPrivileges.length == 0; - } - - bool isEmail() { - return email != null; - } - - bool hasAccount() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('a') : false); - } - - bool hasDelivery() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('d') : false); - } - - bool hasBuyer() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('b') : false); - } - - bool isOwner() { - return claimPrivileges != null ? claimPrivileges.contains('o') : false; - } - - bool isOwnerAndAbove() { - return isOwner() || isBizAdmin() || isSysAdmin(); + bool hasSysAdmin() { + return privileges != null ? privileges.contains('sa') : false; } bool hasAdmin() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('admin') : false); + return privileges != null ? privileges.contains('admin') : false; } - bool hasDO() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('do') : false); + bool hasMaintenance() { + return privileges != null ? privileges.contains('mt') : false; } - bool hasPO() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('po') : false); - } - - bool hasInventory() { - return isOwner() || - (claimPrivileges != null ? claimPrivileges.contains('inv') : false); + bool hasCustomers() { + return privileges != null ? privileges.contains('c') : false; } @override diff --git a/lib/fcs/common/helpers/theme.dart b/lib/fcs/common/helpers/theme.dart index a14073b..c52f8ba 100644 --- a/lib/fcs/common/helpers/theme.dart +++ b/lib/fcs/common/helpers/theme.dart @@ -16,12 +16,13 @@ const TextStyle labelStyleMM = TextStyle( fontSize: 20, color: primaryColor, fontWeight: FontWeight.w500, - fontFamily: "MyanmarUnicode"); + height: 1, + fontFamily: "Myanmar3"); const TextStyle subMenuStyle = TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500); const TextStyle subMenuStyleMM = TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500, - fontFamily: "MyanmarUnicode"); + fontFamily: "Myanmar3"); const TextStyle welcomeLabelStyle = TextStyle(fontSize: 23, color: primaryColor, fontWeight: FontWeight.w500); @@ -53,13 +54,13 @@ TextStyle newLabelStyleMM( color: color == null ? secondaryColor : color, fontWeight: fontWeight == null ? FontWeight.w500 : fontWeight, decoration: underline ? TextDecoration.underline : TextDecoration.none, - fontFamily: "MyanmarUnicode"); + fontFamily: "Myanmar3"); } const TextStyle photoLabelStyle = TextStyle(color: Colors.black, fontSize: 13.0); const TextStyle photoLabelStyleMM = TextStyle( - color: Colors.black, fontSize: 13.0, fontFamily: "MyanmarUnicode"); + color: Colors.black, fontSize: 13.0, fontFamily: "Myanmar3"); const TextStyle textStyle = TextStyle(fontSize: 14, color: Colors.black87, fontWeight: FontWeight.w500); const TextStyle textStyleOdd = TextStyle( diff --git a/lib/fcs/common/pages/contact/contact_editor.dart b/lib/fcs/common/pages/contact/contact_editor.dart index 0404bf8..d43ac31 100644 --- a/lib/fcs/common/pages/contact/contact_editor.dart +++ b/lib/fcs/common/pages/contact/contact_editor.dart @@ -75,68 +75,64 @@ class _ContactEditorState extends State { return LocalProgress( inAsyncCall: _isLoading, - child: CupertinoPageScaffold( - child: NestedScrollView( - headerSliverBuilder: - (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, - ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text( - AppTranslations.of(context) - .text('contact.edit.title'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ - IconButton( - onPressed: () => _submit(), - icon: Icon( - Icons.save, - color: Colors.white, - )) - ], - ), - ]; - }, - body: Material( - child: Form( - key: _formKey, - child: ListView( - shrinkWrap: true, - padding: EdgeInsets.only(left: 24.0, right: 24.0), - children: [ - itemTitle(context, "contact.callus"), - usaPhoneBox, - mmPhoneBox, - Divider(), - itemTitle(context, "contact.findus"), - usaAddreesBox, - mmAddressBox, - Divider(), - itemTitle(context, "contact.emailus"), - emailBox, - Divider(), - itemTitle(context, "contact.visitus"), - faceBookBox - ], - ), + child: Scaffold( + body: CustomScrollView(slivers: [ + SliverAppBar( + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 30, + ), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + expandedHeight: 150.0, + floating: false, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + centerTitle: true, + titlePadding: EdgeInsets.symmetric(vertical: 10), + title: + Text(AppTranslations.of(context).text('contact.edit.title'), + style: TextStyle( + color: Colors.white, + )), + ), + actions: [ + IconButton( + onPressed: () => _submit(), + icon: Icon( + Icons.save, + color: Colors.white, + )) + ], + ), + SliverList( + delegate: SliverChildListDelegate([ + Padding( + padding: const EdgeInsets.only(left:18.0,right:18), + child: Column( + children: [ + itemTitle(context, "contact.callus"), + usaPhoneBox, + mmPhoneBox, + Divider(), + itemTitle(context, "contact.findus"), + usaAddreesBox, + mmAddressBox, + Divider(), + itemTitle(context, "contact.emailus"), + emailBox, + Divider(), + itemTitle(context, "contact.visitus"), + faceBookBox + ], ), - )))); + ), + ]), + ) + ]), + )); } _submit() async { diff --git a/lib/fcs/common/pages/contact/contact_page.dart b/lib/fcs/common/pages/contact/contact_page.dart index ab131c1..8952084 100644 --- a/lib/fcs/common/pages/contact/contact_page.dart +++ b/lib/fcs/common/pages/contact/contact_page.dart @@ -22,93 +22,92 @@ class _ContactPageState extends State { @override Widget build(BuildContext context) { Setting setting = Provider.of(context).setting; + bool isEditable = context.select((MainModel m) => m.contactEditable()); + return Scaffold( - body: NestedScrollView( - headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, - ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text(AppTranslations.of(context).text('contact.title'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ - IconButton( - onPressed: () => - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => ContactEditor( - contact: Contact.fromSetting(setting), - ), - )), - icon: Icon( - CupertinoIcons.pen, - color: Colors.white, - )) - ], + body: CustomScrollView(slivers: [ + SliverAppBar( + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 30, ), - ]; - }, - body: ListView( - children: [ - itemTitle(context, "contact.callus"), - contactItem(context, setting.usaContactNumber, CupertinoIcons.phone, - onTap: () => _call(setting.usaContactNumber), - labelKey: "contact.usa.phone"), - contactItem( - context, - setting.mmContactNumber, - CupertinoIcons.phone, - onTap: () => _call( - setting.mmContactNumber, - ), - labelKey: "contact.mm.phone", - ), - itemTitle(context, "contact.findus"), - contactItem( - context, - setting.usaAddress, - CupertinoIcons.location, - labelKey: "contact.usa.address", - ), - contactItem( - context, - setting.mmAddress, - CupertinoIcons.location, - labelKey: "contact.mm.address", - ), - itemTitle(context, "contact.emailus"), - contactItem( - context, - setting.emailAddress, - CupertinoIcons.mail, - onTap: () => _email(setting.emailAddress), - labelKey: "contact.fcs.email", - ), - itemTitle(context, "contact.visitus"), - contactItem( - context, - setting.facebookLink, - FontAwesomeIcons.facebook, - onTap: () => _opencontactItem(setting.facebookLink), - labelKey: "contact.facebook", - ), - ], + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + expandedHeight: 150.0, + floating: false, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + centerTitle: true, + titlePadding: EdgeInsets.symmetric(vertical: 10), + title: Text(AppTranslations.of(context).text('contact.title'), + style: TextStyle( + color: Colors.white, + )), + ), + actions: isEditable + ? [ + IconButton( + onPressed: () => + Navigator.of(context).push(CupertinoPageRoute( + builder: (context) => ContactEditor( + contact: Contact.fromSetting(setting), + ), + )), + icon: Icon( + CupertinoIcons.pen, + color: Colors.white, + )) + ] + : [], ), - ), + SliverList( + delegate: SliverChildListDelegate([ + itemTitle(context, "contact.callus"), + contactItem(context, setting.usaContactNumber, CupertinoIcons.phone, + onTap: () => _call(setting.usaContactNumber), + labelKey: "contact.usa.phone"), + contactItem( + context, + setting.mmContactNumber, + CupertinoIcons.phone, + onTap: () => _call( + setting.mmContactNumber, + ), + labelKey: "contact.mm.phone", + ), + itemTitle(context, "contact.findus"), + contactItem( + context, + setting.usaAddress, + CupertinoIcons.location, + labelKey: "contact.usa.address", + ), + contactItem( + context, + setting.mmAddress, + CupertinoIcons.location, + labelKey: "contact.mm.address", + ), + itemTitle(context, "contact.emailus"), + contactItem( + context, + setting.emailAddress, + CupertinoIcons.mail, + onTap: () => _email(setting.emailAddress), + labelKey: "contact.fcs.email", + ), + itemTitle(context, "contact.visitus"), + contactItem( + context, + setting.facebookLink, + FontAwesomeIcons.facebook, + onTap: () => _opencontactItem(setting.facebookLink), + labelKey: "contact.facebook", + ), + ])) + ]), ); } diff --git a/lib/fcs/common/pages/customers/customer_editor.dart b/lib/fcs/common/pages/customers/customer_editor.dart new file mode 100644 index 0000000..a740afd --- /dev/null +++ b/lib/fcs/common/pages/customers/customer_editor.dart @@ -0,0 +1,363 @@ +import 'package:fcs/fcs/common/domain/entities/customer.dart'; +import 'package:fcs/fcs/common/domain/entities/role.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; +import 'package:fcs/fcs/common/localization/app_translations.dart'; +import 'package:fcs/fcs/common/pages/model/language_model.dart'; +import 'package:fcs/fcs/common/pages/util.dart'; +import 'package:fcs/fcs/common/pages/widgets/local_text.dart'; +import 'package:fcs/fcs/common/pages/widgets/progress.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:fcs/fcs/common/helpers/theme.dart'; + +typedef void FindCallBack(); + +class CustomerEditor extends StatefulWidget { + final Customer customer; + const CustomerEditor({this.customer}); + @override + _CustomerEditorState createState() => _CustomerEditorState(); +} + +class _CustomerEditorState extends State { + TextEditingController _name = new TextEditingController(); + TextEditingController _phone = new TextEditingController(); + TextEditingController _phoneInput = new TextEditingController(); + TextEditingController _status = new TextEditingController(); + + final _formKey = GlobalKey(); + bool _isLoading = false; + String currentBizId; + bool isSend = false; + User user; + User selectedUser; + List privileges = [ + Privilege(name: 'Manage shipment'), + Privilege(name: 'Manage pickups'), + Privilege(name: 'Manage packages'), + Privilege(name: 'Manage deliveries'), + Privilege(name: 'Admin') + ]; + + @override + void initState() { + super.initState(); + // privileges = Provider.of(context, listen: false).privileges; + if (widget.customer != null) { + _name.text = widget.customer.name; + _phone.text = widget.customer.phoneNumber; + _status.text = widget.customer.status; + // privileges.forEach((p) => widget.employee.privilegeIds.contains(p.id) + // ? p.isChecked = true + // : p.isChecked = false); + } + } + + List showprivilegeList(BuildContext context) { + return privileges.map((p) { + return new ListTile( + title: new Row( + children: [ + new Checkbox( + value: p.isChecked == null ? false : p.isChecked, + activeColor: primaryColor, + onChanged: (bool value) { + setState(() { + p.isChecked = value; + }); + }), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + new Text( + p.name, + style: TextStyle( + fontSize: 15.0, + ), + ), + // Container( + // width: MediaQuery.of(context).size.width * 0.5, + // child: new Text( + // userModel.getPrivileges[index].desc, + // style: + // TextStyle(fontSize: 12.0, color: Colors.grey[600]), + // ), + // ), + ], + ), + ], + )); + }).toList(); + } + + Widget phoneInputbox(BuildContext context, FindCallBack findCallBack) { + var languageModel = Provider.of(context); + return Container( + padding: EdgeInsets.only(top: 10), + child: Stack( + alignment: const Alignment(1.2, 1.0), + children: [ + TextFormField( + controller: _phoneInput, + autofocus: false, + cursorColor: primaryColor, + keyboardType: TextInputType.phone, + style: textStyle, + decoration: new InputDecoration( + labelText: AppTranslations.of(context).text('employee.phone'), + labelStyle: languageModel.isEng ? labelStyle : labelStyleMM, + icon: Icon( + Icons.phone, + color: primaryColor, + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: primaryColor, width: 1.0)), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide(color: primaryColor, width: 1.0)), + ), + ), + new FlatButton( + onPressed: () { + this.isSend = true; + findCallBack(); + }, + child: new Icon( + Icons.search, + size: 25, + )) + ], + )); + } + + @override + Widget build(BuildContext context) { + final namebox = TextFormField( + controller: _name, + autofocus: false, + readOnly: true, + cursorColor: primaryColor, + decoration: new InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + icon: Icon( + Icons.person, + color: primaryColor, + ), + ), + ); + + final displayPhoneNo = TextFormField( + controller: _phone, + autofocus: false, + readOnly: true, + cursorColor: primaryColor, + decoration: new InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + icon: Icon( + Icons.phone, + color: primaryColor, + ), + ), + ); + + var phoneNumberBox = Row( + children: [ + Expanded(child: displayPhoneNo), + Expanded( + child: InkWell( + onTap: () => call(context, _phone.text), + child: Icon( + Icons.open_in_new, + color: Colors.grey, + size: 15, + ), + ), + ), + ], + ); + + final statusbox = TextFormField( + controller: _status, + autofocus: false, + readOnly: true, + cursorColor: primaryColor, + decoration: new InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + icon: Icon( + Icons.av_timer, + color: primaryColor, + ), + ), + ); + + final updateButton = Container( + padding: EdgeInsets.only(top: 40), + child: Container( + height: 45.0, + decoration: BoxDecoration( + color: primaryColor, + shape: BoxShape.rectangle, + ), + child: ButtonTheme( + minWidth: 900.0, + height: 100.0, + child: FlatButton( + onPressed: () {}, + child: LocalText( + context, + 'customer.update', + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ); + + final addButton = Container( + padding: EdgeInsets.only(top: 40), + child: Container( + height: 45.0, + decoration: BoxDecoration( + color: primaryColor, + shape: BoxShape.rectangle, + ), + child: ButtonTheme( + minWidth: 900.0, + height: 100.0, + child: FlatButton( + onPressed: () {}, + child: LocalText( + context, + 'customer.add', + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ); + + return LocalProgress( + 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, + "customer.form.title", + fontSize: 20, + color: Colors.white, + ), + // actions: [ + // widget.customer == null || !mainModel.showHistoryBtn() + // ? Container() + // : IconButton( + // icon: Icon(Icons.history), + // onPressed: () { + // Navigator.push( + // context, + // MaterialPageRoute( + // builder: (context) => DocumentLogPage( + // docID: widget.customer.docID)), + // ); + // }, + // ), + // ], + ), + body: ListView( + shrinkWrap: true, + padding: EdgeInsets.only(left: 24.0, right: 24.0), + children: [ + widget.customer == null + ? phoneInputbox(context, () => _findUser(context)) + : phoneNumberBox, + widget.customer == null + ? this.isSend ? namebox : Container() + : namebox, + statusbox, + // widget.customer == null ? addButton : updateButton, + SizedBox( + height: 20, + ) + ], + ), + )); + } + + _add(BuildContext context) async { + if (selectedUser == null) return; + setState(() { + _isLoading = true; + }); + // var employeeModel = Provider.of(context); + // try { + // await employeeModel.updatePrivileges( + // this.selectedUser.docID, privilegesIDs()); + // Navigator.pop(context); + // } catch (e) { + // showMsgDialog(context, "Error", e.toString()); + // } finally { + // setState(() { + // _isLoading = false; + // }); + // } + } + + List privilegesIDs() { + return this.privileges.where((p) => p.isChecked).map((p) => p.id).toList(); + } + + _save() async { + setState(() { + _isLoading = true; + }); + if (widget.customer == null) return; + // var employeeModel = Provider.of(context); + // try { + // await employeeModel.updatePrivileges( + // widget.customer.docID, privilegesIDs()); + // Navigator.pop(context); + // } catch (e) { + // showMsgDialog(context, "Error", e.toString()); + // } finally { + // setState(() { + // _isLoading = false; + // }); + // } + } + + _findUser(BuildContext context) async { + // var userModel = Provider.of(context); + // setState(() { + // _isLoading = true; + // }); + // try { + // selectedUser = await userModel.findUser(_phoneInput.text); + // setState(() { + // isSend = true; + // _name.text = selectedUser.name; + // if (selectedUser.privilegeIds != null) { + // privileges.forEach((p) => selectedUser.privilegeIds.contains(p.id) + // ? p.isChecked = true + // : p.isChecked = false); + // } + // }); + // } catch (e) { + // showMsgDialog(context, "Error", e.toString()); + // } finally { + // setState(() { + // _isLoading = false; + // }); + // } + } +} diff --git a/lib/fcs/common/pages/customers/customer_list.dart b/lib/fcs/common/pages/customers/customer_list.dart new file mode 100644 index 0000000..aae62c8 --- /dev/null +++ b/lib/fcs/common/pages/customers/customer_list.dart @@ -0,0 +1,142 @@ +import 'package:fcs/fcs/common/domain/entities/customer.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; +import 'package:fcs/fcs/common/localization/app_translations.dart'; +import 'package:fcs/fcs/common/pages/customers/invitation_page.dart'; +import 'package:fcs/fcs/common/pages/customers/model/customer_model.dart'; +import 'package:fcs/fcs/common/pages/util.dart'; +import 'package:fcs/fcs/common/pages/widgets/bottom_up_page_route.dart'; +import 'package:fcs/fcs/common/pages/widgets/local_text.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:fcs/fcs/common/helpers/theme.dart'; +import 'package:fcs/widget/progress.dart'; + +import 'customer_editor.dart'; + +class CustomerList extends StatefulWidget { + @override + _CustomerListState createState() => _CustomerListState(); +} + +class _CustomerListState extends State { + var dateFormatter = new DateFormat('dd MMM yyyy - hh:mm:ss a'); + final double dotSize = 15.0; + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + var customerModel = Provider.of(context); + + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(Icons.close), + onPressed: () => Navigator.of(context).pop(), + ), + actions: [ + IconButton( + icon: Icon( + Icons.search, + color: Colors.white, + ), + iconSize: 30, + onPressed: () => {}, + ), + ], + backgroundColor: primaryColor, + title: LocalText( + context, + 'customer.list.title', + color: Colors.white, + fontSize: 20, + ), + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () { + Navigator.of(context).push(BottomUpPageRoute(InvitationPage())); + }, + icon: Icon(Icons.add), + label: Text(AppTranslations.of(context).text("customer.invite")), + backgroundColor: primaryColor, + ), + body: new ListView.separated( + separatorBuilder: (context, index) => Divider( + color: Colors.black, + ), + scrollDirection: Axis.vertical, + padding: EdgeInsets.only(left: 15, right: 15, top: 15), + shrinkWrap: true, + itemCount: customerModel.customers.length, + itemBuilder: (BuildContext context, int index) { + Customer customer = customerModel.customers[index]; + return Stack( + children: [ + InkWell( + onTap: () { + Navigator.of(context).push( + BottomUpPageRoute(CustomerEditor(customer: customer))); + }, + child: Row( + children: [ + Expanded( + child: new Padding( + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: new Row( + children: [ + new Padding( + padding: new EdgeInsets.symmetric( + horizontal: 32.0 - dotSize / 2), + child: Icon( + Feather.user, + color: primaryColor, + size: 40, + ), + ), + new Expanded( + child: new Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + new Text( + customer.name, + style: new TextStyle( + fontSize: 15.0, + color: primaryColor), + ), + Padding( + padding: + const EdgeInsets.only(top: 8.0), + child: new Text( + customer.phoneNumber, + style: new TextStyle( + fontSize: 15.0, + color: Colors.grey), + ), + ), + ], + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 10), + child: getStatus(customer.status), + ), + ], + ), + ), + ], + ); + }), + ), + ); + } +} diff --git a/lib/fcs/common/pages/customers/invitation_page.dart b/lib/fcs/common/pages/customers/invitation_page.dart new file mode 100644 index 0000000..1b93e4f --- /dev/null +++ b/lib/fcs/common/pages/customers/invitation_page.dart @@ -0,0 +1,67 @@ +import 'package:fcs/fcs/common/helpers/theme.dart'; +import 'package:fcs/fcs/common/localization/app_translations.dart'; +import 'package:fcs/fcs/common/pages/util.dart'; +import 'package:flutter/material.dart'; +import 'package:fcs/widget/progress.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +class InvitationPage extends StatefulWidget { + @override + _InvitationPageState createState() => _InvitationPageState(); +} + +class _InvitationPageState extends State { + TextEditingController _nameController = new TextEditingController(); + TextEditingController _phoneController = new TextEditingController(); + + bool _isLoading = false; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon( + Icons.close, + ), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + title: Text(AppTranslations.of(context).text("customer.form.title")), + ), + body: Container( + padding: EdgeInsets.all(18), + child: Column( + children: [ + Expanded( + child: ListView( + children: [ + fcsInput("Name", Icons.person, controller: _nameController), + fcsInput("Phone Number", Icons.phone, + controller: _phoneController), + SizedBox(height: 30), + ], + ), + ), + fcsButton(context, "Invite", callack: () {}), + SizedBox(height: 10) + ], + ), + ), + ), + ); + } +} diff --git a/lib/fcs/common/pages/customers/model/customer_model.dart b/lib/fcs/common/pages/customers/model/customer_model.dart new file mode 100644 index 0000000..57b9771 --- /dev/null +++ b/lib/fcs/common/pages/customers/model/customer_model.dart @@ -0,0 +1,66 @@ +import 'package:fcs/fcs/common/domain/entities/customer.dart'; +import 'package:fcs/fcs/common/pages/model/base_model.dart'; +import 'package:logging/logging.dart'; + + +class CustomerModel extends BaseModel { + final log = Logger('CustomerModel'); + + List customers = [ + Customer( + name: 'Ko Nyi', + phoneNumber: '+95 9 717273634', + status: 'Invited' + ), + Customer(name: 'Ko Phyu', phoneNumber: '+1 (939) 382-3844',status: 'Signin'), + Customer(name: 'Ko Ye', phoneNumber: '+95 9 983734783', status: 'Invited'), + ]; + + + + void initUser(user) async { + super.initUser(user); + // _loadCustomer(); + } + + @override + logout() async { + customers = []; + } + + // Future _loadCustomer() async { + // if (!user.isOwnerAndAbove() && !user.hasAccount()) { + // return; + // } + + // try { + // Firestore.instance + // .collection("/$biz_collection/${setting.okEnergyId}/$user_collection") + // .where("is_employee", isEqualTo: true) + // .snapshots() + // .listen((QuerySnapshot snapshot) { + // customers.clear(); + // customers = snapshot.documents.map((documentSnapshot) { + // var user = + // User.fromMap(documentSnapshot.data, documentSnapshot.documentID); + // return user; + // }).toList(); + // notifyListeners(); + // }).onError((e) { + // log.warning("Error! $e"); + // }); + // } catch (e) { + // log.warning("Error!! $e"); + // } + // } + + // Future updatePrivileges(String userID, List privileges) async { + // try { + // await request("/employee/privileges", "PUT", + // payload: {"id": userID, "privileges": privileges}, + // token: await getToken()); + // } catch (e) { + // throw Exception(e); + // } + // } +} diff --git a/lib/fcs/common/pages/faq/faq_detail_page.dart b/lib/fcs/common/pages/faq/faq_detail_page.dart index 1a4ea58..2cf0eee 100644 --- a/lib/fcs/common/pages/faq/faq_detail_page.dart +++ b/lib/fcs/common/pages/faq/faq_detail_page.dart @@ -1,84 +1,95 @@ import 'package:fcs/fcs/common/domain/entities/faq.dart'; -import 'package:fcs/fcs/common/domain/entities/setting.dart'; -import 'package:fcs/fcs/common/domain/vo/contact.dart'; import 'package:fcs/fcs/common/helpers/theme.dart'; -import 'package:fcs/fcs/common/localization/app_translations.dart'; -import 'package:fcs/fcs/common/pages/contact/contact_editor.dart'; +import 'package:fcs/fcs/common/pages/faq/faq_edit_page.dart'; +import 'package:fcs/fcs/common/pages/faq/model/faq_model.dart'; import 'package:fcs/fcs/common/pages/model/language_model.dart'; import 'package:fcs/fcs/common/pages/model/main_model.dart'; +import 'package:fcs/fcs/common/pages/util.dart'; import 'package:fcs/fcs/common/pages/widgets/local_text.dart'; +import 'package:fcs/fcs/common/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class FAQDetailPage extends StatelessWidget { +class FAQDetailPage extends StatefulWidget { final FAQ faq; + const FAQDetailPage({this.faq}); + @override + _FAQDetailPageState createState() => _FAQDetailPageState(); +} - const FAQDetailPage({Key key, this.faq}) : super(key: key); +class _FAQDetailPageState extends State { + bool _isLoading = false; @override Widget build(BuildContext context) { - Setting setting = Provider.of(context).setting; - return Scaffold( - body: NestedScrollView( - headerSliverBuilder: - (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, - ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text(AppTranslations.of(context).text('faq.btn'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ + bool isEditable = context.select((MainModel m) => m.faqEditable()); + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + body: CustomScrollView(slivers: [ + SliverAppBar( + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + color: primaryColor, + size: 50, + ), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: Colors.white, + expandedHeight: 100.0, + floating: false, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + centerTitle: true, + titlePadding: EdgeInsets.symmetric(vertical: 10), + ), + actions: isEditable + ? [ IconButton( - onPressed: () => - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => ContactEditor( - contact: Contact.fromSetting(setting), - ), - )), + onPressed: () { + showConfirmDialog(context, "faq.edit.delete.confirm", + () { + _delete(); + }); + }, icon: Icon( CupertinoIcons.delete, - color: Colors.white, + color: primaryColor, + size: 30, )), IconButton( onPressed: () => Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => ContactEditor( - contact: Contact.fromSetting(setting), - ), + builder: (context) => FAQEditor(faq: widget.faq), )), icon: Icon( CupertinoIcons.pen, - color: Colors.white, + color: primaryColor, )) - ], - ), - ]; - }, - body: Padding( - padding: const EdgeInsets.only(left:20.0,right:20), - child: ListView( - children: [getQuestion(context, faq), - SizedBox(height: 30,), - getAnwser(context, faq)], + ] + : [], + ), + SliverList( + delegate: SliverChildListDelegate([ + Padding( + padding: const EdgeInsets.all(28.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + getQuestion(context, widget.faq), + SizedBox( + height: 50, + ), + getAnwser(context, widget.faq) + ], ), - ))); + ), + ])) + ]), + ), + ); } Widget getQuestion(BuildContext context, FAQ faq) { @@ -87,19 +98,34 @@ class FAQDetailPage extends StatelessWidget { context, faq.question(isEng), fontSize: 22, - fontWeight: FontWeight.bold, + fontWeight: FontWeight.bold, ); } - Widget getAnwser(BuildContext context, FAQ faq) { bool isEng = Provider.of(context).isEng; return TextLocalStyle( context, faq.answer(isEng), fontSize: 16, - fontWeight: FontWeight.w200, + fontWeight: FontWeight.w200, ); } + _delete() async { + setState(() { + _isLoading = true; + }); + try { + FAQModel faqModel = Provider.of(context, listen: false); + await faqModel.deleteFAQ(widget.faq); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } + } } diff --git a/lib/fcs/common/pages/faq/faq_edit_page.dart b/lib/fcs/common/pages/faq/faq_edit_page.dart index d3bca39..6b2d442 100644 --- a/lib/fcs/common/pages/faq/faq_edit_page.dart +++ b/lib/fcs/common/pages/faq/faq_edit_page.dart @@ -1,6 +1,7 @@ import 'package:fcs/fcs/common/domain/entities/faq.dart'; import 'package:fcs/fcs/common/helpers/theme.dart'; import 'package:fcs/fcs/common/localization/app_translations.dart'; +import 'package:fcs/fcs/common/pages/faq/model/faq_model.dart'; import 'package:fcs/fcs/common/pages/faq/widgets.dart'; import 'package:fcs/fcs/common/pages/util.dart'; import 'package:fcs/fcs/common/pages/widgets/input_text.dart'; @@ -8,6 +9,7 @@ import 'package:fcs/fcs/common/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; +import 'package:provider/provider.dart'; class FAQEditor extends StatefulWidget { final FAQ faq; @@ -17,6 +19,7 @@ class FAQEditor extends StatefulWidget { } class _FAQEditorState extends State { + TextEditingController _sn = new TextEditingController(); TextEditingController _engQ = new TextEditingController(); TextEditingController _mmQ = new TextEditingController(); TextEditingController _engA = new TextEditingController(); @@ -25,12 +28,12 @@ class _FAQEditorState extends State { final _formKey = GlobalKey(); bool _isLoading = false; bool _isNew = false; - @override void initState() { super.initState(); _isNew = widget.faq == null; if (widget.faq != null) { + _sn.text = widget.faq.sn.toString(); _engQ.text = widget.faq.questionEng; _mmQ.text = widget.faq.questionMm; _engA.text = widget.faq.answerEng; @@ -40,22 +43,29 @@ class _FAQEditorState extends State { @override Widget build(BuildContext context) { - final usaPhoneBox = InputText( + final snBox = InputText( + controller: _sn, + maxLines: 1, + withBorder: true, + textInputType: TextInputType.number, + ); + + final questionEngBox = InputText( controller: _engQ, maxLines: 2, withBorder: true, ); - final mmPhoneBox = InputText( - controller: _mmQ, + final answerEngBox = InputText( + controller: _engA, maxLines: 5, withBorder: true, ); - final usaAddreesBox = InputText( - controller: _engA, + final questionMmBox = InputText( + controller: _mmQ, maxLines: 2, withBorder: true, ); - final mmAddressBox = InputText( + final answerMmBox = InputText( controller: _mmA, maxLines: 5, withBorder: true, @@ -63,76 +73,101 @@ class _FAQEditorState extends State { return LocalProgress( inAsyncCall: _isLoading, - child: CupertinoPageScaffold( - child: NestedScrollView( - headerSliverBuilder: - (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, + child: Scaffold( + body: CustomScrollView(slivers: [ + SliverAppBar( + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 30, + ), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + expandedHeight: 150.0, + floating: true, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + centerTitle: true, + titlePadding: EdgeInsets.symmetric(vertical: 10), + title: Text( + AppTranslations.of(context) + .text(_isNew ? 'faq.add.title' : 'faq.edit.title'), + style: TextStyle( + color: Colors.white, + )), + ), + actions: [ + IconButton( + onPressed: () => _save(), + icon: Icon( + Icons.save, + color: Colors.white, + )) + ], + ), + SliverList( + delegate: SliverChildListDelegate([ + Form( + key: _formKey, + child: Padding( + padding: EdgeInsets.only(left: 24.0, right: 24.0), + child: Column( + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.only(right: 18.0, left: 0), + child: subItemTitle(context, "faq.edit.sn"), ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text( - AppTranslations.of(context) - .text(_isNew?'faq.add.title':'faq.edit.title'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ - IconButton( - onPressed: () => _submit(), - icon: Icon( - Icons.save, - color: Colors.white, - )) + Expanded(child: snBox), ], ), - ]; - }, - body: Material( - child: Form( - key: _formKey, - child: ListView( - shrinkWrap: true, - padding: EdgeInsets.only(left: 24.0, right: 24.0), - children: [ - Center(child: itemTitle(context, "faq.edit.eng")), - subItemTitle(context, "faq.edit.question",iconData: SimpleLineIcons.question), - usaPhoneBox, - subItemTitle(context, "faq.edit.answer",iconData: MaterialCommunityIcons.message_reply_text), - mmPhoneBox, - Divider(), - Center(child: itemTitle(context, "faq.edit.mm")), - subItemTitle(context, "faq.edit.question",iconData: SimpleLineIcons.question), - usaAddreesBox, - subItemTitle(context, "faq.edit.answer",iconData: MaterialCommunityIcons.message_reply_text), - mmAddressBox, - ], - ), - ), - )))); + Center(child: itemTitle(context, "faq.edit.eng")), + subItemTitle(context, "faq.edit.question", + iconData: SimpleLineIcons.question), + questionEngBox, + subItemTitle(context, "faq.edit.answer", + iconData: MaterialCommunityIcons.message_reply_text), + answerEngBox, + Divider(), + Center(child: itemTitle(context, "faq.edit.mm")), + subItemTitle(context, "faq.edit.question", + iconData: SimpleLineIcons.question), + questionMmBox, + subItemTitle(context, "faq.edit.answer", + iconData: MaterialCommunityIcons.message_reply_text), + answerMmBox, + ], + ), + ), + ), + ])) + ]))); } - _submit() async { + _save() async { setState(() { _isLoading = true; }); try { - widget.faq.questionEng = _engQ.text; - // var contactModel = Provider.of(context, listen: false); - // await contactModel.saveContact(widget.contact); + int sn = int.parse( + _sn.text, + onError: (source) => throw Exception("Invalid number"), + ); + FAQModel faqModel = Provider.of(context, listen: false); + FAQ _faq = FAQ( + sn: sn, + questionEng: _engQ.text, + answerEng: _engA.text, + questionMm: _mmQ.text, + answerMm: _mmA.text); + if (_isNew) { + await faqModel.addFAQ(_faq); + } else { + _faq.id = widget.faq.id; + await faqModel.updateFAQ(_faq); + } Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/fcs/common/pages/faq/faq_page.dart b/lib/fcs/common/pages/faq/faq_page.dart index 3233f43..0ffbde2 100644 --- a/lib/fcs/common/pages/faq/faq_page.dart +++ b/lib/fcs/common/pages/faq/faq_page.dart @@ -1,22 +1,16 @@ import 'package:fcs/fcs/common/domain/entities/faq.dart'; -import 'package:fcs/fcs/common/domain/entities/setting.dart'; -import 'package:fcs/fcs/common/domain/vo/contact.dart'; import 'package:fcs/fcs/common/helpers/theme.dart'; import 'package:fcs/fcs/common/localization/app_translations.dart'; -import 'package:fcs/fcs/common/pages/contact/contact_editor.dart'; -import 'package:fcs/fcs/common/pages/contact/widgets.dart'; import 'package:fcs/fcs/common/pages/faq/faq_detail_page.dart'; import 'package:fcs/fcs/common/pages/faq/faq_edit_page.dart'; import 'package:fcs/fcs/common/pages/model/language_model.dart'; import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/fcs/common/pages/widgets/local_text.dart'; -import 'package:fcs/widget/local_text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:package_info/package_info.dart'; import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; + +import 'model/faq_model.dart'; class FAQPage extends StatefulWidget { @override @@ -24,132 +18,62 @@ class FAQPage extends StatefulWidget { } class _FAQPageState extends State { - List faqs = []; @override void initState() { super.initState(); - faqs = [ - FAQ(questionEng: "Question 1?", answerEng: "Answer 1."), - FAQ(questionEng: "Question 2?", answerEng: "Answer 2."), - FAQ(questionEng: "Question 3?", answerEng: "Answer 3."), - FAQ(questionEng: "Question 4?", answerEng: "Answer 4."), - FAQ(questionEng: "Question 5?", answerEng: "Answer 5.") - ]; } @override Widget build(BuildContext context) { + FAQModel faqModel = Provider.of(context); + bool isEditable = context.select((MainModel m) => m.faqEditable()); + return Scaffold( body: CustomScrollView( slivers: [ SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, - ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: false, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text(AppTranslations.of(context).text('faq.title'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ - IconButton( - onPressed: () => - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => FAQEditor(), - )), - icon: Icon( - CupertinoIcons.add, - color: Colors.white, - size: 35, - )) - ], - ), + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 30, + ), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + expandedHeight: 150.0, + floating: false, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + centerTitle: true, + titlePadding: EdgeInsets.symmetric(vertical: 10), + title: Text(AppTranslations.of(context).text('faq.title'), + style: TextStyle( + color: Colors.white, + )), + ), + actions:isEditable? [ + IconButton( + onPressed: () => + Navigator.of(context).push(CupertinoPageRoute( + builder: (context) => FAQEditor(), + )), + icon: Icon( + CupertinoIcons.add, + color: Colors.white, + size: 35, + )) + ]:[], + ), SliverList( - delegate: SliverChildBuilderDelegate( - (context, index) => _faqItem(context, faqs[index]), - childCount: faqs.length, - ), -) - - // SliverFillRemaining( - // child: Padding( - // padding: const EdgeInsets.only(left: 18.0, right: 18), - // child: ListView.separated ( - // separatorBuilder: (_, i) => Divider(), - // itemCount: faqs.length, - // itemBuilder: (BuildContext ctxt, int index) { - // return _faqItem(context, faqs[index]); - // }), - // )), + delegate: SliverChildBuilderDelegate( + (context, index) => _faqItem(context, faqModel.faqs[index]), + childCount: faqModel.faqs.length, + ), + ) ], )); } - @override - Widget build1(BuildContext context) { - Setting setting = Provider.of(context).setting; - return Scaffold( - body: NestedScrollView( - headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { - return [ - SliverAppBar( - leading: IconButton( - icon: Icon( - CupertinoIcons.back, - size: 30, - ), - onPressed: () => Navigator.of(context).pop(), - ), - backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, - pinned: true, - flexibleSpace: FlexibleSpaceBar( - centerTitle: true, - titlePadding: EdgeInsets.symmetric(vertical: 10), - title: Text(AppTranslations.of(context).text('faq.title'), - style: TextStyle( - color: Colors.white, - )), - ), - actions: [ - IconButton( - onPressed: () => - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => FAQEditor(), - )), - icon: Icon( - CupertinoIcons.add, - color: Colors.white, - size: 35, - )) - ], - ), - ]; - }, - body: Padding( - padding: const EdgeInsets.only(left: 18.0, right: 18), - child: ListView.separated( - separatorBuilder: (_, i) => Divider(), - itemCount: faqs.length, - itemBuilder: (BuildContext ctxt, int index) { - return _faqItem(context, faqs[index]); - }), - )), - ); - } - Widget _faqItem(BuildContext context, FAQ faq) { bool isEng = Provider.of(context).isEng; return Column( @@ -167,16 +91,21 @@ class _FAQPageState extends State { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - TextLocalStyle( - context, - faq.question(isEng), - fontSize: 16, + Flexible( + child: TextLocalStyle( + context, + faq.question(isEng), + fontSize: 18, + ), ), - Spacer(), - Icon( - CupertinoIcons.right_chevron, - color: primaryColor, - size: 22, + // Spacer(), + Padding( + padding: const EdgeInsets.only(left:18.0), + child: Icon( + CupertinoIcons.right_chevron, + color: primaryColor, + size: 22, + ), ) ], )), diff --git a/lib/fcs/common/pages/faq/model/faq_model.dart b/lib/fcs/common/pages/faq/model/faq_model.dart index d7082be..b7ceb08 100644 --- a/lib/fcs/common/pages/faq/model/faq_model.dart +++ b/lib/fcs/common/pages/faq/model/faq_model.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fcs/fcs/common/domain/entities/faq.dart'; import 'package:fcs/fcs/common/pages/model/base_model.dart'; import 'package:fcs/fcs/common/services/services.dart'; @@ -8,10 +9,45 @@ import 'package:logging/logging.dart'; class FAQModel extends BaseModel { final log = Logger('FAQModel'); + List faqs = []; + + StreamSubscription listener; + + FAQModel() { + Stream query = Firestore.instance + .collection("/faqs") + .orderBy("sn", descending: false) + .snapshots(); + if (listener != null) { + listener.cancel(); + } + listener = query.listen((snaps) { + faqs.clear(); + snaps.documents.forEach((d) { + faqs.add(FAQ.fromMap(d.data, d.documentID)); + }); + notifyListeners(); + }); + } + Future addFAQ(FAQ faq) async { - await request("/faq", "POST", - payload: faq.toMap(), token: await Services.instance.authService.getToken()); + await request("/faqs", "POST", + payload: faq.toMap(), + token: await Services.instance.authService.getToken()); notifyListeners(); } + Future updateFAQ(FAQ faq) async { + await request("/faqs", "PUT", + payload: faq.toMap(), + token: await Services.instance.authService.getToken()); + notifyListeners(); + } + + Future deleteFAQ(FAQ faq) async { + await request("/faqs", "DELETE", + payload: faq.toMap(), + token: await Services.instance.authService.getToken()); + notifyListeners(); + } } diff --git a/lib/fcs/common/pages/home_page.dart b/lib/fcs/common/pages/home_page.dart index 7baee50..f222cb0 100644 --- a/lib/fcs/common/pages/home_page.dart +++ b/lib/fcs/common/pages/home_page.dart @@ -1,4 +1,5 @@ import 'package:fcs/fcs/common/localization/transalation.dart'; +import 'package:fcs/fcs/common/pages/customers/customer_list.dart'; import 'package:fcs/fcs/common/pages/faq/faq_page.dart'; import 'package:fcs/fcs/common/pages/model/language_model.dart'; import 'package:fcs/fcs/common/pages/model/main_model.dart'; @@ -25,7 +26,6 @@ import 'package:logging/logging.dart'; import 'package:provider/provider.dart'; import '../../../pages/buying_online.dart'; -import '../../../pages/customer_list.dart'; import '../../../pages/fcs_profile_page.dart'; import '../../../pages/invoice/invoce_list.dart'; import '../../../pages/pickup_list.dart'; @@ -71,7 +71,7 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { login = Provider.of(context).isLogin(); - var owner = Provider.of(context).isOwner(); + // var owner =true;// Provider.of(context).isOwner(); var customer = Provider.of(context).isCustomer(); LanguageModel languageModel = Provider.of(context); @@ -169,20 +169,20 @@ class _HomePageState extends State { List widgets = []; widgets.add(faqBtn); - customer ? widgets.add(buyingBtn) : ""; - customer || owner ? widgets.add(pickUpBtn) : ""; - owner ? widgets.add(shipmentBtn) : ""; - customer || owner ? widgets.add(notiBtn) : ""; - owner ? widgets.add(staffBtn) : ""; - owner ? widgets.add(fcsProfileBtn) : ""; - widgets.add(shipmentCostBtn); - customer || owner ? widgets.add(packagesBtn) : ""; - owner ? widgets.add(boxesBtn) : ""; - owner ? widgets.add(deliveryBtn) : ""; - owner ? widgets.add(customersBtn) : ""; - customer || owner ? widgets.add(invoicesBtn) : ""; - owner ? widgets.add(paymentMethodBtn) : ""; - owner ? widgets.add(discountBtn) : ""; + // customer ? widgets.add(buyingBtn) : ""; + // customer || owner ? widgets.add(pickUpBtn) : ""; + !customer ? widgets.add(shipmentBtn) : ""; + // customer || owner ? widgets.add(notiBtn) : ""; + // owner ? widgets.add(staffBtn) : ""; + // owner ? widgets.add(fcsProfileBtn) : ""; + // widgets.add(shipmentCostBtn); + // customer || owner ? widgets.add(packagesBtn) : ""; + // owner ? widgets.add(boxesBtn) : ""; + // owner ? widgets.add(deliveryBtn) : ""; + widgets.add(customersBtn) ; + // customer || owner ? widgets.add(invoicesBtn) : ""; + // owner ? widgets.add(paymentMethodBtn) : ""; + // owner ? widgets.add(discountBtn) : ""; // widgets.add(termBtn); return OfflineRedirect( diff --git a/lib/fcs/common/pages/model/main_model.dart b/lib/fcs/common/pages/model/main_model.dart index c408e95..de1a321 100644 --- a/lib/fcs/common/pages/model/main_model.dart +++ b/lib/fcs/common/pages/model/main_model.dart @@ -9,6 +9,7 @@ import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; import 'package:fcs/fcs/common/domain/entities/setting.dart'; import 'package:fcs/fcs/common/domain/entities/user.dart'; import 'package:fcs/fcs/common/helpers/network_connectivity.dart'; +import 'package:fcs/fcs/common/pages/model/base_model.dart'; import 'package:fcs/fcs/common/services/services.dart'; import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; @@ -16,6 +17,7 @@ import 'package:package_info/package_info.dart'; class MainModel extends ChangeNotifier { final log = Logger('MainModel'); + List models = []; User user; PackageInfo packageInfo; @@ -37,67 +39,50 @@ class MainModel extends ChangeNotifier { notifyListeners(); }); Services.instance.authService.onAuthStatus().listen((event) { + this.user=event; + notifyListeners(); print("main event-->$event"); }); } + bool faqEditable(){ + return this.user != null && false; + } + bool termEditable(){ + return this.user != null && false; + } + bool contactEditable(){ + return this.user != null && false; + } + + + bool isLogin() { return this.user != null; } bool isCustomer() { - return user != null && user.name != "Owner"; - } - - bool isOwner() { - return user != null && user.name == "Owner"; - } - - bool hasEmail() { - return this.user != null && this.user.isEmail(); - } - - bool agreedTerm() { - return this.user != null && this.user.agreeTerms; - } - - bool isBuyer() { - return this.user == null || this.user.isBuyer(); + return user != null && user.isCustomer(); } bool isSysAdmin() { - return this.user != null && this.user.isSysAdmin(); + return this.user != null && this.user.hasSysAdmin(); } - bool isSysSupport() { - return this.user != null && this.user.isSysSupport(); - } - - bool isBizAdmin() { - return this.user != null && this.user.isBizAdmin(); - } - - bool isOwnerAndAbove() { - return this.user != null && this.user.isOwnerAndAbove(); - } bool isAdmin() { return this.user != null && this.user.hasAdmin(); } - bool showHistoryBtn() { - return isSysAdmin() || isSysSupport() || isBizAdmin(); - } - init() async { await _loadSetting(); _loadUser(); this.packageInfo = await PackageInfo.fromPlatform(); } - // void addModel(BaseModel model) { - // models.add(model); - // } + void addModel(BaseModel model) { + models.add(model); + } // void _initUser(User user) { // models.forEach((m) => m.initUser(user)); @@ -107,18 +92,18 @@ class MainModel extends ChangeNotifier { // } // } - // void _initSetting(Setting setting) { - // models.forEach((m) => m.initSetting(setting)); - // } + void _initSetting(Setting setting) { + models.forEach((m) => m.initSetting(setting)); + } Future _loadSetting() async { try { Services.instance.authService.getSetting().listen((event) { this.setting = event; + _initSetting(setting); notifyListeners(); }); } finally {} - // _initSetting(setting); } void _loadUser() async { diff --git a/lib/fcs/common/pages/profile_page.dart b/lib/fcs/common/pages/profile_page.dart index e981e73..b6f6ad4 100644 --- a/lib/fcs/common/pages/profile_page.dart +++ b/lib/fcs/common/pages/profile_page.dart @@ -51,16 +51,7 @@ class _ProfileState extends State { var languageModel = Provider.of(context); MainModel mainModel = Provider.of(context); - // buildLanguage(languageModel); - _selectedDropdown(String selected) { - setState(() { - selectedLanguage = selected; - languageModel.saveLanguage(selectedLanguage); - }); - } - final namebox = Container( - // padding: EdgeInsets.only(left: 25.0, right: 25.0), padding: EdgeInsets.only(top: 10, left: 25.0, right: 25.0), child: Container( height: 45.0, @@ -137,80 +128,7 @@ class _ProfileState extends State { ], ), ); - final emailBox = Container( - padding: EdgeInsets.only(top: 10, left: 25.0, right: 25.0), - child: Row( - children: [ - Text( - AppTranslations.of(context).text("profile.email"), - style: languageModel.isEng - ? TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal) - : TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - fontFamily: "MyanmarUnicode"), - ), - SizedBox( - width: 35, - ), - Text( - mainModel.user == null - ? "" - : mainModel.user.email == null || mainModel.user.email == '' - ? '' - : mainModel.user.email, - style: TextStyle(fontSize: 16.0, fontStyle: FontStyle.normal), - ), - ], - ), - ); - final languageBox = Container( - padding: EdgeInsets.only(bottom: 0, top: 7, left: 25.0, right: 25.0), - child: Container( - height: 45.0, - child: Row( - children: [ - Text( - AppTranslations.of(context).text("profile.language"), - style: languageModel.isEng - ? TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal) - : TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.normal, - fontFamily: "MyanmarUnicode"), - ), - Container( - width: 140, - padding: EdgeInsets.only(left: 30), - child: Theme( - data: new ThemeData( - canvasColor: Colors.white, - ), - child: DropdownButton( - hint: Text("English"), - value: selectedLanguage, - isExpanded: true, - iconSize: 40, - items: languagesList - .map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - onChanged: _selectedDropdown), - )), - ], - ), - )); + final logoutbutton = Container( padding: EdgeInsets.only(left: 20.0, right: 24.0), @@ -283,20 +201,15 @@ class _ProfileState extends State { namebox, Padding( padding: const EdgeInsets.only(left: 18.0), - child: Icon(Icons.edit), + child: Icon(Icons.edit, color: primaryColor), ) ], ), - mainModel.isBuyer() ? Container() : getPrivilegeBox(context), - phonenumberbox, - mainModel.user == null + mainModel.isCustomer() ? Container() - : mainModel.user.email == null || - mainModel.user.email == '' - ? Container() - : emailBox, - languageBox, - getShippingAddressList(context), + : getPrivilegeBox(context), + phonenumberbox, + // getShippingAddressList(context), ], ), ), diff --git a/lib/fcs/common/pages/signin/code_page.dart b/lib/fcs/common/pages/signin/code_page.dart index f534eea..0797353 100644 --- a/lib/fcs/common/pages/signin/code_page.dart +++ b/lib/fcs/common/pages/signin/code_page.dart @@ -193,6 +193,9 @@ class _CodePageState extends State { _resend() async {} _verify() async { + setState(() { + _isLoading = true; + }); try { AuthResult auth = await context.read().signin(this.pin); if (auth.authStatus == AuthStatus.AUTH_VERIFIED) { @@ -202,12 +205,13 @@ class _CodePageState extends State { } else { Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false); } - // Provider.of(context, listen: false) - // .saveUser(pin, widget.phoneNumber); } } catch (e) { showMsgDialog(context, "Error", e.toString()); } + setState(() { + _isLoading = false; + }); } _completeResend() { diff --git a/lib/fcs/common/pages/signin/signin_page.dart b/lib/fcs/common/pages/signin/signin_page.dart index ba1d2b0..12ebcee 100644 --- a/lib/fcs/common/pages/signin/signin_page.dart +++ b/lib/fcs/common/pages/signin/signin_page.dart @@ -1,7 +1,9 @@ import 'package:country_code_picker/country_code_picker.dart'; import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; import 'package:fcs/fcs/common/pages/model/main_model.dart'; +import 'package:fcs/fcs/common/pages/signin/signup_page.dart'; import 'package:fcs/fcs/common/pages/widgets/local_text.dart'; import 'package:fcs/widget/bottom_up_page_route.dart'; import 'package:flutter/material.dart'; @@ -176,6 +178,13 @@ class _SigninPageState extends State { await Navigator.of(context) .push(BottomUpPageRoute(CodePage(phoneNumber: phoneNumber))); Navigator.pop(context); + } else if (auth.authStatus == AuthStatus.AUTH_VERIFIED) { + User user = context.read().user; + if (user != null && !user.hasSignup) { + await Navigator.of(context).push(BottomUpPageRoute(SignupPage())); + } else { + Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false); + } } if (auth.authStatus == AuthStatus.ERROR) { showMsgDialog(context, "Error", auth.authErrorMsg); diff --git a/lib/fcs/common/pages/term/term_page.dart b/lib/fcs/common/pages/term/term_page.dart index 9bb8e7f..70777df 100644 --- a/lib/fcs/common/pages/term/term_page.dart +++ b/lib/fcs/common/pages/term/term_page.dart @@ -49,8 +49,10 @@ class _TermPageState extends State { @override Widget build(BuildContext context) { Setting setting = Provider.of(context).setting; - return CupertinoPageScaffold( - child: CustomScrollView(slivers: [ + bool isEditable = context.select((MainModel m) => m.termEditable()); + + return Scaffold( + body: CustomScrollView(slivers: [ SliverAppBar( leading: IconButton( icon: Icon( @@ -60,8 +62,8 @@ class _TermPageState extends State { onPressed: () => Navigator.of(context).pop(), ), backgroundColor: primaryColor, - expandedHeight: 150.0, - floating: true, + expandedHeight: 100.0, + floating: false, pinned: true, flexibleSpace: FlexibleSpaceBar( centerTitle: true, @@ -72,34 +74,35 @@ class _TermPageState extends State { color: Colors.white, ), ), - actions: [ - IconButton( - onPressed: () => - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => - TermEdit(term: Term.fromSetting(setting)), - )), - icon: Icon( - CupertinoIcons.pen, - color: Colors.white, - )) - ], + actions: isEditable + ? [ + IconButton( + onPressed: () => + Navigator.of(context).push(CupertinoPageRoute( + builder: (context) => + TermEdit(term: Term.fromSetting(setting)), + )), + icon: Icon( + CupertinoIcons.pen, + color: Colors.white, + )) + ] + : [], ), - SliverFillRemaining(child: ZefyrTheme( - data: ZefyrThemeData().copyWith( - defaultLineTheme: LineTheme( - textStyle: TextStyle(color: Colors.black), - padding: EdgeInsets.all(0))), - child: ZefyrScaffold( - child: ZefyrEditor( - mode: ZefyrMode.view, - padding: EdgeInsets.all(16), - controller: ZefyrController(_loadDocument(setting)), - focusNode: _focusNode, - ), - )) - - ), + SliverFillRemaining( + child: ZefyrTheme( + data: ZefyrThemeData().copyWith( + defaultLineTheme: LineTheme( + textStyle: TextStyle(color: Colors.black), + padding: EdgeInsets.all(0))), + child: ZefyrScaffold( + child: ZefyrEditor( + mode: ZefyrMode.view, + padding: EdgeInsets.all(16), + controller: ZefyrController(_loadDocument(setting)), + focusNode: _focusNode, + ), + ))), ])); } diff --git a/lib/fcs/common/pages/widgets/bottom_up_page_route.dart b/lib/fcs/common/pages/widgets/bottom_up_page_route.dart new file mode 100644 index 0000000..cd27cd9 --- /dev/null +++ b/lib/fcs/common/pages/widgets/bottom_up_page_route.dart @@ -0,0 +1,23 @@ +import 'package:flutter/cupertino.dart'; + +class BottomUpPageRoute extends PageRouteBuilder { + final Widget child; + + BottomUpPageRoute(this.child) + : super( + pageBuilder: (context, animation, secondaryAnimation) => child, + transitionsBuilder: (context, animation, secondaryAnimation, child) { + var begin = Offset(0.0, 1.0); + var end = Offset.zero; + var curve = Curves.ease; + + var tween = + Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); + + return SlideTransition( + position: animation.drive(tween), + child: child, + ); + }, + ); +} diff --git a/lib/fcs/common/pages/widgets/input_text.dart b/lib/fcs/common/pages/widgets/input_text.dart index 9cb4f8c..53b00af 100644 --- a/lib/fcs/common/pages/widgets/input_text.dart +++ b/lib/fcs/common/pages/widgets/input_text.dart @@ -13,6 +13,7 @@ class InputText extends StatelessWidget { final int maxLines; final bool withBorder; final Color borderColor; + final TextInputType textInputType; const InputText( {Key key, @@ -22,7 +23,8 @@ class InputText extends StatelessWidget { this.validator, this.maxLines = 1, this.withBorder = false, - this.borderColor}) + this.borderColor, + this.textInputType}) : super(key: key); @override Widget build(BuildContext context) { @@ -36,11 +38,12 @@ class InputText extends StatelessWidget { cursorColor: primaryColor, style: textStyle, maxLines: maxLines, + keyboardType: textInputType, decoration: new InputDecoration( - hintText: '', + // hintText: '', hintStyle: TextStyle( - height: 2.5, - ), + height: 3.5, + ), labelText: labelTextKey == null ? null : AppTranslations.of(context).text(labelTextKey), diff --git a/pubspec.yaml b/pubspec.yaml index 92cfb2c..d4610db 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -115,3 +115,8 @@ flutter: - family: MyanmarUnicode fonts: - asset: assets/fonts/MyMMUnicodeUniversal.ttf + + - family: Myanmar3 + fonts: + - asset: assets/fonts/Myanmar3_2018.ttf +