import 'dart:convert'; import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:employee_selfservice_mobile/Screens/Menu/AjukanCuti/RequestHttp/jenisCuti_post.dart'; import 'package:employee_selfservice_mobile/Screens/Menu/AjukanCuti/RequestHttp/pengajuanCuti_post.dart'; import 'package:employee_selfservice_mobile/Screens/Menu/AjukanCuti/history_cuti.dart'; import 'package:intl/intl.dart'; import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart'; import 'dart:developer' as logDev; import '../SlipGaji/background.dart'; List fileAttach = [""]; TextEditingController deskripsiTeksController = TextEditingController(); class AjukanCutiScreen extends StatefulWidget { const AjukanCutiScreen({Key? key}) : super(key: key); @override State createState() => _AjukanCutiScreenState(); } class _AjukanCutiScreenState extends State { var selectedType; String _fileText = ""; String _totalFile= ""; bool visibleDateFrom = false; bool visibleDateTo = false; late List idCutiType; late List cutiType; DateTime dateFrom = DateTime.now(); DateTime dateTo = DateTime.now(); late String formattedDateFrom = ""; late String formattedDateTo = ""; late String idCuti; initState(){ deskripsiTeksController.clear(); cutiType = [""]; idCutiType = [""]; formattedDateFrom = ""; visibleDateFrom = false; formattedDateTo = ""; visibleDateTo = false; deskripsiTeksController.clear(); WidgetsBinding.instance.addPostFrameCallback((_) { cutiType = getJenisCuti(); }); super.initState(); } getJenisCuti () 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)); await loading.show(); JenisCuti_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: "Jenis Cuti Result"); if (result.contains("Failed")) { await loading.hide(); setState(() { cutiType = [""]; alertDialogFailedRetrievedData(context); }); } else { List jenis = object['result']['jenis']; setState(() { idCutiType.removeAt(0); cutiType.removeAt(0); for (int i = 0; i < jenis.length; i++){ String id = jenis[i]['id'].toString(); String text = jenis[i]['text'].toString(); idCutiType.add(id); cutiType.add(text); } }); await loading.hide(); } } else { setState((){ cutiType = [""]; alertDialogFailedResponse(context); /*Fluttertoast.showToast( msg: "Server Response Error", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1, textColor: Colors.white, fontSize: 16.0);*/ }); await loading.hide(); } }); return cutiType; } @override Widget build(BuildContext context) { var size = MediaQuery.sizeOf(context); return Scaffold( body: SingleChildScrollView( child: Column( children: [ Stack( children: [ WavyHeader(), Container( margin: EdgeInsets.only(top: MediaQuery.of(context).size.height/6 - 20), padding: EdgeInsets.fromLTRB(20, 5, 25, 5), child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( 'Leaves\t\t', maxLines: 1, style: GoogleFonts.luckiestGuy( fontSize: 28, color: Color(0xFF4858A7), fontStyle: FontStyle.italic, ), ), Image.asset( 'assets/icons/menu/ic_cuti.png', width: 40, height: 40, ), ], )), SafeArea( child: Container( width: MediaQuery.of(context).size.width, margin: EdgeInsets.only( top: MediaQuery.of(context).size.height / 5, left: 10, right: 10, bottom : 15, ), child: Column( children: [ InkWell( child: Container( margin: EdgeInsets.only(top: 15, bottom: 15), 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 Leaves 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: () { deskripsiTeksController.clear(); visibleDateFrom = !visibleDateFrom; visibleDateTo = !visibleDateTo; Navigator.push(context, MaterialPageRoute( builder: (context) => HistoryCuti())); }, ), Container( child: Card( elevation: 10, child: Container( decoration: BoxDecoration( color: Color(0XFFFAF7EE), borderRadius: BorderRadius.circular(10)), child: Column( children: [ Container( margin: EdgeInsets.only( left: 10, right: 10, top: 15, bottom: 10), child: Text('Leaves Submission', style: GoogleFonts.josefinSans(fontSize: 18, fontWeight: FontWeight.bold, decoration: TextDecoration.underline, decorationStyle: TextDecorationStyle.dashed),), ), Container( margin: EdgeInsets.only( left: 10, right: 10, top: 10, bottom: 10), child: Column( children: [ Align( alignment: Alignment.centerLeft, child: Text( 'Type', style: GoogleFonts.inconsolata( fontSize: 16, fontWeight: FontWeight.bold), )), Container( margin: EdgeInsets.only(top: 7), decoration: BoxDecoration( color: CupertinoColors.systemGrey2, borderRadius: BorderRadius.circular(5)), child: DropdownButton( menuMaxHeight: size.height * 0.31, dropdownColor: Colors.grey.shade300, value: this.selectedType, isExpanded: true, underline: SizedBox(), hint: Text( '\t\t\tChoose Leaves Type', style: TextStyle( color: Colors.black54), ), onChanged: (value) { logDev.log(value.toString(), name: "VALUENYA"); //print(value); setState(() { selectedType = value!; for (int i = 0; i < cutiType.length; i++){ if (selectedType == cutiType.elementAt(i)){ idCuti = idCutiType.elementAt(i); } } }); }, items: cutiType .map((e) => DropdownMenuItem( value: e, child: Text("\t\t\t" + e)), ).toList(), ), ), ], ), ), Container( margin: EdgeInsets.only( left: 10, right: 10, top: 10, bottom: 10), child: Column( children: [ Align( alignment: Alignment.centerLeft, child: Text('From', style: GoogleFonts.inconsolata( fontSize: 16, fontWeight: FontWeight.bold), ) ), ElevatedButton( onPressed: () async { DateTime? newDate = await showDatePicker( context: context, initialDate: dateFrom, firstDate: DateTime(1900), lastDate: DateTime(2100)); final DateFormat formatter = DateFormat('yyyy-MM-dd'); if (newDate == null) { return; } else { setState(() { if (visibleDateFrom == false){ visibleDateFrom = !visibleDateFrom; } formattedDateFrom = formatter.format(newDate); //dateFrom = formattedFrom as DateTime; }); } }, /*style: ElevatedButton.styleFrom( backgroundColor: CupertinoColors .systemGrey2),*/ child: Container( width: double.infinity, child: Text( "Choose Date", style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w400), ), ), ), Visibility( visible: visibleDateFrom, child: Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only( left: 15, right: 15, bottom: 5), child: Text(formattedDateFrom, overflow: TextOverflow.ellipsis, maxLines: 1, style: TextStyle( color: Colors.black54), ), ), ), ], ), ), Container( margin: EdgeInsets.only( left: 10, right: 10, top: 10, bottom: 10), child: Column( children: [ Align( alignment: Alignment.centerLeft, child: Text( 'To', style: GoogleFonts.inconsolata( fontSize: 16, fontWeight: FontWeight.bold), ), ), Column( children: [ ElevatedButton( onPressed: () async {DateTime? newDate = await showDatePicker(context: context, initialDate: dateTo, firstDate: DateTime(1900), lastDate: DateTime(2100)); final DateFormat formatter = DateFormat('yyyy-MM-dd'); if (newDate == null) { return; } else { setState(() { if (visibleDateTo == false){ visibleDateTo = !visibleDateTo; } formattedDateTo = formatter.format(newDate); }); } }, /*style: ElevatedButton.styleFrom( backgroundColor: CupertinoColors .systemGrey2),*/ child: Container( width: double.infinity, child: Text( "Choose Date", style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w400), ), ), ), Visibility( visible: visibleDateTo, child: Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only( left: 15, right: 15, bottom: 5), child: Text(formattedDateTo, overflow: TextOverflow.ellipsis, maxLines: 1, style: TextStyle( color: Colors.black54), ), ), ) ], ), ], ), ), Container( margin: EdgeInsets.only( left: 10, right: 10, top: 10, bottom: 10), child: Column( children: [ Align( alignment: Alignment.centerLeft, child: Text( 'Description', style: GoogleFonts.inconsolata( fontSize: 16, fontWeight: FontWeight.bold), )), Container( margin: EdgeInsets.only(top: 7), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5)), child: Padding( padding: EdgeInsets.only( left: 10, right: 10, top: 5, bottom: 5), child: TextFormField( keyboardType: TextInputType.multiline, maxLines: null, textInputAction: TextInputAction.done, controller: deskripsiTeksController, decoration: InputDecoration( border: InputBorder.none, hintText: "description")), ) ), ], ), ), Container( margin: EdgeInsets.only( left: 10, right: 10, top: 10), child: Column( children: [ Align( alignment: Alignment.centerLeft, child: Text( 'Attachment', style: GoogleFonts.inconsolata( fontSize: 16, fontWeight: FontWeight.bold), ), ), Container( child: ElevatedButton( onPressed: () { _pickMultipleFiles(); }, /*style: ElevatedButton.styleFrom( backgroundColor: CupertinoColors .systemGrey2),*/ child: Container( width: double.infinity, child: Text("Choose File", style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w400)), ), ), ), Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only( left: 15, right: 15, bottom: 10), child: Text(_totalFile + _fileText, overflow: TextOverflow.ellipsis, /*maxLines: 7,*/ style: TextStyle( color: Colors.black54), ), ), ], ), ), InkWell( child: Container( margin: EdgeInsets.only(left: 10, right: 10, bottom: 15), padding: EdgeInsets.fromLTRB( 10, 10, 10, 10), width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), gradient: LinearGradient(colors: [ Color(0xFFFF9945), Color(0xFFFc6076) ])), child: Text('Submit', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 17, fontWeight: FontWeight.w500)), ), onTap: () 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)); //loading.show(); if (!validateFormCuti(context)){ return; } else if (validateFormCuti(context)){ await loading.show(); PengajuanCuti_Post.connectToAPI(idCuti, formattedDateFrom, formattedDateTo, deskripsiTeksController.text.toString(), fileAttach) .then((valueResult) async { Map object = json.decode(valueResult); logDev.log(fileAttach.toString(), name: "Attachment File Upload"); if (object.containsKey("result").toString() == "true") { /*String employee = object['result']['employee'].toString(); String tipe = object['result']['tipe'].toString(); String from = object['result']['from'].toString(); String to = object['result']['to'].toString(); String deskripsi = object['result']['deskripsi'].toString(); String attachment = object['result']['attachment'].toString();*/ await loading.hide(); deskripsiTeksController.clear(); Widget okButton = TextButton( child: Text("OK"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement(context, MaterialPageRoute( builder: (context) => AjukanCutiScreen())); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text("Success Submit Leaves"), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); /* deskripsiTeksController.clear(); formattedDateFrom = ""; formattedDateTo = ""; visibleDateFrom = false; visibleDateFrom = false;*/ } else if (object.containsKey("error").toString() == "true") { String errorMessage = object['error']['data']['message'] .toString(); await loading.hide(); Widget okButton = TextButton( child: Text("OK"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); }, ); // set up the AlertDialog AlertDialog alert = AlertDialog( title: Text("Employee Self Service"), content: Text(errorMessage), actions: [ okButton, ], ); // show the dialog showDialog( context: context, builder: (BuildContext context) { return alert; }, ); } }); } }, ) ], ), ), ), ), ], ), ), ), ], ), ], )), ); } void _pickMultipleFiles() async { FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true); if (_fileText != ""){ _fileText = ""; } if (result != null) { List files = result.paths.map((path) => File(path!)).toList(); for (int i = 0; i< files.length; i++){ String fileName = files[i].path.split('/').last; _fileText = _fileText + "\n" + fileName; List fileInBytes = files[i].readAsBytesSync(); String toBase64 = base64Encode(fileInBytes); fileAttach.add(toBase64); } fileAttach.removeAt(0); logDev.log(fileAttach.length.toString(), name: "Length File Attach"); logDev.log(files.toString(), name: "Files Picked"); setState(() { _fileText; _totalFile = "Total File : " + files.length.toString(); }); } else { // User canceled the picker } } bool validateFormCuti(BuildContext context) { bool result = true; if (selectedType == null) { Fluttertoast.showToast( msg: " Type Not Selected", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1, textColor: Colors.white, fontSize: 16.0); result = false; } else if (formattedDateFrom == "" || formattedDateTo == "") { Fluttertoast.showToast( msg: "Time Off Date Not Selected", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1, textColor: Colors.white, fontSize: 16.0); result = false; } else if (deskripsiTeksController.text.toString().isEmpty) { Fluttertoast.showToast( msg: "Description Required!", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, timeInSecForIosWeb: 1, textColor: Colors.white, fontSize: 16.0); result = false; } return result; } } alertDialogFailedRetrievedData(BuildContext context){ Widget okButton = TextButton( child: Text("Refresh"), onPressed: () { Navigator.of(context, rootNavigator: true).pop(); Navigator.pushReplacement(context, MaterialPageRoute( builder: (context) => AjukanCutiScreen())); }, ); 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) => AjukanCutiScreen())); }, ); 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; }, ); }