import 'package:flutter/material.dart'; import 'alert_screen2.dart'; import 'family_screen.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:firebase_database/ui/firebase_animated_list.dart'; import 'package:provider/provider.dart'; import 'danger_status_manager.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; final databaseReference = FirebaseDatabase.instance.reference(); class HomeSatpam extends StatefulWidget { @override _HomeSatpamState createState() => _HomeSatpamState(); } class _HomeSatpamState extends State { int _selectedIndex = 0; void _onItemTapped(int index) { if (index == 2) { Navigator.pushReplacementNamed(context, '/login'); return; } setState(() { _selectedIndex = index; }); } @override Widget build(BuildContext context) { final widgetOptions = [ HomeSatpamBody(), FamilyScreen(), ]; return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, backgroundColor: Colors.black, title: Row( children: [ SizedBox(width: 8), Text( "SATPAM", style: TextStyle(fontSize: 20), ), ], ), actions: [ IconButton( icon: Icon(Icons.warning), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => AlertScreen2()), ); }, ), ], ), body: widgetOptions.elementAt(_selectedIndex), bottomNavigationBar: BottomNavigationBar( backgroundColor: Colors.black, items: [ BottomNavigationBarItem( icon: Icon(Icons.home, color: Colors.white), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.group, color: Colors.white), label: 'Penghuni', ), BottomNavigationBarItem( icon: Icon(Icons.logout, color: Colors.white), label: 'Log Out', ), ], currentIndex: _selectedIndex, selectedItemColor: Colors.blueAccent, unselectedItemColor: Colors.white, onTap: _onItemTapped, ), ); } } class HomeSatpamBody extends StatelessWidget { final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); HomeSatpamBody() { final initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); final initializationSettings = InitializationSettings( android: initializationSettingsAndroid, ); flutterLocalNotificationsPlugin.initialize(initializationSettings); } Future showNotification() async { const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails('your_channel_id', 'your_channel_name', channelDescription: 'your_channel_description', importance: Importance.max, priority: Priority.high, ticker: 'ticker'); const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); await flutterLocalNotificationsPlugin.show( 0, 'Peringatan', 'Ada indikasi kebakaran', platformChannelSpecifics, payload: 'item x', ); } @override Widget build(BuildContext context) { final dangerStatusManager = Provider.of(context); return Scaffold( backgroundColor: Colors.blue[900], body: Container( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Status Terkini", style: TextStyle(fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold), ), ], ), SizedBox(height: 20), Expanded( child: FirebaseAnimatedList( query: databaseReference, itemBuilder: (context, snapshot, animation, index) { String deviceId = snapshot.key ?? ''; int flameStatus = int.tryParse(snapshot.child("flameStatus").value.toString()) ?? 0; int smokeStatus = int.tryParse(snapshot.child("smokeDetected").value.toString()) ?? 0; bool isFlameDanger = flameStatus == 2; bool isSmokeDanger = smokeStatus == 2; // Update status outside of the build method to avoid issues WidgetsBinding.instance.addPostFrameCallback((_) { if (isFlameDanger) { dangerStatusManager.setFlameStatus(deviceId, true); showNotification(); } if (isSmokeDanger) { dangerStatusManager.setSmokeStatus(deviceId, true); showNotification(); } }); bool isFlameBlinking = dangerStatusManager.isFlameBlinking(deviceId); bool isSmokeBlinking = dangerStatusManager.isSmokeBlinking(deviceId); return Container( margin: EdgeInsets.only(bottom: 16), padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8.0), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), spreadRadius: 2, blurRadius: 6, offset: Offset(0, 3), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "No Rumah: ${snapshot.child("nomorRumah").value.toString()}", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black), ), SizedBox(height: 8), Text( "Client ip: ${snapshot.child("clientIP").value.toString()}", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black), ), SizedBox(height: 8), Text( "Serial Esp: ${snapshot.child("espSerial").value.toString()}", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black), ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ BlinkingIcon( icon: Icons.cloud, color: dangerStatusManager.isSmokeDanger(deviceId) ? Colors.red : Colors.green, isBlinking: isSmokeBlinking, ), SizedBox(width: 16), // Menambahkan jarak di antara ikon-ikon BlinkingIcon( icon: Icons.local_fire_department, color: dangerStatusManager.isFlameDanger(deviceId) ? Colors.red : Colors.green, isBlinking: isFlameBlinking, ), ], ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), onPressed: () { dangerStatusManager.resetStatus(deviceId); }, child: Text('Reset'), ), ], ), ], ), ); }, ), ), ], ), ), ); } } class BlinkingIcon extends StatefulWidget { final IconData icon; final Color color; final bool isBlinking; BlinkingIcon({required this.icon, required this.color, required this.isBlinking}); @override _BlinkingIconState createState() => _BlinkingIconState(); } class _BlinkingIconState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 500), vsync: this, )..repeat(reverse: true); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( padding: EdgeInsets.all(8.0), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8.0), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), spreadRadius: 2, blurRadius: 6, offset: Offset(0, 3), ), ], ), child: widget.isBlinking ? FadeTransition( opacity: _controller, child: Icon(widget.icon, color: widget.color, size: 32), ) : Icon(widget.icon, color: widget.color, size: 32), ); } }