285 lines
9.9 KiB
Dart
285 lines
9.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:firebase_database/firebase_database.dart';
|
|
import 'package:tugasakhir/screens/history.dart';
|
|
import 'package:tugasakhir/screens/register.dart';
|
|
|
|
class HomeScreen extends StatefulWidget {
|
|
const HomeScreen({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<HomeScreen> createState() => _HomeScreenState();
|
|
}
|
|
|
|
Color warnaBMI(double bmi) {
|
|
if (bmi < 18.5) return Colors.blue;
|
|
if (bmi <= 24.9) return Colors.green;
|
|
if (bmi <= 29.9) return Colors.orange;
|
|
return Colors.red;
|
|
}
|
|
|
|
class _HomeScreenState extends State<HomeScreen> {
|
|
double beratBadan = 0.0;
|
|
double tinggiBadan = 0.0;
|
|
double nilaiBMI = 0.0;
|
|
String kategori = '';
|
|
Color warna = Colors.blue;
|
|
DateTime tanggalPenimbangan = DateTime.now();
|
|
String selectedUser = '';
|
|
|
|
final DatabaseReference _database = FirebaseDatabase.instance.ref();
|
|
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
|
|
|
List<String> userNames = [];
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_fetchUsers();
|
|
|
|
|
|
_database.child('sensor').onValue.listen((event) {
|
|
final data = event.snapshot.value as Map;
|
|
setState(() {
|
|
beratBadan = (data['berat'] as num).toDouble();
|
|
tinggiBadan = (data['tinggi'] as num).toDouble();
|
|
nilaiBMI = hitungBMI(beratBadan, tinggiBadan);
|
|
kategori = kategoriBMI(nilaiBMI);
|
|
warna = warnaBMI(nilaiBMI);
|
|
tanggalPenimbangan = DateTime.now();
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
Future<void> _fetchUsers() async {
|
|
try {
|
|
|
|
QuerySnapshot snapshot = await _firestore.collection('users').get();
|
|
List<String> users = snapshot.docs.map((doc) => doc['nama'] as String).toList();
|
|
|
|
setState(() {
|
|
userNames = users;
|
|
if (userNames.isNotEmpty) {
|
|
selectedUser = userNames[0];
|
|
}
|
|
});
|
|
} catch (e) {
|
|
print('Error fetching users: $e');
|
|
}
|
|
}
|
|
|
|
double hitungBMI(double berat, double tinggi) {
|
|
if (tinggi == 0) return 0;
|
|
double tinggiMeter = tinggi / 100;
|
|
return berat / (tinggiMeter * tinggiMeter);
|
|
}
|
|
|
|
String kategoriBMI(double bmi) {
|
|
if (bmi < 18.5) return 'Kurus';
|
|
if (bmi <= 24.9) return 'Normal';
|
|
if (bmi <= 29.9) return 'Gemuk';
|
|
return 'Obesitas';
|
|
}
|
|
|
|
String saranBMI(double bmi) {
|
|
if (bmi < 18.5) return 'Perbanyak asupan kalori dan protein.';
|
|
if (bmi <= 24.9) return 'Pertahankan pola makan dan gaya hidup sehat.';
|
|
if (bmi <= 29.9) return 'Kurangi makanan tinggi lemak dan tingkatkan aktivitas fisik.';
|
|
return 'Konsultasikan ke ahli gizi dan lakukan olahraga rutin.';
|
|
}
|
|
|
|
IconData ikonBMI(double bmi) {
|
|
if (bmi < 18.5) return Icons.accessibility_new;
|
|
if (bmi <= 24.9) return Icons.mood;
|
|
if (bmi <= 29.9) return Icons.sentiment_dissatisfied;
|
|
return Icons.warning;
|
|
}
|
|
|
|
|
|
void saveData() async {
|
|
try {
|
|
await _firestore.collection('history_timbangan').add({
|
|
'berat': beratBadan,
|
|
'tinggi': tinggiBadan,
|
|
'bmi': nilaiBMI,
|
|
'timestamp': FieldValue.serverTimestamp(),
|
|
'user': selectedUser,
|
|
});
|
|
|
|
await _database.child('users/$selectedUser/history').set({
|
|
'tanggal': tanggalPenimbangan.toIso8601String(),
|
|
'berat': beratBadan,
|
|
'tinggi': tinggiBadan,
|
|
'bmi': nilaiBMI,
|
|
});
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Data Berhasil Disimpan ')),
|
|
);
|
|
} catch (e) {
|
|
print('Error saving data: $e');
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Gagal menyimpan data')),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
backgroundColor: const Color(0xFF59A4EB),
|
|
elevation: 0,
|
|
title: Row(
|
|
children: [
|
|
const Icon(Icons.account_circle, size: 36, color: Colors.white),
|
|
const SizedBox(width: 10),
|
|
// Dropdown untuk memilih pengguna dari Firestore
|
|
DropdownButton<String>(
|
|
value: selectedUser.isEmpty ? null : selectedUser,
|
|
icon: const Icon(Icons.arrow_drop_down, color: Colors.white),
|
|
style: const TextStyle(color: Colors.white),
|
|
dropdownColor: const Color(0xFF59A4EB),
|
|
onChanged: (String? newValue) {
|
|
setState(() {
|
|
selectedUser = newValue!; // Update selected user
|
|
});
|
|
},
|
|
items: userNames
|
|
.map<DropdownMenuItem<String>>((String value) {
|
|
return DropdownMenuItem<String>(
|
|
value: value,
|
|
child: Text(value),
|
|
);
|
|
}).toList(),
|
|
),
|
|
const Spacer(),
|
|
// IconButton untuk menavigasi ke halaman Register
|
|
IconButton(
|
|
icon: const Icon(Icons.add, color: Colors.white), // Tombol tambah pengguna
|
|
onPressed: () {
|
|
// Navigasi ke halaman RegisterScreen
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => const RegisterScreen()),
|
|
).then((_) {
|
|
// Panggil _fetchUsers() untuk reload data setelah kembali dari RegisterScreen
|
|
_fetchUsers();
|
|
});
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 24.0),
|
|
child: Column(
|
|
children: [
|
|
const Center(
|
|
child: Text(
|
|
'SmartScale',
|
|
style: TextStyle(
|
|
fontSize: 30,
|
|
fontWeight: FontWeight.bold,
|
|
color: Color(0xFF59A4EB),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
// Menampilkan hasil pengukuran
|
|
Card(
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
|
elevation: 6,
|
|
color: Colors.white,
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(20.0),
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildDataColumn('${beratBadan.toStringAsFixed(1)} kg', 'Berat'),
|
|
_buildDataColumn('${tinggiBadan.toStringAsFixed(1)} cm', 'Tinggi'),
|
|
Column(
|
|
children: [
|
|
Text(
|
|
nilaiBMI.toStringAsFixed(1),
|
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: warna),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Icon(ikonBMI(nilaiBMI), color: warna, size: 28),
|
|
const SizedBox(height: 6),
|
|
Text(kategori, style: TextStyle(fontSize: 14, color: warna, fontWeight: FontWeight.w600)),
|
|
const Text('BMI', style: TextStyle(fontSize: 16)),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
saranBMI(nilaiBMI),
|
|
style: const TextStyle(fontSize: 14, fontStyle: FontStyle.italic, color: Colors.grey),
|
|
),
|
|
const SizedBox(height: 10),
|
|
Text(
|
|
'Terakhir diukur: ${tanggalPenimbangan.day}/${tanggalPenimbangan.month}/${tanggalPenimbangan.year}',
|
|
style: const TextStyle(fontSize: 13, color: Colors.black54),
|
|
),
|
|
Text(
|
|
'Ulangi penimbangan: ${tanggalPenimbangan.add(const Duration(days: 7)).day}/${tanggalPenimbangan.add(const Duration(days: 7)).month}/${tanggalPenimbangan.add(const Duration(days: 7)).year}',
|
|
style: const TextStyle(fontSize: 13, color: Colors.black54),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 30),
|
|
ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFF59A4EB), // Blue color for the button
|
|
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 30),
|
|
),
|
|
onPressed: saveData, // Menyimpan data
|
|
child: const Text(
|
|
'Save Data',
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white),
|
|
),
|
|
),
|
|
const SizedBox(height: 30),
|
|
ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFF59A4EB), // Blue color for the button
|
|
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 30),
|
|
),
|
|
onPressed: () {
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => const HistoryScreen()), // Navigasi ke HistoryScreen
|
|
);
|
|
},
|
|
child: const Text(
|
|
'Weight Trend',
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Fungsi untuk membuat kolom data
|
|
Widget _buildDataColumn(String value, String label) {
|
|
return Column(
|
|
children: [
|
|
Text(
|
|
value,
|
|
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF638BF7)),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(label, style: const TextStyle(fontSize: 16)),
|
|
],
|
|
);
|
|
}
|
|
}
|