TKK_E32230949/lib/screens/history_screen.dart

386 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';
class HistoryScreen extends StatefulWidget {
const HistoryScreen({super.key});
@override
State<HistoryScreen> createState() => _HistoryScreenState();
}
class _HistoryScreenState extends State<HistoryScreen> {
late String selectedYear;
late String selectedMonth;
final List<String> months = [
"Januari","Februari","Maret","April","Mei","Juni",
"Juli","Agustus","September","Oktober","November","Desember"
];
late List<String> years;
Future<void> deleteOldData() async {
final snapshot = await FirebaseFirestore.instance
.collection("watering_history")
.get();
final now = DateTime.now();
for (var doc in snapshot.docs) {
final data = doc.data();
final dateString = data["date"];
final parsedDate = DateFormat("dd-MM-yyyy").parse(dateString);
final difference = now.difference(parsedDate).inDays;
if (difference >= 7) {
await FirebaseFirestore.instance
.collection("watering_history")
.doc(doc.id)
.delete();
}
}
}
@override
void initState() {
super.initState();
final now = DateTime.now();
selectedYear = now.year.toString();
selectedMonth = months[now.month - 1];
years = List.generate(
5,
(index) => (now.year - 2 + index).toString(),
);
deleteOldData(); // hapus data lama
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[200],
body: SafeArea(
child: Column(
children: [
/// ================= HEADER =================
Padding(
padding: const EdgeInsets.all(16),
child: _buildHeader(),
),
/// ================= LIST =================
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("watering_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"));
}
/// FILTER BULAN & TAHUN
final filteredDocs = docs.where((doc) {
final data = doc.data() as Map<String, dynamic>;
final dateString = data["date"] ?? "";
if (dateString.isEmpty) return false;
final parsedDate =
DateFormat("dd-MM-yyyy").parse(dateString);
final yearMatch =
parsedDate.year.toString() == selectedYear;
final monthMatch =
months[parsedDate.month - 1] == selectedMonth;
return yearMatch && monthMatch;
}).toList()
// SORT TERBARU KE ATAS
..sort((a, b) {
final dateA = DateFormat("dd-MM-yyyy")
.parse((a.data() as Map<String, dynamic>)["date"]);
final dateB = DateFormat("dd-MM-yyyy")
.parse((b.data() as Map<String, dynamic>)["date"]);
return dateB.compareTo(dateA);
});
if (filteredDocs.isEmpty) {
return const Center(
child: Text("Tidak ada data di bulan ini"));
}
return ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 15),
itemCount: filteredDocs.length,
itemBuilder: (context, index) {
final data = filteredDocs[index]
.data() as Map<String, dynamic>;
final date = data["date"] ?? "";
final startTime = data["startTime"] ?? "-";
final endTime = data["endTime"] ?? "-";
final status = data["status"] ?? "unknown";
final type = data["type"] ?? "-";
final parsedDate =
DateFormat("dd-MM-yyyy").parse(date);
final formattedDay =
DateFormat("EEEE, dd MMMM yyyy", "id_ID")
.format(parsedDate);
return HistoryCard(
day: formattedDay,
startTime: startTime,
endTime: endTime ?? "-",
type: type,
status: status,
);
},
);
},
),
),
],
),
),
);
}
/// ================= HEADER WIDGET =================
Widget _buildHeader() {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: const Color(0xFF2ECC71),
borderRadius: BorderRadius.circular(18),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Riwayat Penyiraman",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 12),
Row(
children: [
DropdownButton<String>(
value: selectedYear,
underline: const SizedBox(),
dropdownColor: Colors.white,
items: years.map((year) {
return DropdownMenuItem(
value: year,
child: Text(year),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedYear = value!;
});
},
),
const SizedBox(width: 12),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: months.map((month) {
final isActive = month == selectedMonth;
return Padding(
padding: const EdgeInsets.only(right: 8),
child: GestureDetector(
onTap: () {
setState(() {
selectedMonth = month;
});
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 14, vertical: 6),
decoration: BoxDecoration(
color: isActive
? Colors.black
: Colors.white,
borderRadius:
BorderRadius.circular(20),
),
child: Text(
month,
style: TextStyle(
fontSize: 12,
color: isActive
? Colors.white
: Colors.black,
),
),
),
),
);
}).toList(),
),
),
),
],
),
],
),
);
}
}
/// ================= CARD =================
class HistoryCard extends StatelessWidget {
final String day;
final String startTime;
final String endTime;
final String type;
final String status;
const HistoryCard({
super.key,
required this.day,
required this.startTime,
required this.endTime,
required this.type,
required this.status,
});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
day,
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: 13,
),
),
const SizedBox(height: 8),
Row(
children: [
/// START
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.orange[100],
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
const Text(""),
Text(startTime,
style: const TextStyle(fontSize: 11)),
],
),
),
const SizedBox(width: 8),
/// END
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: status == "done"
? Colors.green[100]
: Colors.red[100],
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Text(status == "done" ? "" : ""),
Text(
endTime,
style: TextStyle(
fontSize: 11,
color: status == "done"
? Colors.green
: Colors.red,
),
),
],
),
),
const Spacer(),
/// TYPE
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
),
child: Text(
type,
style: const TextStyle(
color: Colors.white,
fontSize: 11,
),
),
),
],
)
],
),
);
}
}