import 'dart:async'; // untuk Timer import 'package:flutter/material.dart'; import 'package:quickalert/quickalert.dart'; // asumsi kamu pakai package ini import 'penitipan.dart'; import 'package:ui_loker/Model/locker_model.dart'; import 'package:ui_loker/Model/penitipan_model.dart'; import 'package:ui_loker/Service/api_service.dart'; class LokerTab extends StatefulWidget { final int activeTabIndex; const LokerTab({Key? key, required this.activeTabIndex}) : super(key: key); @override _LokerTabState createState() => _LokerTabState(); } class _LokerTabState extends State { List _lokers = []; bool _loading = true; Timer? _timer; int _cardLimit = 10; @override void initState() { super.initState(); fetchLokers(); _timer = Timer.periodic(Duration(seconds: 3), (timer) { fetchLokers(); }); } @override void dispose() { _timer?.cancel(); super.dispose(); } Future fetchLokers() async { try { final response = await ApiService.getAllLockers(); // Ambil data API setState(() { _lokers = response; // Langsung assign response yang sudah berupa List _loading = false; }); } catch (e) { print('Error fetching lokers: $e'); setState(() { _loading = false; }); } } Future _addNewCard() async { try { int newCardNumber = _lokers.length + 1; final newLoker = await ApiService.addLocker(newCardNumber); setState(() { _lokers.add(newLoker as LockerModel); }); } catch (e) { print('Error adding loker: $e'); } // Menampilkan popup setelah card berhasil ditambahkan _showSuccessPopup(context); } // void _addNewCard() { // setState(() { // if (_lokers.length > _cardLimit) { // _cardLimit += 5; // Tambahkan 5 lebih banyak loker yang akan ditampilkan // } // }); // } void removeLocker(int lockerId) async { if (_lokers.isNotEmpty) { final confirm = await showDialog( context: context, builder: (_) => AlertDialog( title: Text('Konfirmasi'), content: Text('Apakah kamu yakin ingin menghapus loker ini?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: Text('Batal'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: Text('Hapus'), ), ], ), ); if (confirm == true) { try { bool success = await ApiService.deleteLocker(lockerId); if (success) { setState(() { _lokers.removeWhere((l) => l.id == lockerId); }); ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('Loker berhasil dihapus'))); } } catch (e) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text('Gagal menghapus loker: $e'))); } } } else { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text("Tidak ada loker untuk dihapus"))); } } void _showSuccessPopup(BuildContext context) { QuickAlert.show( context: context, type: QuickAlertType.success, text: 'Berhasil membuat loker baru!', ); } void _showRemovePopup(BuildContext context) { QuickAlert.show( context: context, type: QuickAlertType.warning, text: 'Apakah Anda yakin ingin menghapus loker terakhir?', showCancelBtn: true, onCancelBtnTap: () { Navigator.of(context).pop(); }, onConfirmBtnTap: () { setState(() { _lokers.removeLast(); }); Navigator.of(context).pop(); }, ); } void showUserDataPopup(BuildContext context, PenitipanModel data) { showDialog( context: context, builder: (context) { return AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox(height: 14), Text( 'Detail Pengguna Loker', textAlign: TextAlign.center, style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black, ), ), SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon(Icons.person, color: Colors.black54), SizedBox(width: 8), Expanded( child: Text( 'Nama: ${data.nama}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ), ], ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon(Icons.access_time, color: Colors.black54), SizedBox(width: 8), Expanded( child: Text( 'Waktu Penitipan: ${data.waktuMulai ?? 'Tidak tersedia'}', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ), ], ), ], ), ); }, ); } @override Widget build(BuildContext context) { if (_loading) { return Center(child: CircularProgressIndicator()); } return Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Expanded( child: _lokers.isEmpty ? Center(child: Text("Tidak ada data loker")) : GridView.builder( itemCount: _lokers.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 1, ), itemBuilder: (context, index) { final locker = _lokers[index]; Color cardColor; if (locker.status == 'kosong') { cardColor = [ Colors.green.shade700, Colors.green.shade800, Colors.green.shade900, ][index % 3]; } else if (locker.status == 'servis') { cardColor = [ Colors.red.shade700, Colors.red.shade800, Colors.red.shade900, ][index % 3]; } else if (locker.status == 'pending') { cardColor = [ Colors.yellow.shade900, Colors.yellow.shade900, Colors.yellow.shade900, ][index % 3]; } else { cardColor = [ Colors.grey.shade700, Colors.grey.shade800, Colors.grey.shade900, ][index % 3]; } return GestureDetector( onTap: () async { if (locker.status == 'digunakan' ||locker.status == 'pending') { try { List dataList = await ApiService.getPenitipanByLoker(locker.id); if (dataList.isNotEmpty) { PenitipanModel data = dataList.first; showUserDataPopup(context, data); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Data pengguna tidak ditemukan')), ); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Gagal ambil data pengguna: $e')), ); } } else if(locker.status == "servis"){ // Tampilkan dialog scan jika status loker adalah 'servis' await showDialog( context: context, barrierDismissible: false, builder: (context) { return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), child: Padding( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( 'Scan Card', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), SizedBox(height: 12), LayoutBuilder( builder: (context, constraints) { // Maksimal lebar 80% dari lebar layar atau maksimal 300 px double imageWidth = constraints.maxWidth * 0.8; if (imageWidth > 300) imageWidth = 300; return Image.asset( 'assets/scan1.png', width: imageWidth, height: imageWidth, fit: BoxFit.contain, ); }, ), SizedBox(height: 20), SizedBox( width: double.infinity, // tombol lebar penuh dialog child: ElevatedButton( onPressed: () { Navigator.of(context).pop(); // Tutup dialog }, child: Text('Tutup'), ), ), ], ), ), ); }, ); }else{ showModalBottomSheet( context: context, isScrollControlled: true, shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(20)), ), builder: (_) => PenitipanFormSheet(lokerId: locker.id), ); } }, child: Card( color: cardColor, elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.lock, size: 40, color: Colors.white), SizedBox(height: 10), Text( locker.nomorLoker ?? "Loker ${locker.id}", style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16, color: Colors.white, ), ), SizedBox(height: 4), Text( "Status: ${locker.status}", style: TextStyle(color: Colors.white70), ), ], ), ), ), ); }, ), ), SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton.icon( onPressed: _addNewCard, icon: Icon(Icons.add), label: Text("Tambah Loker"), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ), ElevatedButton.icon( onPressed: _lokers.isNotEmpty ? () => removeLocker(_lokers.last.id) : null, // tombol dinonaktifkan jika kosong icon: Icon(Icons.remove, color: Colors.white), label: Text("Hapus Loker"), style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ), ], ), ], ), ); } }