import 'dart:convert'; import 'dart:core'; import 'package:flutter/material.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/models/m_asset_status_model.dart'; import 'package:siopas/models/warehouse_mode.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; import '../../models/user_model.dart'; import '../../providers/auth_provider.dart'; class CreatePeminjamanBarang extends StatefulWidget { const CreatePeminjamanBarang({Key? key}) : super(key: key); @override State createState() => _CreatePeminjamanBarangState(); } class _CreatePeminjamanBarangState extends State { List _dataAsset = []; List _dataWarehouse = []; bool _isLoading = false; String? token; PetiAssetModel? _valAsset; WarehouseModel? _valWarehouse; TextEditingController _exit_atController = TextEditingController(); TextEditingController _est_pengembalianController = TextEditingController(); TextEditingController _penanggungJawabController = 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/peti-asset')); if (mounted) { // Periksa apakah widget masih "mounted" if (response.statusCode == 200) { final jsonData = json.decode(response.body)['data']['petis']; final List newDataAsset = (jsonData as List) .map((item) => PetiAssetModel.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'); } } } Future _onQRViewCreated(QRViewController controller) async { this.controller = controller; bool scanned = false; // code to auto focus kamera belakang controller.flipCamera(); await Future.delayed(const Duration(milliseconds: 400)); controller.flipCamera(); controller.scannedDataStream.listen((scanData) { if (!scanned) { try { setState(() { result = scanData; List lines = result!.code!.split('\n'); String idPeti = ''; String idWarehouse = ''; for (String line in lines) { if (line.contains(';')) { List values = line.split(';'); if (values.length >= 3) { idPeti = values[1]; idWarehouse = values[2]; break; } } } int? petiId = int.tryParse(idPeti); int? warehouseId = int.tryParse(idWarehouse); if (petiId != null && warehouseId != null) { _valAsset = _dataAsset.firstWhere( (peti) => peti.id == petiId, orElse: () => _valAsset!, ); _valWarehouse = _dataWarehouse.firstWhere( (warehouse) => warehouse.id == warehouseId, orElse: () => _valWarehouse!, ); } else { // Jika nilai yang dipindai tidak sesuai, tampilkan pesan kesalahan ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Row( children: [ Icon( Icons.warning, color: Colors.black, // Warna ikon ), SizedBox(width: 8), // Jarak antara ikon dan teks Text( 'Nilai QR Code tidak sesuai dengan yang diharapkan.', style: TextStyle( color: Colors.black, fontSize: 12, ), // Warna teks ), ], ), backgroundColor: Colors.yellow[700], // Warna latar belakang SnackBar ), ); } 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'), ), ); } } }); } // 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); // _exit_atController.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; var scanArea = (MediaQuery.of(context).size.width < 400 || MediaQuery.of(context).size.height < 400) ? 150.0 : 300.0; // 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; }); try { final response = await http.post( Uri.parse('$baseUrl/asset-status/store'), headers: { 'Content-Type': 'application/json', 'Authorization': token!, }, body: jsonEncode({ 'peti_id': _valAsset!.id, 'exit_at': _exit_atController.text, 'exit_pic': _penanggungJawabController.text, 'exit_warehouse': _valWarehouse!.id, 'est_pengembalian': _est_pengembalianController.text, 'created_by': user.fullname, // 'updated_by': user.fullname, }), ); if (response.statusCode == 200) { final jsonData = json.decode(response.body)['data']['peminjam']; print('Berhasil menyimpan 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 disimpan'), ], ), duration: Duration(seconds: 3), // Durasi tampilan snackbar ), ); // Reset form input _exit_atController.text = ''; _valAsset = null; _valWarehouse = null; result = null; } else { // Reset form input _exit_atController.text = ''; _valAsset = null; _valWarehouse = null; result = null; throw Exception('Gagal menyimpan data Asset Status'); } } catch (e) { print('Error storing 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 menyimpan data'), ], ), duration: Duration(seconds: 2), // Durasi tampilan snackbar ), ); } finally { if (mounted) { setState(() { _isLoading = false; }); } } } return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.indigo[700], elevation: 0, title: Text('Buat Peminjaman Barang', style: TextStyle( fontSize: 16, )), leading: IconButton( icon: Icon(Icons.arrow_back), onPressed: () { Navigator.pushNamed(context, '/peminjaman-barang'); }, ), ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(16), 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((PetiAssetModel item) { return DropdownMenuItem( child: Text('${item.fix_lot}'), value: item, ); }).toList(), onChanged: (PetiAssetModel? value) { setState(() { _valAsset = value; if (value != null) { // Set _valWarehouse berdasarkan warehouse_id dari PetiAssetModel _valWarehouse = _dataWarehouse.firstWhere( (warehouse) => warehouse.id == int.parse(value.warehouse_id .toString()), ); } }); }, ), ), ), ), 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: scanArea, ), ), ), 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), Card( elevation: 2, child: Padding( padding: const EdgeInsets.all(8), child: 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', inputType: InputType.date, // format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'), format: DateFormat('yyyy-MM-dd', 'id_ID'), decoration: InputDecoration( labelText: 'Tanggal Peminjaman', border: OutlineInputBorder(), suffixIcon: Icon(Icons.calendar_today), ), ), ), ), SizedBox(height: 16), Card( elevation: 2, child: Padding( padding: const EdgeInsets.all(8), child: 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( 'Estimasi Tanggal Pengembalian harus diisi'), ], ), duration: Duration(seconds: 2), ), ); return null; // Return null jika ada kesalahan } return null; // Return null jika tidak ada kesalahan }, controller: _est_pengembalianController, name: 'tanggal', inputType: InputType.date, // format: DateFormat('yyyy-MM-dd HH:mm:ss.SSS'), format: DateFormat('yyyy-MM-dd', 'id_ID'), decoration: InputDecoration( labelText: 'Estimasi Tanggal Pengembalian', border: OutlineInputBorder(), suffixIcon: Icon(Icons.calendar_today), ), ), ), ), SizedBox(height: 16), Card( elevation: 2, child: Padding( padding: const EdgeInsets.all(8), child: TextFormField( controller: _penanggungJawabController = 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: 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; }); }, ), ), ), SizedBox(height: 16), // FractionallySizedBox( // widthFactor: 1.0, // Lebar penuh // 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 ?? // 'Belum ada data QR Code terpindai' // : 'Belum ada data QR Code terpindai', // style: TextStyle(fontSize: 14), // ), // ], // ), // ), // ), // ), 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, '/peminjaman-barang'); }, icon: Icon(Icons.close, color: Colors.white), ), ), ], ), ), // Container( // // width: 50, // Lebar sesuai kebutuhan // width: 65.0, // height: 50, // Tinggi sesuai kebutuhan // decoration: BoxDecoration( // color: Colors.indigoAccent, // Warna latar belakang // shape: BoxShape.circle, // Membuat lingkaran // ), // child: IconButton( // onPressed: () { // showModalBottomSheet( // context: context, // 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: 16, // child: ElevatedButton( // onPressed: () { // Navigator.of(context).pop(); // }, // child: Text('Tutup'), // ), // ), // ], // ); // }, // ); // }, // icon: Icon( // Icons.qr_code, // size: 30, // ), // color: Colors.white, // Warna ikon // ), // ), 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 (_exit_atController.text.isNotEmpty) { _storePeminjaman(); } } catch (e) { print('Error storing data: $e'); } } }, icon: Icon(Icons.save, color: Colors.white), ), ), ], ), ), ], ), ), ); } }