From 3a0df5bb25c729391b9897828ad3ee2690e8231f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Nov 2023 08:01:10 +0700 Subject: [PATCH] Update: Pembaharuan Login ke User/Operator, Fitur pengembalian --- lib/main.dart | 5 + lib/models/asset_status_model.dart | 11 +- lib/models/warehouse_mode.dart | 32 + lib/pages/home/home_page.dart | 2 +- lib/pages/home/peminjaman_stock_page.dart | 3 +- lib/pages/peminjaman_barang/create.dart | 49 +- lib/pages/peminjaman_barang/show.dart | 2 +- lib/pages/pengembalian_barang/create.dart | 625 ++++++++++++++++++ .../pengembalian-index.dart | 286 ++++++++ lib/pages/sign_in_page.dart | 9 +- lib/widget/peminjaman_tile.dart | 62 -- 11 files changed, 1010 insertions(+), 76 deletions(-) create mode 100644 lib/pages/pengembalian_barang/create.dart create mode 100644 lib/pages/pengembalian_barang/pengembalian-index.dart delete mode 100644 lib/widget/peminjaman_tile.dart diff --git a/lib/main.dart b/lib/main.dart index 87943f4..463c2cb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,8 @@ import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:siopas/pages/pengembalian_barang/create.dart'; +import 'package:siopas/pages/pengembalian_barang/pengembalian-index.dart'; import 'pages/home/main_page.dart'; import 'pages/home/peminjaman_stock_page.dart'; import 'pages/peminjaman_barang/create.dart'; @@ -52,6 +54,9 @@ class MyApp extends StatelessWidget { '/home': (context) => MainPage(), '/peminjaman-barang': (context) => AssetStatusPage(), '/peminjaman-barang/create': (context) => CreatePeminjamanBarang(), + '/pengembalian-barang': (context) => PengembalianBarangPage(), + '/pengembalian-barang/create': (context) => + CreatePengembalianBarangPage(), // '/peminjaman-barang/show': (context) => // DetailPeminjamanBarangPage(assetId: 0), // '/category': (context) => SurveyDetailPage(), diff --git a/lib/models/asset_status_model.dart b/lib/models/asset_status_model.dart index 9be544e..893637d 100644 --- a/lib/models/asset_status_model.dart +++ b/lib/models/asset_status_model.dart @@ -16,6 +16,7 @@ class AssetStatusModel { String? updated_by; PetiAssetModel? peti; WarehouseModel? warehouse; + WarehouseEnterModel? warehouse_enter; AssetStatusModel({ this.id, @@ -30,8 +31,9 @@ class AssetStatusModel { this.kondisi_peti, this.created_by, this.updated_by, - required this.peti, - required this.warehouse, + this.peti, + this.warehouse, + this.warehouse_enter, }); factory AssetStatusModel.fromJson(Map json) { @@ -62,6 +64,10 @@ class AssetStatusModel { warehouse: WarehouseModel.fromJson(json['warehouse'] != null ? json['warehouse'] : {'id': 0, 'name': 'null'}), + warehouse_enter: WarehouseEnterModel.fromJson( + json['warehouse_enter'] != null + ? json['warehouse_enter'] + : {'id': 0, 'name': 'null'}), ); } @@ -80,5 +86,6 @@ class AssetStatusModel { 'updated_by': updated_by, 'peti': peti!.toJson(), 'warehouse': warehouse!.toJson(), + 'warehouse_enter': warehouse_enter!.toJson(), }; } diff --git a/lib/models/warehouse_mode.dart b/lib/models/warehouse_mode.dart index c49c97b..d3c6312 100644 --- a/lib/models/warehouse_mode.dart +++ b/lib/models/warehouse_mode.dart @@ -1,3 +1,5 @@ +import 'package:siopas/models/m_asset_status_model.dart'; + class WarehouseModel { int? id; String? name; @@ -33,3 +35,33 @@ class WarehouseModel { 'updated_by': updated_by, }; } + +class WarehouseEnterModel { + int? id; + String? name; + String? description; + String? address; + + WarehouseEnterModel({ + this.id, + this.name, + this.description, + this.address, + }); + + factory WarehouseEnterModel.fromJson(Map json) { + return WarehouseEnterModel( + id: json['id'], + name: json['name'], + description: json['description'], + address: json['address'], + ); + } + + Map toJson() => { + 'id': id, + 'name': name, + 'description': description, + 'address': address, + }; +} diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index c23cf3b..fcf91e6 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -252,7 +252,7 @@ class _HomePageState extends State { child: InkWell( onTap: () { // Aksi ketika card diklik - // Navigator.pushNamed(context, '/peminjaman-barang'); + Navigator.pushNamed(context, '/pengembalian-barang'); }, child: Container( padding: EdgeInsets.all(16.0), diff --git a/lib/pages/home/peminjaman_stock_page.dart b/lib/pages/home/peminjaman_stock_page.dart index 0755bd3..3485854 100644 --- a/lib/pages/home/peminjaman_stock_page.dart +++ b/lib/pages/home/peminjaman_stock_page.dart @@ -7,7 +7,6 @@ import 'package:provider/provider.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:siopas/widget/peminjaman_tile.dart'; import 'package:http/http.dart' as http; import '../../connection/connection.dart'; @@ -116,7 +115,7 @@ class AssetStatusPageState extends State { child: SizedBox( width: double.infinity, child: PaginatedDataTable( - header: const Text('Data Table Header'), + header: const Text('Peminjaman Barang'), rowsPerPage: _pageSize, availableRowsPerPage: const [10, 25, 50], onRowsPerPageChanged: (value) { diff --git a/lib/pages/peminjaman_barang/create.dart b/lib/pages/peminjaman_barang/create.dart index cba9c52..4eef83e 100644 --- a/lib/pages/peminjaman_barang/create.dart +++ b/lib/pages/peminjaman_barang/create.dart @@ -11,6 +11,7 @@ import 'package:siopas/models/m_asset_status_model.dart'; import 'package:siopas/models/warehouse_mode.dart'; import 'package:siopas/providers/asset_status_provider.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:intl/date_symbol_data_local.dart'; // Import package intl import '../../connection/connection.dart'; import 'package:http/http.dart' as http; @@ -49,6 +50,7 @@ class _CreatePeminjamanBarangState extends State { _getUserToken(); fetchDataWarehouse(); fetchDataAsset(); + initializeDateFormatting('id_ID'); } void _getUserToken() async { @@ -196,6 +198,13 @@ class _CreatePeminjamanBarangState extends State { Provider.of(context, listen: false); UserModel user = authProvider.user; + // var now = DateTime.now(); + // var dt = DateTime(DateTime.now().year, DateTime.now().month, + // DateTime.now().day, DateTime.now().hour, DateTime.now().minute); + + // // _exit_atController.text = DateFormat('yyyy-MM-dd HH:mm:ss').format(dt); + // _exit_atController.text = DateFormat('dd-MM-yyyy').format(dt); + Future _storePeminjaman() async { setState(() { _isLoading = true; @@ -214,8 +223,8 @@ class _CreatePeminjamanBarangState extends State { 'exit_pic': _penanggungJawabController.text, 'exit_warehouse': _valWarehouse!.id, 'est_pengembalian': _est_pengembalianController.text, - 'created_by': user.id, - 'updated_by': user.id, + 'created_by': user.fullname, + // 'updated_by': user.fullname, }), ); @@ -452,7 +461,8 @@ class _CreatePeminjamanBarangState extends State { controller: _exit_atController, name: 'tanggal', inputType: InputType.date, - format: DateFormat('yyyy-MM-dd HH:mm:ss'), + // format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'), + format: DateFormat('yyyy-MM-dd', 'id_ID'), decoration: InputDecoration( labelText: 'Tanggal Peminjaman', border: OutlineInputBorder(), @@ -493,7 +503,8 @@ class _CreatePeminjamanBarangState extends State { controller: _est_pengembalianController, name: 'tanggal', inputType: InputType.date, - format: DateFormat('yyyy-MM-dd HH:mm:ss'), + // format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'), + format: DateFormat('yyyy-MM-dd', 'id_ID'), decoration: InputDecoration( labelText: 'Estimasi Tanggal Pengembalian', border: OutlineInputBorder(), @@ -585,6 +596,36 @@ class _CreatePeminjamanBarangState extends State { // ), // ), // ), + Visibility( + visible: false, + child: FractionallySizedBox( + widthFactor: 1.0, + child: Card( + elevation: 1, + child: Padding( + padding: const EdgeInsets.all(8), + child: Column( + children: [ + Text( + 'Data dari QR Code:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 8), + Text( + result != null && result!.code != null + ? result!.code! + : 'Belum ada data QR Code terpindai', + style: TextStyle(fontSize: 14), + ), + ], + ), + ), + ), + ), + ), ], ), ), diff --git a/lib/pages/peminjaman_barang/show.dart b/lib/pages/peminjaman_barang/show.dart index 8261e4f..13c3bc8 100644 --- a/lib/pages/peminjaman_barang/show.dart +++ b/lib/pages/peminjaman_barang/show.dart @@ -147,7 +147,7 @@ class _DetailPeminjamanBarangPageState children: [ Text( label, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), ), Text(value), ], diff --git a/lib/pages/pengembalian_barang/create.dart b/lib/pages/pengembalian_barang/create.dart new file mode 100644 index 0000000..57fd7bc --- /dev/null +++ b/lib/pages/pengembalian_barang/create.dart @@ -0,0 +1,625 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:intl/date_symbol_data_local.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:qr_code_scanner/qr_code_scanner.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:siopas/connection/connection.dart'; +import 'package:http/http.dart' as http; +import 'package:siopas/models/asset_status_model.dart'; +// import 'package:siopas/models/m_asset_status_model.dart'; +import 'package:siopas/models/user_model.dart'; +import 'package:siopas/models/warehouse_mode.dart'; +import 'package:siopas/providers/auth_provider.dart'; + +class CreatePengembalianBarangPage extends StatefulWidget { + const CreatePengembalianBarangPage({super.key}); + + @override + State createState() => + _CreatePengembalianBarangPageState(); +} + +class _CreatePengembalianBarangPageState + extends State { + List _dataAsset = []; + List _dataWarehouse = []; + bool _isLoading = false; + String? token; + AssetStatusModel? _valAsset; + WarehouseModel? _valWarehouse; + TextEditingController _enterAtController = TextEditingController(); + TextEditingController _enterPicController = TextEditingController(); + TextEditingController _kondisiPetiController = TextEditingController(); + final _formKey = GlobalKey(); + + final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); + Barcode? result; + QRViewController? controller; + + @override + void initState() { + super.initState(); + _getUserToken(); + fetchDataWarehouse(); + fetchDataAsset(); + initializeDateFormatting('id_ID'); + } + + void _getUserToken() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + if (mounted) { + setState(() { + token = prefs.getString('token'); + }); + } + } + + Future fetchDataAsset() async { + setState(() { + _isLoading = true; + }); + + final response = await http.get(Uri.parse('$baseUrl/asset-status')); + + if (mounted) { + // Periksa apakah widget masih "mounted" + if (response.statusCode == 200) { + final jsonData = json.decode(response.body)['data']['asset_status']; + + final List newDataAsset = (jsonData as List) + .map((item) => AssetStatusModel.fromJson(item)) + .toList(); + + if (mounted) { + // Periksa lagi sebelum memanggil setState + setState(() { + _dataAsset.addAll(newDataAsset); + _isLoading = false; + }); + } + } else { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + throw Exception('Failed to fetch data Asset Status'); + } + } + } + + Future fetchDataWarehouse() async { + setState(() { + _isLoading = true; + }); + + final response = await http.get(Uri.parse('$baseUrl/m-warehouse')); + + if (mounted) { + if (response.statusCode == 200) { + final jsonData = json.decode(response.body)['data']['warehouse']; + + final List newDataWarehouse = (jsonData as List) + .map((item) => WarehouseModel.fromJson(item)) + .toList(); + + if (mounted) { + setState(() { + _dataWarehouse.addAll(newDataWarehouse); + _isLoading = false; + }); + } + } else { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + throw Exception('Failed to fetch data Warehouse'); + } + } + } + + void _onQRViewCreated(QRViewController controller) { + this.controller = controller; + bool scanned = false; + + controller.scannedDataStream.listen((scanData) { + if (!scanned) { + try { + setState(() { + result = scanData; + + List lines = result!.code!.split('\n'); + + for (String line in lines) { + if (line.startsWith('ID Peti')) { + String idPeti = line.split(': ')[1]; + // Isi formulir dropdown asset + _valAsset = _dataAsset + .firstWhere((peti) => peti.id == int.parse(idPeti)); + } else if (line.startsWith('Date:')) { + String datePeminjaman = line.split(': ')[1]; + try { + DateTime parsedDate = + DateFormat('dd-MM-yyyy').parse(datePeminjaman); + String formattedDate = + DateFormat('yyyy-MM-dd HH:mm:ss.SSS').format(parsedDate); + _enterAtController.text = formattedDate; + } catch (e) { + print('Error parsing date: $e'); + // Lakukan penanganan jika format tanggal tidak sesuai + } + } + // else if (line.startsWith('ID Warehouse')) { + // String idWarehouse = line.split(': ')[1]; + // // Isi formulir dropdown gudang + // _valWarehouse = _dataWarehouse.firstWhere( + // (warehouse) => warehouse.id == int.parse(idWarehouse)); + // } + } + + scanned = true; + }); + + controller.stopCamera(); + + Future.delayed(Duration(milliseconds: 500), () { + if (mounted) { + Navigator.of(context).pop(); + } + }); + } catch (e) { + print('Error scanning QR Code: $e'); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text('Error scanning QR Code: $e'), + )); + } + } + }); + } + + @override + void dispose() { + super.dispose(); + controller?.dispose(); + } + + @override + Widget build(BuildContext context) { + AuthProvider authProvider = + Provider.of(context, listen: false); + UserModel user = authProvider.user; + + Future _updatePeminjaman() async { + setState(() { + _isLoading = true; + }); + + try { + final response = await http.put( + Uri.parse('$baseUrl/asset-status/update/${_valAsset!.id}'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': token!, + }, + body: jsonEncode({ + 'enter_at': _enterAtController.text, + 'enter_pic': _enterPicController.text, + 'enter_warehouse': _valWarehouse!.id, + 'kondisi_peti': _kondisiPetiController.text, + 'updated_by': user.fullname, + }), + ); + + print(response.body); + + if (response.statusCode == 200) { + final jsonData = json.decode(response.body)['data']['asset_status']; + + print('Berhasil memperbarui data: $jsonData'); + + // Tampilkan snackbar + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + backgroundColor: Colors.greenAccent[700], + content: Row( + children: [ + Icon( + Icons.check_circle_outline, + color: Colors.white, + ), + SizedBox(width: 5), + Text('Data berhasil diperbarui'), + ], + ), + duration: Duration(seconds: 3), // Durasi tampilan snackbar + ), + ); + + // Reset form input + _enterAtController.text = ''; + _enterPicController.text = ''; + _kondisiPetiController.text = ''; + _valWarehouse = null; + } else { + throw Exception('Gagal memperbarui data Asset Status'); + } + } catch (e) { + print('Error updating data: $e'); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + backgroundColor: Colors.redAccent[700], + content: Row( + children: [ + Icon( + Icons.error_outline, + color: Colors.white, + ), + SizedBox(width: 5), + Text('Gagal memperbarui data'), + ], + ), + duration: Duration(seconds: 2), // Durasi tampilan snackbar + ), + ); + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } + } + + return Scaffold( + appBar: AppBar( + elevation: 0, + backgroundColor: Color.fromARGB(255, 5, 28, 158), + title: Text('Pengembalian Barang'), + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + Navigator.pushNamed(context, '/pengembalian-barang'); + }, + )), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + child: Container( + padding: EdgeInsets.all(10.0), + child: Form( + key: _formKey, + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Card( + elevation: 2, + child: Container( + margin: EdgeInsets.all(8), + child: + DropdownButtonFormField( + validator: (value) { + if (value == null) { + return 'Harus diisi'; + } + return null; + }, + decoration: InputDecoration( + labelText: 'Peti', + border: OutlineInputBorder(), + ), + hint: Text("Pilih Peti"), + value: _valAsset, + items: + _dataAsset.map((AssetStatusModel item) { + return DropdownMenuItem( + child: Text('${item.peti!.fix_lot!}'), + value: item, + ); + }).toList(), + onChanged: (AssetStatusModel? value) { + setState(() { + _valAsset = value; + }); + }, + ), + ), + ), + ), + + SizedBox(width: 8), // Spacer antara dua card + Card( + elevation: 2, + child: Container( + margin: EdgeInsets.all(8), + height: MediaQuery.of(context).size.height / 10, + decoration: BoxDecoration( + color: Colors.indigoAccent, + borderRadius: BorderRadius.circular(5), + ), + child: IconButton( + onPressed: () { + showModalBottomSheet( + context: context, + isScrollControlled: + true, // Set modal menjadi fullscreen + builder: (BuildContext context) { + return Stack( + alignment: Alignment.center, + children: [ + Container( + height: double.infinity, + width: double.infinity, + child: QRView( + key: qrKey, + onQRViewCreated: _onQRViewCreated, + overlay: QrScannerOverlayShape( + borderColor: Colors.red, + borderRadius: 10, + borderLength: 30, + borderWidth: 10, + cutOutSize: 300, + ), + ), + ), + Positioned( + bottom: 30, + height: 60, + child: Container( + height: + 60, // Lebar dan tinggi sesuai kebutuhan + width: 60, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors + .red, // Warna merah untuk close + ), + + child: IconButton( + onPressed: () { + Navigator.of(context).pop(); + }, + icon: Icon( + Icons.close, + size: 40, + ), + color: Colors.white, + ), + ), + ), + ], + ); + }, + ); + }, + icon: Icon( + Icons.qr_code, + size: 30, + ), + color: Colors.white, // Warna ikon + ), + ), + ), + ], + ), + + SizedBox(height: 16), + // Visibility( + // visible: false, + // child: + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(8), + child: TextFormField( + controller: _enterPicController = + TextEditingController(text: user.fullname), + decoration: InputDecoration( + labelText: 'Penanggung Jawab', + border: OutlineInputBorder(), + ), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Harus diisi'; + } + return null; // Return null jika tidak ada kesalahan + }, + ), + ), + ), + // ), + SizedBox(height: 16), + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(8), + child: FormBuilderDateTimePicker( + validator: (value) { + if (_enterAtController.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 Pengembalian'), + ], + ), + duration: Duration(seconds: 2), + ), + ); + return null; // Return null jika ada kesalahan + } + return null; // Return null jika tidak ada kesalahan + }, + controller: _enterAtController, + name: 'tanggal', + inputType: InputType.date, + // format: DateFormat('dd-MMMM-yyyy', 'id_ID'), + format: DateFormat('yyyy-MM-dd', 'id_ID'), + decoration: InputDecoration( + labelText: 'Tanggal Pengembalian', + border: OutlineInputBorder(), + suffixIcon: Icon(Icons.calendar_today), + ), + ), + ), + ), + + SizedBox(height: 16), + Card( + elevation: 2, + child: Padding( + padding: const EdgeInsets.all(8), + child: DropdownButtonFormField( + validator: (value) { + if (value == null) { + return 'Harus diisi'; + } + return null; + }, + decoration: InputDecoration( + labelText: 'Pilih Gudang', + border: OutlineInputBorder(), + ), + hint: Text("Pilih Gudang"), + value: _valWarehouse, + items: + _dataWarehouse.map((WarehouseModel warehouse) { + return DropdownMenuItem( + child: Text('${warehouse.name}'), + value: warehouse, + ); + }).toList(), + onChanged: (WarehouseModel? value) { + setState(() { + _valWarehouse = value; + }); + }, + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: TextField( + controller: _kondisiPetiController, + decoration: InputDecoration( + labelText: 'Kondisi Barang', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10.0), + ), + ), + ), + ), + SizedBox(height: 20.0), + Visibility( + visible: false, + child: FractionallySizedBox( + widthFactor: 1.0, + child: Card( + elevation: 1, + child: Padding( + padding: const EdgeInsets.all(8), + child: Column( + children: [ + Text( + 'Data dari QR Code:', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 8), + Text( + result != null && result!.code != null + ? result!.code! + : 'Belum ada data QR Code terpindai', + style: TextStyle(fontSize: 14), + ), + ], + ), + ), + ), + ), + ), + ], + ), + ), + ), + ), + bottomNavigationBar: BottomAppBar( + height: MediaQuery.of(context).size.height / 8, + color: Color.fromARGB(255, 5, 28, 158), // Warna latar belakang + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + 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.red, // Warna merah untuk close + ), + child: IconButton( + onPressed: () { + // Navigator.pop(context); + Navigator.pushNamed(context, '/pengembalian-barang'); + }, + icon: Icon(Icons.close, color: Colors.white), + ), + ), + ], + ), + ), + 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: () { + if (_formKey.currentState!.validate()) { + try { + if (_enterAtController.text.isNotEmpty) { + _updatePeminjaman(); + } + } catch (e) { + print('Error storing data: $e'); + } + } + }, + icon: Icon(Icons.save, color: Colors.white), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/pengembalian_barang/pengembalian-index.dart b/lib/pages/pengembalian_barang/pengembalian-index.dart new file mode 100644 index 0000000..e5af7ad --- /dev/null +++ b/lib/pages/pengembalian_barang/pengembalian-index.dart @@ -0,0 +1,286 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:data_table_2/data_table_2.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.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:http/http.dart' as http; + +import '../../connection/connection.dart'; +import '../peminjaman_barang/show.dart'; + +class PengembalianBarangPage extends StatefulWidget { + const PengembalianBarangPage({super.key}); + + @override + State createState() => PengembalianBarangPageState(); +} + +class PengembalianBarangPageState extends State { + String? token; + int _currentPage = 1; + int _pageSize = 10; + List _data = []; + bool _isLoading = false; + + @override + void initState() { + super.initState(); + _getUserToken(); + fetchData(); + } + + void _getUserToken() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + if (mounted) { + setState(() { + token = prefs.getString('token'); + }); + } + } + + Future fetchData() async { + if (mounted) { + setState(() { + _isLoading = true; + }); + + try { + final response = await http.get(Uri.parse('$baseUrl/asset-status')); + + if (response.statusCode == 200) { + final jsonData = json.decode(response.body)['data']['asset_status']; + + final List newData = (jsonData as List) + .map((item) => AssetStatusModel.fromJson(item)) + .toList(); + + if (mounted) { + setState(() { + _data.addAll(newData); + _isLoading = false; + }); + } + } else { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + throw Exception('Failed to fetch data'); + } + } catch (e) { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + print('Error fetching data: $e'); + } + } + } + + void _loadMoreData() { + if (mounted && !_isLoading) { + setState(() { + _currentPage++; + }); + fetchData(); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.indigo[700], + elevation: 0, + title: Text('Data Pengembalian Barang', + style: TextStyle( + fontSize: 16, + )), + leading: IconButton( + icon: Icon(Icons.arrow_back, color: Colors.white), + onPressed: () { + Navigator.pushNamed(context, '/home'); + }, + ), + ), + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : SingleChildScrollView( + child: SizedBox( + width: double.infinity, + child: PaginatedDataTable( + header: const Text('Pengembalian Barang'), + rowsPerPage: _pageSize, + availableRowsPerPage: const [10, 25, 50], + onRowsPerPageChanged: (value) { + setState(() { + _pageSize = value!; + }); + }, + columns: const [ + DataColumn(label: Text('No')), + DataColumn(label: Text('Kode Peti')), + DataColumn(label: Text('Tgl Peminjaman')), + DataColumn(label: Text('Estimasi Pengembalian')), + DataColumn(label: Text('PJ Peminjaman')), + DataColumn(label: Text('Asal WH Peminjaman')), + DataColumn(label: Text('Tgl Pengembalian')), + DataColumn(label: Text('PJ Pengembalian')), + DataColumn(label: Text('Tujuan WH Pengembalian')), + DataColumn(label: Text('Kondisi Peti')), + DataColumn(label: Text('Status')), + ], + source: _DataSource(data: _data, context: context), + ), + ), + ), + bottomNavigationBar: 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: [ + InkWell( + customBorder: CircleBorder(), + onTap: () { + // Aksi ketika ikon diklik + Navigator.pushNamed(context, '/pengembalian-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, + ), + ), + ), + ], + ), + ), + ), + ); + } +} + +class _DataSource extends DataTableSource { + final List data; + final BuildContext context; + + _DataSource({required this.data, required this.context}); + @override + DataRow? getRow(int index) { + if (index >= data.length) { + return null; + } + + final item = data[index]; + + return DataRow(cells: [ + DataCell( + Text( + (index + 1).toString(), + ), + ), + DataCell( + Text( + // item.asset.exit_at.toString(), + item.peti!.customer!.code_customer.toString() + + '-' + + item.peti!.tipe_peti!.type.toString(), + ), + ), + DataCell( + GestureDetector( + onTap: () { + if (item.id != null) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => DetailPeminjamanBarangPage( + assetId: item.id!, + ), + ), + ); + + print('asset id: ${item.id}'); + } + }, + child: Text( + item.exit_at != null + ? DateFormat('dd-MM-yyyy').format(item.exit_at!) + : '-', + ), + ), + ), + DataCell( + Text( + // item.asset.exit_at.toString(), + item.est_pengembalian != null + ? DateFormat('dd-MM-yyyy').format(item.est_pengembalian!) + : '-', + ), + ), + DataCell( + Text( + item.exit_pic.toString() != 'null' ? item.exit_pic.toString() : '-', + ), + ), + DataCell( + Text(item.warehouse!.name.toString() != 'null' + ? item.warehouse!.name.toString() + : '-'), + ), + DataCell( + Text( + item.enter_at != null + ? DateFormat('dd-MM-yyyy').format(item.enter_at!) + : '-', + ), + ), + DataCell( + Text( + item.enter_pic.toString() != 'null' ? item.enter_pic.toString() : '-', + ), + ), + DataCell( + Text( + item.warehouse_enter!.id == item.enter_warehouse + ? item.warehouse_enter!.name.toString() + : '-', + ), + ), + DataCell( + Text(item.kondisi_peti.toString() != 'null' + ? item.kondisi_peti.toString() + : '-'), + ), + DataCell( + Text(item.warehouse_enter!.name == 'null' ? '-' : 'Sudah Dikembalikan'), + ), + ]); + } + + @override + bool get isRowCountApproximate => false; + + @override + int get rowCount => data.length; + + @override + int get selectedRowCount => 0; +} diff --git a/lib/pages/sign_in_page.dart b/lib/pages/sign_in_page.dart index 2bc4837..5fee0df 100644 --- a/lib/pages/sign_in_page.dart +++ b/lib/pages/sign_in_page.dart @@ -330,10 +330,11 @@ class __FormContentState extends State<_FormContent> { print('token dapat login: ${user.token}'); // Periksa apakah pengguna memiliki roles - if (user.role_id == 1) { - print('Berhasil login HALAMAN ADMIN'); - Navigator.pushNamed(context, '/home'); - } else if (user.role_id == 2) { + // if (user.role_id == 1) { + // print('Berhasil login HALAMAN ADMIN'); + // Navigator.pushNamed(context, '/home'); + // } else + if (user.role_id == 2) { print('Berhasil login HALAMAN USER'); Navigator.pushNamed(context, '/home'); } else { diff --git a/lib/widget/peminjaman_tile.dart b/lib/widget/peminjaman_tile.dart deleted file mode 100644 index 4607196..0000000 --- a/lib/widget/peminjaman_tile.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:siopas/models/asset_status_model.dart'; - -class AssetStatusPageTile extends StatelessWidget { - // final AssetStatusModel assetStatus; - // AssetStatusPageTile(this.assetStatus); - - @override - Widget build(BuildContext context) { - return DataTable( - columns: const [ - DataColumn( - label: Expanded( - child: Text( - 'Name', - style: TextStyle(fontStyle: FontStyle.italic), - ), - ), - ), - DataColumn( - label: Expanded( - child: Text( - 'Age', - style: TextStyle(fontStyle: FontStyle.italic), - ), - ), - ), - DataColumn( - label: Expanded( - child: Text( - 'Role', - style: TextStyle(fontStyle: FontStyle.italic), - ), - ), - ), - ], - rows: const [ - DataRow( - cells: [ - DataCell(Text('Sarah')), - DataCell(Text('19')), - DataCell(Text('Student')), - ], - ), - DataRow( - cells: [ - DataCell(Text('Janine')), - DataCell(Text('43')), - DataCell(Text('Professor')), - ], - ), - DataRow( - cells: [ - DataCell(Text('William')), - DataCell(Text('27')), - DataCell(Text('Associate Professor')), - ], - ), - ], - ); - } -}