import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_map/plugin_api.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hris_selfservice_mobile/Screens/Menu/Absensi/RequestHttp/checkIn_post.dart'; import 'package:hris_selfservice_mobile/Screens/Menu/Absensi/RequestHttp/checkStatus_post.dart'; import 'package:hris_selfservice_mobile/Screens/Menu/Absensi/absensi_history_screen.dart'; import 'package:latlong2/latlong.dart' as latlong; import 'dart:developer' as logDev; import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart'; import 'RequestHttp/checkOut_post.dart'; class AbsensiScreen extends StatefulWidget { const AbsensiScreen({Key? key}) : super(key: key); @override State createState() => _AbsensiScreenState(); } class _AbsensiScreenState extends State { //Visibility Button Check In & Check Out bool visibleCheckIn = false; bool visibleCheckOut = false; latlong.LatLng point = latlong.LatLng(-6.183580253674716, 106.93103973792664); late Position position; MapController _mapController = MapController(); @override void initState() { WidgetsBinding.instance.addPostFrameCallback((_) { determinePosition(); }); super.initState(); } determinePosition() async { ProgressDialog loading = ProgressDialog(context); loading = ProgressDialog(context, type: ProgressDialogType.normal, isDismissible: false, showLogs: true); loading.style( message: 'Please Wait .....', borderRadius: 3, backgroundColor: Colors.white, progressWidget: CircularProgressIndicator(), elevation: 10.0, padding: EdgeInsets.all(10), insetAnimCurve: Curves.easeInOut, progress: 0.0, maxProgress: 100.0, progressTextStyle: TextStyle( color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400), messageTextStyle: TextStyle( color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600)); bool serviceEnabled; LocationPermission permission; loading.show(); serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { loading.hide(); return Future.error('Location services are disabled.'); } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.deniedForever) { loading.hide(); //return Future.error('Location permissions are permanently denied, we cannot request permissions.'); return alertDialogPermissionDeniedForever(context); } else if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission != LocationPermission.whileInUse && permission != LocationPermission.always) { loading.hide(); //return Future.error('Location permissions are denied (actual value: $permission).'); return alertDialogPermissionDenied(context); } } position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); logDev.log(position.toString(), name: "Position GEOLOCATOR"); if (position.isMocked) { loading.hide(); setState(() { alertDialogFakeGPSDetected(context); }); } else { point = latlong.LatLng(position.latitude, position.longitude); logDev.log(point.toString(), name: "POINT GEOLOCATOR"); _mapController.move(point, 18); //Check Status CheckStatus_Post.connectToAPI().then((valueResult) async { Map object = json.decode(valueResult); if (object.containsKey("result").toString() == "true") { String result = object['result'].toString(); logDev.log(result, name: "Status Absensi Result"); if (result.contains("belum")) { setState(() { visibleCheckIn = !visibleCheckIn; visibleCheckOut = visibleCheckOut; }); loading.hide(); } else if (result.contains("sudah")) { setState(() { visibleCheckIn = visibleCheckIn; visibleCheckOut = !visibleCheckOut; }); loading.hide(); } } else { setState(() { alertDialogFailedResponse(context); }); loading.hide(); } }); //loading.hide(); } } updatePosition() async { ProgressDialog loading = ProgressDialog(context); loading = ProgressDialog(context, type: ProgressDialogType.normal, isDismissible: false, showLogs: true); loading.style( message: 'Please Wait .....', borderRadius: 3, backgroundColor: Colors.white, progressWidget: CircularProgressIndicator(), elevation: 10.0, padding: EdgeInsets.all(10), insetAnimCurve: Curves.easeInOut, progress: 0.0, maxProgress: 100.0, progressTextStyle: TextStyle( color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400), messageTextStyle: TextStyle( color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600)); bool serviceEnabled; LocationPermission permission; loading.show(); serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { loading.hide(); return Future.error('Location services are disabled.'); } permission = await Geolocator.checkPermission(); if (permission == LocationPermission.deniedForever) { loading.hide(); //return Future.error('Location permissions are permanently denied, we cannot request permissions.'); return alertDialogPermissionDeniedForever(context); } else if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission != LocationPermission.whileInUse && permission != LocationPermission.always) { loading.hide(); //return Future.error('Location permissions are denied (actual value: $permission).'); return alertDialogPermissionDenied(context); } } position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); logDev.log(position.toString(), name: "Position GEOLOCATOR"); if (position.isMocked) { loading.hide(); setState(() { alertDialogFakeGPSDetected(context); }); } else { setState((){ point = latlong.LatLng(position.latitude, position.longitude); logDev.log(point.toString(), name: "POINT GEOLOCATOR"); _mapController.move(point, 18); }); loading.hide(); } } goCheckIn() { ProgressDialog loading = ProgressDialog(context); loading = ProgressDialog(context, type: ProgressDialogType.normal, isDismissible: false, showLogs: true); loading.style( message: 'Please Wait .....', borderRadius: 3, backgroundColor: Colors.white, progressWidget: CircularProgressIndicator(), elevation: 10.0, padding: EdgeInsets.all(10), insetAnimCurve: Curves.easeInOut, progress: 0.0, maxProgress: 100.0, progressTextStyle: TextStyle( color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400), messageTextStyle: TextStyle( color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600)); loading.show(); CheckIn_Post.connectToAPI().then((valueResult) async { Map object = json.decode(valueResult); if (object.containsKey("result").toString() == "true") { String result = object['result'].toString(); logDev.log(result, name: "Check In Result"); if (result.contains("failed")) { loading.hide(); setState(() { alertDialogFailedRetrievedData(context); }); } else if (result.contains("Anda sudah check in")) { loading.hide(); setState(() { alertDialogFailedCheckIn(context); }); } else { loading.hide(); setState(() { alertDialogSuccessCheckIn(context); }); } } else { setState(() { alertDialogFailedResponse(context); }); loading.hide(); } }); } goCheckOut() { ProgressDialog loading = ProgressDialog(context); loading = ProgressDialog(context, type: ProgressDialogType.normal, isDismissible: false, showLogs: true); loading.style( message: 'Please Wait .....', borderRadius: 3, backgroundColor: Colors.white, progressWidget: CircularProgressIndicator(), elevation: 10.0, padding: EdgeInsets.all(10), insetAnimCurve: Curves.easeInOut, progress: 0.0, maxProgress: 100.0, progressTextStyle: TextStyle( color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400), messageTextStyle: TextStyle( color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600)); loading.show(); CheckOut_Post.connectToAPI().then((valueResult) async { Map object = json.decode(valueResult); if (object.containsKey("result").toString() == "true") { String result = object['result'].toString(); logDev.log(result, name: "Check Out Result"); if (result.contains("failed")) { loading.hide(); setState(() { alertDialogFailedRetrievedData(context); }); } else if (result.contains("Anda belum check in")) { loading.hide(); setState(() { alertDialogFailedCheckOut(context); }); } else { loading.hide(); setState(() { alertDialogSuccessCheckOut(context); }); } } else { setState(() { alertDialogFailedResponse(context); }); loading.hide(); } }); } @override Widget build(BuildContext context) { var size = MediaQuery.of(context).size; return Scaffold( body: SingleChildScrollView( child: Column( children: [ Container( height: size.height * 0.6, child: Stack( children: [ FlutterMap( mapController: _mapController, options: new MapOptions( onTap: (p, point) async {}, center: point, zoom: 15), children: [ TileLayer( minZoom: 1, maxZoom: 22, maxNativeZoom: 18, minNativeZoom: 1, backgroundColor: Colors.black54, urlTemplate: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains: ['a', 'b', 'c'], ), MarkerLayer(markers: [ Marker( width: 135, height: 135, point: point, builder: (ctx) => Container( child: Icon( Icons.location_on, color: Colors.red, ), )) ]) ], ), Align( alignment: AlignmentDirectional.bottomEnd, child: Container( margin: EdgeInsets.fromLTRB(10, 15, 0, 15), child: RawMaterialButton( onPressed: () { setState(() { updatePosition(); }); }, elevation: 5.0, fillColor: Colors.white, child: Image.asset('assets/images/location1.png', height: 40, width: 40), padding: EdgeInsets.all(5.0), shape: CircleBorder(), ), ), ) ], ), ), Container( width: double.infinity, margin: EdgeInsets.fromLTRB(10, 15, 10, 10), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Container( child: Text( "Attendance Today", style: GoogleFonts.patrickHand( fontSize: 21, color: Colors.white), ), width: double.infinity, alignment: Alignment.center, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ /*Color(0xFFD21404), Color(0xFFFD7267),*/ Color(0xFF4858A7), Color(0xFF6474C6), ]), border: Border.all(color: Colors.black)), ), Container( width: double.infinity, padding: EdgeInsets.all(15), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Expanded( flex: 5, child: Column( children: [ Text('Check In', style: GoogleFonts.fredokaOne( fontSize: 19)), Text('07.15', style: GoogleFonts.barlowSemiCondensed( fontSize: 19)), ], )), Expanded( flex: 5, child: Column( children: [ Text('Check Out', style: GoogleFonts.fredokaOne( fontSize: 19)), Text('16.45', style: GoogleFonts.barlowSemiCondensed( fontSize: 19)), ], )), ], ), Row( children: [ Visibility( visible: visibleCheckIn, child: Container( margin: EdgeInsets.fromLTRB(0, 10, 0, 0), width: size.width - 54, child: ElevatedButton( onPressed: () { goCheckIn(); }, child: Text('Check In'), style: ButtonStyle( backgroundColor: MaterialStateProperty.all( Color(0xFF6474C6))), ), ), ), Visibility( visible: visibleCheckOut, child: Container( margin: EdgeInsets.fromLTRB(0, 10, 0, 0), width: size.width - 54, child: ElevatedButton( onPressed: () { goCheckOut(); }, child: Text('Check Out'), style: ButtonStyle( backgroundColor: MaterialStateProperty.all( Color(0xFF6474C6))), ), ), ), ], ) ], ), ) ], ), ), /*Container( width: double.infinity, margin: EdgeInsets.fromLTRB(10, 10, 10, 0), padding: EdgeInsets.all(15), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Rabu, 23 November 2022', maxLines: 1), Column( children: [Text('Check In'), Text('07.00')], ), Column( children: [ Text('Check Out'), Text('16.30'), ], ), ], ), Text('Location : Global Service Indonesia', maxLines: 1), ], )), Container( width: double.infinity, margin: EdgeInsets.fromLTRB(10, 10, 10, 0), padding: EdgeInsets.all(15), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Rabu, 23 November 2022', maxLines: 1), Column( children: [Text('Check In'), Text('07.00')], ), Column( children: [ Text('Check Out'), Text('16.30'), ], ), ], ), Text('Location : Global Service Indonesia', maxLines: 1), ], )), Container( width: double.infinity, margin: EdgeInsets.fromLTRB(10, 10, 10, 0), padding: EdgeInsets.all(15), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Rabu, 23 November 2022', maxLines: 1), Column( children: [Text('Check In'), Text('07.00')], ), Column( children: [ Text('Check Out'), Text('16.30'), ], ), ], ), Text('Location : Global Service Indonesia', maxLines: 1), ], )), Container( width: double.infinity, margin: EdgeInsets.fromLTRB(10, 10, 10, 0), padding: EdgeInsets.all(15), decoration: BoxDecoration(border: Border.all(color: Colors.black)), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Rabu, 23 November 2022', maxLines: 1), Column( children: [Text('Check In'), Text('07.00')], ), Column( children: [ Text('Check Out'), Text('16.30'), ], ), ], ), Text('Location : Global Service Indonesia', maxLines: 1), ], )),*/ Container( margin: EdgeInsets.fromLTRB(10, 15, 10, 15), child: InkWell( child: Container( padding: EdgeInsets.fromLTRB(10, 10, 10, 10), width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), gradient: LinearGradient(colors: [ Color(0xFF2D4059), Color(0xFF2D4059), /*Color(0xFFEAFFD0), Color(0xFF95E1D3),*/ ])), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(' See Attendance History \t\t', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 17, fontWeight: FontWeight.w500)), Image.asset( 'assets/images/ic_arrow_white.png', width: 30, height: 30, ) ], )), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => HistoryAbsensi())); }, ), ), ], ), ), ); } } alertDialogFailedRetrievedData(BuildContext context) { Widget okButton = TextButton( child: Text("Refresh"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); Widget noButton = TextButton( child: Text("Back"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pop(context); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Failed to Retrieve Data"), actions: [ noButton, okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogFailedResponse(BuildContext context) { Widget okButton = TextButton( child: Text("Refresh"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); Widget noButton = TextButton( child: Text("Back"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pop(context); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Server Response Error"), actions: [ noButton, okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogSuccessCheckIn(BuildContext context) { Widget okButton = TextButton( child: Text("Ok"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Successfully Checked In"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogSuccessCheckOut(BuildContext context) { Widget okButton = TextButton( child: Text("Ok"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Successfully Checked Out"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogFailedCheckIn(BuildContext context) { Widget okButton = TextButton( child: Text("Ok"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("You've already checked in"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogFailedCheckOut(BuildContext context) { Widget okButton = TextButton( child: Text("Ok"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("You haven't checked in"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogFakeGPSDetected(BuildContext context) { Widget okButton = TextButton( child: Text("Refresh"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Fake GPS Detected, Please Use Default GPS!"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogPermissionDenied(BuildContext context) { Widget okButton = TextButton( child: Text("Refresh"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => AbsensiScreen())); }, ); Widget noButton = TextButton( child: Text("Back"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pop(context); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Location permissions are denied, we cannot request permissions"), actions: [ noButton, okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } alertDialogPermissionDeniedForever(BuildContext context) { Widget noButton = TextButton( child: Text("Back"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pop(context); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text( "Location permissions are permanently denied, we cannot request permissions.\nPlease configure it in your device settings."), actions: [noButton], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); }