diff --git a/android/app/build.gradle b/android/app/build.gradle index 596d981..a3de0ed 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -27,7 +27,7 @@ apply plugin: 'com.google.gms.google-services' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 31 + compileSdkVersion 32 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -46,7 +46,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "hmg.cloudSolutions.mohem" minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 32 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d44cea3..dd9a8de 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/logos/bn_cloud_soloution.jpg b/assets/images/logos/bn_cloud_soloution.jpg new file mode 100644 index 0000000..844bc43 Binary files /dev/null and b/assets/images/logos/bn_cloud_soloution.jpg differ diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 60f956f..d3ac0ba 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -301,10 +301,11 @@ "requestName":"اسم الطلب", "createdFor":"انشاء لأجل", "requestCreatedSuccessfully": "تم انشاء الطلب بنجاح", - "search": "Search", + "search": "بحث", "wantToReject": "هل انت متأكد تريد الرفض", - "Reject": "رفض", "requestType":"نوع الطلب", + "employeeDigitalID":"هويةالموظف الرقمية", + "businessCard": "بطاقة العمل", "profile": { "reset_password": { "label": "Reset Password", diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index 59f3bf4..838d20f 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -304,7 +304,8 @@ "requestCreatedSuccessfully": "Request created successfully", "search": "Search", "wantToReject": "Are you sure want to reject?", - "reject": "Reject", + "employeeDigitalID":"Employee Digital ID", + "businessCard": "Business Card", "profile": { "reset_password": { "label": "Reset Password", diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 215af90..1dd58b1 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -88,7 +88,7 @@ class DashboardApiClient { } //Mark Attendance - Future markAttendance({String lat = "0", String? long = "0", required int pointType, String nfcValue = "", bool isGpsRequired = false}) async { + Future markAttendance({String lat = "0", String? long = "0", required int pointType, String nfcValue = "", bool isGpsRequired = false, String QRValue = ""}) async { String url = "${ApiConsts.swpRest}AuthenticateAndSwipeUserSupportNFC"; var uuid = Uuid(); // Generate a v4 (random) id @@ -97,7 +97,7 @@ class DashboardApiClient { "UID": uuid.v4(), //Mobile Id "Latitude": lat, "Longitude": long, - "QRValue": "", + "QRValue": QRValue, "PointType": pointType, // NFC=2, Wifi = 3, QR= 1, "NFCValue": nfcValue, "WifiValue": pointType == 3 ? "100" : "", diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index 9fc4efe..5b433e7 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -317,10 +317,11 @@ class CodegenLoader extends AssetLoader{ "requestName": "اسم الطلب", "createdFor": "انشاء لأجل", "requestCreatedSuccessfully": "تم انشاء الطلب بنجاح", - "search": "Search", + "search": "بحث", "wantToReject": "هل انت متأكد تريد الرفض", - "Reject": "رفض", "requestType": "نوع الطلب", + "employeeDigitalID": "هويةالموظف الرقمية", + "businessCard": "بطاقة العمل", "profile": { "reset_password": { "label": "Reset Password", @@ -658,6 +659,8 @@ static const Map en_US = { "requestCreatedSuccessfully": "Request created successfully", "search": "Search", "wantToReject": "Are you sure want to reject?", + "employeeDigitalID": "Employee Digital ID", + "businessCard": "Business Card", "profile": { "reset_password": { "label": "Reset Password", diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 8b9f42a..6ff58d6 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -304,8 +304,9 @@ abstract class LocaleKeys { static const requestCreatedSuccessfully = 'requestCreatedSuccessfully'; static const search = 'search'; static const wantToReject = 'wantToReject'; - static const Reject = 'Reject'; static const requestType = 'requestType'; + static const employeeDigitalID = 'employeeDigitalID'; + static const businessCard = 'businessCard'; static const profile_reset_password_label = 'profile.reset_password.label'; static const profile_reset_password_username = 'profile.reset_password.username'; static const profile_reset_password_password = 'profile.reset_password.password'; diff --git a/lib/ui/dialogs/id/business_card_dialog.dart b/lib/ui/dialogs/id/business_card_dialog.dart new file mode 100644 index 0000000..3488958 --- /dev/null +++ b/lib/ui/dialogs/id/business_card_dialog.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; + +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/classes/utils.dart'; + +class BusinessCardDialog extends StatelessWidget { + @override + Widget build(BuildContext context) { + return RotatedBox( + quarterTurns: 1, + child: Container( + width: MediaQuery.of(context).size.height / 2, + color: Colors.white, + margin: EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Image.asset( + "assets/images/logos/bn_cloud_soloution.jpg", + width: 80, + height: 80, + ), + 12.height, + (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText20(), + ], + ), + ), + Image.memory( + Utils.getPostBytes(AppState().memberInformationList!.businessCardQR ?? ""), + width: 100, + height: 100, + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + 1.height, + (AppState().memberInformationList!.pOSITIONNAME ?? "").toText12(isBold: false), + 12.height, + (AppState().memberInformationList!.eMPLOYEENUMBER ?? "").toText12(isBold: false), + 1.height, + (AppState().memberInformationList!.eMPLOYEEEMAILADDRESS ?? "").toText12(isBold: false), + 1.height, + (AppState().memberInformationList!.jOBNAME ?? "").toText12(isBold: false), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/ui/dialogs/id/employee_digital_id_dialog.dart b/lib/ui/dialogs/id/employee_digital_id_dialog.dart new file mode 100644 index 0000000..e0e1054 --- /dev/null +++ b/lib/ui/dialogs/id/employee_digital_id_dialog.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +import 'package:mohem_flutter_app/classes/utils.dart'; +import 'package:mohem_flutter_app/main.dart'; + +class EmployeeDigitialIdDialog extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset("assets/images/bn_logo.png"), + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Container( + width: 80, + height: 80, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(12)), + boxShadow: [BoxShadow(color: Colors.white60, blurRadius: 10, spreadRadius: 10)], + ), + clipBehavior: Clip.antiAlias, + child: Image.memory( + Utils.getPostBytes( + AppState().memberInformationList!.eMPLOYEEIMAGE ?? "", + ), + fit: BoxFit.cover, + ), + ), + 16.width, + (AppState().memberInformationList!.eMPLOYEENUMBER ?? "").toText20(), + ], + ), + Container( + width: double.infinity, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + 12.height, + (AppState().memberInformationList!.eMPLOYEENAME ?? "").toText16(), + 4.height, + (AppState().memberInformationList!.pOSITIONNAME ?? "").toText12(isBold: false), + ], + ), + ), + Image.memory( + Utils.getPostBytes(AppState().memberInformationList!.employeeQR ?? ""), + width: 160, + height: 160, + ), + DefaultButton("Cancel", () { + Navigator.pop(context); + }) + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 74688da..e957f29 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -29,6 +29,7 @@ class DashboardScreen extends StatefulWidget { class _DashboardScreenState extends State { late DashboardProviderModel data; final GlobalKey _scaffoldState = GlobalKey(); + @override void initState() { super.initState(); diff --git a/lib/ui/landing/today_attendance_screen.dart b/lib/ui/landing/today_attendance_screen.dart index 4b5332e..fcc4adb 100644 --- a/lib/ui/landing/today_attendance_screen.dart +++ b/lib/ui/landing/today_attendance_screen.dart @@ -1,5 +1,6 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; @@ -15,12 +16,17 @@ 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/provider/dashboard_provider_model.dart'; import 'package:mohem_flutter_app/widgets/circular_step_progress_bar.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart'; import 'package:mohem_flutter_app/widgets/location/Location.dart'; import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:provider/provider.dart'; import 'package:wifi_iot/wifi_iot.dart'; +import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; + + + class TodayAttendanceScreen extends StatefulWidget { TodayAttendanceScreen({Key? key}) : super(key: key); @@ -33,7 +39,7 @@ class TodayAttendanceScreen extends StatefulWidget { class _TodayAttendanceScreenState extends State { ValueNotifier result = ValueNotifier(null); late DashboardProviderModel data; - bool isNfcEnabled = true, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; + bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false; @override void initState() { @@ -189,25 +195,39 @@ class _TodayAttendanceScreenState extends State { padding: EdgeInsets.zero, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8), children: [ - attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - if (isNfcLocationEnabled) { - Location.getCurrentLocation((LatLng? latlng) { - performNfcAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); - }); - } else { - performNfcAttendance(model); - } - }), - attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { - if (isWifiLocationEnabled) { - Location.getCurrentLocation((LatLng? latlng) { - performWifiAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); - }); - } else { - performWifiAttendance(model); - } - // connectWifi(); - }), + if (isNfcEnabled) + attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { + if (isNfcLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performNfcAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performNfcAttendance(model); + } + }), + if (isWifiEnabled) + attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { + if (isWifiLocationEnabled) { + + Location.getCurrentLocation((LatLng? latlng) { + performWifiAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performWifiAttendance(model); + } + // connectWifi(); + }), + if (isQrEnabled) + attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { + if (isQrLocationEnabled) { + Location.getCurrentLocation((LatLng? latlng) { + performQrCodeAttendance(model, lat: latlng?.latitude.toString() ?? "", lng: latlng?.longitude.toString() ?? ""); + }); + } else { + performQrCodeAttendance(model); + } + // performQrCodeAttendance(model); + }), ], ) ], @@ -272,6 +292,7 @@ class _TodayAttendanceScreenState extends State { } else { print("wifi not location enabled"); } + bool v = await WiFiForIoTPlugin.connect(AppState().mohemmWifiSSID ?? "", password: AppState().mohemmWifiPassword ?? "", joinOnce: true, security: NetworkSecurity.WPA, withInternet: false); if (v) { await WiFiForIoTPlugin.forceWifiUsage(true); @@ -301,6 +322,29 @@ class _TodayAttendanceScreenState extends State { return v; } + Future performQrCodeAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { + var qrCodeValue = await Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => QrScannerDialog(), + ), + ); + if(qrCodeValue!=null){ + print("qrCode: " + qrCodeValue); + 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); + } catch (ex) { + print(ex); + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + } + } + Widget attendanceMethod(String title, String image, bool isEnabled, VoidCallback onPress) => Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(15), @@ -317,7 +361,11 @@ class _TodayAttendanceScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded(child: SvgPicture.asset(image)), + Expanded( + child: SvgPicture.asset( + image, + color: Colors.white, + )), title.toText17(isBold: true, color: Colors.white), ], ), diff --git a/lib/ui/landing/widget/app_drawer.dart b/lib/ui/landing/widget/app_drawer.dart index fb7421b..9bc9985 100644 --- a/lib/ui/landing/widget/app_drawer.dart +++ b/lib/ui/landing/widget/app_drawer.dart @@ -1,10 +1,14 @@ -import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:mohem_flutter_app/config/routes.dart'; -import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/ui/dialogs/id/employee_digital_id_dialog.dart'; import 'package:mohem_flutter_app/ui/landing/widget/drawer_item.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart'; +import 'package:mohem_flutter_app/ui/dialogs/id/business_card_dialog.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; + class AppDrawer extends StatefulWidget { @override _AppDrawerState createState() => _AppDrawerState(); @@ -39,25 +43,48 @@ class _AppDrawerState extends State { }), const Divider(), InkWell( - child: new DrawerItem( - // 'Mowadhafhi', - LocaleKeys.mowadhafhi.tr(), - icon: Icons.person, - color: Colors.grey, - ), - onTap: () { - drawerNavigator(context, AppRoutes.mowadhafhi); - }), + child: DrawerItem( + // 'Mowadhafhi', + LocaleKeys.mowadhafhi.tr(), + icon: Icons.person, + color: Colors.grey, + ), + onTap: () { + drawerNavigator(context, AppRoutes.mowadhafhi); + }, + ), const Divider(), InkWell( - child: const DrawerItem( - 'Pending Transactions', - icon: Icons.person, - color: Colors.grey, - ), - onTap: () { - drawerNavigator(context, AppRoutes.pendingTransactions); - }) + child: DrawerItem( + LocaleKeys.pendingTransactions.tr(), + icon: Icons.person, + color: Colors.grey, + ), + onTap: () { + drawerNavigator(context, AppRoutes.pendingTransactions); + }, + ), + InkWell( + child: DrawerItem( + LocaleKeys.employeeDigitalID.tr(), + icon: Icons.insert_drive_file_outlined, + color: Colors.grey, + ), + onTap: () { + showMDialog(context, child: EmployeeDigitialIdDialog()); + }, + ), + Divider(), + InkWell( + child: DrawerItem( + LocaleKeys.businessCard.tr(), + icon: Icons.insert_drive_file_outlined, + color: Colors.grey, + ), + onTap: () { + showMDialog(context, child: BusinessCardDialog()); + }, + ), ], ), ) diff --git a/lib/ui/landing/widget/drawer_item.dart b/lib/ui/landing/widget/drawer_item.dart index 65c3132..4654e5b 100644 --- a/lib/ui/landing/widget/drawer_item.dart +++ b/lib/ui/landing/widget/drawer_item.dart @@ -32,7 +32,7 @@ class _DrawerItemState extends State { if (widget.assetLink == null) Icon( widget.icon, - color: widget.color ?? Colors.black87, + color: widget.color, size: 25, ), Expanded( diff --git a/lib/ui/screens/profile/profile_screen.dart b/lib/ui/screens/profile/profile_screen.dart index 52d567c..35c4a57 100644 --- a/lib/ui/screens/profile/profile_screen.dart +++ b/lib/ui/screens/profile/profile_screen.dart @@ -44,53 +44,63 @@ class _ProfileScreenState extends State { backgroundColor: const Color(0xffefefef), body: Stack(children: [ Container( - height: 300, - margin: EdgeInsets.only(top: 50), - decoration: BoxDecoration(image: DecorationImage(image: MemoryImage(Utils.getPostBytes(memberInformationList.eMPLOYEEIMAGE)), fit: BoxFit.cover)), - child: new BackdropFilter( - filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), - child: new Container( - decoration: new BoxDecoration(color: Colors.white.withOpacity(0.0)), - ), - )), + height: 300, + margin: EdgeInsets.only(top: 50), + decoration: BoxDecoration(image: DecorationImage(image: MemoryImage(Utils.getPostBytes(memberInformationList.eMPLOYEEIMAGE)), fit: BoxFit.cover)), + child: new BackdropFilter( + filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0), + child: new Container( + decoration: new BoxDecoration(color: Colors.white.withOpacity(0.0)), + ), + ), + ), SingleChildScrollView( scrollDirection: Axis.vertical, - child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ - SizedBox( - height: 80, - ), - Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: 80, + ), + Container( padding: EdgeInsets.only(left: 15, right: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( - onPressed: () { - Navigator.pop(context); - }, - icon: Icon( - Icons.arrow_back_ios, - color: Colors.white, - )), + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.arrow_back_ios, + color: Colors.white, + ), + ), InkWell( - onTap: () { - startImageSheet(); - }, - child: Container( - padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.black.withOpacity(.3)), - child: Row(children: [ - Icon(Icons.photo, color: Colors.white), - Text( - 'Edit', - style: TextStyle(color: Colors.white, fontSize: 12), - ) - ]))), + onTap: () { + startImageSheet(); + }, + child: Container( + padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(15), color: Colors.black.withOpacity(.3)), + child: Row( + children: [ + Icon(Icons.photo, color: Colors.white), + Text( + 'Edit', + style: TextStyle(color: Colors.white, fontSize: 12), + ) + ], + ), + ), + ), ], - )), - HeaderPanel(memberInformationList), - ProfilePanle(memberInformationList) - ]), + ), + ), + HeaderPanel(memberInformationList), + ProfilePanle(memberInformationList) + ], + ), ) ])); } diff --git a/lib/ui/screens/profile/widgets/header.dart b/lib/ui/screens/profile/widgets/header.dart index ca3d829..abd5ce6 100644 --- a/lib/ui/screens/profile/widgets/header.dart +++ b/lib/ui/screens/profile/widgets/header.dart @@ -4,16 +4,19 @@ import 'package:mohem_flutter_app/models/member_information_list_model.dart'; class HeaderPanel extends StatelessWidget { HeaderPanel(this.memberInformationList); + late MemberInformationListModel memberInformationList; + @override Widget build(BuildContext context) { double _width = MediaQuery.of(context).size.width; return Container( - padding: EdgeInsets.symmetric(horizontal: _width / 10, vertical: 0), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [], - )); + padding: EdgeInsets.symmetric(horizontal: _width / 10, vertical: 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [], + ), + ); } } diff --git a/lib/ui/screens/profile/widgets/profile_info.dart b/lib/ui/screens/profile/widgets/profile_info.dart index b777b8e..0bef6e9 100644 --- a/lib/ui/screens/profile/widgets/profile_info.dart +++ b/lib/ui/screens/profile/widgets/profile_info.dart @@ -13,6 +13,7 @@ import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listv class ProfileInFo extends StatelessWidget { ProfileInFo(this.memberInfo); + MemberInformationListModel memberInfo; String data = '.'; double sliderValue = 75; @@ -26,68 +27,79 @@ class ProfileInFo extends StatelessWidget { ProfileMenu(name: LocaleKeys.profile_contactDetails.tr(), icon: 'contact-details.svg', route: AppRoutes.contactDetails, dynamicUrl: ''), ProfileMenu(name: LocaleKeys.profile_familyDetails.tr(), icon: 'family-members.svg', route: AppRoutes.familyMembers, dynamicUrl: ''), ]; + @override Widget build(BuildContext context) { return Container( - child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ - /// card header - customLabel(memberInfo.eMPLOYEENAME.toString(), 22, Colors.black, true), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + /// card header + customLabel(memberInfo.eMPLOYEENAME.toString(), 22, Colors.black, true), - customLabel(memberInfo.eMPLOYEENUMBER.toString() + ' | ' + memberInfo.jOBNAME.toString(), 14, Colors.grey, false), + customLabel(memberInfo.eMPLOYEENUMBER.toString() + ' | ' + memberInfo.jOBNAME.toString(), 14, Colors.grey, false), - customLabel(memberInfo.eMPLOYEEEMAILADDRESS.toString(), 13, Colors.black, true), + customLabel(memberInfo.eMPLOYEEEMAILADDRESS.toString(), 13, Colors.black, true), - Divider(height: 40, thickness: 8, color: const Color(0xffefefef)), + Divider(height: 40, thickness: 8, color: const Color(0xffefefef)), - customLabel(LocaleKeys.completingYear.tr(), 10, Colors.black, true), + customLabel(LocaleKeys.completingYear.tr(), 10, Colors.black, true), - SizedBox(height: 10), - Container( - child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Column( - children: [customLabel(LocaleKeys.year.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEYEARS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], - ), - Column( - children: [customLabel(LocaleKeys.month.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEMONTHS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], - ), - Column( - children: [customLabel(LocaleKeys.day.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEDAYS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], - ) - ])), + SizedBox(height: 10), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Column( + children: [customLabel(LocaleKeys.year.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEYEARS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], + ), + Column( + children: [customLabel(LocaleKeys.month.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEMONTHS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], + ), + Column( + children: [customLabel(LocaleKeys.day.tr(), 14, const Color(0xff808080), true), customLabel(memberInfo.sERVICEDAYS.toString().padLeft(2, '0'), 22, Color(0xff2BB8A6), true)], + ) + ], + ), + ), - Divider(height: 40, thickness: 8, color: const Color(0xffefefef)), - Container( - padding: EdgeInsets.only( - left: 20, - right: 20, + Divider(height: 40, thickness: 8, color: const Color(0xffefefef)), + Container( + padding: EdgeInsets.only( + left: 20, + right: 20, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + customLabel(LocaleKeys.profile_profileCompletionPer.tr() + ' 75%', 18, Colors.black, true), + const SizedBox(height: 10), + Row( + children: [ + for (var i = 0; i < 4; i++) + if (i < 3) Expanded(child: drawSlider(Color(0xff2BB8A6))) else Expanded(child: drawSlider(const Color(0xffefefef))) + ], + ), + const SizedBox(height: 10), + Text( + LocaleKeys.profile_completeProfile.tr(), + style: TextStyle(color: Color(0xff2BB8A6), fontWeight: FontWeight.bold, decoration: TextDecoration.underline), + ), + ], + ), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - customLabel(LocaleKeys.profile_profileCompletionPer.tr() + ' 75%', 18, Colors.black, true), - const SizedBox(height: 10), - Row( - children: [ - for (var i = 0; i < 4; i++) - if (i < 3) Expanded(child: drawSlider(Color(0xff2BB8A6))) else Expanded(child: drawSlider(const Color(0xffefefef))) - ], - ), - const SizedBox(height: 10), - Text( - LocaleKeys.profile_completeProfile.tr(), - style: TextStyle(color: Color(0xff2BB8A6), fontWeight: FontWeight.bold, decoration: TextDecoration.underline), - ), - ], - )), - /// description - Divider(height: 50, thickness: 8, color: const Color(0xffefefef)), + /// description + Divider(height: 50, thickness: 8, color: const Color(0xffefefef)), - Column( - children: menu.map((i) => rowItem(i, context)).toList(), - ) - ])); + Column( + children: menu.map((i) => rowItem(i, context)).toList(), + ) + ], + ), + ); } Widget drawSlider(color) { diff --git a/lib/ui/screens/profile/widgets/profile_panel.dart b/lib/ui/screens/profile/widgets/profile_panel.dart index fd99abb..1facf52 100644 --- a/lib/ui/screens/profile/widgets/profile_panel.dart +++ b/lib/ui/screens/profile/widgets/profile_panel.dart @@ -6,7 +6,9 @@ import 'package:mohem_flutter_app/ui/screens/profile/widgets/profile_info.dart'; class ProfilePanle extends StatelessWidget { ProfilePanle(this.memberInformationList); + late MemberInformationListModel memberInformationList; + @override Widget build(BuildContext context) { double _width = MediaQuery.of(context).size.width; @@ -19,9 +21,10 @@ class ProfilePanle extends StatelessWidget { margin: EdgeInsets.only(top: 50), padding: EdgeInsets.only(top: 50), decoration: BoxDecoration( - color: Colors.white, - borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), - boxShadow: [BoxShadow(color: Colors.white60, blurRadius: 10, spreadRadius: 10)]), + color: Colors.white, + borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), + boxShadow: [BoxShadow(color: Colors.white60, blurRadius: 10, spreadRadius: 10)], + ), child: ProfileInFo(memberInformationList), ), Container(height: 100, alignment: Alignment.center, child: ProfileImage()) diff --git a/lib/widgets/dialogs/dialogs.dart b/lib/widgets/dialogs/dialogs.dart new file mode 100644 index 0000000..9a5a822 --- /dev/null +++ b/lib/widgets/dialogs/dialogs.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +void showMDialog( + context, { + Widget? child, +}) async { + return showDialog( + context: context, + barrierDismissible: true, + builder: (context) { + return Dialog( + child: child, + ); + }, + ); +} diff --git a/lib/widgets/qr_scanner_dialog.dart b/lib/widgets/qr_scanner_dialog.dart new file mode 100644 index 0000000..a3adb79 --- /dev/null +++ b/lib/widgets/qr_scanner_dialog.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:qr_code_scanner/qr_code_scanner.dart'; + +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; + +class QrScannerDialog extends StatefulWidget { + @override + State createState() => _QrScannerDialogState(); +} + +class _QrScannerDialogState extends State { + 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: DefaultButton( + "Cancel", + () { + 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); + } + }); + }); + } + + @override + void dispose() { + controller?.dispose(); + super.dispose(); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 365819d..789d51c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,7 +40,7 @@ dependencies: easy_localization: ^3.0.0 http: ^0.13.4 permission_handler: ^9.2.0 - flutter_svg: ^0.23.0+1 + flutter_svg: any sizer: ^2.0.15 local_auth: ^1.1.9 fluttertoast: ^8.0.8 @@ -68,6 +68,14 @@ dependencies: open_file: ^3.2.1 wifi_iot: ^0.3.16 flutter_html: ^2.2.1 +# flutter_barcode_scanner: ^2.0.0 + qr_code_scanner: ^1.0.0 + qr_flutter: ^4.0.0 + + + + + dev_dependencies: flutter_test: