Browse Source

perbaikan sistem peminjaman, scan qr code, dropdown peti, list peti, pembuatan create finish, pembaharuan tampilan peminjaman, search peminjaman, total peminjaman, perubahan tampilan dashboard home

master
unknown 11 months ago
parent
commit
daa21c4f8b
  1. BIN
      assets/item/empty.png
  2. 1
      lib/main.dart
  3. 5
      lib/migrations/databasehelper.dart
  4. 12
      lib/models/asset_status_model.dart
  5. 7
      lib/models/m_asset_status_model.dart
  6. 8
      lib/pages/home/conn_home_page.dart/syncronize.dart
  7. 402
      lib/pages/home/home_page.dart
  8. 2
      lib/pages/home/main_page.dart
  9. 2
      lib/pages/home/setting_page.dart
  10. 6
      lib/pages/peminjaman_barang/conn/syncronize.dart
  11. 4
      lib/pages/peminjaman_barang/controller/peminjaman_controller.dart
  12. 873
      lib/pages/peminjaman_barang/create-finish.dart
  13. 1387
      lib/pages/peminjaman_barang/create.dart
  14. 949
      lib/pages/peminjaman_barang/peminjaman_stock_page.dart
  15. 84
      lib/pages/peminjaman_barang/show.dart
  16. 15
      lib/pages/pengembalian_barang/edit.dart
  17. 24
      lib/pages/pengembalian_barang/index.dart
  18. 10
      lib/pages/pengembalian_barang/show.dart
  19. 9
      lib/pages/sign_in_page.dart
  20. 6
      lib/pages/transfer_peti/index.dart
  21. 13
      lib/widget/component_query.dart
  22. 299
      lib/widget/loading_shimmer_show.dart
  23. 8
      pubspec.lock
  24. 2
      pubspec.yaml

BIN
assets/item/empty.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

1
lib/main.dart

@ -1,6 +1,7 @@
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:siopas/migrations/databasehelper.dart';
import 'package:siopas/pages/peminjaman_barang/create-finish.dart';
import 'package:siopas/pages/transfer_peti/edit.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';

5
lib/migrations/databasehelper.dart

