You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1067 lines
34 KiB
1067 lines
34 KiB
import 'dart:async'; |
|
import 'dart:convert'; |
|
import 'dart:developer'; |
|
|
|
import 'package:flutter/material.dart'; |
|
import 'package:data_table_2/data_table_2.dart'; |
|
import 'package:flutter_easyloading/flutter_easyloading.dart'; |
|
import 'package:intl/date_symbol_data_local.dart'; |
|
import 'package:shimmer/shimmer.dart'; |
|
import 'package:siopas/models/customer_model.dart'; |
|
import 'package:siopas/models/disposal_model.dart'; |
|
import 'package:siopas/models/m_asset_status_model.dart'; |
|
import 'package:siopas/models/type_peti_model.dart'; |
|
import 'package:siopas/models/warehouse_mode.dart'; |
|
import 'package:siopas/pages/peminjaman_barang/conn/syncronize.dart'; |
|
import 'package:siopas/services/syncronizeAPI.dart'; |
|
import 'package:siopas/services/controllerApi.dart'; |
|
import 'package:siopas/pages/peminjaman_barang/controller/peminjaman_controller.dart'; |
|
import 'package:intl/intl.dart'; |
|
import 'package:shared_preferences/shared_preferences.dart'; |
|
import 'package:siopas/models/asset_status_model.dart'; |
|
import 'package:siopas/providers/asset_status_provider.dart'; |
|
import 'package:collection/collection.dart'; |
|
import 'package:loading_animation_widget/loading_animation_widget.dart'; |
|
import 'package:flutter_slidable/flutter_slidable.dart'; |
|
|
|
import '../../models/condition_peti_model.dart'; |
|
import '../../widget/loading_shimmer_show.dart'; |
|
import '../home/controller/home_controller.dart'; |
|
import 'show.dart'; |
|
|
|
class AssetStatusPage extends StatefulWidget { |
|
AssetStatusPage({super.key}); |
|
final ControllerHome controllerHome = ControllerHome(); // Declare here |
|
|
|
@override |
|
State<AssetStatusPage> createState() => AssetStatusPageState(); |
|
} |
|
|
|
class AssetStatusPageState extends State<AssetStatusPage> { |
|
String? token; |
|
bool loading = true; |
|
|
|
// Reinit atau Upload Only |
|
WarehouseModel? warehouseSqfliteApi; |
|
List<TypePetiModel>? typePetiSqfliteApi; |
|
List<CustomerModel>? customerSqfliteApi; |
|
PetiAssetModel? petiSqfliteApi; |
|
DisposalPetiModel? disposalSqfliteApi; |
|
|
|
List<PetiAssetModel>? _valpeti; // Change this line |
|
List<WarehouseModel>? _valwarehouse; |
|
List<DisposalPetiModel>? _valdisposal; |
|
|
|
// Datatable |
|
int _currentPage = 1; |
|
int _pageSize = 10; |
|
List<AssetStatusModel>? _data; |
|
List<PetiAssetModel>? _petiData; |
|
List<TypePetiModel>? _tipePetiData; |
|
List<CustomerModel>? _customerData; |
|
List<WarehouseModel>? _warehouseData; |
|
|
|
Timer? _timer; |
|
|
|
String _searchQuery = ''; |
|
int _peminjamanCount = 0; |
|
bool _isLoading = false; |
|
|
|
@override |
|
void initState() { |
|
super.initState(); |
|
_getUserToken(); |
|
|
|
// Mengatur _isLoading ke true sebelum tugas dimulai |
|
if (mounted) { |
|
setState(() { |
|
_isLoading = true; |
|
}); |
|
} |
|
|
|
Future.wait([ |
|
warehouseListAPI(), |
|
typePetiListAPI(), |
|
customerListAPI(), |
|
petiListAPI(), |
|
datatablesAssetStatusList(), |
|
datatablesPetiList(), |
|
datatablesTipePetiList(), |
|
datatablesCustomerList(), |
|
datatablesWarehouseList(), |
|
_initData(), |
|
initializeDateFormatting('id_ID', null), |
|
]).then((_) { |
|
// Mengatur _isLoading ke false setelah semua tugas selesai |
|
if (mounted) { |
|
setState(() { |
|
_isLoading = false; |
|
}); |
|
} |
|
}); |
|
|
|
// Inisialisasi _data di sini jika diperlukan |
|
_data = <AssetStatusModel>[]; |
|
} |
|
|
|
void _getUserToken() async { |
|
SharedPreferences prefs = await SharedPreferences.getInstance(); |
|
if (mounted) { |
|
setState(() { |
|
token = prefs.getString('token'); |
|
}); |
|
} |
|
} |
|
|
|
Future<void> _initData() async { |
|
try { |
|
_peminjamanCount = await widget.controllerHome.getPeminjamanCount(); |
|
} catch (error) { |
|
print('Error fetching peminjamanCount: $error'); |
|
} |
|
// ... tambahkan inisialisasi lainnya |
|
} |
|
|
|
// 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<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> reinitTypePetiApi() async { |
|
EasyLoading.show(status: 'Mengambil data Type Peti...'); |
|
List<TypePetiModel> typePetiApiData = |
|
await SyncronizationDataAPI().fetchTipePetiFromApi(); |
|
await ControllerApi() |
|
.deleteAllTipePetiDataAPI(); // Clear existing data in SQLite |
|
await ControllerApi() |
|
.addAllTipePetiDataAPI(typePetiApiData); // 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 { |
|
EasyLoading.show(status: 'Mengambil data dari Server...'); |
|
await Future.delayed(Duration(seconds: 3)); |
|
|
|
try { |
|
await syncToMysql(); |
|
|
|
await reinitWarehouseApi(); |
|
await reinitPetiApi(); |
|
await reinitCustomerApi(); |
|
await reinitConditionPetiApi(); |
|
|
|
await datatablesAssetStatusList(); |
|
EasyLoading.showSuccess('Data berhasil diperbarui'); |
|
} catch (e) { |
|
EasyLoading.showError('Gagal memperbarui data: $e'); |
|
} finally { |
|
EasyLoading.dismiss(); |
|
} |
|
} |
|
|
|
Future syncToMysql() async { |
|
await SyncronizationPeminjamanData() |
|
.fetchAllInfo() |
|
.then((peminjamanList) async { |
|
EasyLoading.show( |
|
status: 'Jangan tutup aplikasi. Kami sedang menyinkronkan...'); |
|
await Future.delayed(Duration(seconds: 2)); |
|
|
|
// Tambahkan penanganan pengunggahan |
|
bool uploadSuccess = await SyncronizationPeminjamanData() |
|
.saveToPeminjamanWith(peminjamanList); |
|
|
|
// Jika pengunggahan berhasil, hapus data lokal |
|
if (uploadSuccess) { |
|
await SyncronizationPeminjamanData().deleteAllAssetStatusData(); |
|
// Setelah selesai, tampilkan pesan sukses |
|
EasyLoading.showSuccess('Berhasil disinkronkan dengan Server'); |
|
await datatablesAssetStatusList(); |
|
} else { |
|
// Tampilkan pesan gagal jika pengunggahan tidak berhasil |
|
EasyLoading.showError('Gagal disinkronkan dengan Server'); |
|
} |
|
}); |
|
} |
|
|
|
// Future syncToMysql() async { |
|
// await SyncronizationData().fetchAllInfo().then((assetList) async { |
|
// EasyLoading.show(status: 'Don\'t close app. We are syncing...'); |
|
// await SyncronizationData().saveToMysqlWith(assetList); |
|
// await SyncronizationData().deleteAllAssetStatusData(); |
|
// // EasyLoading.showSuccess('Successfully saved to MySQL'); |
|
// }); |
|
// } |
|
|
|
Future<void> isInteret() async { |
|
await SyncronizationPeminjamanData.isInternet().then((connection) { |
|
if (connection) { |
|
print("Internet connection available"); |
|
} else { |
|
ScaffoldMessenger.of(context).showSnackBar( |
|
SnackBar(content: Text("Tidak ada koneksi 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; |
|
}); |
|
}); |
|
} |
|
} |
|
|
|
String _formatDate(String? date) { |
|
if (date != null) { |
|
DateTime parsedDate = DateTime.parse(date); |
|
String formattedDate = |
|
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate); |
|
return formattedDate; |
|
} else { |
|
return ''; |
|
} |
|
} |
|
|
|
List<AssetStatusModel> get _filteredData { |
|
return _data != null |
|
? _data!.where((item) { |
|
// Sesuaikan dengan properti yang ingin Anda cari |
|
return item.exit_pic! |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()) || |
|
_formatDate(item.exit_at.toString()) |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()) || |
|
_formatDate(item.est_pengembalian.toString()) |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()) || |
|
(_petiData?.firstWhere((peti) => peti.id == item.peti_id, orElse: () => PetiAssetModel(fix_lot: ''))?.fix_lot ?? '') |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()) || |
|
(_customerData |
|
?.firstWhere( |
|
(customer) => customer.id == item.customer_id, |
|
orElse: () => CustomerModel(name: '')) |
|
?.name ?? |
|
'') |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()) || |
|
(_warehouseData |
|
?.firstWhere( |
|
(warehouse) => warehouse.id == item.warehouse_id, |
|
orElse: () => WarehouseModel(name: '')) |
|
?.name ?? |
|
'') |
|
.toLowerCase() |
|
.contains(_searchQuery.toLowerCase()); |
|
}).toList() |
|
: []; |
|
} |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
// Add this function outside the build method |
|
// void showSyncDialog(BuildContext context) { |
|
// 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 Peminjaman", |
|
// 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 |
|
// ), |
|
|
|
// // Re-init Button |
|
// Container( |
|
// width: double.infinity, |
|
// child: TextButton( |
|
// onPressed: () { |
|
// Navigator.pop(context); // Close dialog |
|
// fetchDataFromApiAndSync(); |
|
// }, |
|
// child: Text( |
|
// "Upload + Download", |
|
// style: TextStyle( |
|
// color: Colors.black, |
|
// fontSize: 16.0, |
|
// fontFamily: 'Poppins', |
|
// ), |
|
// ), |
|
// ), |
|
// ), |
|
// ], |
|
// ), |
|
// ); |
|
// }, |
|
// ); |
|
// } |
|
|
|
return DefaultTabController( |
|
length: 1, |
|
child: Scaffold( |
|
appBar: appBarPeminjaman(context), |
|
body: _isLoading |
|
? Column( |
|
children: [ |
|
// shimmerSearch(), |
|
Expanded( |
|
child: ListView.builder( |
|
itemCount: |
|
4, // Set the number of shimmer cards based on your data count |
|
itemBuilder: (context, index) { |
|
return ShimmerLoadingAssetStatusCard(); |
|
}, |
|
), |
|
), |
|
], |
|
) |
|
: bodyPeminjaman(), |
|
bottomNavigationBar: bottomAppBar(context), |
|
), |
|
); |
|
} |
|
|
|
BottomAppBar bottomAppBar(BuildContext context) { |
|
return BottomAppBar( |
|
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang |
|
child: Container( |
|
height: 65.0, |
|
child: Row( |
|
mainAxisSize: MainAxisSize.max, |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: <Widget>[ |
|
InkWell( |
|
customBorder: CircleBorder(), |
|
onTap: () { |
|
// Aksi ketika ikon diklik |
|
Navigator.pushNamed(context, '/peminjaman-barang/create'); |
|
}, |
|
child: Container( |
|
width: 45, |
|
height: 45, |
|
decoration: BoxDecoration( |
|
shape: BoxShape.circle, |
|
color: Colors.greenAccent[700], |
|
), |
|
child: Icon( |
|
Icons.add, |
|
size: 30, |
|
color: Colors.white, |
|
), |
|
), |
|
), |
|
], |
|
), |
|
), |
|
); |
|
} |
|
|
|
Column bodyPeminjaman() { |
|
return Column( |
|
children: [ |
|
// Container( |
|
// margin: EdgeInsets.only(top: 7, bottom: 7), |
|
// child: Padding( |
|
// padding: const EdgeInsets.symmetric(horizontal: 16), |
|
// child: TextField( |
|
// style: TextStyle(fontSize: 16), |
|
// decoration: InputDecoration( |
|
// hintText: 'Masukkan data pencarian...', |
|
// prefixIcon: Icon(Icons.search), |
|
// border: InputBorder.none, |
|
// enabledBorder: OutlineInputBorder( |
|
// borderRadius: BorderRadius.circular(12), |
|
// borderSide: BorderSide(color: Colors.grey, width: 1.0), |
|
// ), |
|
// focusedBorder: OutlineInputBorder( |
|
// borderRadius: BorderRadius.circular(12), |
|
// borderSide: BorderSide(color: Colors.indigo, width: 1.0), |
|
// ), |
|
// contentPadding: EdgeInsets.all(16), |
|
// labelStyle: TextStyle( |
|
// color: Colors.grey, |
|
// fontSize: 16, |
|
// ), |
|
// hintStyle: TextStyle( |
|
// color: Colors.grey, |
|
// fontSize: 16, |
|
// ), |
|
// prefixIconConstraints: BoxConstraints( |
|
// minWidth: 40, |
|
// ), |
|
// suffixIcon: _searchQuery.isNotEmpty |
|
// ? IconButton( |
|
// icon: Icon(Icons.clear), |
|
// onPressed: () { |
|
// setState(() { |
|
// _searchQuery = ''; |
|
// }); |
|
// }, |
|
// ) |
|
// : null, |
|
// ), |
|
// onChanged: (value) { |
|
// setState(() { |
|
// _searchQuery = value; |
|
// }); |
|
// }, |
|
// ), |
|
// ), |
|
// ), |
|
Expanded( |
|
child: TabBarView( |
|
children: [ |
|
SingleChildScrollView( |
|
child: Column( |
|
children: _filteredData.isNotEmpty |
|
? _filteredData.asMap().entries.map((entry) { |
|
final index = entry.key + 1; |
|
final item = entry.value; |
|
|
|
return AssetStatusCard( |
|
assetStatus: item, |
|
petiData: _petiData ?? [], |
|
tipePetiData: _tipePetiData ?? [], |
|
customerData: _customerData ?? [], |
|
warehouseData: _warehouseData ?? [], |
|
index: index, |
|
); |
|
}).toList() |
|
// : [Text('No results')], |
|
: [ |
|
Center( |
|
child: Column( |
|
children: [ |
|
Image.asset( |
|
'assets/item/empty.png', |
|
width: 250, // Set the width as needed |
|
height: 250, // Set the height as needed |
|
), |
|
Text( |
|
'Tidak ada data ditemukan', |
|
style: TextStyle( |
|
fontSize: 16, |
|
fontWeight: FontWeight.bold, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
], |
|
), |
|
), |
|
], |
|
), |
|
), |
|
], |
|
); |
|
} |
|
|
|
AppBar appBarPeminjaman(BuildContext context) { |
|
Future<int> peminjamanCount = widget.controllerHome.getPeminjamanCount(); |
|
|
|
return AppBar( |
|
backgroundColor: Colors.indigo[700], |
|
elevation: 0, |
|
title: Text('Data Peminjaman Peti', |
|
style: TextStyle( |
|
fontSize: 16, |
|
)), |
|
// actions: [ |
|
// IconButton( |
|
// icon: Icon(Icons.backup), |
|
// onPressed: () async { |
|
// if (await SyncronizationPeminjamanData.isInternet()) { |
|
// // Display custom dialog when the IconButton is pressed |
|
// showSyncDialog(context); |
|
// } else { |
|
// ScaffoldMessenger.of(context).showSnackBar( |
|
// SnackBar(content: Text("Tidak ada koneksi internet")), |
|
// ); |
|
// } |
|
// }, |
|
// ), |
|
// ], |
|
leading: IconButton( |
|
icon: Icon(Icons.arrow_back, color: Colors.white), |
|
onPressed: () { |
|
Navigator.pushNamed(context, '/home'); |
|
}, |
|
), |
|
bottom: TabBar( |
|
indicator: BoxDecoration( |
|
color: Color.fromARGB(255, 255, 165, 9), |
|
), |
|
tabs: [ |
|
Tab( |
|
height: 65, |
|
child: Container( |
|
padding: const EdgeInsets.symmetric(horizontal: 16), |
|
decoration: BoxDecoration( |
|
color: Colors.white, |
|
borderRadius: BorderRadius.circular(0), |
|
border: Border.all(color: Colors.grey, width: 1.0), |
|
), |
|
child: Row( |
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
children: [ |
|
Expanded( |
|
child: TextField( |
|
style: TextStyle(fontSize: 18), |
|
decoration: InputDecoration( |
|
hintText: 'Masukkan data pencarian...', |
|
prefixIcon: Icon(Icons.search), |
|
border: InputBorder.none, |
|
contentPadding: EdgeInsets.all(10), |
|
labelStyle: TextStyle( |
|
color: Colors.grey, |
|
fontSize: 12, |
|
), |
|
hintStyle: TextStyle( |
|
color: Colors.grey, |
|
fontSize: 12, |
|
), |
|
// suffixIcon: _searchQuery.isNotEmpty |
|
// ? IconButton( |
|
// icon: Icon(Icons.clear), |
|
// onPressed: () { |
|
// setState(() { |
|
// // _searchQuery = null; // Mengganti dengan null |
|
// }); |
|
// }, |
|
// ) |
|
// : null, |
|
), |
|
onChanged: (value) { |
|
setState(() { |
|
_searchQuery = value.isNotEmpty |
|
? value |
|
: ''; // Memperbarui dengan null jika value kosong |
|
}); |
|
}, |
|
), |
|
), |
|
Text( |
|
'Total: $_peminjamanCount', |
|
style: TextStyle(color: Colors.black), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
], |
|
), |
|
); |
|
} |
|
} |
|
|
|
class AssetStatusCard extends StatelessWidget { |
|
final AssetStatusModel assetStatus; |
|
final List<PetiAssetModel> petiData; |
|
final List<TypePetiModel> tipePetiData; |
|
final List<CustomerModel> customerData; |
|
final List<WarehouseModel> warehouseData; |
|
final int index; // Tambahkan parameter nomor urutan |
|
|
|
AssetStatusCard({ |
|
required this.assetStatus, |
|
required this.petiData, |
|
required this.tipePetiData, |
|
required this.customerData, |
|
required this.warehouseData, |
|
required this.index, // Inisialisasi parameter nomor urutan |
|
}); |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
PetiAssetModel? petiSqfliteApi = petiData.firstWhereOrNull( |
|
(peti) => peti.id == assetStatus.peti_id, |
|
); |
|
|
|
TypePetiModel? tipePetiSqfliteApi = tipePetiData.firstWhereOrNull( |
|
(tipePeti) => tipePeti.id == petiSqfliteApi?.tipe_peti_id, |
|
); |
|
|
|
CustomerModel? customerSqfliteApi = customerData.firstWhereOrNull( |
|
(customer) => customer.id == assetStatus.customer_id, |
|
); |
|
|
|
WarehouseModel? warehouseSqfliteApi = warehouseData.firstWhereOrNull( |
|
(warehouse) => warehouse.id == assetStatus.warehouse_id, |
|
); |
|
|
|
// WarehouseModel? warehouseTujuanSqfliteApi = warehouseData.firstWhereOrNull( |
|
// (warehouse) => warehouse.id == assetStatus.exit_warehouse, |
|
// ); |
|
|
|
String _formatDate(String? date) { |
|
if (date != null) { |
|
DateTime parsedDate = DateTime.parse(date); |
|
String formattedDate = |
|
DateFormat('EEEE, dd MMMM yyyy', 'id_ID').format(parsedDate); |
|
return formattedDate; |
|
} else { |
|
return ''; |
|
} |
|
} |
|
|
|
Future<void> _deletePeminjaman() async { |
|
try { |
|
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID |
|
await Controller().deletePeminjamanById(assetStatus.id.toString()); |
|
// Navigasi kembali ke halaman sebelumnya atau halaman yang sesuai |
|
Navigator.pushReplacementNamed(context, '/peminjaman-barang'); |
|
} catch (e) { |
|
// Tangani kesalahan jika terjadi |
|
print('Gagal menghapus peminjaman: $e'); |
|
} |
|
} |
|
|
|
Future<void> _showDeleteConfirmationDialog() async { |
|
return showDialog<void>( |
|
context: context, |
|
builder: (BuildContext context) { |
|
return AlertDialog( |
|
shape: RoundedRectangleBorder( |
|
borderRadius: BorderRadius.circular(16.0), |
|
), |
|
title: Row( |
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
children: [ |
|
Row( |
|
children: [ |
|
Icon( |
|
Icons.info, |
|
color: Colors.blue, |
|
), |
|
SizedBox(width: 8), |
|
Text( |
|
'Konfirmasi Hapus', |
|
style: TextStyle( |
|
fontSize: 18, |
|
), |
|
), |
|
], |
|
), |
|
IconButton( |
|
icon: Icon( |
|
Icons.close, |
|
color: Colors.black54, |
|
), |
|
onPressed: () { |
|
Navigator.of(context).pop(); |
|
}, |
|
), |
|
], |
|
), |
|
content: SingleChildScrollView( |
|
child: ListBody( |
|
children: <Widget>[ |
|
Text( |
|
'Anda yakin ingin menghapus peminjaman ini? ${petiSqfliteApi!.fix_lot.toString()}', |
|
style: TextStyle( |
|
fontSize: 16, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
actions: <Widget>[ |
|
Container( |
|
margin: EdgeInsets.only(right: 3.0), |
|
child: ElevatedButton( |
|
child: Text('Hapus'), |
|
onPressed: () { |
|
// Panggil fungsi untuk menghapus peminjaman berdasarkan ID |
|
_deletePeminjaman(); |
|
// Navigator.pushNamed(context, '/peminjaman-barang'); |
|
EasyLoading.showSuccess( |
|
'Berhasil menghapus data peminjaman'); |
|
}, |
|
style: ElevatedButton.styleFrom( |
|
primary: Colors.red, |
|
), |
|
), |
|
), |
|
], |
|
); |
|
}, |
|
); |
|
} |
|
|
|
return Slidable( |
|
key: Key(assetStatus.id.toString()), |
|
endActionPane: ActionPane( |
|
motion: ScrollMotion(), |
|
children: [ |
|
SlidableAction( |
|
onPressed: (context) { |
|
_showDeleteConfirmationDialog(); |
|
}, |
|
backgroundColor: Color(0xFFFE4A49), |
|
foregroundColor: Colors.white, |
|
icon: Icons.delete, |
|
label: 'Hapus', |
|
), |
|
], |
|
), |
|
child: GestureDetector( |
|
onTap: () { |
|
// Tindakan yang dilakukan saat card diklik |
|
if (assetStatus != null) { |
|
Navigator.push( |
|
context, |
|
MaterialPageRoute( |
|
builder: (context) => DetailPeminjamanBarangPage( |
|
peminjamanId: assetStatus.id.toString(), |
|
), |
|
), |
|
); |
|
} |
|
}, |
|
child: Card( |
|
color: Colors.white60, |
|
elevation: 0.0, |
|
shape: RoundedRectangleBorder( |
|
side: BorderSide(color: Colors.grey, width: 1.0), |
|
), |
|
child: Padding( |
|
padding: const EdgeInsets.only( |
|
top: 8.0, |
|
bottom: 8.0, |
|
left: 16.0, |
|
right: 16.0, |
|
), |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
_buildAvatarAndIndex(index), |
|
Divider(), |
|
_buildInfoRow( |
|
'Nama Peminjam:', |
|
'${customerSqfliteApi?.name ?? '-'}', |
|
'PIC:', |
|
'${assetStatus.exit_pic ?? '-'}', |
|
13), |
|
_buildInfoRow( |
|
'Tanggal Peminjaman:', |
|
'${_formatDate(assetStatus.exit_at.toString())}', |
|
'Estimasi Pengembalian:', |
|
'${_formatDate(assetStatus.est_pengembalian.toString())}', |
|
13), |
|
_buildInfoRow('Tujuan Gudang:', |
|
'${warehouseSqfliteApi?.name ?? '-'}', '', '', 13), |
|
], |
|
), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget _buildAvatarAndIndex(int index) { |
|
PetiAssetModel? petiSqfliteApi = petiData.firstWhereOrNull( |
|
(peti) => peti.id == assetStatus.peti_id, |
|
); |
|
return Row( |
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
_buildAvatar(index), |
|
Expanded( |
|
child: Padding( |
|
padding: const EdgeInsets.only( |
|
left: 8.0, |
|
top: 8.0, |
|
), |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Text( |
|
'${petiSqfliteApi?.fix_lot ?? '-'}', |
|
style: TextStyle( |
|
fontWeight: FontWeight.bold, |
|
fontSize: 14.5, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
], |
|
); |
|
} |
|
|
|
Widget _buildAvatar(int index) { |
|
return Container( |
|
child: CircleAvatar( |
|
radius: 11, |
|
backgroundColor: Colors.indigo[700], |
|
child: Text( |
|
'$index', |
|
style: TextStyle( |
|
fontWeight: FontWeight.bold, |
|
fontSize: 13, |
|
color: Colors.white, |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
Widget _buildInfoRow(String title1, String content1, String title2, |
|
String content2, double fontSize) { |
|
return Row( |
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Expanded( |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Text( |
|
title1, |
|
style: TextStyle( |
|
fontWeight: FontWeight.bold, |
|
fontSize: fontSize, |
|
), |
|
), |
|
SizedBox(height: 3), |
|
Text( |
|
content1, |
|
style: TextStyle( |
|
fontSize: fontSize - |
|
0.5, // Mengurangkan ukuran font agar cocok dengan judul |
|
), |
|
), |
|
], |
|
), |
|
), |
|
SizedBox(width: 10), // Memberi jarak antara dua kolom |
|
Expanded( |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Text( |
|
title2, |
|
style: TextStyle( |
|
fontWeight: FontWeight.bold, |
|
fontSize: fontSize, |
|
), |
|
), |
|
SizedBox(height: 3), |
|
Text( |
|
content2, |
|
style: TextStyle( |
|
fontSize: fontSize - |
|
0.5, // Mengurangkan ukuran font agar cocok dengan judul |
|
), |
|
), |
|
], |
|
), |
|
), |
|
], |
|
); |
|
} |
|
}
|
|
|