You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			390 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			390 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Dart
		
	
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';
 | 
						|
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/date_uitl.dart';
 | 
						|
import 'package:mohem_flutter_app/classes/utils.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/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);
 | 
						|
 | 
						|
  @override
 | 
						|
  _TodayAttendanceScreenState createState() {
 | 
						|
    return _TodayAttendanceScreenState();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
class _TodayAttendanceScreenState extends State<TodayAttendanceScreen> {
 | 
						|
  ValueNotifier<dynamic> result = ValueNotifier(null);
 | 
						|
  late DashboardProviderModel data;
 | 
						|
  bool isNfcEnabled = false, isNfcLocationEnabled = false, isQrEnabled = false, isQrLocationEnabled = false, isWifiEnabled = false, isWifiLocationEnabled = false;
 | 
						|
 | 
						|
  @override
 | 
						|
  void initState() {
 | 
						|
    super.initState();
 | 
						|
    checkAttendanceAvailablity();
 | 
						|
    data = Provider.of<DashboardProviderModel>(context, listen: false);
 | 
						|
  }
 | 
						|
 | 
						|
  void checkAttendanceAvailablity() async {
 | 
						|
    bool isAvailable = await NfcManager.instance.isAvailable();
 | 
						|
    setState(() {
 | 
						|
      AppState().privilegeListModel!.forEach((element) {
 | 
						|
        print(element.serviceName.toString() + "   " + element.previlege.toString()); // Check availability
 | 
						|
 | 
						|
        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;
 | 
						|
        }
 | 
						|
      });
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  void dispose() {
 | 
						|
    super.dispose();
 | 
						|
    // Stop Session
 | 
						|
    NfcManager.instance.stopSession();
 | 
						|
  }
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    return Scaffold(
 | 
						|
      appBar: AppBar(
 | 
						|
        backgroundColor: MyColors.backgroundBlackColor,
 | 
						|
        leading: IconButton(
 | 
						|
          icon: const Icon(Icons.arrow_back_ios, color: Colors.white),
 | 
						|
          onPressed: () => Navigator.pop(context),
 | 
						|
        ),
 | 
						|
        actions: [
 | 
						|
          IconButton(
 | 
						|
            onPressed: () {
 | 
						|
              data.fetchAttendanceTracking(context);
 | 
						|
            },
 | 
						|
            icon: Icon(
 | 
						|
              Icons.ac_unit,
 | 
						|
              color: Colors.white,
 | 
						|
            ),
 | 
						|
          )
 | 
						|
        ],
 | 
						|
      ),
 | 
						|
      backgroundColor: MyColors.backgroundBlackColor,
 | 
						|
      body: Consumer<DashboardProviderModel>(
 | 
						|
        builder: (context, model, child) {
 | 
						|
          return (model.isAttendanceTrackingLoading
 | 
						|
                  ? Center(child: CircularProgressIndicator())
 | 
						|
                  : ListView(
 | 
						|
                      children: [
 | 
						|
                        Container(
 | 
						|
                          color: MyColors.backgroundBlackColor,
 | 
						|
                          padding: EdgeInsets.only(top: 4, left: 21, right: 21, bottom: 21),
 | 
						|
                          child: Column(
 | 
						|
                            crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                            children: [
 | 
						|
                              DateUtil.getWeekDayMonthDayYearDateFormatted(DateTime.now(), "en").toText24(isBold: true, color: Colors.white),
 | 
						|
                              LocaleKeys.timeLeftToday.tr().toText16(color: Color(0xffACACAC)),
 | 
						|
                              21.height,
 | 
						|
                              Center(
 | 
						|
                                child: CircularStepProgressBar(
 | 
						|
                                  totalSteps: 16 * 4,
 | 
						|
                                  currentStep: (model.progress * 100).toInt(),
 | 
						|
                                  width: 216,
 | 
						|
                                  height: 216,
 | 
						|
                                  selectedColor: MyColors.gradiantEndColor,
 | 
						|
                                  unselectedColor: MyColors.grey70Color,
 | 
						|
                                  child: Center(
 | 
						|
                                    child: Column(
 | 
						|
                                      mainAxisSize: MainAxisSize.min,
 | 
						|
                                      children: [
 | 
						|
                                        CountdownTimer(
 | 
						|
                                          endTime: model.endTime,
 | 
						|
                                          onEnd: null,
 | 
						|
                                          endWidget: "00:00:00".toText32(color: Colors.white, isBold: true),
 | 
						|
                                          textStyle: TextStyle(color: Colors.white, fontSize: 32, letterSpacing: -1.92, fontWeight: FontWeight.bold, height: 1),
 | 
						|
                                        ),
 | 
						|
                                        19.height,
 | 
						|
                                        LocaleKeys.shiftTime.tr().tr().toText12(color: MyColors.greyACColor),
 | 
						|
                                        (model.attendanceTracking!.pShtName ?? "00:00:00").toString().toText22(color: Colors.white, isBold: true),
 | 
						|
                                      ],
 | 
						|
                                    ),
 | 
						|
                                  ),
 | 
						|
                                ),
 | 
						|
                              ),
 | 
						|
                            ],
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                        Container(
 | 
						|
                          color: MyColors.backgroundBlackColor,
 | 
						|
                          child: Stack(
 | 
						|
                            children: [
 | 
						|
                              Container(
 | 
						|
                                height: 187,
 | 
						|
                                padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
 | 
						|
                                decoration: BoxDecoration(
 | 
						|
                                  borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)),
 | 
						|
                                  gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
 | 
						|
                                    MyColors.gradiantEndColor,
 | 
						|
                                    MyColors.gradiantStartColor,
 | 
						|
                                  ]),
 | 
						|
                                ),
 | 
						|
                                child: Column(
 | 
						|
                                  children: [
 | 
						|
                                    Row(
 | 
						|
                                      children: [
 | 
						|
                                        commonStatusView(LocaleKeys.checkIn.tr(), (model.attendanceTracking!.pSwipeIn) ?? "- - : - -"),
 | 
						|
                                        commonStatusView(LocaleKeys.checkOut.tr(), (model.attendanceTracking!.pSwipeOut) ?? "- - : - -")
 | 
						|
                                      ],
 | 
						|
                                    ),
 | 
						|
                                    21.height,
 | 
						|
                                    Row(
 | 
						|
                                      children: [
 | 
						|
                                        commonStatusView(LocaleKeys.lateIn.tr(), (model.attendanceTracking!.pLateInHours) ?? "- - : - -"),
 | 
						|
                                        commonStatusView(LocaleKeys.regular.tr(), (model.attendanceTracking!.pScheduledHours) ?? "- - : - -")
 | 
						|
                                      ],
 | 
						|
                                    ),
 | 
						|
                                  ],
 | 
						|
                                ),
 | 
						|
                              ),
 | 
						|
                              Container(
 | 
						|
                                width: double.infinity,
 | 
						|
                                decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
 | 
						|
                                margin: EdgeInsets.only(top: 187 - 31),
 | 
						|
                                padding: EdgeInsets.only(left: 21, right: 21, top: 24, bottom: 24),
 | 
						|
                                child: Column(
 | 
						|
                                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                                  mainAxisSize: MainAxisSize.min,
 | 
						|
                                  children: [
 | 
						|
                                    LocaleKeys.mark.tr().tr().toText12(),
 | 
						|
                                    LocaleKeys.attendance.tr().tr().toText24(),
 | 
						|
                                    LocaleKeys.selectMethodOfAttendance.tr().tr().toText12(color: Color(0xff535353)),
 | 
						|
                                    24.height,
 | 
						|
                                    GridView(
 | 
						|
                                      physics: const NeverScrollableScrollPhysics(),
 | 
						|
                                      shrinkWrap: true,
 | 
						|
                                      padding: EdgeInsets.zero,
 | 
						|
                                      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
 | 
						|
                                      children: <Widget>[
 | 
						|
                                        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);
 | 
						|
                                          }),
 | 
						|
                                      ],
 | 
						|
                                    )
 | 
						|
                                  ],
 | 
						|
                                ),
 | 
						|
                              ),
 | 
						|
                              // Positioned(
 | 
						|
                              //   top: 187 - 21,
 | 
						|
                              //   child: Container(
 | 
						|
                              //     padding: EdgeInsets.only(left: 31, right: 31, top: 31, bottom: 16),
 | 
						|
                              //     decoration: BoxDecoration(borderRadius: BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25)), color: Colors.white),
 | 
						|
                              //     child: Column(
 | 
						|
                              //       children: [
 | 
						|
                              //         Row(
 | 
						|
                              //           children: [commonStatusView("Check In", "09:27"), commonStatusView("Check Out", "- - : - -")],
 | 
						|
                              //         ),
 | 
						|
                              //         21.height,
 | 
						|
                              //         Row(
 | 
						|
                              //           children: [commonStatusView("Late In", "00:27"), commonStatusView("Regular", "08:00")],
 | 
						|
                              //         ),
 | 
						|
                              //       ],
 | 
						|
                              //     ),
 | 
						|
                              //   ),
 | 
						|
                              // ),
 | 
						|
                            ],
 | 
						|
                          ),
 | 
						|
                        )
 | 
						|
                      ],
 | 
						|
                    ))
 | 
						|
              .animatedSwither();
 | 
						|
        },
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
 | 
						|
    if (isNfcLocationEnabled) {
 | 
						|
      print("nfc location enabled");
 | 
						|
    } else {
 | 
						|
      print("nfc not location enabled");
 | 
						|
    }
 | 
						|
 | 
						|
    showNfcReader(context, onNcfScan: (String? nfcId) async {
 | 
						|
      print(nfcId);
 | 
						|
      Utils.showLoading(context);
 | 
						|
      try {
 | 
						|
        GenericResponseModel? g = await DashboardApiClient().markAttendance(pointType: 2, nfcValue: nfcId ?? "", isGpsRequired: isNfcLocationEnabled, lat: lat, long: lng);
 | 
						|
        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);
 | 
						|
        });
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> performWifiAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {
 | 
						|
    if (isWifiLocationEnabled) {
 | 
						|
      print("wifi location enabled");
 | 
						|
    } 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);
 | 
						|
      print("connected");
 | 
						|
      Utils.showLoading(context);
 | 
						|
      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();
 | 
						|
      } catch (ex) {
 | 
						|
        print(ex);
 | 
						|
        await closeWifiRequest();
 | 
						|
        Utils.hideLoading(context);
 | 
						|
        Utils.handleException(ex, context, (msg) {
 | 
						|
          Utils.confirmDialog(context, msg);
 | 
						|
        });
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      Utils.confirmDialog(context, LocaleKeys.comeNearHMGWifi.tr());
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Future<bool> closeWifiRequest() async {
 | 
						|
    await WiFiForIoTPlugin.forceWifiUsage(false);
 | 
						|
    bool v = await WiFiForIoTPlugin.disconnect();
 | 
						|
    return v;
 | 
						|
  }
 | 
						|
 | 
						|
  Future<void> 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),
 | 
						|
          gradient: const LinearGradient(transform: GradientRotation(.64), begin: Alignment.topRight, end: Alignment.bottomLeft, colors: [
 | 
						|
            MyColors.gradiantEndColor,
 | 
						|
            MyColors.gradiantStartColor,
 | 
						|
          ]),
 | 
						|
        ),
 | 
						|
        clipBehavior: Clip.antiAlias,
 | 
						|
        child: Stack(
 | 
						|
          children: [
 | 
						|
            Container(
 | 
						|
              padding: const EdgeInsets.only(left: 10, right: 10, top: 14, bottom: 14),
 | 
						|
              child: Column(
 | 
						|
                crossAxisAlignment: CrossAxisAlignment.start,
 | 
						|
                children: [
 | 
						|
                  Expanded(
 | 
						|
                      child: SvgPicture.asset(
 | 
						|
                    image,
 | 
						|
                    color: Colors.white,
 | 
						|
                  )),
 | 
						|
                  title.toText17(isBold: true, color: Colors.white),
 | 
						|
                ],
 | 
						|
              ),
 | 
						|
            ),
 | 
						|
            if (!isEnabled)
 | 
						|
              Container(
 | 
						|
                width: double.infinity,
 | 
						|
                height: double.infinity,
 | 
						|
                color: Colors.grey.withOpacity(0.7),
 | 
						|
              )
 | 
						|
          ],
 | 
						|
        ),
 | 
						|
      ).onPress(onPress);
 | 
						|
 | 
						|
  Widget commonStatusView(String title, String time) => Expanded(
 | 
						|
        child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
 | 
						|
          title.toText12(color: Colors.white),
 | 
						|
          time.toText22(color: Colors.white, isBold: true),
 | 
						|
        ]),
 | 
						|
      );
 | 
						|
}
 |