@ -24,6 +24,8 @@ class SqfliteDatabaseHelper {
// static final assetLocalTable = 'asset_statuses_local';
static final peminjamanTable = 'peminjamans';
static final temporaryPeminjamanTable = 'temporary_peminjamans';
static final pengembalianTable = 'pengembalians';
static final _version = 1; // Versi database ditingkatkan
@ -73,7 +75,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,
@ -97,7 +98,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,
@ -121,7 +121,6 @@ class SqfliteDatabaseHelper {
exit_at DATETIME NULL,
est_pengembalian DATETIME NULL,
exit_pic TEXT NULL,
exit_warehouse INTEGER NULL,
enter_at DATETIME NULL,
enter_pic TEXT NULL,
enter_warehouse INTEGER NULL,

12
lib/models/asset_status_model.dart

@ -9,7 +9,7 @@ class AssetStatusModel {
int? warehouse_id;
DateTime? exit_at;
String? exit_pic;
int? exit_warehouse;
// int? exit_warehouse;
DateTime? enter_at;
String? enter_pic;
int? enter_warehouse;
@ -33,7 +33,7 @@ class AssetStatusModel {
this.warehouse_id,
this.exit_at,
this.exit_pic,
this.exit_warehouse,
// this.exit_warehouse,
this.enter_at,
this.enter_pic,
this.enter_warehouse,
@ -64,9 +64,9 @@ class AssetStatusModel {
: 0,
exit_at: parseDateTime(json['exit_at']),
exit_pic: json['exit_pic'],
exit_warehouse: json['exit_warehouse'] != null
? int.parse(json['exit_warehouse'].toString())
: 0,
// exit_warehouse: json['exit_warehouse'] != null
// ? int.parse(json['exit_warehouse'].toString())
// : 0,
enter_at: parseDateTime(json['enter_at']),
enter_pic: json['enter_pic'],
enter_warehouse: json['enter_warehouse'] != null
@ -92,7 +92,7 @@ class AssetStatusModel {
'warehouse_id': warehouse_id,
'exit_at': exit_at?.toIso8601String(),
'exit_pic': exit_pic.toString(),
'exit_warehouse': exit_warehouse,
// 'exit_warehouse': exit_warehouse,
'enter_at': enter_at?.toIso8601String(),
'enter_pic': enter_pic,
'enter_warehouse': enter_warehouse?.toString(),

7
lib/models/m_asset_status_model.dart

@ -6,7 +6,7 @@ class PetiAssetModel {
int? id;
int? tipe_peti_id;
String? warna;
final String fix_lot;
String? fix_lot;
int? packing_no;
int? customer_id;
int? jumlah;
@ -47,7 +47,7 @@ class PetiAssetModel {
? int.parse(json['tipe_peti_id'].toString())
: null,
warna: json['warna'] != null ? json['warna'].toString() : null,
fix_lot: json['fix_lot'],
fix_lot: json['fix_lot'] != null ? json['fix_lot'].toString() : null,
packing_no: json['packing_no'] != null
? int.parse(json['packing_no'].toString())
: null,
@ -95,7 +95,8 @@ class PetiAssetModel {
'kondisipeti_id': kondisipeti_id,
'status': status,
'jumlah': jumlah,
'date_pembuatan': date_pembuatan!.toIso8601String(),
'date_pembuatan':
date_pembuatan != null ? date_pembuatan.toString() : null,
'created_by': created_by,
'updated_by': updated_by,
'created_at': created_at!.toIso8601String(),

8
lib/pages/home/conn_home_page.dart/syncronize.dart

@ -148,11 +148,12 @@ class SyncronizationGlobalData {
Map<String, dynamic> data = {
"mobile_id": assetStatusesLocalList[i].mobile_id.toString(),
"peti_id": assetStatusesLocalList[i].peti_id.toString(),
"warehouse_id": assetStatusesLocalList[i].warehouse_id.toString(),
"exit_at": assetStatusesLocalList[i].exit_at.toString(),
"est_pengembalian":
assetStatusesLocalList[i].est_pengembalian.toString(),
"exit_pic": assetStatusesLocalList[i].exit_pic.toString(),
"exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(),
// "exit_warehouse": assetStatusesLocalList[i].exit_warehouse.toString(),
// "status": assetStatusesLocalList[i].status.toString(),
"created_by": assetStatusesLocalList[i].created_by.toString(),
"created_at": formattedCreatedAt,
@ -216,12 +217,13 @@ class SyncronizationGlobalData {
Map<String, dynamic> data = {
"mobile_id": assetStatusesLocalList[i]['mobile_id'].toString(),
"peti_id": assetStatusesLocalList[i]['peti_id'].toString(),
"warehouse_id": assetStatusesLocalList[i]['warehouse_id'].toString(),
"exit_at": assetStatusesLocalList[i]['exit_at'].toString(),
"est_pengembalian":
assetStatusesLocalList[i]['est_pengembalian'].toString(),
"exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(),
"exit_warehouse":
assetStatusesLocalList[i]['exit_warehouse'].toString(),
// "exit_warehouse":
// assetStatusesLocalList[i]['exit_warehouse'].toString(),
"status": assetStatusesLocalList[i]['status'].toString(),
"created_by": assetStatusesLocalList[i]['created_by'].toString(),
"created_at": formattedCreatedAt,

402
lib/pages/home/home_page.dart

@ -28,6 +28,8 @@ import 'conn_home_page.dart/syncronize.dart';
import 'controller/home_controller.dart';
class HomePage extends StatefulWidget {
final ControllerHome controllerHome = ControllerHome(); // Declare here
@override
State<HomePage> createState() => _HomePageState();
}
@ -55,13 +57,17 @@ class _HomePageState extends State<HomePage> {
List<WarehouseModel>? _warehouseData;
Timer? _timer;
int _peminjamanCount = 0;
int _pengembalianCount = 0;
int _transferCount = 0;
bool _isLoading = true;
@override
void initState() {
super.initState();
_getUserToken();
_initData();
// Menerapkan Future untuk menangani tugas asinkronus
Future.wait([
warehouseListAPI(),
@ -75,15 +81,35 @@ class _HomePageState extends State<HomePage> {
datatablesWarehouseList(),
]).then((_) {
// Selesaikan loading setelah semua tugas selesai
if (mounted) {
setState(() {
_isLoading = false;
});
}
});
// Inisialisasi _data di sini jika diperlukan
_data = <AssetStatusModel>[];
}
@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) {
@ -286,6 +312,7 @@ class _HomePageState extends State<HomePage> {
// Datatables ------------------------------------------------------------------------
Future datatablesAssetStatusList() async {
if (mounted) {
await Controller().fetchAssetStatusLocalController().then((value) {
setState(() {
_data = (value as List<dynamic>)
@ -295,8 +322,10 @@ class _HomePageState extends State<HomePage> {
});
});
}
}
Future datatablesPetiList() async {
if (mounted) {
await Controller().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
@ -306,8 +335,10 @@ class _HomePageState extends State<HomePage> {
});
});
}
}
Future datatablesTipePetiList() async {
if (mounted) {
await Controller().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
@ -317,8 +348,10 @@ class _HomePageState extends State<HomePage> {
});
});
}
}
Future datatablesCustomerList() async {
if (mounted) {
await Controller().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
@ -328,8 +361,10 @@ class _HomePageState extends State<HomePage> {
});
});
}
}
Future datatablesWarehouseList() async {
if (mounted) {
await Controller().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
@ -339,10 +374,11 @@ class _HomePageState extends State<HomePage> {
});
});
}
}
@override
void dispose() {
// Memastikan untuk membatalkan timer saat widget di-dispose
_timer?.cancel();
super.dispose();
}
@ -354,31 +390,31 @@ class _HomePageState extends State<HomePage> {
Widget cardMenuPeminjaman() {
return Container(
margin: EdgeInsets.all(10),
height: 125,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
elevation: 3,
child: InkWell(
onTap: () {
// Aksi ketika card diklik
Navigator.pushNamed(context, '/peminjaman-barang');
},
child: Container(
padding: EdgeInsets.all(16.0),
// padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.vertical_align_top,
size: 50,
size: 30,
color: Colors.greenAccent[700],
),
SizedBox(height: 10),
SizedBox(height: 5),
Text(
'Peminjaman',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
),
@ -390,31 +426,66 @@ class _HomePageState extends State<HomePage> {
Widget cardMenuPengembalian() {
return Container(
margin: EdgeInsets.all(10),
height: 125,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
elevation: 3,
child: InkWell(
onTap: () {
// Aksi ketika card diklik
Navigator.pushNamed(context, '/pengembalian-barang');
},
child: Container(
padding: EdgeInsets.all(16.0),
// padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.vertical_align_bottom,
size: 50,
size: 30,
color: Colors.blueAccent[700],
),
SizedBox(height: 10),
SizedBox(height: 5),
Text(
'Pengembalian',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
],
),
),
),
),
);
}
Widget cardMenuTransfer() {
return Container(
height: 125,
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),
),
],
),
@ -463,42 +534,6 @@ class _HomePageState extends State<HomePage> {
);
}
Widget cardMenuTransfer() {
return Container(
margin: EdgeInsets.all(10),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: InkWell(
onTap: () {
// Aksi ketika card diklik
Navigator.pushNamed(context, '/transfer-peti');
},
child: Container(
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.input_outlined,
size: 50,
color: Colors.yellow[700],
),
SizedBox(height: 10),
Text(
'Transfer Peti',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
),
),
),
);
}
Widget _buildCountTile(IconData icon, int count, Color color, String text) {
return Column(
children: [
@ -622,39 +657,176 @@ class _HomePageState extends State<HomePage> {
),
),
),
],
),
);
},
);
}
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: [
_buildCountTile(
Icons.vertical_align_top,
_peminjamanCount,
Colors.green[700]!,
'Peminjaman',
),
_buildCountTile(
Icons.vertical_align_bottom,
_pengembalianCount,
Colors.blue[700]!,
'Pengembalian',
),
_buildCountTile(
Icons.input_outlined,
_transferCount,
Colors.yellow[700]!,
'Transfer',
),
],
),
SizedBox(height: 10),
// Re-init Button
ElevatedButton(
onPressed: () {
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
// ),
Divider(
height: 1,
thickness: 1,
color: Colors.black, // Black divider
),
// Upload Only Button
// Container(
// width: double.infinity,
// child: TextButton(
// onPressed: () {
// Navigator.pop(context); // Close dialog
// syncToGlobal('Peminjaman');
// syncToGlobal('Pengembalian');
// syncToGlobal('Transfer');
// },
// child: Text(
// "Upload Only",
// style: TextStyle(
// color: Colors.black,
// fontSize: 16.0,
// fontFamily: 'Poppins',
// ),
// ),
// ),
// ),
// 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: () {
Navigator.pop(context); // Close dialog
fetchDataFromApiAndSync();
},
style: TextButton.styleFrom(
backgroundColor: Colors.blue[700],
),
child: Text(
"Upload + Download",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontFamily: 'Poppins',
),
),
),
],
),
);
},
);
},
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 Scaffold(
@ -663,24 +835,25 @@ class _HomePageState extends State<HomePage> {
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.indigo[700],
actions: [
IconButton(
icon: Icon(
Icons.cloud_sync,
size: 30,
),
onPressed: () async {
if (await SyncronizationGlobalData.isInternet()) {
// Display custom dialog when the IconButton is pressed
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
);
}
},
),
],
// actions: [
// IconButton(
// icon: Icon(
// Icons.cloud_sync,
// size: 30,
// ),
// onPressed: () async {
// if (await SyncronizationGlobalData.isInternet()) {
// // Display custom dialog when the IconButton is pressed
// showSyncDialog(context);
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text("No internet connection")),
// );
// }
// },
// ),
// ],
centerTitle: true,
title: Row(
children: [
SizedBox(width: 10),
@ -707,14 +880,39 @@ class _HomePageState extends State<HomePage> {
),
body: ListView(
children: [
GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
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: [
cardMenuPeminjaman(),
cardMenuPengembalian(),
cardMenuTransfer(),
Expanded(
child: cardMenuTransfer(),
),
Expanded(
child: Container(),
// child: cardMenuPengembalian(),
),
],
),
],

2
lib/pages/home/main_page.dart

@ -28,9 +28,11 @@ class _MainPageState extends State<MainPage> {
currentIndex: currentIndex,
selectedItemColor: Colors.indigoAccent, // Warna saat dipilih
onTap: (index) {
if (mounted) {
setState(() {
currentIndex = index;
});
}
},
items: [
BottomNavigationBarItem(

2
lib/pages/home/setting_page.dart

@ -27,9 +27,11 @@ class SettingPageState extends State<SettingPage> {
void _getUserToken() async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
});
}
} catch (e) {
print("Error: $e");
}

6
lib/pages/peminjaman_barang/conn/syncronize.dart

@ -173,7 +173,7 @@ class SyncronizationPeminjamanData {
"exit_at": assetStatus.exit_at.toString(),
"est_pengembalian": assetStatus.est_pengembalian.toString(),
"exit_pic": assetStatus.exit_pic.toString(),
"exit_warehouse": assetStatus.exit_warehouse.toString(),
// "exit_warehouse": assetStatus.exit_warehouse.toString(),
"created_by": assetStatus.created_by.toString(),
"created_at": formattedCreatedAt,
};
@ -248,8 +248,8 @@ class SyncronizationPeminjamanData {
"est_pengembalian":
assetStatusesLocalList[i]['est_pengembalian'].toString(),
"exit_pic": assetStatusesLocalList[i]['exit_pic'].toString(),
"exit_warehouse":
assetStatusesLocalList[i]['exit_warehouse'].toString(),
// "exit_warehouse":
// assetStatusesLocalList[i]['exit_warehouse'].toString(),
"status": assetStatusesLocalList[i]['status'].toString(),
"created_by": assetStatusesLocalList[i]['created_by'].toString(),
"created_at": formattedCreatedAt,

4
lib/pages/peminjaman_barang/controller/peminjaman_controller.dart

@ -127,11 +127,11 @@ class Controller {
await dbClient!.delete(SqfliteDatabaseHelper.peminjamanTable);
}
Future<void> addAllData(List<AssetStatusModel> contactList) async {
Future<void> addAllData(List<AssetStatusModel> peminjamanList) async {
var dbclient = await conn.db;
Batch batch = dbclient!.batch();
for (var contact in contactList) {
for (var contact in peminjamanList) {
batch.insert(
SqfliteDatabaseHelper.peminjamanTable,
contact.toJson(),

873
lib/pages/peminjaman_barang/create-finish.dart

@ -0,0 +1,873 @@
import 'dart:convert';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:collection/collection.dart';
import 'package:uuid/uuid.dart';
import '../../models/asset_status_model.dart';
import '../../models/customer_model.dart';
import '../../models/disposal_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 '../../services/controllerApi.dart';
import 'conn/syncronize.dart';
import 'controller/peminjaman_controller.dart';
class InformasiDataEntryPage extends StatefulWidget {
final List<AssetStatusModel> temporaryDataList;
InformasiDataEntryPage({required this.temporaryDataList});
@override
_InformasiDataEntryPageState createState() => _InformasiDataEntryPageState();
}
class _InformasiDataEntryPageState extends State<InformasiDataEntryPage> {
String? token;
// List<CustomerModel>? customerSqfliteApi;
PetiAssetModel? petiSqfliteApi;
WarehouseModel? warehouseSqfliteApi;
WarehouseModel? warehouseTujuanSqfliteApi;
DisposalPetiModel? disposalSqfliteApi;
CustomerModel? customerSqfliteApi;
List<PetiAssetModel>? _valpeti; // Change this line
List<WarehouseModel>? _valwarehouse;
List<WarehouseModel>? _valwarehouseTujuan;
List<CustomerModel>? _valcustomer;
List<DisposalPetiModel>? _valdisposal;
List<PetiAssetModel> _allPetiList = [];
List<PetiAssetModel> _unrestrictedPetiList = [];
List<PetiAssetModel> _filteredPetiList = [];
bool isQRCodeScanned = false;
String searchText = '';
PetiAssetModel? selectedPeti;
TextEditingController searchBoxController = TextEditingController();
TextEditingController _exit_atController = TextEditingController();
TextEditingController _est_pengembalianController = TextEditingController();
TextEditingController _penanggungJawabController = TextEditingController();
TextEditingController _warehouseController = TextEditingController();
List<PetiAssetModel> selectedPetiList = [];
List<AssetStatusModel>? _data;
List<AssetStatusModel> temporaryDataList = [];
final _formKey = GlobalKey<FormState>();
bool loading = true;
late Future<void> _dataFuture;
// bool _isLoading = false;
@override
void initState() {
super.initState();
// Set loading ke true pada awalnya
if (mounted) {
if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await _getUserToken();
await warehouseListAPI();
await petiListAPI();
await disposalListAPI();
await customerListAPI();
initializeDateFormatting('id_ID', null);
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
Future<void> _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (mounted) {
setState(() {
token = prefs.getString('token');
loading = false;
});
}
}
void addDataToDropdown(PetiAssetModel peti) {
if (mounted) {
setState(() {
selectedPetiList.add(peti);
});
}
}
Future disposalListAPI() async {
if (mounted) {
await ControllerApi().fetchDisposalDataAPI().then((value) {
setState(() {
_valdisposal = (value as List<dynamic>)
.map((item) => DisposalPetiModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
Future customerListAPI() async {
if (mounted) {
await ControllerApi().fetchCustomerDataAPI().then((value) {
setState(() {
_valcustomer = (value as List<dynamic>)
.map((item) => CustomerModel.fromJson(item))
.toList();
loading = false;
});
});
}
}
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 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> isInteret() async {
await SyncronizationPeminjamanData.isInternet().then((connection) {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
}
});
}
@override
Widget build(BuildContext context) {
AuthProvider authProvider =
Provider.of<AuthProvider>(context, listen: false);
UserModel user = authProvider.user;
// WarehouseModel? warehouseSqfliteApi = _valwarehouse?.firstWhereOrNull(
// (warehouse) => warehouse.id == _valwarehouse?.first.id,
// );
var uuid = Uuid();
DateTime? parseDateTime(String? dateTimeString) {
if (dateTimeString == null || dateTimeString.isEmpty) {
return null;
}
try {
return DateTime.parse(dateTimeString);
} catch (e) {
print('Error parsing DateTime: $e');
return null;
}
}
Future<void> removePetiFromSharedPreferences(
PetiAssetModel removedPeti) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
// Retrieve existing data from SharedPreferences
List<String>? petiListJson = prefs.getStringList('selectedPetiList');
if (petiListJson != null) {
// Convert JSON strings to PetiAssetModel objects
List<PetiAssetModel> existingPetiList = petiListJson
.map((petiJson) => PetiAssetModel.fromJson(json.decode(petiJson)))
.toList();
// Remove the specified peti from the list
existingPetiList.removeWhere((peti) => peti.id == removedPeti.id);
// Save the updated list back to SharedPreferences
List<String> updatedPetiListJson =
existingPetiList.map((peti) => json.encode(peti.toJson())).toList();
prefs.setStringList('selectedPetiList', updatedPetiListJson);
}
}
void removePeti(int index) async {
PetiAssetModel? selectedPeti =
selectedPetiList != null ? selectedPetiList[index] : null;
print('Before Remove: ${selectedPeti?.fix_lot}');
if (index >= 0 && index < selectedPetiList.length) {
if (mounted) {
PetiAssetModel removedPeti = selectedPetiList[index];
// Remove the data with the specified peti_id from temporaryDataList
temporaryDataList
.removeWhere((data) => data.peti_id == removedPeti.id);
selectedPetiList.removeAt(index);
await removePetiFromSharedPreferences(removedPeti);
print('After Remove: ${selectedPeti?.fix_lot}');
}
} else {
print('Invalid index: $index. No removal performed.');
}
}
List<PetiAssetModel> selectedPetis = widget.temporaryDataList
.map((data) {
PetiAssetModel? peti =
_valpeti?.firstWhereOrNull((peti) => peti.id == data.peti_id);
print("Checking conditions for Peti ID: ${data.peti_id}");
print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
print("petiSqfliteApi: ${peti != null}");
print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (peti != null) {
return peti;
} else {
print("Peti not found for ID: ${data.peti_id}");
return PetiAssetModel(
id: -1,
fix_lot: '', /* other default values */
);
}
})
.where((peti) => peti != null && peti.id != -1)
.cast<PetiAssetModel>()
.toList();
Future<void> saveAssetData(List<PetiAssetModel> selectedPetis) async {
DateTime now = DateTime.now().toLocal();
String formattedDate = DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(now);
List<int?> savedPetiIds = [];
for (PetiAssetModel selectedPeti in selectedPetis) {
// print("Checking conditions for Peti ID: ${selectedPeti.id}");
// print("Exit_atController: ${_exit_atController.text.isNotEmpty}");
// print("petiSqfliteApi: ${petiSqfliteApi != null}");
// print("warehouseSqfliteApi: ${warehouseSqfliteApi != null}");
if (selectedPeti == null) {
print("Selected Peti is null");
continue;
}
// Ensure that _valpeti is not null before trying to find the PetiAssetModel
if (_valpeti == null) {
print("_valpeti is null");
continue;
}
petiSqfliteApi =
_valpeti?.firstWhereOrNull((peti) => peti.id == selectedPeti.id);
if (petiSqfliteApi == null) {
print("Peti not found for ID: ${selectedPeti.id}");
continue;
}
if (_exit_atController.text.isNotEmpty &&
petiSqfliteApi != null &&
warehouseSqfliteApi != null) {
print("All conditions met. Saving data...");
AssetStatusModel assetAddModel = AssetStatusModel(
id: null,
peti_id: selectedPeti.id,
customer_id: customerSqfliteApi?.id,
warehouse_id: warehouseSqfliteApi?.id,
exit_at: parseDateTime(_exit_atController.text),
exit_pic: _penanggungJawabController.text,
est_pengembalian: parseDateTime(_est_pengembalianController.text),
created_by: user.fullname,
created_at: parseDateTime(formattedDate),
mobile_id: uuid.v4(),
);
// Call addData function
int result = await Controller().addPeminjamanData(assetAddModel);
if (result > 0) {
savedPetiIds.add(selectedPeti.id!);
if (mounted) {
setState(() {
_exit_atController.text = '';
_penanggungJawabController.text = '';
_est_pengembalianController.text = '';
warehouseSqfliteApi?.id = null;
customerSqfliteApi?.id = null;
});
}
print("Success Tambah data untuk Peti ID: ${selectedPeti.id}");
EasyLoading.showSuccess("Data Berhasil Disimpan");
// Reset controllers and make fields nullable
} else {
print("Failed untuk Peti ID: ${selectedPeti.id}");
}
} else {
print("Conditions not met. Unable to save data.");
if (_exit_atController.text.isEmpty) {
print("Exit_atController is empty");
}
if (petiSqfliteApi == null) {
print("petiSqfliteApi is null");
}
if (warehouseSqfliteApi == null) {
print("warehouseSqfliteApi is null");
}
}
}
// Hapus peti-peti yang baru saja disimpan dari SharedPreferences
for (PetiAssetModel selectedPeti in selectedPetis) {
if (selectedPeti != null) {
await removePetiFromSharedPreferences(selectedPeti);
}
}
// Jika Anda ingin pindah ke halaman setelah menyimpan data untuk semua peti
Navigator.pushNamed(context, '/peminjaman-barang');
}
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: true,
backgroundColor: Colors.indigo[700],
elevation: 0,
title: Text('Isikan Data Peminjaman Peti',
style: TextStyle(
fontSize: 16,
)),
),
body: Form(
key: _formKey,
child: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.indigo,
size: 40,
),
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8),
Text(
'List Peti:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Container(
height: 250,
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey.withOpacity(0.5),
width: 1,
),
borderRadius: BorderRadius.circular(8),
color: Colors.grey[100],
),
padding: EdgeInsets.all(8),
child: Expanded(
child: ListView.builder(
itemCount: widget.temporaryDataList.length,
itemBuilder: (context, index) {
int? petiId =
widget.temporaryDataList[index].peti_id;
PetiAssetModel? petiSqfliteApi =
_valpeti?.firstWhereOrNull(
(peti) => peti.id == petiId,
);
return ConstrainedBox(
constraints: BoxConstraints(
maxHeight:
100, // Set your desired height here
),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Colors.grey.withOpacity(0.5),
width: 1,
),
),
margin: EdgeInsets.symmetric(vertical: 4),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Row(
children: [
Text(
'${index + 1}.',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
SizedBox(width: 16),
Text(
' ${petiSqfliteApi?.fix_lot ?? ''}',
style: TextStyle(fontSize: 13),
),
// Tambahkan properti lainnya sesuai kebutuhan
],
),
),
),
),
);
},
),
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Pilih Customer:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
DropdownSearch<CustomerModel>(
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
hintText: 'Pilih Customer',
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
),
),
popupProps: PopupProps.bottomSheet(
showSearchBox: true,
itemBuilder: (context, CustomerModel? customer,
bool? isSelected) {
if (customer == null) {
return SizedBox.shrink();
}
return Container(
child: Column(
children: [
ListTile(
title: Text(
customer.name.toString(),
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
),
),
leading: Icon(
Icons.person_pin,
size: 24,
color: customer.id ==
customerSqfliteApi?.id
? Colors.indigo[700]
: Colors.grey,
),
),
Divider(
height: 1,
color: Colors
.grey, // Warna pembatas (divider)
),
],
),
color: customer.id == customerSqfliteApi?.id
? Colors.grey.withOpacity(0.7)
: Colors.white,
);
},
fit: FlexFit.loose,
title: Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Pilih Customer',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold),
),
IconButton(
icon: Icon(
Icons.close,
color: Colors.red,
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
Divider(),
],
),
),
),
items: (_valcustomer ?? [])
.where((customer) =>
customer.deleted_at != true)
.where((customer) => customer.name!
.toLowerCase()
.contains(searchBoxController.text
.toLowerCase()))
.toList() ??
[],
itemAsString: (CustomerModel customer) =>
customer.name ??
"", // Ganti dengan properti yang sesuai
selectedItem: customerSqfliteApi,
onChanged: (CustomerModel? value) {
setState(() {
customerSqfliteApi = value;
});
},
validator: (CustomerModel? value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tanggal Peminjaman:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_exit_atController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text(
'Tanggal Peminjaman harus diisi'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _exit_atController,
name: 'tanggal_peminjaman',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Tanggal Peminjaman',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
onChanged: (DateTime? selectedDate) {
if (selectedDate != null) {
// Mengisi tanggal estimasi 7 hari ke depan
DateTime estimasiPengembalian =
selectedDate.add(Duration(days: 7));
_est_pengembalianController.text =
DateFormat('yyyy-MM-dd')
.format(estimasiPengembalian);
}
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Estimasi Pengembalian:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 4),
Text(
'* Terisi otomatis 7 hari setelah tanggal peminjaman',
style: TextStyle(
fontSize: 12,
color: Colors.red,
fontStyle: FontStyle.italic),
),
SizedBox(height: 8),
FormBuilderDateTimePicker(
validator: (value) {
if (_est_pengembalianController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Tanggal Estimasi Pengembalian'),
],
),
duration: Duration(seconds: 2),
),
);
return null; // Return null jika ada kesalahan
}
return null; // Return null jika tidak ada kesalahan
},
controller: _est_pengembalianController,
name: 'estimasi_pengembalian',
inputType: InputType.date,
format: DateFormat('yyyy-MM-dd', 'id_ID'),
decoration: InputDecoration(
hintText: 'Estimasi Tanggal Pengembalian',
border: OutlineInputBorder(),
suffixIcon: Icon(Icons.calendar_today),
),
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Penanggung Jawab:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
TextFormField(
controller: _penanggungJawabController =
TextEditingController(text: user.fullname),
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Penanggung Jawab',
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Harus diisi';
}
return null; // Return null jika tidak ada kesalahan
},
),
],
),
),
SizedBox(height: 16),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Gudang:',
style: TextStyle(
fontSize: 14, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
DropdownButtonFormField<WarehouseModel>(
validator: (value) {
if (value == null) {
return 'Harus diisi';
}
return null;
},
decoration: InputDecoration(
hintText: 'Gudang',
border: OutlineInputBorder(),
),
hint: Text("Gudang"),
value: warehouseSqfliteApi,
items: (_valwarehouse ?? [])
.where((warehouse) =>
warehouse.deleted_at != true)
.map((WarehouseModel warehouse)
// _valwarehouse?.map((WarehouseModel warehouse)
{
return DropdownMenuItem<WarehouseModel>(
child: Row(
children: [
Icon(
Icons.warehouse,
color: warehouseSqfliteApi?.id ==
warehouse.id
? Colors.indigo[700]
: Colors.grey,
),
SizedBox(
width:
8), // Jarak antara ikon dan teks
Text(
'${warehouse.name}',
style: TextStyle(
fontSize: 16,
fontFamily: 'OpenSansCondensed',
fontWeight:
warehouseSqfliteApi?.id ==
warehouse.id
? FontWeight.bold
: FontWeight.normal,
),
),
],
),
value: warehouse,
);
}).toList() ??
[],
onChanged: (value) {
setState(() {
warehouseSqfliteApi = value;
});
},
),
],
),
),
],
),
),
);
}
},
),
),
bottomNavigationBar: BottomAppBar(
height: MediaQuery.of(context).size.height / 10,
color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: MediaQuery.of(context).size.width / 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 50, // Lebar dan tinggi sesuai kebutuhan
width: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.green, // Warna hijau untuk save
),
child: IconButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
try {
if (_exit_atController.text.isNotEmpty &&
warehouseSqfliteApi != null) {
await saveAssetData(selectedPetis);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent[700],
content: Row(
children: [
Icon(
Icons.error_outline,
color: Colors.white,
),
SizedBox(width: 5),
Text('Data belum lengkap'),
],
),
duration: Duration(seconds: 2),
),
);
}
} catch (e) {
print('Error storing data: $e');
}
}
},
icon: Icon(Icons.check, color: Colors.white),
),
),
],
),
),
],
),
),
);
}
}

