non hmg mark attendance module added.

design_3.0_latest
Sikander Saleem 11 months ago
parent 561881c7f2
commit ef38c3d2bd

Binary file not shown.

@ -0,0 +1,420 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
// import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_api_availability/google_api_availability.dart';
// import 'package:mohem_flutter_app/app_state/app_state.dart';
// import 'package:mohem_flutter_app/classes/colors.dart';
// import 'package:mohem_flutter_app/config/routes.dart';
// import 'package:mohem_flutter_app/exceptions/api_exception.dart';
// import 'package:mohem_flutter_app/extensions/int_extensions.dart';
// import 'package:mohem_flutter_app/extensions/string_extensions.dart';
// import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
// import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
// import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
// import 'package:mohem_flutter_app/widgets/loading_dialog.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager/platform_tags.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/views/widgets/dialogs/confirm_dialog.dart';
// ignore_for_file: avoid_annotating_with_dynamic
class Utils {
static bool _isLoadingVisible = false;
static bool get isLoading => _isLoadingVisible;
static void showToast(String message, {bool longDuration = true}) {
Fluttertoast.showToast(
msg: message,
toastLength: longDuration ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.black54,
textColor: Colors.white,
fontSize: 13.0);
}
static dynamic getNotNullValue(List<dynamic> list, int index) {
try {
return list[index];
} catch (ex) {
return null;
}
}
static int stringToHex(String colorCode) {
try {
return int.parse(colorCode.replaceAll("#", "0xff"));
} catch (ex) {
return (0xff000000);
}
}
static Future delay(int millis) async {
return await Future.delayed(Duration(milliseconds: millis));
}
static void showLoading(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_isLoadingVisible = true;
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
showDialog(
context: context,
barrierColor: Colors.black.withOpacity(0.5),
useRootNavigator: false,
builder: (BuildContext context) => const AppLazyLoading(),
).then((value) {
_isLoadingVisible = false;
});
});
}
static void hideLoading(BuildContext context) {
if (_isLoadingVisible) {
_isLoadingVisible = false;
Navigator.of(context).pop();
}
_isLoadingVisible = false;
}
static Future<String> getStringFromPrefs(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString(key) ?? "";
}
static Future<bool> removeStringFromPrefs(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.remove(key);
}
static Future<bool> saveStringFromPrefs(String key, String value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setString(key, value);
}
// static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
// String errorMessage;
// if (exception.error.errorType != null && exception.error.errorType == 4) {
// Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.appUpdateScreen, (_) => false, arguments: exception.error?.errorMessage);
// } else {
// if (exception is APIException) {
// if (exception.message == APIException.UNAUTHORIZED) {
// return;
// } else {
// errorMessage = exception.error?.errorMessage ?? exception.message;
// }
// } else {
// errorMessage = APIException.UNKNOWN;
// }
// if (onErrorMessage != null) {
// onErrorMessage(errorMessage);
// } else {
// if (!AppState().isAuthenticated) {
// showDialog(
// barrierDismissible: false,
// context: cxt,
// builder: (cxt) => ConfirmDialog(
// message: errorMessage,
// onTap: () {
// Navigator.pushNamedAndRemoveUntil(cxt, AppRoutes.login, (Route<dynamic> route) => false);
// },
// onCloseTap: () {},
// ),
// );
// } else {
// if (cxt != null) {
// confirmDialog(cxt, errorMessage);
// } else {
// showToast(errorMessage);
// }
// }
// }
// }
// }
//
// static Future showErrorDialog({required BuildContext context, required VoidCallback onOkTapped, required String message}) async {
// return showDialog(
// context: context,
// builder: (BuildContext context) => ConfirmDialog(
// message: message,
// onTap: onOkTapped,
// ),
// );
// }
//
static void confirmDialog(cxt, String message, {VoidCallback? onTap}) {
showDialog(
context: cxt,
builder: (BuildContext cxt) => ConfirmDialog(
message: message,
onTap: onTap,
),
);
}
//
// static Widget getNoDataWidget(BuildContext context) {
// return Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0),
// LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15),
// ],
// ).center;
// }
//
// static Widget getNoChatWidget(BuildContext context) {
// return Column(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// SvgPicture.asset('assets/images/not_found.svg', width: 110.0, height: 110.0),
// LocaleKeys.noDataAvailable.tr().toText16().paddingOnly(top: 15),
// ],
// ).center;
// }
//
// static Uint8List getPostBytes(img) {
// try {
// var b64 = img.replaceFirst('data:image/png;base64,', '');
// if (img != null && Utils.isBase64(b64)) return Utils.dataFromBase64String(b64);
// } catch (e) {}
// return Uint8List.fromList([]);
// }
//
// static String getBase64FromJpeg(img) {
// try {
// var b64 = img.replaceFirst('data:image/jpeg;base64,', '');
// return b64;
// } catch (e) {}
// return "";
// }
//
// static bool isBase64(String str) {
// RegExp _base64 = RegExp(r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$');
// return _base64.hasMatch(str);
// }
//
// static Uint8List dataFromBase64String(String base64String) {
// return base64Decode(base64String);
// }
//
// static Widget tableColumnTitle(String? text, {bool showDivider = true, bool alignCenter = false}) {
// text ??= "";
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// 6.height,
// alignCenter ? text.toText12().center : text.toText12(),
// 5.height,
// if (showDivider)
// const Divider(
// height: 1,
// color: Color(0xff2E303A),
// thickness: 1,
// )
// ],
// );
// }
//
// static Decoration containerRadius(Color background, double radius) {
// return BoxDecoration(
// color: background,
// border: Border.all(
// width: 1, //
// color: background // <--- border width here
// ),
// borderRadius: BorderRadius.circular(radius),
// );
// }
//
// static Widget mHeight(double h) {
// return Container(
// height: h,
// );
// }
//
// static Widget mDivider(Color color) {
// return Divider(
// // width: double.infinity,
// height: 1,
// color: color,
// );
// }
//
// static Widget tableColumnValue(String text, {bool isCapitable = true, bool alignCenter = false}) {
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// 12.height,
// if (alignCenter)
// (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor).center
// else
// (isCapitable ? text.toLowerCase().capitalizeFirstofEach : text).toText12(color: MyColors.normalTextColor),
// 12.height,
// ],
// );
// }
//
// /// EIT Forms date formats
//
// static String getMonthNamedFormat(DateTime date) {
// /// it will return like "29-Sep-2022"
// return DateFormat('dd-MMM-yyyy', "en_US").format(date);
// }
//
// static String reverseFormatDate(String date) {
// String formattedDate;
// if (date.isNotEmpty) {
// formattedDate = date.replaceAll('/', '-');
// formattedDate = formattedDate.replaceAll(' 00:00:00', '');
// } else {
// formattedDate = date;
// }
// return formattedDate;
// }
//
// static String formatStandardDate(String date) {
// String formattedDate;
// if (date.isNotEmpty) {
// formattedDate = date.replaceAll('-', '/');
// } else {
// formattedDate = date;
// }
// return formattedDate;
// }
//
// static String reverseFormatStandardDate(String date) {
// String formattedDate;
// if (date.isNotEmpty) {
// formattedDate = date.replaceAll('/', '-');
// } else {
// formattedDate = date;
// }
// return formattedDate;
// }
//
// static String formatDate(String date) {
// String formattedDate;
//
// if (date.isNotEmpty) {
// date = date.substring(0, 10);
// formattedDate = date.replaceAll('-', '/');
// formattedDate = formattedDate + ' 00:00:00';
// } else {
// formattedDate = date;
// }
// return formattedDate;
// }
//
// static String formatDateNew(String date) {
// String formattedDate;
// if (date.isNotEmpty) {
// formattedDate = date.split('T')[0];
// if (!formattedDate.contains("00:00:00")) {
// formattedDate = formattedDate + ' 00:00:00';
// }
// } else {
// formattedDate = date;
// }
// return formattedDate;
// }
//
// static String formatDateDefault(String date) {
// if (date.isNotEmpty) {
// if (date.toLowerCase().contains("t")) {
// date = date.toLowerCase().split("t")[0];
// if (!date.contains("00:00:00")) {
// date = date + ' 00:00:00';
// }
// return date;
// } else {
// if (date.toLowerCase().split("-")[1].length == 3) {
// return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('dd-MMM-yyyy', "en_US").parseLoose(date));
// } else {
// return DateFormat('dd-MM-yyyy', "en_US").format(DateFormat('yyyy-MM-dd', "en_US").parseLoose(date));
// }
// // return DateFormat('yyyy-MM-dd').format(DateFormat('dd-MM-yyyy').parseLoose(date));
// }
// } else {
// return date;
// }
// }
//
// static Future<DateTime> selectDate(BuildContext context, DateTime selectedDate) async {
// if (!Platform.isIOS) {
// await showCupertinoModalPopup(
// context: context,
// builder: (BuildContext cxt) => Container(
// height: 250,
// color: Colors.white,
// child: CupertinoDatePicker(
// backgroundColor: Colors.white,
// mode: CupertinoDatePickerMode.date,
// onDateTimeChanged: (DateTime value) {
// if (value != null && value != selectedDate) {
// selectedDate = value;
// }
// },
// initialDateTime: selectedDate,
// ),
// ),
// );
// } else {
// DateTime? picked = await showDatePicker(context: context, initialDate: selectedDate, initialEntryMode: DatePickerEntryMode.calendarOnly, firstDate: DateTime(2015, 8), lastDate: DateTime(2101));
// if (picked != null && picked != selectedDate) {
// selectedDate = picked;
// }
// }
// return selectedDate;
// }
static void readNFc({required Function(String) onRead}) {
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
MifareUltralight f;
if (Platform.isAndroid) {
f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
} else {
f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
}
String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
NfcManager.instance.stopSession();
onRead(identifier);
}).catchError((err) {
print(err);
});
}
//HUAWEI DECISION MAKING
static Future<bool> isGoogleServicesAvailable() async {
GooglePlayServicesAvailability availability = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
String status = availability.toString().split('.').last;
if (status == "success") {
return true;
}
return false;
}
//
// static bool isDate(String input, String format) {
// try {
// DateTime d = DateFormat(format).parseStrict(input);
// //print(d);
// return true;
// } catch (e) {
// //print(e);
// return false;
// }
// }
}

