Merge branch 'master' of tzw/fcs into master
This commit is contained in:
BIN
assets/fonts/OpenSans-Bold.ttf
Normal file
BIN
assets/fonts/OpenSans-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/OpenSans-BoldItalic.ttf
Normal file
BIN
assets/fonts/OpenSans-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/OpenSans-Italic.ttf
Normal file
BIN
assets/fonts/OpenSans-Italic.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/OpenSans-Regular.ttf
Normal file
BIN
assets/fonts/OpenSans-Regular.ttf
Normal file
Binary file not shown.
@@ -358,6 +358,12 @@
|
|||||||
"box.delete.btn":"Delete carton",
|
"box.delete.btn":"Delete carton",
|
||||||
"box.update_title":"Edit carton",
|
"box.update_title":"Edit carton",
|
||||||
"box.update.btn":"Update carton",
|
"box.update.btn":"Update carton",
|
||||||
|
"box.ship.btn":"Ship this Carton",
|
||||||
|
"box.arrive.btn":"Arrive this Carton",
|
||||||
|
"box.invoice.btn":"Invoice this Carton",
|
||||||
|
"box.ship.confirm":"Confirm ship?",
|
||||||
|
"box.arrive.confirm":"Confirm arrive?",
|
||||||
|
"box.invoice.confirm":"Confirm invoice?",
|
||||||
"Boxes End ================================================================":"",
|
"Boxes End ================================================================":"",
|
||||||
|
|
||||||
"Delivery Start ================================================================":"",
|
"Delivery Start ================================================================":"",
|
||||||
@@ -400,6 +406,9 @@
|
|||||||
"FCSshipment.cancel.confirm":"Cancel this shipment?",
|
"FCSshipment.cancel.confirm":"Cancel this shipment?",
|
||||||
"FCSshipment.carton":"Cartons",
|
"FCSshipment.carton":"Cartons",
|
||||||
"FCSshipment.package":"Packages",
|
"FCSshipment.package":"Packages",
|
||||||
|
"FCSshipment.process.confirm":"Confirm process?",
|
||||||
|
"FCSshipment.arrive.confirm":"Confirm arrive?",
|
||||||
|
"FCSshipment.invoice.confirm":"Confirm invoice?",
|
||||||
"FCS Shipment End ================================================================":"",
|
"FCS Shipment End ================================================================":"",
|
||||||
|
|
||||||
"Shipment Start ================================================================":"",
|
"Shipment Start ================================================================":"",
|
||||||
@@ -458,6 +467,7 @@
|
|||||||
"shipment.confirm.complete.confirm":"Complete confirm?",
|
"shipment.confirm.complete.confirm":"Complete confirm?",
|
||||||
"shipment.receive.complete.btn":"Complete receive",
|
"shipment.receive.complete.btn":"Complete receive",
|
||||||
"shipment.receive.complete.confirm":"Complete receive?",
|
"shipment.receive.complete.confirm":"Complete receive?",
|
||||||
|
|
||||||
"Shipment End ================================================================":"",
|
"Shipment End ================================================================":"",
|
||||||
|
|
||||||
"Rate Start ================================================================":"",
|
"Rate Start ================================================================":"",
|
||||||
|
|||||||
@@ -358,6 +358,12 @@
|
|||||||
"box.delete.btn":"Delete carton",
|
"box.delete.btn":"Delete carton",
|
||||||
"box.update_title":"Edit carton",
|
"box.update_title":"Edit carton",
|
||||||
"box.update.btn":"Update carton",
|
"box.update.btn":"Update carton",
|
||||||
|
"box.ship.btn":"Ship this Carton",
|
||||||
|
"box.arrive.btn":"Arrive this Carton",
|
||||||
|
"box.invoice.btn":"Invoice this Carton",
|
||||||
|
"box.ship.confirm":"ပို့ဆောင်မှုကို အတည်ပြုပါ ?",
|
||||||
|
"box.arrive.confirm":"ရောက်ရှိကြောင်း အတည်ပြုပါ ?",
|
||||||
|
"box.invoice.confirm":"ပြေစာ အတည်ပြုပါ ?",
|
||||||
"Boxes End ================================================================":"",
|
"Boxes End ================================================================":"",
|
||||||
|
|
||||||
"Delivery Start ================================================================":"",
|
"Delivery Start ================================================================":"",
|
||||||
@@ -403,6 +409,9 @@
|
|||||||
"FCSshipment.popupmenu.shipped":"Shipped shipments",
|
"FCSshipment.popupmenu.shipped":"Shipped shipments",
|
||||||
"FCSshipment.carton":"FCS ပုံးများ",
|
"FCSshipment.carton":"FCS ပုံးများ",
|
||||||
"FCSshipment.package":"FCS အထုပ်",
|
"FCSshipment.package":"FCS အထုပ်",
|
||||||
|
"FCSshipment.process.confirm":"လုပ်ငန်းစဉ်ကို အတည်ပြုပါ ?",
|
||||||
|
"FCSshipment.arrive.confirm":"ရောက်ရှိကြောင်း အတည်ပြုပါ ?",
|
||||||
|
"FCSshipment.invoice.confirm":"ပြေစာအတည်ပြုပါ ?",
|
||||||
"FCS Shipment End ================================================================":"",
|
"FCS Shipment End ================================================================":"",
|
||||||
|
|
||||||
"Shipment Start ================================================================":"",
|
"Shipment Start ================================================================":"",
|
||||||
@@ -461,6 +470,7 @@
|
|||||||
"shipment.confirm.complete.confirm":"Complete confirm?",
|
"shipment.confirm.complete.confirm":"Complete confirm?",
|
||||||
"shipment.receive.complete.btn":"Complete receive",
|
"shipment.receive.complete.btn":"Complete receive",
|
||||||
"shipment.receive.complete.confirm":"Complete receive?",
|
"shipment.receive.complete.confirm":"Complete receive?",
|
||||||
|
|
||||||
"Shipment End ================================================================":"",
|
"Shipment End ================================================================":"",
|
||||||
|
|
||||||
"Rate Start ================================================================":"",
|
"Rate Start ================================================================":"",
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import 'package:fcs/helpers/firebase_helper.dart';
|
|||||||
import 'package:firebase_auth/firebase_auth.dart' as fb;
|
import 'package:firebase_auth/firebase_auth.dart' as fb;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
|
import '../services/services.dart';
|
||||||
|
|
||||||
class AuthFb {
|
class AuthFb {
|
||||||
final log = Logger('AuthFb');
|
final log = Logger('AuthFb');
|
||||||
|
|
||||||
@@ -21,6 +23,10 @@ class AuthFb {
|
|||||||
late StreamController<User?> controller;
|
late StreamController<User?> controller;
|
||||||
static final fb.FirebaseAuth _fb = fb.FirebaseAuth.instance;
|
static final fb.FirebaseAuth _fb = fb.FirebaseAuth.instance;
|
||||||
static String _verificationId = '';
|
static String _verificationId = '';
|
||||||
|
static bool _logIn = false;
|
||||||
|
|
||||||
|
StreamSubscription<DocumentSnapshot>? userListener;
|
||||||
|
StreamSubscription<DocumentSnapshot>? userAuthListener;
|
||||||
|
|
||||||
Future<fcs.AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber) {
|
Future<fcs.AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber) {
|
||||||
Completer<fcs.AuthResult> completer = Completer();
|
Completer<fcs.AuthResult> completer = Completer();
|
||||||
@@ -99,9 +105,13 @@ class AuthFb {
|
|||||||
return Future.value(fcs.AuthResult(authStatus: AuthStatus.AUTH_VERIFIED));
|
return Future.value(fcs.AuthResult(authStatus: AuthStatus.AUTH_VERIFIED));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> signout() async {
|
Future<void> signoutStart() async {
|
||||||
if (userListener != null) await userListener!.cancel();
|
await userListener?.cancel();
|
||||||
return _fb.signOut();
|
await userAuthListener?.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> signoutEnd() async {
|
||||||
|
await _fb.signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _addUserToStream({bool refreshIdToken = false}) async {
|
Future<void> _addUserToStream({bool refreshIdToken = false}) async {
|
||||||
@@ -111,7 +121,6 @@ class AuthFb {
|
|||||||
await getClaims(refreshIdToken: refreshIdToken);
|
await getClaims(refreshIdToken: refreshIdToken);
|
||||||
|
|
||||||
log.info("Claims:$claims");
|
log.info("Claims:$claims");
|
||||||
if (claims == null) return;
|
|
||||||
|
|
||||||
String? cid = claims["cid"];
|
String? cid = claims["cid"];
|
||||||
User? user;
|
User? user;
|
||||||
@@ -123,6 +132,11 @@ class AuthFb {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadUserClaim(claims, user);
|
||||||
|
controller.add(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadUserClaim(Map claims, User user) {
|
||||||
// add privileges
|
// add privileges
|
||||||
String? privileges = claims["pr"];
|
String? privileges = claims["pr"];
|
||||||
if (privileges != null && privileges != "") {
|
if (privileges != null && privileges != "") {
|
||||||
@@ -130,7 +144,6 @@ class AuthFb {
|
|||||||
} else {
|
} else {
|
||||||
user.privileges = [];
|
user.privileges = [];
|
||||||
}
|
}
|
||||||
controller.add(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<User?> _getUserFromFirestore(String userID) async {
|
Future<User?> _getUserFromFirestore(String userID) async {
|
||||||
@@ -205,13 +218,12 @@ class AuthFb {
|
|||||||
fb.User? firebaseUser = _fb.currentUser;
|
fb.User? firebaseUser = _fb.currentUser;
|
||||||
if (firebaseUser == null) return null;
|
if (firebaseUser == null) return null;
|
||||||
Map? claims = await getClaims();
|
Map? claims = await getClaims();
|
||||||
if (claims == null) return null;
|
|
||||||
String cid = claims["cid"];
|
String cid = claims["cid"];
|
||||||
return cid;
|
return cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _startUserListener() async {
|
Future<void> _startUserListener() async {
|
||||||
if (userListener != null) userListener!.cancel();
|
_startAuthListener();
|
||||||
String? _userID = await _getCurrentUserID();
|
String? _userID = await _getCurrentUserID();
|
||||||
if (_userID == null) {
|
if (_userID == null) {
|
||||||
return;
|
return;
|
||||||
@@ -221,6 +233,7 @@ class AuthFb {
|
|||||||
.collection(user_collection)
|
.collection(user_collection)
|
||||||
.doc(_userID)
|
.doc(_userID)
|
||||||
.snapshots();
|
.snapshots();
|
||||||
|
userListener?.cancel();
|
||||||
userListener = snapshot.listen((snap) async {
|
userListener = snapshot.listen((snap) async {
|
||||||
User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||||
|
|
||||||
@@ -229,14 +242,12 @@ class AuthFb {
|
|||||||
userListener?.cancel();
|
userListener?.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_logIn) return;
|
||||||
try {
|
try {
|
||||||
// get privilege from claim
|
// get privilege from claim
|
||||||
fb.IdTokenResult idToken = await firebaseUser.getIdTokenResult(true);
|
Map<dynamic, dynamic> claims = await getClaims(refreshIdToken: true);
|
||||||
|
loadUserClaim(claims, user);
|
||||||
String? privileges = idToken.claims?["pr"] ?? '';
|
|
||||||
if (privileges != null && privileges != "") {
|
|
||||||
user.privileges = privileges.split(":").toList();
|
|
||||||
}
|
|
||||||
controller.add(user);
|
controller.add(user);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
controller.add(null);
|
controller.add(null);
|
||||||
@@ -244,13 +255,47 @@ class AuthFb {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamSubscription<DocumentSnapshot>? userListener;
|
Future<void> _startAuthListener() async {
|
||||||
|
String? authId = _fb.currentUser?.uid;
|
||||||
|
if (authId == null) return;
|
||||||
|
|
||||||
|
Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
|
||||||
|
.collection(authCollection)
|
||||||
|
.doc(authId)
|
||||||
|
.snapshots();
|
||||||
|
userAuthListener?.cancel();
|
||||||
|
userAuthListener = snapshot.listen((snap) async {
|
||||||
|
if (snap.exists) {
|
||||||
|
Map<String, dynamic> map = snap.data() as Map<String, dynamic>;
|
||||||
|
String userID = map['user_id'] ?? "";
|
||||||
|
|
||||||
|
User? user = await Services.instance.userService.getUser(userID);
|
||||||
|
if (user == null) return;
|
||||||
|
|
||||||
|
if (_fb.currentUser == null) {
|
||||||
|
userAuthListener?.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<dynamic, dynamic> claims = await getClaims(refreshIdToken: true);
|
||||||
|
loadUserClaim(claims, user);
|
||||||
|
|
||||||
|
log.info("_startAuthListener: $user");
|
||||||
|
if (_logIn) {
|
||||||
|
controller.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Stream<User?> user() {
|
Stream<User?> user() {
|
||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
StreamSubscription<fb.User?>? authListener;
|
StreamSubscription<fb.User?>? authListener;
|
||||||
|
|
||||||
Future<void> _start() async {
|
Future<void> _start() async {
|
||||||
authListener = _fb.authStateChanges().listen((firebaseUser) {
|
await authListener?.cancel();
|
||||||
|
authListener = _fb.authStateChanges().listen((firebaseUser) async {
|
||||||
|
_logIn = firebaseUser != null;
|
||||||
if (firebaseUser == null) {
|
if (firebaseUser == null) {
|
||||||
controller.add(null);
|
controller.add(null);
|
||||||
} else {
|
} else {
|
||||||
@@ -261,12 +306,8 @@ class AuthFb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _stop() {
|
void _stop() {
|
||||||
if (userListener != null) {
|
userListener?.cancel();
|
||||||
userListener!.cancel();
|
authListener?.cancel();
|
||||||
}
|
|
||||||
if (authListener != null) {
|
|
||||||
authListener!.cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controller = StreamController<User?>(
|
controller = StreamController<User?>(
|
||||||
|
|||||||
@@ -85,4 +85,29 @@ class UserDataProvider {
|
|||||||
return await requestAPI("/enable_user", "PUT",
|
return await requestAPI("/enable_user", "PUT",
|
||||||
payload: {"id": userID, "enabled": enabled}, token: await getToken());
|
payload: {"id": userID, "enabled": enabled}, token: await getToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<User?> getUser(String userID) async {
|
||||||
|
if (userID == "") return null;
|
||||||
|
|
||||||
|
String path = "/$user_collection";
|
||||||
|
try {
|
||||||
|
var snap = await FirebaseFirestore.instance
|
||||||
|
.collection(path)
|
||||||
|
.doc(userID)
|
||||||
|
.get(const GetOptions(source: Source.server));
|
||||||
|
|
||||||
|
if (snap.data() == null) return null;
|
||||||
|
Map<String, dynamic>? data = snap.data() as Map<String, dynamic>;
|
||||||
|
|
||||||
|
if (data['delete_time'] == 0) {
|
||||||
|
User user = User.fromMap(data, snap.id);
|
||||||
|
return user;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log.warning("Error!! $e");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,6 @@ class AuthServiceImp implements AuthService {
|
|||||||
return authFb.signInWithPhoneNumber(smsCode);
|
return authFb.signInWithPhoneNumber(smsCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> signout() {
|
|
||||||
return authFb.signout();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Stream<User?> getUserStream() {
|
Stream<User?> getUserStream() {
|
||||||
return authFb.user();
|
return authFb.user();
|
||||||
@@ -64,4 +59,14 @@ class AuthServiceImp implements AuthService {
|
|||||||
Future<void> updatePreferredCurrency(String currency) {
|
Future<void> updatePreferredCurrency(String currency) {
|
||||||
return authFb.updatePreferredCurrency(currency);
|
return authFb.updatePreferredCurrency(currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> signoutEnd() {
|
||||||
|
return authFb.signoutEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> signoutStart() {
|
||||||
|
return authFb.signoutStart();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import 'package:fcs/domain/entities/user.dart';
|
|||||||
abstract class AuthService {
|
abstract class AuthService {
|
||||||
Future<AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber);
|
Future<AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber);
|
||||||
Future<AuthResult> signInWithSmsCode(String smsCode);
|
Future<AuthResult> signInWithSmsCode(String smsCode);
|
||||||
Future<void> signout();
|
Future<void> signoutStart();
|
||||||
|
Future<void> signoutEnd();
|
||||||
Future<void> signup(String userName);
|
Future<void> signup(String userName);
|
||||||
Future<void> joinInvite(String userName);
|
Future<void> joinInvite(String userName);
|
||||||
Future<void> updateProfileName(String newUserName);
|
Future<void> updateProfileName(String newUserName);
|
||||||
|
|||||||
@@ -52,4 +52,9 @@ class UserServiceImp implements UserService {
|
|||||||
Future<void> enableUser(String userID, bool enabled) {
|
Future<void> enableUser(String userID, bool enabled) {
|
||||||
return userDataProvider.enableUser(userID, enabled);
|
return userDataProvider.enableUser(userID, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<User?> getUser(String userID) {
|
||||||
|
return userDataProvider.getUser(userID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ abstract class UserService {
|
|||||||
Future<void> uploadMsgToken(String token);
|
Future<void> uploadMsgToken(String token);
|
||||||
Future<void> removeMsgToken(String token);
|
Future<void> removeMsgToken(String token);
|
||||||
Future<void> enableUser(String userID, bool enabled);
|
Future<void> enableUser(String userID, bool enabled);
|
||||||
|
Future<User?> getUser(String userID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const uploadPhotoLimit = 10;
|
|||||||
|
|
||||||
const config_collection = "configs";
|
const config_collection = "configs";
|
||||||
const user_collection = "users";
|
const user_collection = "users";
|
||||||
|
const authCollection = "auths";
|
||||||
const invitations_collection = "invitations";
|
const invitations_collection = "invitations";
|
||||||
const privilege_collection = "privileges";
|
const privilege_collection = "privileges";
|
||||||
const markets_collection = "markets";
|
const markets_collection = "markets";
|
||||||
@@ -113,8 +114,8 @@ const carton_processing_status = "processing";
|
|||||||
const carton_arrived_status = "arrived";
|
const carton_arrived_status = "arrived";
|
||||||
const carton_invoiced_status = "invoiced";
|
const carton_invoiced_status = "invoiced";
|
||||||
const carton_canceled_status = "canceled";
|
const carton_canceled_status = "canceled";
|
||||||
const all_status= "All stauts";
|
const all_status = "All stauts";
|
||||||
const all ="All";
|
const all = "All";
|
||||||
|
|
||||||
// shipment status
|
// shipment status
|
||||||
const shipment_pending_status = "pending";
|
const shipment_pending_status = "pending";
|
||||||
@@ -141,6 +142,6 @@ const payment_canceled_status = "canceled";
|
|||||||
const delivery_caton = "Delivery carton";
|
const delivery_caton = "Delivery carton";
|
||||||
const pickup_carton = "Pick-up carton";
|
const pickup_carton = "Pick-up carton";
|
||||||
|
|
||||||
// bill
|
// bill
|
||||||
const billToSender ="Bill to sender";
|
const billToSender = "Bill to sender";
|
||||||
const billToConsignee="Bill to consignee";
|
const billToConsignee = "Bill to consignee";
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class User {
|
|||||||
String? preferCurrency;
|
String? preferCurrency;
|
||||||
bool enablePinLogin;
|
bool enablePinLogin;
|
||||||
String? pinDigit;
|
String? pinDigit;
|
||||||
String? confirmPinDigit;
|
|
||||||
|
|
||||||
String get initial =>
|
String get initial =>
|
||||||
name != null && name != "" ? name!.substring(0, 1) : "?";
|
name != null && name != "" ? name!.substring(0, 1) : "?";
|
||||||
@@ -60,21 +59,21 @@ class User {
|
|||||||
bool get disabled => status != null && status == user_disabled_status;
|
bool get disabled => status != null && status == user_disabled_status;
|
||||||
|
|
||||||
String get share => "Your phone number:$phoneNumber";
|
String get share => "Your phone number:$phoneNumber";
|
||||||
User(
|
User({
|
||||||
{this.id,
|
this.id,
|
||||||
this.name,
|
this.name,
|
||||||
this.phoneNumber,
|
this.phoneNumber,
|
||||||
this.fcsID,
|
this.fcsID,
|
||||||
this.status,
|
this.status,
|
||||||
this.privileges = const [],
|
this.privileges = const [],
|
||||||
this.lastMessage,
|
this.lastMessage,
|
||||||
this.lastMessageTime,
|
this.lastMessageTime,
|
||||||
this.userUnseenCount = 0,
|
this.userUnseenCount = 0,
|
||||||
this.fcsUnseenCount = 0,
|
this.fcsUnseenCount = 0,
|
||||||
this.preferCurrency,
|
this.preferCurrency,
|
||||||
this.enablePinLogin = false,
|
this.enablePinLogin = false,
|
||||||
this.pinDigit,
|
this.pinDigit,
|
||||||
this.confirmPinDigit});
|
});
|
||||||
|
|
||||||
factory User.fromJson(Map<String, dynamic> json) {
|
factory User.fromJson(Map<String, dynamic> json) {
|
||||||
return User(
|
return User(
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ Future<String> getToken() async {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map?> getClaims({bool refreshIdToken = false}) async {
|
Future<Map> getClaims({bool refreshIdToken = false}) async {
|
||||||
fb.User? firebaseUser = auth.currentUser;
|
fb.User? firebaseUser = auth.currentUser;
|
||||||
if (firebaseUser == null) return null;
|
if (firebaseUser == null) return {};
|
||||||
fb.IdTokenResult idToken =
|
fb.IdTokenResult idToken =
|
||||||
await firebaseUser.getIdTokenResult(refreshIdToken);
|
await firebaseUser.getIdTokenResult(refreshIdToken);
|
||||||
return idToken.claims;
|
return idToken.claims ?? {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns list of url
|
// returns list of url
|
||||||
|
|||||||
69
lib/helpers/pdf.dart
Normal file
69
lib/helpers/pdf.dart
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:open_file/open_file.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
import 'package:pdf/pdf.dart';
|
||||||
|
import 'package:pdf/widgets.dart' as pw;
|
||||||
|
|
||||||
|
import '../domain/entities/carton.dart';
|
||||||
|
|
||||||
|
Future<void> generateCartonPdf(Carton carton) async {
|
||||||
|
var myTheme = pw.ThemeData.withFont(
|
||||||
|
base:
|
||||||
|
pw.Font.ttf(await rootBundle.load("assets/fonts/OpenSans-Regular.ttf")),
|
||||||
|
bold: pw.Font.ttf(await rootBundle.load("assets/fonts/OpenSans-Bold.ttf")),
|
||||||
|
italic:
|
||||||
|
pw.Font.ttf(await rootBundle.load("assets/fonts/OpenSans-Italic.ttf")),
|
||||||
|
boldItalic: pw.Font.ttf(
|
||||||
|
await rootBundle.load("assets/fonts/OpenSans-BoldItalic.ttf")),
|
||||||
|
);
|
||||||
|
|
||||||
|
final doc = pw.Document(
|
||||||
|
theme: myTheme,
|
||||||
|
);
|
||||||
|
|
||||||
|
PdfPageFormat format =
|
||||||
|
const PdfPageFormat(PdfPageFormat.inch * 3, PdfPageFormat.inch * 1);
|
||||||
|
doc.addPage(pw.Page(
|
||||||
|
pageFormat: format,
|
||||||
|
build: (pw.Context context) {
|
||||||
|
return pw.Padding(
|
||||||
|
padding: const pw.EdgeInsets.all(5),
|
||||||
|
child: pw.Row(
|
||||||
|
mainAxisAlignment: pw.MainAxisAlignment.start,
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
||||||
|
children: <pw.Widget>[
|
||||||
|
pw.BarcodeWidget(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
color: PdfColor.fromHex("#000000"),
|
||||||
|
barcode: pw.Barcode.qrCode(),
|
||||||
|
data: carton.cartonNumber!),
|
||||||
|
pw.Padding(
|
||||||
|
padding: const pw.EdgeInsets.all(5),
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Text(carton.cartonNumber!,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
)),
|
||||||
|
pw.Text(carton.userName!,
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
)),
|
||||||
|
pw.Text("${carton.actualWeight} lb",
|
||||||
|
style: pw.TextStyle(
|
||||||
|
fontSize: 10,
|
||||||
|
color: PdfColor.fromInt(0xFF757575)))
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
}));
|
||||||
|
|
||||||
|
List<int> d = await doc.save();
|
||||||
|
final path = (await getExternalStorageDirectory())?.path ?? "";
|
||||||
|
final file = File("$path/${carton.cartonNumber}.pdf");
|
||||||
|
await file.writeAsBytes(d, flush: true);
|
||||||
|
OpenFile.open(file.path);
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart' show rootBundle;
|
import 'package:flutter/services.dart' show rootBundle;
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:fcs/pages/widgets/display_text.dart';
|
|||||||
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
|
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
|
||||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -315,8 +315,8 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
child: LocalText(context, "box.imageupload.title",
|
child: LocalText(context, "box.imageupload.title",
|
||||||
color: Colors.white, fontSize: 14)),
|
color: Colors.white, fontSize: 14)),
|
||||||
);
|
);
|
||||||
|
|
||||||
final deleteBtn = Padding(
|
final deleteBtn = Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: LocalButton(
|
child: LocalButton(
|
||||||
color: dangerColor,
|
color: dangerColor,
|
||||||
@@ -397,9 +397,10 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
_cargoTypes.isEmpty ? const SizedBox() : cargosBox,
|
_cargoTypes.isEmpty ? const SizedBox() : cargosBox,
|
||||||
_surchareItems.isEmpty ? const SizedBox() : surchargeItemBox,
|
_surchareItems.isEmpty ? const SizedBox() : surchargeItemBox,
|
||||||
uploadImageBtn,
|
uploadImageBtn,
|
||||||
|
const SizedBox(height: 30),
|
||||||
img,
|
img,
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 40),
|
||||||
deleteBtn,
|
deleteBtn,
|
||||||
const SizedBox(height: 20)
|
const SizedBox(height: 20)
|
||||||
]))));
|
]))));
|
||||||
}
|
}
|
||||||
@@ -445,8 +446,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
_init();
|
_init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_delete() {
|
||||||
_delete() {
|
|
||||||
showConfirmDialog(context, "box.delete.confirm", () {
|
showConfirmDialog(context, "box.delete.confirm", () {
|
||||||
_deleteCarton();
|
_deleteCarton();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import 'package:fcs/domain/entities/carton.dart';
|
import 'package:fcs/domain/entities/carton.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
|
import 'package:fcs/pages/carton/model/carton_model.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../../helpers/pdf.dart';
|
||||||
import '../carton_info.dart';
|
import '../carton_info.dart';
|
||||||
|
|
||||||
class CartonListRow extends StatelessWidget {
|
class CartonListRow extends StatelessWidget {
|
||||||
@@ -64,7 +67,11 @@ class CartonListRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 15),
|
const SizedBox(width: 15),
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {}, icon: Icon(AntDesign.qrcode,color: Colors.black))
|
onPressed: () {
|
||||||
|
_pdf(box, context);
|
||||||
|
},
|
||||||
|
icon:
|
||||||
|
Icon(AntDesign.qrcode, color: Colors.black))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -100,4 +107,11 @@ class CartonListRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pdf(Carton carton, BuildContext context) async {
|
||||||
|
Carton? c = await context.read<CartonModel>().getCarton(carton.id!);
|
||||||
|
if (c == null) return;
|
||||||
|
|
||||||
|
generateCartonPdf(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class _CustomerListState extends State<CustomerList> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: new Padding(
|
child: new Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 5.0),
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
child: new Row(
|
child: new Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
InkWell(
|
InkWell(
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:country_code_picker/country_code_picker.dart';
|
import 'package:country_code_picker/country_code_picker.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/customer/model/customer_model.dart';
|
import 'package:fcs/pages/customer/model/customer_model.dart';
|
||||||
|
|||||||
@@ -135,21 +135,21 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: LocalButton(
|
child: LocalButton(
|
||||||
textKey: "FCSshipment.process.btn",
|
textKey: "FCSshipment.process.btn",
|
||||||
callBack: () {},
|
callBack: _process,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final arriveBtn = Padding(
|
final arriveBtn = Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: LocalButton(
|
child: LocalButton(
|
||||||
textKey: "FCSshipment.arrive.btn",
|
textKey: "FCSshipment.arrive.btn",
|
||||||
callBack: () {},
|
callBack: _arrive,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final invoiceBtn = Padding(
|
final invoiceBtn = Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||||
child: LocalButton(
|
child: LocalButton(
|
||||||
textKey: "FCSshipment.invoice.btn",
|
textKey: "FCSshipment.invoice.btn",
|
||||||
callBack: () {},
|
callBack: _invoice,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -281,6 +281,30 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_process() {
|
||||||
|
showConfirmDialog(context, "FCSshipment.process.confirm", () {
|
||||||
|
_processFcsShipment();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_processFcsShipment() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
FcsShipmentModel fcsShipmentModel =
|
||||||
|
Provider.of<FcsShipmentModel>(context, listen: false);
|
||||||
|
await fcsShipmentModel.process(_fcsShipment!.id!);
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_ship() {
|
_ship() {
|
||||||
showConfirmDialog(context, "FCSshipment.ship.confirm", () {
|
showConfirmDialog(context, "FCSshipment.ship.confirm", () {
|
||||||
_shipFcsShipment();
|
_shipFcsShipment();
|
||||||
@@ -305,6 +329,54 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_arrive() {
|
||||||
|
showConfirmDialog(context, "FCSshipment.arrive.confirm", () {
|
||||||
|
_arriveFcsShipment();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_arriveFcsShipment() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
FcsShipmentModel fcsShipmentModel =
|
||||||
|
Provider.of<FcsShipmentModel>(context, listen: false);
|
||||||
|
await fcsShipmentModel.arrive(_fcsShipment!.id!);
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_invoice() {
|
||||||
|
showConfirmDialog(context, "FCSshipment.invoice.confirm", () {
|
||||||
|
_invoiceFcsShipment();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_invoiceFcsShipment() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
FcsShipmentModel fcsShipmentModel =
|
||||||
|
Provider.of<FcsShipmentModel>(context, listen: false);
|
||||||
|
await fcsShipmentModel.invoice(_fcsShipment!.id!);
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_showPDF(int id) async {
|
_showPDF(int id) async {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:fcs/domain/entities/shipment.dart';
|
|||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
typedef OnAdd(Shipment shipment);
|
typedef OnAdd(Shipment shipment);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ abstract class BaseModel extends ChangeNotifier {
|
|||||||
Setting? setting;
|
Setting? setting;
|
||||||
MainModel? mainModel;
|
MainModel? mainModel;
|
||||||
|
|
||||||
void initUser(User user) async {
|
void initUser(User? user) async {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class MainModel extends ChangeNotifier {
|
|||||||
|
|
||||||
set setMessaginToken(token) {
|
set setMessaginToken(token) {
|
||||||
this.messagingToken = token;
|
this.messagingToken = token;
|
||||||
uploadMsgToken();
|
_uploadMsgToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Setting? setting;
|
Setting? setting;
|
||||||
@@ -84,24 +84,33 @@ class MainModel extends ChangeNotifier {
|
|||||||
this.isFirstLaunch = await SharedPref.isFirstLaunch() ?? true;
|
this.isFirstLaunch = await SharedPref.isFirstLaunch() ?? true;
|
||||||
this.packageInfo = await PackageInfo.fromPlatform();
|
this.packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
if (userListener != null) userListener!.cancel();
|
userListener?.cancel();
|
||||||
userListener =
|
userListener =
|
||||||
Services.instance.authService.getUserStream().listen((_user) {
|
Services.instance.authService.getUserStream().listen((_user) {
|
||||||
|
bool isFirstTime = user == null && _user != null;
|
||||||
|
bool diffPrivilege =
|
||||||
|
_user != null && (user == null || user!.diffPrivileges(_user));
|
||||||
|
bool loggingOut = user != null && _user == null;
|
||||||
|
user = _user;
|
||||||
|
|
||||||
if (_user != null) {
|
if (_user != null) {
|
||||||
models.forEach((m) => m.initUser(_user));
|
for (final m in models) {
|
||||||
// call diffPrivileges if privilege changed or first time login
|
m.initUser(_user);
|
||||||
if (this.user == null || _user.diffPrivileges(this.user!)) {
|
if (diffPrivilege) {
|
||||||
models.forEach((m) => m.privilegeChanged());
|
m.privilegeChanged();
|
||||||
}
|
}
|
||||||
if (this.user == null) {
|
|
||||||
uploadMsgToken();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.user != null) {
|
|
||||||
models.forEach((m) => m.logout());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.user = _user;
|
if (loggingOut) {
|
||||||
|
for (final m in models) {
|
||||||
|
m.logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFirstTime) {
|
||||||
|
_uploadMsgToken();
|
||||||
|
}
|
||||||
|
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
@@ -136,22 +145,29 @@ class MainModel extends ChangeNotifier {
|
|||||||
return authResult;
|
return authResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void>? uploadMsgToken() {
|
Future<void> _uploadMsgToken() {
|
||||||
if (messagingToken == null || user == null) return null;
|
if (messagingToken == null || user == null) return Future.value();
|
||||||
return Services.instance.userService.uploadMsgToken(messagingToken!);
|
return Services.instance.userService.uploadMsgToken(messagingToken!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void>? removeMsgToken() {
|
Future<void> _removeMsgToken() {
|
||||||
if (messagingToken == null || user == null) return null;
|
if (messagingToken == null || user == null) return Future.value();
|
||||||
return Services.instance.userService.removeMsgToken(messagingToken!);
|
return Services.instance.userService.removeMsgToken(messagingToken!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> signout() async {
|
Future<void> signout() async {
|
||||||
try {
|
try {
|
||||||
await removeMsgToken();
|
await Services.instance.authService.signoutStart();
|
||||||
} catch (e) {}
|
await _removeMsgToken();
|
||||||
await Services.instance.authService.signout();
|
for (var i = 0; i < models.length; i++) {
|
||||||
models.forEach((m) => m.logout());
|
models[i].initUser(null);
|
||||||
|
models[i].logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
await Services.instance.authService.signoutEnd();
|
||||||
|
} catch (e) {
|
||||||
|
log.info("signout:${e.toString()}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> hasInvite() async {
|
Future<bool> hasInvite() async {
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import 'package:fcs/pages/widgets/local_app_bar.dart';
|
|||||||
import 'package:fcs/pages/widgets/local_dropdown.dart';
|
import 'package:fcs/pages/widgets/local_dropdown.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:fcs/pages/widgets/progress.dart';
|
import 'package:fcs/pages/widgets/progress.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|||||||
@@ -44,10 +44,11 @@ class _PinLoginPageState extends State<PinLoginPage> {
|
|||||||
cursorColor: primaryColor,
|
cursorColor: primaryColor,
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
decoration: new InputDecoration(
|
decoration: new InputDecoration(
|
||||||
prefix: Text(
|
prefixIcon: Text(
|
||||||
prefixText,
|
prefixText,
|
||||||
style: TextStyle(color: Colors.black),
|
style: TextStyle(color: Colors.black),
|
||||||
),
|
),
|
||||||
|
prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
|
||||||
contentPadding: EdgeInsets.all(0),
|
contentPadding: EdgeInsets.all(0),
|
||||||
labelStyle: newLabelStyle(color: Colors.black54, fontSize: 17),
|
labelStyle: newLabelStyle(color: Colors.black54, fontSize: 17),
|
||||||
enabledBorder: UnderlineInputBorder(
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class StaffModel extends BaseModel {
|
|||||||
Future<void> updatePin(
|
Future<void> updatePin(
|
||||||
{required String userID,
|
{required String userID,
|
||||||
required bool enablePin,
|
required bool enablePin,
|
||||||
required int pin}) async {
|
required int? pin}) async {
|
||||||
// await request("/employee/pin", "PUT",
|
// await request("/employee/pin", "PUT",
|
||||||
// payload: {
|
// payload: {
|
||||||
// "id": userID,
|
// "id": userID,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class _StaffPinEditorState extends State<StaffPinEditor> {
|
|||||||
_staff = widget.staff;
|
_staff = widget.staff;
|
||||||
_enablePinLogin = _staff.enablePinLogin;
|
_enablePinLogin = _staff.enablePinLogin;
|
||||||
_newPin = _staff.pinDigit ?? "";
|
_newPin = _staff.pinDigit ?? "";
|
||||||
_confirmPin = _staff.confirmPinDigit ?? "";
|
_confirmPin = _staff.pinDigit ?? "";
|
||||||
_newPinCtl.text = _newPin;
|
_newPinCtl.text = _newPin;
|
||||||
_confirmPinCtl.text = _confirmPin;
|
_confirmPinCtl.text = _confirmPin;
|
||||||
_checkFocusNode();
|
_checkFocusNode();
|
||||||
@@ -298,7 +298,9 @@ class _StaffPinEditorState extends State<StaffPinEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_save() async {
|
_save() async {
|
||||||
if (!_formKey.currentState!.validate()) return;
|
if (_enablePinLogin) {
|
||||||
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
@@ -308,7 +310,7 @@ class _StaffPinEditorState extends State<StaffPinEditor> {
|
|||||||
await context.read<StaffModel>().updatePin(
|
await context.read<StaffModel>().updatePin(
|
||||||
userID: _staff.id!,
|
userID: _staff.id!,
|
||||||
enablePin: _enablePinLogin,
|
enablePin: _enablePinLogin,
|
||||||
pin: int.parse(_confirmPin));
|
pin: _enablePinLogin ? int.parse(_confirmPin) : null);
|
||||||
Navigator.pop(context, true);
|
Navigator.pop(context, true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'callbacks.dart';
|
import 'callbacks.dart';
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'show_img.dart';
|
import 'show_img.dart';
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/localization/app_translations.dart';
|
import 'package:fcs/localization/app_translations.dart';
|
||||||
import 'package:fcs/pages/main/model/language_model.dart';
|
import 'package:fcs/pages/main/model/language_model.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:photo_view/photo_view.dart';
|
import 'package:photo_view/photo_view.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ dependencies:
|
|||||||
cached_network_image: ^3.3.1
|
cached_network_image: ^3.3.1
|
||||||
flutter_cache_manager: ^3.1.2
|
flutter_cache_manager: ^3.1.2
|
||||||
flutter_vector_icons: ^2.0.0
|
flutter_vector_icons: ^2.0.0
|
||||||
|
open_file: ^3.3.2
|
||||||
|
pdf: ^3.10.8
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -65,6 +67,7 @@ flutter:
|
|||||||
assets:
|
assets:
|
||||||
- assets/
|
- assets/
|
||||||
- assets/local/
|
- assets/local/
|
||||||
|
- assets/fonts/
|
||||||
|
|
||||||
fonts:
|
fonts:
|
||||||
- family: Roboto
|
- family: Roboto
|
||||||
|
|||||||
Reference in New Issue
Block a user