1387
lib/pages/peminjaman_barang/create.dart

File diff suppressed because it is too large Load Diff

949
lib/pages/peminjaman_barang/peminjaman_stock_page.dart

File diff suppressed because it is too large Load Diff

84
lib/pages/peminjaman_barang/show.dart

@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:shimmer/shimmer.dart';
import 'package:siopas/models/asset_status_model.dart';
import 'package:siopas/models/customer_model.dart';
import 'package:siopas/models/m_asset_status_model.dart';
@ -10,6 +11,7 @@ import 'package:collection/collection.dart';
import '../../models/warehouse_mode.dart';
import '../../services/controllerApi.dart';
import '../../widget/loading_shimmer_show.dart';
class DetailPeminjamanBarangPage extends StatefulWidget {
final String peminjamanId;
@ -31,20 +33,39 @@ class _DetailPeminjamanBarangPageState
List<CustomerModel>? customerData;
List<WarehouseModel>? warehouseData;
bool loading = true;
late Future<void> _dataFuture;
bool loading = true; // Atur loading ke true pada awalnya
@override
void initState() {
super.initState();
getPeminjamanIdData();
customerListAPI();
petiListAPI();
warehouseListAPI();
// Set loading ke true pada awalnya
if (mounted) {
if (mounted) {
setState(() {
loading = false;
});
}
}
_dataFuture = fetchData();
}
Future<void> fetchData() async {
await getPeminjamanIdData();
await customerListAPI();
await petiListAPI();
await warehouseListAPI();
initializeDateFormatting('id_ID', null);
// Tandai bahwa proses loading telah selesai
if (mounted) {
setState(() {
loading = false;
});
}
}
Future customerListAPI() async {
if (mounted) {
@ -91,9 +112,10 @@ class _DetailPeminjamanBarangPageState
peminjamanInfo = peminjamans.firstWhereOrNull(
(peminjaman) => peminjaman.id.toString() == widget.peminjamanId,
);
if (mounted) {
setState(() {});
}
}
String _formatDate(String? date) {
if (date != null) {
@ -134,10 +156,10 @@ class _DetailPeminjamanBarangPageState
warehouseSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.warehouse_id,
);
WarehouseModel? warehouseTujuanSqfliteApi;
warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
(warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
);
// WarehouseModel? warehouseTujuanSqfliteApi;
// warehouseTujuanSqfliteApi = warehouseData?.firstWhereOrNull(
// (warehouse) => warehouse.id == peminjamanInfo!.exit_warehouse,
// );
Future<void> _showDeleteConfirmationDialog() async {
return showDialog<void>(
@ -224,10 +246,10 @@ class _DetailPeminjamanBarangPageState
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/peminjaman-barang');
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back),
),
actions: [
IconButton(
@ -238,7 +260,15 @@ class _DetailPeminjamanBarangPageState
),
],
),
body: Padding(
body: FutureBuilder<void>(
future: _dataFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return ShimmerShow();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
@ -262,7 +292,8 @@ class _DetailPeminjamanBarangPageState
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
Icon(Icons.article,
size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -306,7 +337,8 @@ class _DetailPeminjamanBarangPageState
Divider(thickness: 1),
_buildDetailItem(
'Nama Customer',
customerSqfliteApi != null && customerSqfliteApi.name != null
customerSqfliteApi != null &&
customerSqfliteApi.name != null
? customerSqfliteApi!.name.toString()
: '-',
),
@ -314,33 +346,37 @@ class _DetailPeminjamanBarangPageState
_buildDetailItem('Tgl Peminjaman',
_formatDate(peminjamanInfo!.exit_at.toString())),
Divider(thickness: 1),
_buildDetailItem('Est Peminjaman',
_formatDate(peminjamanInfo!.est_pengembalian.toString())),
_buildDetailItem(
'Est Peminjaman',
_formatDate(
peminjamanInfo!.est_pengembalian.toString())),
Divider(thickness: 1),
_buildDetailItem(
'PJ Peminjaman', peminjamanInfo!.exit_pic.toString()),
Divider(thickness: 1),
_buildDetailItem(
'Asal Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
' Gudang',
warehouseSqfliteApi != null &&
warehouseSqfliteApi.name != null
? warehouseSqfliteApi!.name.toString()
: '-'),
Divider(thickness: 1),
_buildDetailItem(
'Tujuan Gudang',
// peminjamanInfo!.exit_warehouse.toString()),
warehouseTujuanSqfliteApi != null &&
warehouseTujuanSqfliteApi.name != null
? warehouseTujuanSqfliteApi!.name.toString()
'PIC',
peminjamanInfo!.exit_pic != null
? peminjamanInfo!.exit_pic.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],
),
),
);
}
},
),
);
}

