import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:siopas/migrations/databasehelper.dart'; import 'package:siopas/models/transfer_peti_model.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../models/asset_status_model.dart'; import '../../models/condition_peti_model.dart'; import '../../models/customer_model.dart'; import '../../models/m_asset_status_model.dart'; import '../../models/type_peti_model.dart'; import '../../models/user_model.dart'; import '../../models/warehouse_mode.dart'; import '../../providers/auth_provider.dart'; import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; import '../../services/controllerApi.dart'; import '../../services/syncronizeAPI.dart'; import '../../theme.dart'; import '../../widget/loading_shimmer_show.dart'; import '../peminjaman_barang/conn/syncronize.dart'; import '../peminjaman_barang/controller/peminjaman_controller.dart'; import '../pengembalian_barang/conn/syncronize.dart'; import '../transfer_peti/conn/syncronize.dart'; import 'conn_home_page.dart/syncronize.dart'; import 'controller/home_controller.dart'; class HomePage extends StatefulWidget { final ControllerHome controllerHome = ControllerHome(); // Declare here final VoidCallback? onReinitStarted; final VoidCallback? onReinitFinished; HomePage({ Key? key, this.onReinitStarted, this.onReinitFinished, }) : super(key: key); @override State createState() => _HomePageState(); } class _HomePageState extends State { String? token; bool loading = true; // Reinit atau Upload Only WarehouseModel? warehouseSqfliteApi; List? typePetiSqfliteApi; List? customerSqfliteApi; PetiAssetModel? petiSqfliteApi; List? _valpeti; // Change this line List? _valwarehouse; List? _valcondition; // Datatable int _currentPage = 1; int _pageSize = 10; List? _data; List? _petiData; List? _tipePetiData; List? _customerData; List? _warehouseData; Timer? _timer; int _peminjamanCount = 0; int _pengembalianCount = 0; int _transferCount = 0; bool _isLoading = false; bool _isFetchingData = false; @override void initState() { super.initState(); _getUserToken(); // Mengatur _isLoading dan _isFetchingData ke true sebelum tugas dimulai if (mounted) { setState(() { _isLoading = true; _isFetchingData = true; }); } // Memanggil _refreshPage untuk menginisialisasi dan memuat data _refreshPage(); _data = []; } Future _refreshPage() async { // Menggunakan Future.wait untuk menunggu hasil dari semua tugas selesai await Future.wait([ _initData(), warehouseListAPI(), typePetiListAPI(), customerListAPI(), petiListAPI(), datatablesAssetStatusList(), datatablesPetiList(), datatablesTipePetiList(), datatablesCustomerList(), datatablesWarehouseList(), initializeDateFormatting('id_ID', null), ]); // Mengatur _isLoading dan _isFetchingData ke false setelah semua tugas selesai if (mounted) { setState(() { _isLoading = false; _isFetchingData = false; }); } } @override void setState(fn) { if (mounted) { super.setState(fn); } } Future _initData() async { try { _peminjamanCount = await widget.controllerHome.getPeminjamanCount(); _pengembalianCount = await widget.controllerHome.getPengembalianCount(); _transferCount = await widget.controllerHome.getTransferCount(); } catch (error) { print(error); } // ... tambahkan inisialisasi lainnya } void _getUserToken() async { SharedPreferences prefs = await SharedPreferences.getInstance(); if (mounted) { setState(() { token = prefs.getString('token'); }); } } // Reinit atau Upload Only ------------------------------------------------------------------------ Future warehouseListAPI() async { if (mounted) { await ControllerApi().fetchWarehouseDataAPI().then((value) { setState(() { _valwarehouse = (value as List) .map((item) => WarehouseModel.fromJson(item)) .toList(); loading = false; }); }); } } Future typePetiListAPI() async { if (mounted) { await ControllerApi().fetchTipePetiDataAPI().then((value) { setState(() { typePetiSqfliteApi = (value as List) .map((item) => TypePetiModel.fromJson(item)) .toList(); loading = false; }); }); } } Future customerListAPI() async { if (mounted) { await ControllerApi().fetchCustomerDataAPI().then((value) { setState(() { customerSqfliteApi = (value as List) .map((item) => CustomerModel.fromJson(item)) .toList(); loading = false; }); }); } } Future petiListAPI() async { if (mounted) { await ControllerApi().fetchPetiDataAPI().then((value) { setState(() { _valpeti = (value as List) .map((item) => PetiAssetModel.fromJson(item)) .toList(); loading = false; }); }); } } Future kondisiPetiListAPI() async { if (mounted) { await ControllerApi().fetchKondisiPetiDataAPI().then((value) { setState(() { _valcondition = (value as List) .map((item) => ConditionPetiModel.fromJson(item)) .toList(); loading = false; }); }); } } Future reinitWarehouseApi() async { EasyLoading.show(status: 'Mengambil data Warehouse...'); List warehouseApiData = await SyncronizationDataAPI().fetchWarehouseFromApi(); await ControllerApi() .deleteAllWarehouseDataAPI(); // Clear existing data in SQLite await ControllerApi() .addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite EasyLoading.dismiss(); } Future reinitPetiApi() async { EasyLoading.show(status: 'Mengambil data Peti...'); List petiApiData = await SyncronizationDataAPI().fetchPetiFromApi(); await ControllerApi() .deleteAllPetiDataAPI(); // Clear existing data in SQLite // Menentukan ukuran chunk, misalnya 100 int chunkSize = 100; // Memasukkan data ke SQLite dengan menggunakan chunk await ControllerApi().addAllPetiDataAPI(petiApiData, chunkSize); EasyLoading.dismiss(); } Future reinitCustomerApi() async { EasyLoading.show(status: 'Mengambil data Customer...'); List customerApiData = await SyncronizationDataAPI().fetchCustomerFromApi(); await ControllerApi() .deleteAllCustomerDataAPI(); // Clear existing data in SQLite await ControllerApi() .addAllCustomerDataAPI(customerApiData); // Add new data to SQLite EasyLoading.dismiss(); } Future reinitConditionPetiApi() async { EasyLoading.show(status: 'Mengambil data Condition Peti...'); List conditionPetiApiData = await SyncronizationDataAPI().fetchKondisiPetiFromApi(); await ControllerApi() .deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite await ControllerApi().addAllKondisiPetiDataAPI( conditionPetiApiData); // Add new data to SQLite EasyLoading.dismiss(); } Future fetchDataFromApiAndSync() async { if (_isFetchingData) { // Data is already being fetched, don't start another process return; } // Set _isFetchingData to true to disable the button setState(() { _isFetchingData = true; }); // Callback to inform that Reinit process has started widget.onReinitStarted?.call(); EasyLoading.show(status: 'Mengambil data dari Server...'); try { // Cek koneksi internet bool hasInternet = await SyncronizationGlobalData.isInternet(); if (!hasInternet) { EasyLoading.showError('Tidak ada koneksi internet'); return; } // Lanjutkan sinkronisasi jika ada koneksi await syncToGlobal('Peminjaman'); await syncToGlobal('Pengembalian'); await syncToGlobal('Transfer'); // await reinitAssetStatusApi(); await reinitWarehouseApi(); await reinitPetiApi(); await reinitCustomerApi(); // await reinitTypePetiApi(); await reinitConditionPetiApi(); await datatablesAssetStatusList(); Navigator.pushNamed(context, '/home'); EasyLoading.showSuccess('Data berhasil diperbarui'); } catch (e) { EasyLoading.showError('Gagal memperbarui data: $e'); } finally { // Set _isFetchingData back to false when the process finishes if (mounted) { setState(() { _isFetchingData = false; }); EasyLoading.dismiss(); // Callback to inform that Reinit process has finished widget.onReinitFinished?.call(); } } } // Future fetchDataFromApiAndSync() async { // if (_isFetchingData) { // // Data is already being fetched, don't start another process // return; // } // // Set _isFetchingData to true to disable the button // setState(() { // _isFetchingData = true; // }); // EasyLoading.show(status: 'Mengambil data dari Server...'); // try { // // Cek koneksi internet // bool hasInternet = await SyncronizationGlobalData.isInternet(); // if (!hasInternet) { // EasyLoading.showError('Tidak ada koneksi internet'); // return; // } // // Lanjutkan sinkronisasi jika ada koneksi // await syncToGlobal('Peminjaman'); // await syncToGlobal('Pengembalian'); // await syncToGlobal('Transfer'); // // await reinitAssetStatusApi(); // await reinitWarehouseApi(); // await reinitPetiApi(); // await reinitCustomerApi(); // // await reinitTypePetiApi(); // await reinitConditionPetiApi(); // await datatablesAssetStatusList(); // Navigator.pushNamed(context, '/home'); // EasyLoading.showSuccess('Data berhasil diperbarui'); // } catch (e) { // EasyLoading.showError('Gagal memperbarui data: $e'); // } finally { // // Set _isFetchingData back to false when the process finishes // if (mounted) { // setState(() { // _isFetchingData = false; // }); // EasyLoading.dismiss(); // } // } // } Future syncToGlobal(String type) async { try { EasyLoading.show( status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...'); await Future.delayed(Duration(seconds: 3)); // Tambahkan penanganan pengunggahan bool uploadSuccess = false; // Berikan nilai awal false if (type == 'Peminjaman') { List peminjamanList = await SyncronizationGlobalData().fetchAllPeminjamanInfo(); uploadSuccess = await SyncronizationPeminjamanData() .saveToPeminjamanWith(peminjamanList); // Jika pengunggahan berhasil, hapus data lokal Peminjaman if (uploadSuccess) { await SyncronizationGlobalData().deleteAllPeminjamanData(); } } else if (type == 'Pengembalian') { List pengembalianList = await SyncronizationGlobalData().fetchAllPengembalianInfo(); uploadSuccess = await SyncronizationPengembalianData() .savePengembalianToServerWith(pengembalianList); // Jika pengunggahan berhasil, hapus data lokal Pengembalian if (uploadSuccess) { await SyncronizationGlobalData().deleteAllPengembalianData(); } } else if (type == 'Transfer') { List transferPetiList = await SyncronizationGlobalData().fetchAllTransferInfo(); uploadSuccess = await SyncronizationTransferPetiData() .saveTransferPetiServerWith(transferPetiList); // Jika pengunggahan berhasil, hapus data lokal Pengembalian if (uploadSuccess) { await SyncronizationGlobalData().deleteAllTransferData(); } } // Setelah selesai, tampilkan pesan sukses atau gagal if (uploadSuccess) { EasyLoading.showSuccess('Berhasil disinkronkan dengan Server'); } else { EasyLoading.showError('Gagal disinkronkan dengan Server'); } } catch (error) { // Handle error jika terjadi EasyLoading.showError('Terjadi kesalahan: $error'); } } Future isInteret() async { await SyncronizationGlobalData.isInternet().then((connection) { if (connection) { print("Internet connection available"); } else { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text("No Internet"))); } }); } // Datatables ------------------------------------------------------------------------ Future datatablesAssetStatusList() async { if (mounted) { await Controller().fetchAssetStatusLocalController().then((value) { setState(() { _data = (value as List) .map((e) => AssetStatusModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesPetiList() async { if (mounted) { await Controller().fetchPetiData().then((value) { setState(() { _petiData = (value as List) .map((e) => PetiAssetModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesTipePetiList() async { if (mounted) { await Controller().fetchTipePetiData().then((value) { setState(() { _tipePetiData = (value as List) .map((e) => TypePetiModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesCustomerList() async { if (mounted) { await Controller().fetchCustomerData().then((value) { setState(() { _customerData = (value as List) .map((e) => CustomerModel.fromJson(e)) .toList(); loading = false; }); }); } } Future datatablesWarehouseList() async { if (mounted) { await Controller().fetchWarehouseData().then((value) { setState(() { _warehouseData = (value as List) .map((e) => WarehouseModel.fromJson(e)) .toList(); loading = false; }); }); } } @override void dispose() { _timer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { AuthProvider authProvider = Provider.of(context); UserModel user = authProvider.user; // String? token = authProvider.token; Widget cardMenuPeminjaman() { return Container( height: 125, margin: EdgeInsets.only(left: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), elevation: 3, child: InkWell( onTap: () { // Aksi ketika card diklik Navigator.pushNamed(context, '/peminjaman-barang'); }, child: Container( // padding: EdgeInsets.only(top: 8.0, bottom: 8.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.vertical_align_top, size: 30, color: Colors.greenAccent[700], ), SizedBox(height: 5), Text( 'Peminjaman (Peti Out)', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), ], ), ), ), ), ); } Widget cardMenuPengembalian() { return Container( height: 125, margin: EdgeInsets.only(right: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), elevation: 3, child: InkWell( onTap: () { // Aksi ketika card diklik Navigator.pushNamed(context, '/pengembalian-barang'); }, child: Container( // padding: EdgeInsets.all(8.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.vertical_align_bottom, size: 30, color: Colors.blueAccent[700], ), SizedBox(height: 5), Text( 'Pengembalian (Peti In)', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), ], ), ), ), ), ); } Widget cardMenuTransfer() { return Container( height: 125, margin: EdgeInsets.only(left: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), ), elevation: 3, child: InkWell( onTap: () { // Aksi ketika card diklik Navigator.pushNamed(context, '/transfer-peti'); }, child: Container( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.input_outlined, size: 30, color: Colors.yellow[700], ), SizedBox(height: 5), Text( 'Transfer Peti', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), ], ), ), ), ), ); } Widget cardTotal(String title, int total, IconData icon) { return Expanded( child: Card( margin: EdgeInsets.all(5), child: Container( padding: EdgeInsets.all(5), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( icon, size: 20, color: Colors.blue[700], ), SizedBox(height: 2), Text( title, style: TextStyle( fontSize: 8, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), SizedBox(height: 2), Text( total.toString(), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.blue[700], ), ), ], ), ), ), ); } Widget _buildCountTile(IconData icon, int count, Color color, String text) { return Column( children: [ CircleAvatar( backgroundColor: color, radius: 12, child: Icon(icon, size: 12, color: Colors.white), ), SizedBox(height: 4), Text( text, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, ), ), Text( '$count', style: TextStyle(fontSize: 12), ), ], ); } Future showSyncDialog(BuildContext context) async { // Create an instance of ControllerHome ControllerHome controllerHome = ControllerHome(); // Fetch counts from the ControllerHome int peminjamanCount = await controllerHome.getPeminjamanCount(); int pengembalianCount = await controllerHome.getPengembalianCount(); int transferCount = await controllerHome.getTransferCount(); showDialog( context: context, builder: (BuildContext context) { return Dialog( // Dialog shape and style shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), backgroundColor: Colors.grey[100], elevation: 0, // Dialog content child: Column( mainAxisSize: MainAxisSize.min, children: [ // Dialog title with close button Container( width: double.infinity, color: Colors.indigo[700], // Indigo background child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( "Sync Server Global", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0, ), ), ), IconButton( icon: Icon( Icons.close, color: Colors.white, ), onPressed: () { Navigator.pop(context); // Close dialog }, ), ], ), ), Divider( height: 1, thickness: 1, color: Colors.black, // Black divider ), // Display counts for each table SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildCountTile(Icons.vertical_align_top, peminjamanCount, Colors.green[700]!, 'Peminjaman (Peti Out)'), _buildCountTile( Icons.vertical_align_bottom, pengembalianCount, Colors.blue[700]!, 'Pengembalian (Peti In)'), _buildCountTile(Icons.input_outlined, transferCount, Colors.yellow[700]!, 'Transfer'), ], ), SizedBox(height: 10), // Divider Divider( height: 1, thickness: 1, color: Colors.black, // Black divider ), // Re-init Button Container( width: double.infinity, child: TextButton( onPressed: _isFetchingData ? null : () { fetchDataFromApiAndSync(); }, child: Text( "Upload + Download", style: TextStyle( color: Colors.black, fontSize: 16.0, fontFamily: 'Poppins', ), ), ), ), ], ), ); }, ); } Widget cardMenuSync() { return Card( elevation: 3, margin: EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Container( color: Color.fromARGB(255, 50, 39, 122), padding: EdgeInsets.all(16.0), child: Text( "Sync Data Global", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20.0, ), ), ), SizedBox(height: 10), // Display counts for each table Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _isLoading ? ShimmerLoadingReinit() : _buildCountTile( Icons.vertical_align_top, _peminjamanCount, Colors.green[700]!, 'Peti Out', ), _isLoading ? ShimmerLoadingReinit() : _buildCountTile( Icons.vertical_align_bottom, _pengembalianCount, Colors.blue[700]!, 'Peti In', ), _isLoading ? ShimmerLoadingReinit() : _buildCountTile( Icons.input_outlined, _transferCount, Colors.yellow[700]!, 'Transfer Peti', ), ], ), SizedBox(height: 10), // Re-init Button ElevatedButton( onPressed: () async { bool hasInternet = await ControllerApi.isInternetApi(); if (hasInternet) { showDialog( context: context, builder: (BuildContext context) { return Dialog( backgroundColor: Colors.grey[100], // Set the background color shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), elevation: 0, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Dialog title with close button Container( width: double.infinity, color: Colors.indigo[700], // Indigo background child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( "Konfirmasi Sync", style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16.0, ), ), ), IconButton( icon: Icon( Icons.close, color: Colors.white, ), onPressed: () { Navigator.pop(context); // Close dialog }, ), ], ), ), // Divider Divider( height: 1, thickness: 1, color: Colors.black, // Black divider ), // Description text Container( padding: EdgeInsets.all(16.0), child: Text( "Apakah Anda yakin ingin mengunggah dan mengunduh data?", style: TextStyle( fontSize: 16.0, ), ), ), // Re-init Button with blue background ElevatedButton( onPressed: () { if (hasInternet) { Navigator.pop(context); // Close dialog fetchDataFromApiAndSync(); } else { EasyLoading.showError( "Tidak ada koneksi internet"); } }, style: TextButton.styleFrom( backgroundColor: Colors.blue[700], ), child: Text( "Upload + Download", style: TextStyle( color: Colors.white, fontSize: 16.0, fontFamily: 'Poppins', ), ), ), ], ), ); }, ); } else { EasyLoading.showError("Tidak ada koneksi internet"); } }, style: ElevatedButton.styleFrom( primary: Colors.blue[700], ), child: Padding( padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Upload + Download", style: TextStyle( color: Colors.white, fontSize: 16.0, fontFamily: 'Poppins', ), ), Icon( Icons.cloud_upload, color: Colors.white, ), ], ), ), ) ], ), ); } return WillPopScope( onWillPop: () async { // Mencegah kembali ke halaman sebelumnya return false; }, child: AbsorbPointer( absorbing: _isFetchingData, child: Scaffold( backgroundColor: Colors.grey[200], appBar: AppBar( elevation: 0, automaticallyImplyLeading: false, backgroundColor: Colors.indigo[700], centerTitle: true, title: Row( children: [ SizedBox(width: 10), Expanded( child: Center( child: Column( children: [ Text( 'SIOPAS-ISTW', textAlign: TextAlign.center, ), Text( '${user.fullname}', style: TextStyle( fontSize: 10, ), ), ], ), ), ), ], ), ), body: RefreshIndicator( color: Colors.white, backgroundColor: Colors.indigo[700], onRefresh: () async { // Tampilkan Shimmer loading selama proses refresh setState(() { _isLoading = true; }); // Selesaikan proses refresh await _refreshPage(); // Sembunyikan Shimmer loading setelah selesai setState(() { _isLoading = false; }); }, child: ListView( children: [ cardMenuSync(), SizedBox(height: 10), Container( padding: EdgeInsets.all(10), child: Text( 'Menu Aplikasi', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: cardMenuPeminjaman(), ), Expanded( child: cardMenuPengembalian(), ), ], ), SizedBox(height: 10), // Add some space between rows Row( children: [ Expanded( child: cardMenuTransfer(), ), Expanded( child: Container(), // child: cardMenuPengembalian(), ), ], ), ], ), ), ), ), ); } }