import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'servo_button.dart'; import 'history_item.dart'; class DashboardScreen extends StatefulWidget { const DashboardScreen({super.key}); @override State createState() => _DashboardScreenState(); } class _DashboardScreenState extends State { final DatabaseReference servoRef = FirebaseDatabase.instance.ref('servo/'); final DatabaseReference statusRef = FirebaseDatabase.instance.ref( 'Gambar/status/', ); final DatabaseReference urlGambarRef = FirebaseDatabase.instance.ref( 'Gambar/url/', ); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @override void initState() { super.initState(); initNotifications(); listenToStatus(); } Future initNotifications() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid); await flutterLocalNotificationsPlugin.initialize(initializationSettings); } Future showNotification() async { const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails( 'deteksi_channel', 'Deteksi Objek', channelDescription: 'Notifikasi saat objek terdeteksi', importance: Importance.max, priority: Priority.high, showWhen: true, ); const NotificationDetails platformChannelSpecifics = NotificationDetails( android: androidPlatformChannelSpecifics, ); await flutterLocalNotificationsPlugin.show( 0, 'Notifikasi', 'ADA PAKETT!!!!!', platformChannelSpecifics, ); } void listenToStatus() { statusRef.onValue.listen((event) async { final status = event.snapshot.value; if (status == true) { final urlSnapshot = await urlGambarRef.get(); final url = urlSnapshot.value?.toString(); if (url != null && url.isNotEmpty) { await FirebaseFirestore.instance.collection('history').add({ 'timestamp': Timestamp.now(), 'imageUrl': url, }); await showNotification(); await statusRef.set(false); } } }); } void sendServoCommand(bool state) { servoRef.set(state); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Dashboard Paket')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ const Text( 'Tombol Manual Servo', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ServoButton( label: 'BUKA', color: Colors.green, onPressed: () => sendServoCommand(true), ), const SizedBox(width: 20), ServoButton( label: 'TUTUP', color: Colors.red, onPressed: () => sendServoCommand(false), ), ], ), const SizedBox(height: 30), const Divider(thickness: 1.5), const Align( alignment: Alignment.centerLeft, child: Text( 'Riwayat Paket', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), const SizedBox(height: 10), Expanded( child: StreamBuilder( stream: FirebaseFirestore.instance .collection('history') .orderBy('timestamp', descending: true) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) { return const Center(child: CircularProgressIndicator()); } final docs = snapshot.data!.docs; if (docs.isEmpty) { return const Center( child: Text( 'Belum ada riwayat paket.', style: TextStyle(color: Colors.grey), ), ); } return ListView.separated( itemCount: docs.length, separatorBuilder: (context, index) => const SizedBox(height: 8), itemBuilder: (context, index) { final data = docs[index].data() as Map; return Card( elevation: 3, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: const EdgeInsets.symmetric( vertical: 10, horizontal: 16, ), child: HistoryItem( timestamp: (data['timestamp'] as Timestamp).toDate(), imageUrl: data['imageUrl'] ?? '', ), ), ); }, ); }, ), ), ], ), ), ); } }