15
lib/pages/pengembalian_barang/edit.dart

@ -90,10 +90,12 @@ class _CreatePengembalianBarangPageState
kondisiPetiListAPI();
initializeDateFormatting('id_ID', null);
if (mounted) {
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
});
}
}
void _getUserToken() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
@ -179,6 +181,7 @@ class _CreatePengembalianBarangPageState
(scanData) {
if (!scanned) {
try {
if (mounted) {
setState(() {
result = scanData;
List<String> lines = result!.code!.split('\n');
@ -217,7 +220,8 @@ class _CreatePengembalianBarangPageState
isQRCodeScanned = true;
// Mengisi _filteredPetiList untuk dropdown hasil QR Code
_filteredPetiList = [
_valpeti!.firstWhere((peti) => peti.id == allowedPeti.id)
_valpeti!
.firstWhere((peti) => peti.id == allowedPeti.id)
];
petiSqfliteApi = allowedPeti;
@ -280,6 +284,7 @@ class _CreatePengembalianBarangPageState
scanned = true;
});
}
controller.stopCamera();
@ -292,10 +297,12 @@ class _CreatePengembalianBarangPageState
controller.stopCamera();
// Reset nilai dropdown Peti dan Warehouse
if (mounted) {
setState(() {
petiSqfliteApi = null;
warehouseSqfliteApi = null;
});
}
print('Error scanning QR Code: $e');
ScaffoldMessenger.of(context).showSnackBar(
@ -521,6 +528,7 @@ class _CreatePengembalianBarangPageState
selectedItem: petiSqfliteApi,
onChanged: (PetiAssetModel? value) {
if (mounted) {
setState(() {
petiSqfliteApi = value;
if (value != null) {
@ -531,6 +539,7 @@ class _CreatePengembalianBarangPageState
];
}
});
}
},
validator: (PetiAssetModel? value) {
if (value == null) {
@ -711,9 +720,11 @@ class _CreatePengembalianBarangPageState
}).toList() ??
[],
onChanged: (WarehouseModel? value) {
if (mounted) {
setState(() {
warehouseSqfliteApi = value;
});
}
},
),
),
@ -769,9 +780,11 @@ class _CreatePengembalianBarangPageState
}).toList() ??
[],
onChanged: (ConditionPetiModel? value) {
if (mounted) {
setState(() {
conditionPetiSqfliteApi = value;
});
}
},
),
),

