import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:intl/intl.dart'; class RealtimeMonitoring extends StatefulWidget { const RealtimeMonitoring({super.key}); @override State createState() => _RealtimeMonitoringState(); } class _RealtimeMonitoringState extends State { final DatabaseReference _ref = FirebaseDatabase.instance.ref('monitoring'); Map _data = {}; @override void initState() { super.initState(); // Mendengarkan perubahan data pada node 'monitoring' di Firebase _ref.onValue.listen((event) { final value = event.snapshot.value; if (value != null && value is Map) { setState(() { _data = value; }); } }); } @override Widget build(BuildContext context) { // Mengambil data dari _data map, dengan nilai default jika null final suhu = _data['suhu_udara']?.toStringAsFixed(1) ?? '-'; final ph = _data['ph']?.toStringAsFixed(2) ?? '-'; final tds = _data['tds']?.toString() ?? '-'; final timestamp = _data['timestamp']; String timeString = '-'; if (timestamp != null && timestamp is int) { // Mengonversi Unix timestamp ke format tanggal dan waktu yang mudah dibaca final time = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); timeString = DateFormat('dd MMM yyyy HH:mm:ss').format(time); } // Status perangkat final fanStatus = (_data['fan'] ?? false) ? 'ON' : 'OFF'; final pompaUtamaStatus = (_data['pompa'] ?? false) ? 'ON' : 'OFF'; final pompaAbMixStatus = (_data['pompa_abmix'] ?? false) ? 'ON' : 'OFF'; final abmixHabisStatus = (_data['abmix_habis'] ?? false) ? 'YA' : 'TIDAK'; return Scaffold( appBar: AppBar(title: const Text('Realtime Data'), centerTitle: true), body: SingleChildScrollView( // <--- PERBAIKAN: Tambahkan SingleChildScrollView di sini padding: const EdgeInsets.all(16.0), child: Card( elevation: 6, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Padding( padding: const EdgeInsets.all(20.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, // Agar tabel mengisi lebar children: [ const Text( "📊 Data Realtime Monitoring", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.green, ), textAlign: TextAlign.center, ), const SizedBox(height: 20), // Tabel untuk menampilkan data Table( columnWidths: const { 0: FlexColumnWidth(1.5), // Label 1: FlexColumnWidth(2.5), // Value }, border: TableBorder.all( color: Colors.grey.shade300, borderRadius: BorderRadius.circular(10), width: 1.0, ), children: [ _buildTableRow('Waktu Update', timeString), _buildTableRow('Suhu Udara', '$suhu °C'), _buildTableRow('TDS', '$tds ppm'), _buildTableRow('pH', ph), _buildTableRow( 'Kipas', fanStatus, statusColor: fanStatus == 'ON' ? Colors.green : Colors.red, ), _buildTableRow( 'Pompa Utama', pompaUtamaStatus, statusColor: pompaUtamaStatus == 'ON' ? Colors.green : Colors.red, ), _buildTableRow( 'Pompa AB Mix', pompaAbMixStatus, statusColor: pompaAbMixStatus == 'ON' ? Colors.green : Colors.red, ), _buildTableRow( 'AB Mix Habis', abmixHabisStatus, statusColor: abmixHabisStatus == 'YA' ? Colors.red : Colors.green, ), ], ), const SizedBox(height: 20), Text( "Data diperbarui secara otomatis dari ESP32.", style: TextStyle(fontSize: 12, color: Colors.grey[600]), textAlign: TextAlign.center, ), ], ), ), ), ), ); } // Fungsi pembantu untuk membuat baris tabel TableRow _buildTableRow(String label, String value, {Color? statusColor}) { return TableRow( children: [ Padding( padding: const EdgeInsets.all(10.0), child: Text( label, style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 16), ), ), Padding( padding: const EdgeInsets.all(10.0), child: Text( value, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 16, color: statusColor ?? Colors.black, // Gunakan warna status jika ada ), textAlign: TextAlign.right, // Rata kanan untuk nilai ), ), ], ); } }