TKK_E32220332/lib/screens/analytics_screen.dart

177 lines
7.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import '../services/supabase_service.dart';
import '../constants/app_colors.dart'; // <-- IMPORT APP COLORS DITAMBAHKAN
class AnalyticsScreen extends StatefulWidget {
const AnalyticsScreen({super.key});
@override
State<AnalyticsScreen> createState() => _AnalyticsScreenState();
}
class _AnalyticsScreenState extends State<AnalyticsScreen> {
List<Map<String, dynamic>> _logs = [];
bool _isLoading = true;
@override
void initState() {
super.initState();
_fetchLogs();
}
Future<void> _fetchLogs() async {
try {
final data = await SupabaseService().getFotoDataset();
setState(() {
_logs = data;
_isLoading = false;
});
} catch (e) {
debugPrint('Error fetching logs: $e');
setState(() => _isLoading = false);
}
}
@override
Widget build(BuildContext context) {
final args = (ModalRoute.of(context)?.settings.arguments as Map<String, dynamic>?) ?? {};
final String title = args['title'] ?? 'Grafik';
final Color color = args['color'] ?? AppColors.primary; // --- BERUBAH: Fallback color ---
final String sensorKey = title.contains('Suhu') ? 'suhu' : title.contains('Kelembaban') ? 'kelembapan' : 'intensitas';
return Scaffold(
// --- BERUBAH: Background Scaffold Utama ---
backgroundColor: AppColors.background,
appBar: AppBar(
// --- BERUBAH: Dibuat transparan agar menyatu dengan background ---
backgroundColor: Colors.transparent,
elevation: 0,
// --- BERUBAH: Warna Teks Judul ---
title: Text(title, style: const TextStyle(color: AppColors.textMain)),
leading: IconButton(
// --- BERUBAH: Warna Ikon Back ---
icon: const Icon(Icons.arrow_back, color: AppColors.primary),
onPressed: () => Navigator.pop(context),
),
),
body: _isLoading
// --- BERUBAH: Warna Loading Indicator ---
? const Center(child: CircularProgressIndicator(color: AppColors.primary))
: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
_buildChartCard(title, color, _logs, sensorKey),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// --- BERUBAH: Warna Teks Judul Riwayat ---
const Text('Riwayat Data', style: TextStyle(color: AppColors.textMain, fontSize: 18, fontWeight: FontWeight.bold)),
// --- BERUBAH: Warna Ikon Refresh ---
IconButton(icon: const Icon(Icons.refresh, color: AppColors.primary), onPressed: _fetchLogs),
],
),
const SizedBox(height: 10),
Expanded(
child: Container(
decoration: BoxDecoration(
// --- BERUBAH: Warna Latar Daftar Riwayat ---
color: AppColors.cardBg,
borderRadius: BorderRadius.circular(20),
// --- BERUBAH: Menambahkan border halus agar serasi dengan kartu lain ---
border: Border.all(color: AppColors.textSecondary.withValues(alpha: 0.15)),
),
child: ListView.separated(
padding: const EdgeInsets.all(15),
itemCount: _logs.length,
// --- BERUBAH: Warna Garis Pemisah (Divider) antar item ---
separatorBuilder: (context, index) => Divider(color: AppColors.textSecondary.withValues(alpha: 0.3)),
itemBuilder: (context, index) {
final log = _logs[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// --- BERUBAH: Warna Teks Tanggal/Waktu ---
Text(log['timestamp'] ?? '', style: const TextStyle(color: AppColors.textSecondary, fontSize: 10)),
// --- BERUBAH: Warna Teks Status Kipas ---
Text('Kipas 1: ${log['kipas1']} | Kipas 2: ${log['kipas2']}', style: const TextStyle(color: AppColors.primary, fontSize: 10)),
],
),
// Warna nilai sensor tetap mengikuti `color` dinamis (Merah/Cyan/Orange)
Text('${log[sensorKey]}', style: TextStyle(color: color, fontWeight: FontWeight.bold)),
],
),
);
},
),
),
),
],
),
),
);
}
Widget _buildChartCard(String title, Color color, List<Map<String, dynamic>> logs, String key) {
List<FlSpot> spots = [];
if (logs.isNotEmpty) {
final reversedLogs = logs.reversed.toList();
for (int i = 0; i < reversedLogs.length; i++) {
spots.add(FlSpot(i.toDouble(), double.tryParse(reversedLogs[i][key].toString()) ?? 0));
}
}
return Container(
height: 250,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
// --- BERUBAH: Warna Latar Kartu Grafik ---
color: AppColors.cardBg,
borderRadius: BorderRadius.circular(20),
// --- BERUBAH: Menambahkan border halus agar serasi dengan kartu lain ---
border: Border.all(color: AppColors.textSecondary.withValues(alpha: 0.15)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: LineChart(
LineChartData(
gridData: FlGridData(show: false),
titlesData: FlTitlesData(show: false),
borderData: FlBorderData(show: false),
lineBarsData: [
LineChartBarData(
spots: spots.isEmpty ? [const FlSpot(0, 0)] : spots,
isCurved: true,
// Warna garis grafik tetap mengikuti `color` dinamis
color: color,
barWidth: 4,
dotData: FlDotData(show: false),
// --- BERUBAH: Gunakan withValues untuk transparansi area bawah grafik ---
belowBarData: BarAreaData(show: true, color: color.withValues(alpha: 0.1)),
),
],
),
),
),
Align(
alignment: Alignment.bottomRight,
child: Text(
'Terakhir: ${logs.isNotEmpty ? logs.first[key] : "-"}',
// Warna teks terakhir tetap mengikuti `color` dinamis
style: TextStyle(color: color, fontSize: 12)
),
),
],
),
);
}
}