@ -15,6 +15,7 @@ import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/pages/land_page/create_request-type_bottomsheet.dart';
import 'package:test_sa/new_views/pages/land_page/mark_attendance_widget.dart';
import 'package:test_sa/new_views/pages/land_page/my_request/my_requests_page.dart';
import 'package:test_sa/new_views/pages/land_page/non_hmg_employee_swipe_view.dart';
import 'package:test_sa/new_views/pages/settings_page.dart';
@ -143,7 +144,7 @@ class _LandPageState extends State<LandPage> {
))
: null,
drawer: const AppDrawer(),
body: _pages.isEmpty ? NonHmgEmployeeSwipeView() : _pages[currentPageIndex],
body: _pages.isEmpty ? MarkAttendanceWidget() : _pages[currentPageIndex],
bottomNavigationBar: _pages.isEmpty
? null
: AppBottomNavigationBar(

@ -0,0 +1,677 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:geolocator/geolocator.dart';
import 'package:huawei_location/huawei_location.dart';
// import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart';
// import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:permission_handler/permission_handler.dart';
// import 'package:platform_device_id/platform_device_id.dart';
import 'package:test_sa/dashboard_latest/widgets/app_bar_widget.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/helper/utils.dart';
import 'package:test_sa/nfc/nfc_reader_sheet.dart';
// import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
// import 'package:mohem_flutter_app/app_state/app_state.dart';
// import 'package:mohem_flutter_app/classes/colors.dart';
// import 'package:mohem_flutter_app/classes/utils.dart';
// import 'package:mohem_flutter_app/extensions/string_extensions.dart';
// import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
// import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
// import 'package:mohem_flutter_app/models/generic_response_model.dart';
// import 'package:mohem_flutter_app/models/privilege_list_model.dart';
// import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
// import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart';
// import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
// import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart';im
import 'package:test_sa/utilities/Location.dart' as location;
import 'package:test_sa/views/widgets/dialogs/confirm_dialog.dart';
import 'package:test_sa/views/widgets/dialogs/success_dialog.dart';
import 'package:test_sa/views/widgets/qr_scanner_dialog.dart';
import 'package:wifi_iot/wifi_iot.dart';
import '../../app_style/app_color.dart';
class MarkAttendanceWidget extends StatefulWidget {
// DashboardProviderModel model;
double topPadding;
bool isFromDashboard;
MarkAttendanceWidget( {Key? key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key);
// todo MarkAttendanceWidget(this.model, {Key? key, this.topPadding = 0, this.isFromDashboard = false}) : super(key: key);
@override
_MarkAttendanceWidgetState createState() {
return _MarkAttendanceWidgetState();
}
}
class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false;
int _locationUpdateCbId = 0;
@override
void initState() {
super.initState();
checkAttendanceAvailability();
}
void checkAttendanceAvailability() async {
bool isAvailable = await NfcManager.instance.isAvailable();
// setState(() {
// AppState().privilegeListModel!.forEach((PrivilegeListModel element) {
// if (element.serviceName == "enableNFC") {
// if (isAvailable) if (element.previlege ?? false) isNfcEnabled = true;
// } else if (element.serviceName == "enableQR") {
// if (element.previlege ?? false) isQrEnabled = true;
// } else if (element.serviceName == "enableWIFI") {
// if (element.previlege ?? false) isWifiEnabled = true;
// } else if (element.serviceName!.trim() == "enableLocationNFC") {
// if (element.previlege ?? false) isNfcLocationEnabled = true;
// } else if (element.serviceName == "enableLocationQR") {
// if (element.previlege ?? false) isQrLocationEnabled = true;
// } else if (element.serviceName == "enableLocationWIFI") {
// if (element.previlege ?? false) isWifiLocationEnabled = true;
// }
// });
// });
}
void checkHuaweiLocationPermission(String attendanceType) async {
// Permission_Handler permissionHandler = PermissionHandler();
location.Location.isEnabled((bool isEnabled) async {
if (isEnabled) {
location.Location.havePermission((bool permission) async {
if (permission) {
getHuaweiCurrentLocation(attendanceType);
} else {
bool has = await requestPermissions();
if (has) {
getHuaweiCurrentLocation(attendanceType);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () {
Navigator.pop(context);
},
),
);
}
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
// if (await permissionHandler.hasLocationPermission()) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// bool has = await requestPermissions();
// if (has) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "You need to give location permission to mark attendance",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// }
// }
}
Future<bool> requestPermissions() async {
var result = await [
Permission.location,
].request();
return (result[Permission.location] == PermissionStatus.granted || result[Permission.locationAlways] == PermissionStatus.granted);
}
@override
void dispose() {
super.dispose();
// Stop Session
NfcManager.instance.stopSession();
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 21, right: 21, bottom: 21, top: widget.topPadding),
decoration: const BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
// LocaleKeys.markAttendance.tr().toSectionHeading(),
// LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)),
GridView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: const EdgeInsets.only(bottom: 0, top: 21),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
children: <Widget>[
attendanceMethod("NFC", Icons.nfc, isNfcEnabled, () {
// if (AppState().getIsHuawei) {
if (false) {
checkHuaweiLocationPermission("NFC");
} else {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
Utils.showLoading(context);
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
Utils.hideLoading(context);
markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
Utils.hideLoading(context);
//todo performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
() {
Utils.hideLoading(context);
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
}
}),
//if (isWifiEnabled) //todo
attendanceMethod("Wifi", Icons.wifi, isWifiEnabled, () {
// if (AppState().getIsHuawei) {
if (false) {
checkHuaweiLocationPermission("WIFI");
} else {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
Utils.showLoading(context);
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
Utils.hideLoading(context);
markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
Utils.hideLoading(context);
//todo performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
() {
Utils.hideLoading(context);
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
}
}),
// if (isQrEnabled) //todo
attendanceMethod("QR", Icons.qr_code_2, isQrEnabled, () async {
// if (AppState().getIsHuawei) {
if (false) {
checkHuaweiLocationPermission("QR");
} else {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
Utils.showLoading(context);
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
Utils.hideLoading(context);
markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
Utils.hideLoading(context);
//todo performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
() {
Utils.hideLoading(context);
Utils.confirmDialog(context, "Unable to determine your location, Please make sure that your location services are turned on & working.");
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
}
}),
],
)
],
),
);
}
void getHuaweiCurrentLocation(String attendanceType) async {
try {
Utils.showLoading(context);
FusedLocationProviderClient locationService = FusedLocationProviderClient()..initFusedLocationService();
LocationRequest locationRequest = LocationRequest();
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
locationRequest.interval = 500;
List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest];
LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList);
late StreamSubscription<Location> _streamSubscription;
int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!;
_streamSubscription = locationService.onLocationData!.listen(
(Location location) async {
Utils.hideLoading(context);
await locationService.removeLocationUpdates(requestCode);
if (attendanceType == "QR") {
// todo performQrCodeAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
if (attendanceType == "WIFI") {
// todo performWifiAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
if (attendanceType == "NFC") {
//todo performNfcAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
requestCode = 0;
},
);
// locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
// await locationService.getLastLocation().then((value) {
// if (value.latitude == null || value.longitude == null) {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "Unable to get your location, Please check your location settings & try again.",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// } else {
// if (attendanceType == "QR") {
// performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "WIFI") {
// performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "NFC") {
// performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// }
// }).catchError((error) {
// print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
// print(error);
// });
// }).catchError((error) {
// print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
// print(error);
// if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
// // Location service not enabled.
// }
// });
} catch (error) {
print("HUAWEI LOCATION ERROR!!!!!");
print(error);
Utils.hideLoading(context);
// Utils.handleException(error, context, null);
}
}
//
// Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
// if (Platform.isIOS) {
// Utils.readNFc(onRead: (String nfcId) async {
// Utils.showLoading(context);
// try {
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId, isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
// if (g?.messageStatus != 1) {
// Utils.hideLoading(context);
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: g?.errorEndUserMessage ?? "Unexpected error occurred",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// } else {
// bool status = await model.fetchAttendanceTracking(context);
// if (Platform.isIOS) await Future.delayed(const Duration(seconds: 3));
// Utils.hideLoading(context);
// showMDialog(
// context,
// backgroundColor: Colors.transparent,
// isDismissable: true,
// child: SuccessDialog(widget.isFromDashboard),
// );
// }
// } catch (ex) {
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// }
// });
// } else {
// showNfcReader(context, onNcfScan: (String? nfcId) async {
// Utils.showLoading(context);
// try {
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
// if (g?.messageStatus != 1) {
// Utils.hideLoading(context);
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: g?.errorEndUserMessage ?? "Unexpected error occurred",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// } else {
// bool status = await model.fetchAttendanceTracking(context);
// Utils.hideLoading(context);
// showMDialog(
// context,
// backgroundColor: Colors.transparent,
// isDismissable: false,
// child: SuccessDialog(widget.isFromDashboard),
// );
// }
// } catch (ex) {
// print(ex);
// Utils.hideLoading(context);
// // Utils.handleException(ex, context, (String msg) {
// // Utils.confirmDialog(context, msg);
// // });
// }
// });
// }
// }
void showMDialog(context, {Widget? child, Color? backgroundColor, bool isDismissable = true, bool isBusniessCard = false}) async {
return showDialog(
context: context,
barrierDismissible: isDismissable,
builder: (context) {
return Dialog(
shape: isBusniessCard
? const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0),
),
)
: null,
backgroundColor: backgroundColor,
child: child,
);
},
);
}
//
// Future<bool> checkSession() async {
// try {
// Utils.showLoading(context);
// await DashboardApiClient().getOpenMissingSwipes();
// Utils.hideLoading(context);
// return true;
// } catch (ex) {
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// return false;
// }
// }
// Future<void> performWifiAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
// if (Platform.isAndroid) {
// if (!(await checkSession())) {
// return;
// }
// }
// Utils.showLoading(context);
// bool isConnected = await WiFiForIoTPlugin.connect(AppState().getMohemmWifiSSID ?? "",
// password: AppState().getMohemmWifiPassword ?? "", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false);
//
// if (Platform.isIOS) {
// if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) {
// isConnected = true;
// } else {
// isConnected = false;
// }
// }
//
// if (isConnected && AppState().isAuthenticated) {
// await WiFiForIoTPlugin.forceWifiUsage(true);
// await Future.delayed(const Duration(seconds: 6));
// try {
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 3, nfcValue: "", isGpsRequired: isWifiLocationEnabled, lat: lat, long: lng);
// bool status = await model.fetchAttendanceTracking(context);
// Utils.hideLoading(context);
// await closeWifiRequest();
// if (g?.messageStatus == 2) {
// showDialog(
// barrierDismissible: true,
// context: context,
// builder: (cxt) => ConfirmDialog(
// message: g?.errorEndUserMessage ?? "",
// onTap: () {
// Navigator.pop(context);
// },
// onCloseTap: () {},
// ),
// );
// } else {
// showMDialog(
// context,
// backgroundColor: Colors.transparent,
// isDismissable: false,
// child: SuccessDialog(widget.isFromDashboard),
// );
// }
// } catch (ex) {
// await closeWifiRequest();
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// }
// } else {
// if (AppState().isAuthenticated) {
// Utils.hideLoading(context);
// Utils.confirmDialog(context, "LocaleKeys.comeNearHMGWifi.tr()");
// } else {
// await closeWifiRequest();
// }
// }
// }
Future<bool> closeWifiRequest() async {
if (Platform.isAndroid) {
await WiFiForIoTPlugin.forceWifiUsage(false);
}
return await WiFiForIoTPlugin.disconnect();
}
// Future<void> performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
// var qrCodeValue = await Navigator.of(context).push(
// MaterialPageRoute(
// builder: (BuildContext context) => QrScannerDialog(),
// ),
// );
// if (qrCodeValue != null) {
// Utils.showLoading(context);
// try {
// GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 1, isGpsRequired: isQrLocationEnabled, lat: lat, long: lng, QRValue: qrCodeValue);
// bool status = await model.fetchAttendanceTracking(context);
// Utils.hideLoading(context);
// if (g?.messageStatus == 2) {
// showDialog(
// barrierDismissible: true,
// context: context,
// builder: (cxt) => ConfirmDialog(
// message: g?.errorEndUserMessage ?? "",
// onTap: () {
// Navigator.pop(context);
// },
// onCloseTap: () {},
// ),
// );
// } else {
// showMDialog(
// context,
// backgroundColor: Colors.transparent,
// isDismissable: true,
// child: SuccessDialog(widget.isFromDashboard),
// );
// }
// } catch (ex) {
// print(ex);
// Utils.hideLoading(context);
// Utils.handleException(ex, context, null);
// }
// }
// }
void markFakeAttendance(String sourceName, String lat, String long) async {
Utils.showLoading(context);
try {
// await DashboardApiClient().markFakeLocation(sourceName: sourceName, lat: lat, long: long);
Utils.hideLoading(context);
Utils.confirmDialog(context, "LocaleKeys.fakeLocation.tr()");
} catch (ex) {
print(ex);
Utils.hideLoading(context);
//Utils.handleException(ex, context, null);
}
}
Widget attendanceMethod(String title, IconData iconData, bool isEnabled, VoidCallback onPress) => Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: isEnabled ? null : Colors.grey.withOpacity(.5),
gradient: isEnabled
? const LinearGradient(
transform: GradientRotation(.64),
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
//MyColors.gradiantEndColor,
// MyColors.gradiantStartColor,
],
)
: null,
),
clipBehavior: Clip.antiAlias,
padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// SvgPicture.asset(image, color: Colors.white, alignment: Alignment.topLeft).expanded,
Icon(iconData, color: isEnabled ? AppColor.black35 : Colors.grey),
title.heading6(context),
// title.toText17(isBold: true, color: Colors.white),
],
),
).onPress(
() {
if (!isEnabled) return;
onPress();
},
);
}

