|
|
|
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<HomePage> createState() => _HomePageState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _HomePageState extends State<HomePage> {
|
|
|
|
String? token;
|
|
|
|
bool loading = true;
|
|
|
|
|
|
|
|
// Reinit atau Upload Only
|
|
|
|
WarehouseModel? warehouseSqfliteApi;
|
|
|
|
List<TypePetiModel>? typePetiSqfliteApi;
|
|
|
|
List<CustomerModel>? customerSqfliteApi;
|
|
|
|
PetiAssetModel? petiSqfliteApi;
|
|
|
|
|
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line
|
|
|
|
List<WarehouseModel>? _valwarehouse;
|
|
|
|
List<ConditionPetiModel>? _valcondition;
|
|
|
|
|
|
|
|
// Datatable
|
|
|
|
int _currentPage = 1;
|
|
|
|
int _pageSize = 10;
|
|
|
|
List<AssetStatusModel>? _data;
|
|
|
|
List<PetiAssetModel>? _petiData;
|
|
|
|
List<TypePetiModel>? _tipePetiData;
|
|
|
|
List<CustomerModel>? _customerData;
|
|
|
|
List<WarehouseModel>? _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 = <AssetStatusModel>[];
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> _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<void> _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<dynamic>)
|
|
|
|
.map((item) => WarehouseModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future typePetiListAPI() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerApi().fetchTipePetiDataAPI().then((value) {
|
|
|
|
setState(() {
|
|
|
|
typePetiSqfliteApi = (value as List<dynamic>)
|
|
|
|
.map((item) => TypePetiModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future customerListAPI() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerApi().fetchCustomerDataAPI().then((value) {
|
|
|
|
setState(() {
|
|
|
|
customerSqfliteApi = (value as List<dynamic>)
|
|
|
|
.map((item) => CustomerModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future petiListAPI() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerApi().fetchPetiDataAPI().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_valpeti = (value as List<dynamic>)
|
|
|
|
.map((item) => PetiAssetModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future kondisiPetiListAPI() async {
|
|
|
|
if (mounted) {
|
|
|
|
await ControllerApi().fetchKondisiPetiDataAPI().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_valcondition = (value as List<dynamic>)
|
|
|
|
.map((item) => ConditionPetiModel.fromJson(item))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> reinitWarehouseApi() async {
|
|
|
|
EasyLoading.show(status: 'Mengambil data Warehouse...');
|
|
|
|
List<WarehouseModel> warehouseApiData =
|
|
|
|
await SyncronizationDataAPI().fetchWarehouseFromApi();
|
|
|
|
await ControllerApi()
|
|
|
|
.deleteAllWarehouseDataAPI(); // Clear existing data in SQLite
|
|
|
|
await ControllerApi()
|
|
|
|
.addAllWarehouseDataAPI(warehouseApiData); // Add new data to SQLite
|
|
|
|
EasyLoading.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> reinitPetiApi() async {
|
|
|
|
EasyLoading.show(status: 'Mengambil data Peti...');
|
|
|
|
List<PetiAssetModel> 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<void> reinitCustomerApi() async {
|
|
|
|
EasyLoading.show(status: 'Mengambil data Customer...');
|
|
|
|
List<CustomerModel> customerApiData =
|
|
|
|
await SyncronizationDataAPI().fetchCustomerFromApi();
|
|
|
|
await ControllerApi()
|
|
|
|
.deleteAllCustomerDataAPI(); // Clear existing data in SQLite
|
|
|
|
await ControllerApi()
|
|
|
|
.addAllCustomerDataAPI(customerApiData); // Add new data to SQLite
|
|
|
|
EasyLoading.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> reinitConditionPetiApi() async {
|
|
|
|
EasyLoading.show(status: 'Mengambil data Condition Peti...');
|
|
|
|
List<ConditionPetiModel> conditionPetiApiData =
|
|
|
|
await SyncronizationDataAPI().fetchKondisiPetiFromApi();
|
|
|
|
await ControllerApi()
|
|
|
|
.deleteAllKondisiPetiDataAPI(); // Clear existing data in SQLite
|
|
|
|
await ControllerApi().addAllKondisiPetiDataAPI(
|
|
|
|
conditionPetiApiData); // Add new data to SQLite
|
|
|
|
EasyLoading.dismiss();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<void> 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<void> 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<AssetStatusModel> 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<AssetStatusModel> 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<TransferPetiModel> 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<void> 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<dynamic>)
|
|
|
|
.map((e) => AssetStatusModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesPetiList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await Controller().fetchPetiData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_petiData = (value as List<dynamic>)
|
|
|
|
.map((e) => PetiAssetModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesTipePetiList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await Controller().fetchTipePetiData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_tipePetiData = (value as List<dynamic>)
|
|
|
|
.map((e) => TypePetiModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesCustomerList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await Controller().fetchCustomerData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_customerData = (value as List<dynamic>)
|
|
|
|
.map((e) => CustomerModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Future datatablesWarehouseList() async {
|
|
|
|
if (mounted) {
|
|
|
|
await Controller().fetchWarehouseData().then((value) {
|
|
|
|
setState(() {
|
|
|
|
_warehouseData = (value as List<dynamic>)
|
|
|
|
.map((e) => WarehouseModel.fromJson(e))
|
|
|
|
.toList();
|
|
|
|
loading = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_timer?.cancel();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
AuthProvider authProvider = Provider.of<AuthProvider>(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: <Widget>[
|
|
|
|
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<void> 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(),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|