From 9451c0dc0bca51b53faf9ef0e6e0afd9ab711460 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Jan 2024 22:33:04 +0700 Subject: [PATCH] Perubahan fitur Pengaturan login domain/IPport, perbaikan typo tampilan peminjaman, pengembalian, transfer peti, perbaikan loading shimmer, dan perbaikan bug reinit --- lib/connection/connection.dart | 31 ++- lib/pages/home/home_page.dart | 71 +++++- lib/pages/home/main_page.dart | 189 ++++++++------ lib/pages/pengembalian_barang/index.dart | 4 +- lib/pages/sign_in_page.dart | 55 ++--- lib/pages/transfer_peti/index.dart | 4 +- lib/widget/loading_shimmer_show.dart | 300 ++++++++++++++++++++++- 7 files changed, 535 insertions(+), 119 deletions(-) diff --git a/lib/connection/connection.dart b/lib/connection/connection.dart index 7fd965a..d50558c 100644 --- a/lib/connection/connection.dart +++ b/lib/connection/connection.dart @@ -1,25 +1,32 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../pages/sign_in_page.dart'; + +import 'package:path_provider/path_provider.dart'; Future getBaseUrl() async { try { - SharedPreferences prefs = await SharedPreferences.getInstance(); - String ipAddress = - prefs.getString('ipAddress') ?? '192.168.1.14'; // Default value - String port = prefs.getString('port') ?? '8000'; // Default value + String savedValue = await getSavedValue(); + + // Check if savedValue is a domain, IP with or without port + String baseUrl; - String baseUrl = 'http://$ipAddress:$port/api/v1'; + if (savedValue.contains(':')) { + // If savedValue contains a colon, assume it's an IP with port + baseUrl = 'http://$savedValue/api/v1'; + } else if (RegExp(r'^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$').hasMatch(savedValue)) { + // If savedValue matches the domain pattern, assume it's a domain + baseUrl = 'https://$savedValue/api/v1'; + } else { + // If it doesn't match both patterns, assume it's an IP without port + baseUrl = 'https://$savedValue/api/v1'; + } return baseUrl; } catch (e) { - // Penanganan kesalahan + // Error handling print('Error reading SharedPreferences: $e'); - return ''; // Atau nilai default lainnya jika terjadi kesalahan + return ''; // Or any other default value in case of an error } } - - // return 'http://$ipAddress:$port/api/v1'; -// String baseUrl = 'http://192.168.0.18:8000/api/v1'; -// Gunakan fungsi ini saat diperlukan, misalnya di tempat-tempat yang membutuhkan baseUrl -// Contoh penggunaan: String url = await getBaseUrl(); diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index 3f331e4..1bd7868 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -30,6 +30,14 @@ 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(); @@ -71,10 +79,11 @@ class _HomePageState extends State { super.initState(); _getUserToken(); - // Mengatur _isLoading ke true sebelum tugas dimulai + // Mengatur _isLoading dan _isFetchingData ke true sebelum tugas dimulai if (mounted) { setState(() { _isLoading = true; + _isFetchingData = true; }); } @@ -100,10 +109,11 @@ class _HomePageState extends State { initializeDateFormatting('id_ID', null), ]); - // Mengatur _isLoading ke false setelah semua tugas selesai + // Mengatur _isLoading dan _isFetchingData ke false setelah semua tugas selesai if (mounted) { setState(() { _isLoading = false; + _isFetchingData = false; }); } } @@ -262,6 +272,9 @@ class _HomePageState extends State { _isFetchingData = true; }); + // Callback to inform that Reinit process has started + widget.onReinitStarted?.call(); + EasyLoading.show(status: 'Mengambil data dari Server...'); try { // Cek koneksi internet @@ -295,10 +308,61 @@ class _HomePageState extends State { _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( @@ -444,6 +508,7 @@ class _HomePageState extends State { Widget cardMenuPeminjaman() { return Container( height: 125, + margin: EdgeInsets.only(left: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), @@ -480,6 +545,7 @@ class _HomePageState extends State { Widget cardMenuPengembalian() { return Container( height: 125, + margin: EdgeInsets.only(right: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), @@ -516,6 +582,7 @@ class _HomePageState extends State { Widget cardMenuTransfer() { return Container( height: 125, + margin: EdgeInsets.only(left: 10), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.0), diff --git a/lib/pages/home/main_page.dart b/lib/pages/home/main_page.dart index 1831fa1..b200447 100644 --- a/lib/pages/home/main_page.dart +++ b/lib/pages/home/main_page.dart @@ -1,8 +1,87 @@ +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import '../../providers/auth_provider.dart'; +// import 'home_page.dart'; +// import 'setting_page.dart'; + +// class MainPage extends StatefulWidget { +// @override +// State createState() => _MainPageState(); +// } + +// class _MainPageState extends State { +// int currentIndex = 0; +// bool isReinitInProgress = false; +// @override +// Widget build(BuildContext context) { +// AuthProvider authProvider = Provider.of(context); + +// Widget customBottomNav() { +// return ClipRRect( +// // borderRadius: BorderRadius.only( +// // topLeft: Radius.circular(20.0), +// // topRight: Radius.circular(20.0), +// // ), +// child: BottomNavigationBar( +// type: BottomNavigationBarType.fixed, +// currentIndex: currentIndex, +// selectedItemColor: Colors.indigoAccent, // Warna saat dipilih +// onTap: (index) { +// if (mounted) { +// setState(() { +// currentIndex = index; +// }); +// } +// }, +// items: [ +// BottomNavigationBarItem( +// icon: Icon(Icons.home), +// label: 'Beranda', +// ), +// BottomNavigationBarItem( +// icon: Icon(Icons.settings), +// label: 'Pengaturan', +// ), +// ], +// ), +// ); +// } + +// Widget body() { +// switch (currentIndex) { +// case 0: +// return HomePage(); +// case 1: +// // Return your MapsPage here +// return SettingPage(); // Ganti dengan MapsPage + +// default: +// return Container(); // Add more cases if needed +// } +// } + +// return Scaffold( +// backgroundColor: currentIndex == 0 +// ? Color.fromRGBO(255, 255, 255, 0.973) +// : Colors.grey, +// bottomNavigationBar: customBottomNav(), +// body: Stack( +// children: [ +// body(), +// ], +// ), +// // extendBody: true, // Membuat latar belakang menembus hingga ke bawah +// ); +// } +// } + +// main_page.dart + import 'package:flutter/material.dart'; +import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:provider/provider.dart'; import '../../providers/auth_provider.dart'; import 'home_page.dart'; -import '../peminjaman_barang/peminjaman_stock_page.dart'; import 'setting_page.dart'; class MainPage extends StatefulWidget { @@ -12,67 +91,38 @@ class MainPage extends StatefulWidget { class _MainPageState extends State { int currentIndex = 0; + bool isReinitInProgress = false; @override Widget build(BuildContext context) { AuthProvider authProvider = Provider.of(context); Widget customBottomNav() { - return ClipRRect( - // borderRadius: BorderRadius.only( - // topLeft: Radius.circular(20.0), - // topRight: Radius.circular(20.0), - // ), - child: BottomNavigationBar( - type: BottomNavigationBarType.fixed, - currentIndex: currentIndex, - selectedItemColor: Colors.indigoAccent, // Warna saat dipilih - onTap: (index) { - if (mounted) { - setState(() { - currentIndex = index; - }); - } - }, - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.home), - label: 'Beranda', - ), - // BottomNavigationBarItem( - // icon: Icon(Icons.assignment_return), - // label: 'Return', - // ), - // BottomNavigationBarItem( - // icon: GestureDetector( - // onTap: () { - // setState(() { - // currentIndex = 2; - // }); - // }, - // child: Container( - // width: 60.0, - // height: 60.0, - // decoration: BoxDecoration( - // color: Colors.indigoAccent, - // shape: BoxShape.circle, - // ), - // child: Center( - // child: Icon(Icons.qr_code, size: 30.0, color: Colors.white), - // ), - // ), - // ), - // label: '', // Menghilangkan teks label - // ), - // BottomNavigationBarItem( - // icon: Icon(Icons.markunread_mailbox), - // label: 'Receive', - // ), - BottomNavigationBarItem( - icon: Icon(Icons.settings), - label: 'Pengaturan', - ), - ], + return AbsorbPointer( + absorbing: isReinitInProgress, + child: ClipRRect( + child: BottomNavigationBar( + type: BottomNavigationBarType.fixed, + currentIndex: currentIndex, + selectedItemColor: Colors.indigoAccent, + onTap: (index) { + if (!isReinitInProgress) { + setState(() { + currentIndex = index; + }); + } + }, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Beranda', + ), + BottomNavigationBarItem( + icon: Icon(Icons.settings), + label: 'Pengaturan', + ), + ], + ), ), ); } @@ -80,21 +130,21 @@ class _MainPageState extends State { Widget body() { switch (currentIndex) { case 0: - return HomePage(); + return HomePage(onReinitStarted: () { + // Callback untuk memberi tahu bahwa Reinit dimulai + setState(() { + isReinitInProgress = true; + }); + }, onReinitFinished: () { + // Callback untuk memberi tahu bahwa Reinit selesai + setState(() { + isReinitInProgress = false; + }); + }); case 1: - // Return your MapsPage here - return SettingPage(); // Ganti dengan MapsPage - // case 2: - // // Add your QR Code page here - // return Placeholder(); // Ganti dengan halaman QR Code - // case 3: - // // Return your HistoryPage here - // return Placeholder(); // Ganti dengan HistoryPage - // case 4: - // // Return your ProfilePage here - // return SettingPage(); // Ganti dengan ProfilePage + return SettingPage(); default: - return Container(); // Add more cases if needed + return Container(); } } @@ -108,7 +158,6 @@ class _MainPageState extends State { body(), ], ), - // extendBody: true, // Membuat latar belakang menembus hingga ke bawah ); } } diff --git a/lib/pages/pengembalian_barang/index.dart b/lib/pages/pengembalian_barang/index.dart index 4fb3d0c..c324d61 100644 --- a/lib/pages/pengembalian_barang/index.dart +++ b/lib/pages/pengembalian_barang/index.dart @@ -319,7 +319,7 @@ class PengembalianBarangPageState extends State { itemCount: 4, // Set the number of shimmer cards based on your data count itemBuilder: (context, index) { - return ShimmerLoadingAssetStatusCard(); + return ShimmerLoadingAssetStatusPengembalianCard(); }, ), ), @@ -693,7 +693,7 @@ class AssetStatusCard extends StatelessWidget { _buildInfoRow( 'Gudang:', '${warehouseSqfliteApi?.name ?? '-'}', - 'Kondisi Barang', + 'Kondisi Barang:', '${conditionPetiSqfliteApi?.nama_kondisi ?? '-'}', 13), ], diff --git a/lib/pages/sign_in_page.dart b/lib/pages/sign_in_page.dart index 62c2493..8212235 100644 --- a/lib/pages/sign_in_page.dart +++ b/lib/pages/sign_in_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter/services.dart'; import 'package:siopas/theme.dart'; @@ -357,24 +358,19 @@ class SettingsModal extends StatefulWidget { } class _SettingsModalState extends State { - TextEditingController ipAddressController = TextEditingController(); - TextEditingController portController = TextEditingController(); + TextEditingController inputController = TextEditingController(); @override void initState() { super.initState(); - // Load saved IP Address and Port when the modal is initialized + // Load saved IP Address or Port when the modal is initialized loadSettings(); } void loadSettings() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - String ipAddress = prefs.getString('ipAddress') ?? ''; - String port = prefs.getString('port') ?? ''; - + String savedValue = await getSavedValue(); setState(() { - ipAddressController.text = ipAddress; - portController.text = port; + inputController.text = savedValue; }); } @@ -397,23 +393,20 @@ class _SettingsModalState extends State { mainAxisSize: MainAxisSize.min, children: [ TextFormField( - controller: ipAddressController, - keyboardType: TextInputType.number, // Set numeric keyboard - decoration: InputDecoration(labelText: 'IP Address'), - ), - SizedBox(height: 16), - TextFormField( - controller: portController, - keyboardType: TextInputType.number, // Set numeric keyboard - decoration: InputDecoration(labelText: 'Port'), + controller: inputController, + inputFormatters: [ + FilteringTextInputFormatter.allow( + RegExp(r'[a-zA-Z0-9@#$%^&*()_+={}|\[\]\\:;"<>,.?/~`-]')) + ], + decoration: InputDecoration(labelText: 'Domain atau IP:Port'), ), ], ), actions: [ ElevatedButton( onPressed: () { - // Save IP Address and Port to SharedPreferences - saveSettings(ipAddressController.text, portController.text); + // Save value to SharedPreferences + saveSettings(inputController.text); Navigator.of(context).pop(); // Close the modal }, child: Text('Simpan'), @@ -422,21 +415,23 @@ class _SettingsModalState extends State { ); } - void saveSettings(String ipAddress, String port) async { + Future saveSettings(String value) async { SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString('ipAddress', ipAddress); - prefs.setString('port', port); + prefs.setString('savedValue', value); // Print the saved data - print('IP Address saved: $ipAddress'); - print('Port saved: $port'); + print('Value saved: $value'); } - // Function to clear the IP Address and Port in SharedPreferences - void clearSettings() async { + Future clearSettings() async { SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.remove('ipAddress'); - prefs.remove('port'); - print('IP Address and Port cleared'); + prefs.remove('savedValue'); + print('Value cleared'); } } + +Future getSavedValue() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String savedValue = prefs.getString('savedValue') ?? ''; + return savedValue; +} diff --git a/lib/pages/transfer_peti/index.dart b/lib/pages/transfer_peti/index.dart index a9fbe70..be67dc6 100644 --- a/lib/pages/transfer_peti/index.dart +++ b/lib/pages/transfer_peti/index.dart @@ -267,7 +267,7 @@ class TransferPetiPageState extends State { itemCount: 4, // Set the number of shimmer cards based on your data count itemBuilder: (context, index) { - return ShimmerLoadingAssetStatusCard(); + return ShimmerLoadingAssetStatusTransferPetiCard(); }, ), ), @@ -634,7 +634,7 @@ class TransferPetiCard extends StatelessWidget { _buildInfoRow( 'Asal Gudang:', '${warehouseSqfliteApi?.name ?? '-'}', - 'Tujuan Gudang', + 'Tujuan Gudang:', '${warehouseTujuanSqfliteApi?.name ?? '-'}', 13), ], diff --git a/lib/widget/loading_shimmer_show.dart b/lib/widget/loading_shimmer_show.dart index 288202a..982b378 100644 --- a/lib/widget/loading_shimmer_show.dart +++ b/lib/widget/loading_shimmer_show.dart @@ -137,9 +137,307 @@ class ShimmerLoadingAssetStatusCard extends StatelessWidget { children: [ _buildAvatarAndIndex(), Divider(), - _buildInfoRow('Nama Peminjam:', '', 'PIC:', '', 11.5), + _buildInfoRow('Nama Customer:', '', 'PIC/PJ:', '', 11.5), _buildInfoRow('Tanggal Peminjaman:', '', 'Estimasi Pengembalian:', '', 11.5), + _buildInfoRow('Gudang:', '', '', '', 11.5), + ], + ), + ), + ), + ), + ], + ); + } + + Widget _buildAvatarAndIndex() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildAvatar(), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 8.0, + top: 8.0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // '', + // style: TextStyle( + // fontWeight: FontWeight.bold, + // fontSize: 11.5, + // ), + // ), + lineDivider(), + ], + ), + ), + ), + ], + ); + } + + Widget lineDivider() { + return Container( + height: 13, + width: double.infinity, + decoration: BoxDecoration( + color: Colors.grey[500], + borderRadius: BorderRadius.vertical( + top: Radius.circular(6), // Adjust top radius as needed + bottom: Radius.circular(6), // Adjust bottom radius as needed + ), + ), + ); + } + + Widget _buildAvatar() { + return Container( + child: CircleAvatar( + radius: 11, + backgroundColor: Colors.indigo, + ), + ); + } + + 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), + lineDivider(), + // Text( + // content1, + // style: TextStyle( + // fontSize: fontSize - 0.5, + // ), + // ), + ], + ), + ), + SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // lineDivider(), + Text( + title2, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: fontSize, + ), + ), + SizedBox(height: 3), + lineDivider() + // Text( + // content2, + // style: TextStyle( + // fontSize: fontSize - 0.5, + // ), + // ), + ], + ), + ), + ], + ); + } +} + +class ShimmerLoadingAssetStatusPengembalianCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Column( + children: [ + Card( + elevation: 0.0, + shape: RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 1.0), + // borderRadius: BorderRadius.circular(10), + ), + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + 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(), + Divider(), + _buildInfoRow( + 'PIC/PJ:', '', 'Tanggal Pengembalian:', '', 11.5), + _buildInfoRow('Gudang:', '', 'Kondisi Barang:', '', 11.5), + ], + ), + ), + ), + ), + ], + ); + } + + Widget _buildAvatarAndIndex() { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildAvatar(), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + left: 8.0, + top: 8.0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Text( + // '', + // style: TextStyle( + // fontWeight: FontWeight.bold, + // fontSize: 11.5, + // ), + // ), + lineDivider(), + ], + ), + ), + ), + ], + ); + } + + Widget lineDivider() { + return Container( + height: 13, + width: double.infinity, + decoration: BoxDecoration( + color: Colors.grey[500], + borderRadius: BorderRadius.vertical( + top: Radius.circular(6), // Adjust top radius as needed + bottom: Radius.circular(6), // Adjust bottom radius as needed + ), + ), + ); + } + + Widget _buildAvatar() { + return Container( + child: CircleAvatar( + radius: 11, + backgroundColor: Colors.indigo, + ), + ); + } + + 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), + lineDivider(), + // Text( + // content1, + // style: TextStyle( + // fontSize: fontSize - 0.5, + // ), + // ), + ], + ), + ), + SizedBox(width: 10), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // lineDivider(), + Text( + title2, + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: fontSize, + ), + ), + SizedBox(height: 3), + lineDivider() + // Text( + // content2, + // style: TextStyle( + // fontSize: fontSize - 0.5, + // ), + // ), + ], + ), + ), + ], + ); + } +} + +class ShimmerLoadingAssetStatusTransferPetiCard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Column( + children: [ + Card( + elevation: 0.0, + shape: RoundedRectangleBorder( + side: BorderSide(color: Colors.grey, width: 1.0), + // borderRadius: BorderRadius.circular(10), + ), + child: Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + 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(), + Divider(), + _buildInfoRow( + 'Nama Customer:', '', 'Tanggal Transfer Peti:', '', 11.5), _buildInfoRow('Asal Gudang:', '', 'Tujuan Gudang:', '', 11.5), ], ),