@ -0,0 +1,199 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:nfc_manager/nfc_manager.dart';
import 'package:nfc_manager/platform_tags.dart';
void showNfcReader(BuildContext context, {required Function(String? nfcId) onNcfScan}) {
showModalBottomSheet(
context: context,
enableDrag: false,
isDismissible: false,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
),
backgroundColor: Colors.white,
builder: (context) {
return NfcLayout(
onNcfScan: onNcfScan,
);
},
);
}
class NfcLayout extends StatefulWidget {
Function(String? nfcId) onNcfScan;
NfcLayout({required this.onNcfScan});
@override
_NfcLayoutState createState() => _NfcLayoutState();
}
class _NfcLayoutState extends State<NfcLayout> {
bool _reading = false;
Widget? mainWidget;
String? nfcId;
@override
void initState() {
super.initState();
NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
var f;
if (Platform.isAndroid) {
f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
} else {
f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22);
}
String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join('');
nfcId = identifier;
setState(() {
_reading = true;
mainWidget = doneNfc();
});
Future.delayed(const Duration(seconds: 1), () {
NfcManager.instance.stopSession();
Navigator.pop(context);
// if (Platform.isAndroid) {
// Navigator.pop(context);
// } else {
// Navigator.pop(context);
// Navigator.pop(context);
// }
widget.onNcfScan(nfcId);
});
}).catchError((err) {
print(err);
});
}
@override
Widget build(BuildContext context) {
(mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc();
return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget);
}
Widget scanNfc() {
return Container(
key: ValueKey(1),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 30,
),
Text(
"Ready To Scan",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
SizedBox(
height: 30,
),
Image.asset(
"assets/icons/nfc/ic_nfc.png",
height: MediaQuery.of(context).size.width / 3,
),
SizedBox(
height: 30,
),
Text(
"Approach an NFC Tag",
style: TextStyle(
fontSize: 18,
),
),
SizedBox(
height: 30,
),
ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.2,
height: 45.0,
buttonColor: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: TextButton(
onPressed: () {
NfcManager.instance.stopSession();
Navigator.pop(context);
},
// elevation: 0,
child: Text("CANCEL"),
),
),
SizedBox(
height: 30,
),
],
),
);
}
Widget doneNfc() {
return Container(
key: ValueKey(2),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: 30,
),
Text(
"Successfully Scanned",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
SizedBox(
height: 30,
),
Image.asset(
"assets/icons/nfc/ic_done.png",
height: MediaQuery.of(context).size.width / 3,
),
SizedBox(
height: 30,
),
Text(
"Approach an NFC Tag",
style: TextStyle(
fontSize: 18,
),
),
SizedBox(
height: 30,
),
ButtonTheme(
minWidth: MediaQuery.of(context).size.width / 1.2,
height: 45.0,
buttonColor: Colors.grey[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: TextButton(
// onPressed: () {
// _stream?.cancel();
// widget.onNcfScan(nfcId);
// Navigator.pop(context);
// },
onPressed: null,
// elevation: 0,
child: Text("DONE"),
),
),
SizedBox(
height: 30,
),
],
),
);
}
}

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
class ConfirmDialog extends StatelessWidget {
final String? title;
final String message;
final String? okTitle;
final VoidCallback? onTap;
final VoidCallback? onCloseTap;
const ConfirmDialog({Key? key, this.title, required this.message, this.okTitle, this.onTap, this.onCloseTap}) : super(key: key);
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(),
insetPadding: const EdgeInsets.only(left: 21, right: 21),
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 18, bottom: 28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
title ?? "Confirm",
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black87, height: 35 / 24, letterSpacing: -0.96),
).paddingOnly(top: 16),
),
IconButton(
padding: EdgeInsets.zero,
icon: const Icon(Icons.close),
color: Colors.black87,
constraints: const BoxConstraints(),
onPressed: () => onCloseTap ?? Navigator.pop(context),
// onPressed: () => Navigator.pop(context),
)
],
),
message.bodyText(context),
28.height,
AppFilledButton(
label: okTitle ?? "OK",
onPressed: onTap ?? () => Navigator.pop(context),
textColor: Colors.white,
//color: Ap.green,
),
],
),
),
);
}
}