24
lib/pages/pengembalian_barang/index.dart

@ -69,9 +69,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
_getUserToken();
// Set _isLoading ke true sebelum memulai tugas
if (mounted) {
setState(() {
_isLoading = true;
});
}
Future.wait([
warehouseListAPI(),
@ -88,9 +90,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
datatablesConditionList(),
]).then((_) {
// Set _isLoading ke false setelah semua tugas selesai
if (mounted) {
setState(() {
_isLoading = false;
});
}
});
// Inisialisasi _data di sini jika diperlukan
@ -313,14 +317,15 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Tidak ada koneksi internet")));
}
});
}
// Datatables ------------------------------------------------------------------------
Future datatablesPengembalianList() async {
if (mounted) {
await ControllerPengembalian()
.fetchPengembalianLocalController()
.then((value) {
@ -332,8 +337,10 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
Future datatablesPetiList() async {
if (mounted) {
await ControllerPengembalian().fetchPetiData().then((value) {
setState(() {
_petiData = (value as List<dynamic>)
@ -343,8 +350,10 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
Future datatablesTipePetiList() async {
if (mounted) {
await ControllerPengembalian().fetchTipePetiData().then((value) {
setState(() {
_tipePetiData = (value as List<dynamic>)
@ -354,8 +363,10 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
Future datatablesCustomerList() async {
if (mounted) {
await ControllerPengembalian().fetchCustomerData().then((value) {
setState(() {
_customerData = (value as List<dynamic>)
@ -365,8 +376,10 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
Future datatablesWarehouseList() async {
if (mounted) {
await ControllerPengembalian().fetchWarehouseData().then((value) {
setState(() {
_warehouseData = (value as List<dynamic>)
@ -376,8 +389,10 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
Future datatablesConditionList() async {
if (mounted) {
await ControllerPengembalian().fetchConditionData().then((value) {
setState(() {
_conditionData = (value as List<dynamic>)
@ -387,6 +402,7 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
});
});
}
}
void _loadMoreData() {
if (mounted && !_isLoading) {
@ -524,7 +540,7 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
SnackBar(content: Text("Tidak ada koneksi internet")),
);
}
},
@ -562,9 +578,11 @@ class PengembalianBarangPageState extends State<PengembalianBarangPage> {
rowsPerPage: _pageSize,
availableRowsPerPage: [10, 25, 50], // Removed const
onRowsPerPageChanged: (value) {
if (mounted) {
setState(() {
_pageSize = value!;
});
}
},
columns: [
DataColumn(label: Text('No')),

10
lib/pages/pengembalian_barang/show.dart

@ -48,6 +48,7 @@ class _DetailPengembalianBarangPageState
initializeDateFormatting('id_ID', null);
// Delay sejenak sebelum memanggil EasyLoading.dismiss()
if (mounted) {
Future.delayed(Duration(seconds: 1), () {
setState(() {
loading = false; // Mengatur loading ke false setelah tugas selesai
@ -55,6 +56,7 @@ class _DetailPengembalianBarangPageState
EasyLoading.dismiss();
});
}
}
Future customerListAPI() async {
if (mounted) {
@ -115,8 +117,10 @@ class _DetailPengembalianBarangPageState
(pengembalian) => pengembalian.id.toString() == widget.pengembalianId,
);
if (mounted) {
setState(() {});
}
}
String _formatDate(String? date) {
if (date != null) {
@ -351,6 +355,12 @@ class _DetailPengembalianBarangPageState
: '-',
),
Divider(thickness: 1),
_buildDetailItem(
'PIC',
pengembalianInfo!.enter_pic != null
? pengembalianInfo!.enter_pic.toString()
: '-'),
Divider(thickness: 1),
// ... tambahkan data lainnya sesuai kebutuhan
],
],

9
lib/pages/sign_in_page.dart

@ -172,9 +172,13 @@ class __FormContentState extends State<_FormContent> {
// final String roleId = 'A5C7B207-1A1C-43B8-89BF-222222222222';
print('token dapat login: ${user.token}');
if (user.role_id == 2) {
if (user != null && user.role_id == 2) {
print('Berhasil login HALAMAN USER');
Navigator.pushNamed(context, '/home');
if (context != null) {
Navigator.pushReplacementNamed(context, '/home');
} else {
print('Context is null');
}
} else {
print('Tidak ada informasi peran (roles) yang tersedia');
}
@ -239,6 +243,7 @@ class __FormContentState extends State<_FormContent> {
prefixIcon: Icon(Icons.email_outlined),
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
),
_gap(),
TextFormField(

6
lib/pages/transfer_peti/index.dart

@ -299,8 +299,8 @@ class TransferPetiPageState extends State<TransferPetiPage> {
if (connection) {
print("Internet connection available");
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text("No Internet")));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Tidak ada koneksi internet")));
}
});
}
@ -500,7 +500,7 @@ class TransferPetiPageState extends State<TransferPetiPage> {
showSyncDialog(context);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("No internet connection")),
SnackBar(content: Text("Tidak ada koneksi internet")),
);
}
},

13
lib/widget/component_query.dart

@ -0,0 +1,13 @@
import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
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 '';
}
}

299
lib/widget/loading_shimmer_show.dart

@ -0,0 +1,299 @@
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
class ShimmerShow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16.0),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
elevation: 5,
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
children: [
Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(15.0)),
),
elevation: 0,
margin: EdgeInsets.all(0),
color: Colors.grey[300],
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.article, size: 30, color: Colors.white),
SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'ID:',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(
'-',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
],
),
],
),
],
),
),
),
SizedBox(height: 10),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
Divider(thickness: 1),
_buildShimmerDetailItem(),
// ... tambahkan shimmer item lainnya sesuai kebutuhan
],
),
),
),
);
}
Widget _buildShimmerDetailItem() {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 80,
height: 12,
color: Colors.grey[300],
),
Container(
width: 120,
height: 12,
color: Colors.grey[300],
),
],
),
);
}
}
class ShimmerLoadingAssetStatusCard 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 Peminjam:', '', 'PIC:', '', 11.5),
_buildInfoRow('Tanggal Peminjaman:', '',
'Estimasi Pengembalian:', '', 11.5),
_buildInfoRow('Asal Gudang:', '', 'Tujuan 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,
// ),
// ),
],
),
),
],
);
}
}
Widget shimmerSearch() {
return Container(
margin: EdgeInsets.only(top: 8, bottom: 8),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey, width: 1.0),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Icon(Icons.search),
SizedBox(width: 8),
Expanded(
child: Container(
height: 16, // Match the font size in the original search
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
),
),
],
),
),
),
),
),
);
}

8
pubspec.lock

@ -222,6 +222,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.13.1"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
sha256: "19ed4813003a6ff4e9c6bcce37e792a2a358919d7603b2b31ff200229191e44c"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
flutter_spinkit:
dependency: transitive
description:

2
pubspec.yaml

@ -55,6 +55,7 @@ dependencies:
dropdown_search: ^5.0.6
shimmer: ^3.0.0
loading_animation_widget: ^1.2.0+4
flutter_slidable: ^3.0.1
@ -95,6 +96,7 @@ flutter:
# To add assets to your application, add an assets section, like this:
assets:
- assets/img/
- assets/item/
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see

Loading…
Cancel
Save