@ -0,0 +1,75 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
import 'package:lottie/lottie.dart';
class SuccessDialog extends StatefulWidget {
bool isFromDashboard;
SuccessDialog(this.isFromDashboard);
@override
State<SuccessDialog> createState() => _SuccessDialogState();
}
class _SuccessDialogState extends State<SuccessDialog> with TickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
_controller = AnimationController(vsync: this);
super.initState();
}
Future<void> playSuccessSound() async {
AudioPlayer player = AudioPlayer();
String audioAsset = "";
if (Platform.isAndroid) {
audioAsset = "assets/audio/success_tone_android.mp3";
} else {
audioAsset = "assets/audio/success_tone_ios.caf";
}
await player.setAsset(audioAsset);
await player.load();
player.play();
}
@override
Widget build(BuildContext context) {
double size = MediaQuery.of(context).size.width / 1.8;
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: size,
height: size,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
child: Lottie.asset(
'assets/lottie/lt_success.json',
repeat: false,
reverse: false,
controller: _controller,
frameRate: FrameRate(60.0),
onLoaded: (LottieComposition v) async {
await playSuccessSound();
_controller
..duration = v.duration
..forward().whenComplete(() async {
Navigator.pop(context);
if (widget.isFromDashboard) Navigator.pop(context);
});
},
),
),
),
],
);
}
}

@ -0,0 +1,79 @@
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
class QrScannerDialog extends StatefulWidget {
@override
State<QrScannerDialog> createState() => _QrScannerDialogState();
}
class _QrScannerDialogState extends State<QrScannerDialog> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
bool isPicked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.white,
child: Column(
children: [
Expanded(
flex: 1,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
// Expanded(
// flex: 1,
// child: Center(
// child: (result != null)
// ? Text(
// 'Barcode Type: ${result!.format} Data: ${result!.code}')
// : Text('Scan a code'),
// ),
// ),
Padding(
padding: const EdgeInsets.all(12.0),
child: AppFilledButton(
label: "LocaleKeys.cancel.tr()",
onPressed: () {
Navigator.pop(context);
},
),
),
],
),
),
);
}
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
if (!isPicked) {
isPicked = true;
Navigator.pop(context, result!.code);
}
});
});
controller.pauseCamera();
controller.resumeCamera();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}

@ -41,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
audio_session:
dependency: transitive
description:
name: audio_session
sha256: b2a26ba8b7efa1790d6460e82971fde3e398cfbe2295df9dea22f3499d2c12a7
url: "https://pub.dev"
source: hosted
version: "0.1.23"
audioplayers:
dependency: "direct main"
description:
@ -813,6 +821,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.9.0"
just_audio:
dependency: "direct main"
description:
name: just_audio
sha256: a49e7120b95600bd357f37a2bb04cd1e88252f7cdea8f3368803779b925b1049
url: "https://pub.dev"
source: hosted
version: "0.9.42"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
url: "https://pub.dev"
source: hosted
version: "4.3.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
sha256: "9a98035b8b24b40749507687520ec5ab404e291d2b0937823ff45d92cb18d448"
url: "https://pub.dev"
source: hosted
version: "0.4.13"
leak_tracker:
dependency: transitive
description:
@ -1642,6 +1674,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
wifi_iot:
dependency: "direct main"
description:
name: wifi_iot
sha256: "4a3301f71663a908bb50ffe6d9dc9e8b8383fab48368accf978409bde96e9aca"
url: "https://pub.dev"
source: hosted
version: "0.3.19+1"
win32:
dependency: "direct overridden"
description:

@ -90,6 +90,8 @@ dependencies:
huawei_location: ^6.11.0+301
geolocator: ^9.0.2
nfc_manager: ^3.2.0
wifi_iot: ^0.3.19+1
just_audio: ^0.9.30
local_auth_darwin: any
dev_dependencies:
@ -120,6 +122,7 @@ flutter:
uses-material-design: true
assets:
- assets/
- assets/audio/
- assets/images/
- assets/lottie/
- assets/subtitles/

Loading…
Cancel
Save