// import 'dart:convert'; // import 'package:flutter/material.dart'; // import 'package:piring_baru/bloc/nav/bottom_nav.dart'; // import 'package:syncfusion_flutter_charts/charts.dart'; // import 'package:http/http.dart' as http; // import 'package:intl/intl.dart'; // import 'package:fl_chart/fl_chart.dart'; // import 'package:piring_baru/model/makanan.dart'; // class Riwayat extends StatefulWidget { // const Riwayat({super.key}); // @override // State createState() => _RiwayatState(); // } // class _RiwayatState extends State { // List makananList = []; // Map totalCaloriesByDate = {}; // DateTime startDate = // DateTime.now().subtract(const Duration(days: 7)); // 7 hari terakhir // DateTime endDate = DateTime.now(); // Future _selectStartDate(BuildContext context) async { // final DateTime? picked = await showDatePicker( // context: context, // initialDate: startDate, // firstDate: DateTime(2020), // lastDate: DateTime(2101), // ); // if (picked != null && picked != startDate) { // setState(() { // startDate = picked; // }); // fetchData(); // } // } // Future _selectEndDate(BuildContext context) async { // final DateTime? picked = await showDatePicker( // context: context, // initialDate: endDate, // firstDate: DateTime(2020), // lastDate: DateTime(2101), // ); // if (picked != null && picked != endDate) { // setState(() { // endDate = picked; // }); // fetchData(); // } // } // Future fetchData() async { // final Uri uri = Uri.parse( // 'https://isipiringku.esolusindo.com/api/Makanan/allKonsumsi?id_user=36'); // final response = await http.get(uri); // if (response.statusCode == 200) { // final jsonData = json.decode(response.body); // final responseList = jsonData['response']; // setState(() { // makananList = // responseList.map((item) => Makanan.fromJson(item)).toList(); // // Filter data makanan berdasarkan rentang waktu // makananList = makananList.where((makanan) { // final makananDate = makanan.waktu.toLocal(); // return makananDate // .isAfter(startDate.subtract(const Duration(days: 1))) && // makananDate.isBefore(endDate.add(const Duration(days: 1))); // }).toList(); // // Kelompokkan data dan hitung total kalori per tanggal // totalCaloriesByDate.clear(); // Bersihkan totalCaloriesByDate // makananList.forEach((makanan) { // String dateKey = makanan.waktu.toLocal().toString().split(' ')[0]; // if (totalCaloriesByDate.containsKey(dateKey)) { // totalCaloriesByDate[dateKey] ??= 0.0; // totalCaloriesByDate[dateKey] = // totalCaloriesByDate[dateKey]! + makanan.energi!; // } else { // totalCaloriesByDate[dateKey] = makanan.energi; // } // }); // }); // } else { // print(response.body); // } // } // @override // void initState() { // super.initState(); // fetchData(); // } // @override // Widget build(BuildContext context) { // return Scaffold( // bottomNavigationBar: const BottomNavBar(selected: 2), // body: SingleChildScrollView( // child: Stack(children: [ // Container( // height: 130, // width: double.infinity, // decoration: const BoxDecoration( // image: DecorationImage( // image: AssetImage('assets/images/head2.jpg'), // fit: BoxFit.cover)), // ), // SafeArea( // child: Padding( // padding: const EdgeInsets.symmetric(horizontal: 15.0), // child: Container( // width: MediaQuery.of(context).size.width, // child: Stack( // children: [ // Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // const Padding(padding: EdgeInsets.only(top: 64)), // const SizedBox(height: 20), // Center( // child: Container( // width: MediaQuery.of(context).size.height * 0.4, // height: 30, // decoration: BoxDecoration( // gradient: const LinearGradient( // colors: [ // Color.fromARGB(255, 250, 154, 0), // Color.fromARGB(255, 246, 80, 20), // Color.fromARGB(255, 235, 38, 16), // ], // ), // borderRadius: BorderRadius.circular(30), // boxShadow: kElevationToShadow[1], // ), // padding: const EdgeInsets.symmetric( // horizontal: 5, // vertical: 0, // ), // child: const Center( // child: Text( // 'Riwayat', // style: TextStyle( // color: Colors.white, // fontWeight: FontWeight.bold, // ), // ), // ), // ), // ), // SizedBox( // height: 20, // ), // Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Container( // child: Text( // 'Grafik Konsumsi Kalori Selama 7 Hari Terakhir', // style: TextStyle(fontWeight: FontWeight.bold), // ), // ) // ], // ), // const SizedBox( // height: 30, // ), // Container( // height: // 200, // Atur tinggi grafik sesuai kebutuhan Anda // child: SfCartesianChart( // isTransposed: true, // // Konfigurasi jenis grafik menjadi BarSeries // series: [ // BarSeries, String>( // spacing: 0, // dataSource: // _getChartData(), // Sumber data dari listview yang difilter // xValueMapper: // (Map data, _) => data[ // 'date'], // Kolom tanggal dari sumber data // yValueMapper: // (Map data, _) => data[ // 'totalCalories'], // Kolom total kalori dari sumber data // name: 'Total Kalori', // width: 0.4, // ), // ], // primaryXAxis: CategoryAxis(), // primaryYAxis: NumericAxis( // title: AxisTitle(text: 'Total Kalori'), // ), // ), // ), // const SizedBox(height: 10), // Container( // height: 5, // width: double.infinity, // child: ListView.separated( // itemCount: totalCaloriesByDate // .length, // Jumlah item adalah jumlah tanggal unik // separatorBuilder: // (BuildContext context, int index) => // const Divider(), // itemBuilder: (BuildContext context, int index) { // String dateKey = // totalCaloriesByDate.keys.elementAt(index); // double? totalCaloriesForDate = // totalCaloriesByDate[dateKey]; // return ListTile( // title: Text("Tanggal: $dateKey"), // subtitle: Text( // "Total Kalori: $totalCaloriesForDate", // ), // ); // }, // ), // ), // Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Column( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Text( // "Start Date: ${DateFormat('yyyy-MM-dd').format(startDate)}"), // ElevatedButton( // onPressed: () => _selectStartDate(context), // child: const Text("Select Start Date"), // ), // ], // ), // Column( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Text( // "End Date: ${DateFormat('yyyy-MM-dd').format(endDate)}"), // ElevatedButton( // onPressed: () => _selectEndDate(context), // child: const Text("Select End Date"), // ), // ], // ), // ], // ), // ], // ), // ], // ), // )), // ), // ]), // ), // ); // } // List> _getChartData() { // List> chartData = []; // // Iterate melalui data makanan yang sudah difilter // for (String dateKey in totalCaloriesByDate.keys) { // double? totalCalories = totalCaloriesByDate[dateKey]; // chartData.add({ // 'date': dateKey, // 'totalCalories': totalCalories, // }); // } // return chartData; // } // } // lagi import 'dart:convert'; import 'package:flutter/material.dart'; // import 'package:piring/bloc/nav/bottom_nav.dart'; // import 'package:piring/model/makanan.dart'; // import 'package:piring/model/piechartlagi.dart'; // import 'package:piring/model/user.dart'; import 'package:piring_baru/bloc/nav/bottom_nav.dart'; import 'package:piring_baru/model/makanan.dart'; import 'package:piring_baru/model/nutrisi.dart'; import 'package:piring_baru/model/piechartlagi.dart'; import 'package:piring_baru/model/user.dart'; import 'package:shared_preferences/shared_preferences.dart'; // import 'package:piring/model/nutrisi.dart'; import 'package:syncfusion_flutter_charts/charts.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; class Riwayat extends StatefulWidget { const Riwayat({super.key}); @override State createState() => _RiwayatState(); } class _RiwayatState extends State { List makananList = []; Map totalCaloriesByDate = {}; String Id = ''; String ceknutrisi = ''; String getriwayat = ''; String getriwayatall = ''; String umur = ''; String jekel = ''; DateTime startDate = DateTime.now().subtract(const Duration(days: 7)); // 7 hari terakhir DateTime endDate = DateTime.now(); Future _selectStartDate(BuildContext context) async { final DateTime? picked = await showDatePicker( context: context, initialDate: startDate, firstDate: DateTime(2020), lastDate: DateTime(2101), ); if (picked != null && picked != startDate) { setState(() { startDate = picked; }); fetchData(); } } Future loadUserData() async { final prefs = await SharedPreferences.getInstance(); final userDataString = prefs.getString('user_data'); if (userDataString != null) { final userData = UserData.fromJson(json.decode(userDataString)); setState(() { Id = userData.idUser.toString(); umur = userData.umur; jekel = userData.jekel; getriwayat = 'https://isipiringku.esolusindo.com/api/Makanan/konsumsi?id_user=$Id&waktu='; getriwayatall = 'https://isipiringku.esolusindo.com/api/Makanan/allKonsumsi?id_user=$Id'; ceknutrisi = 'https://isipiringku.esolusindo.com/api/Kalori/kalori?umur=$umur&jekel=$jekel'; print(getriwayatall); }); } } Future _selectEndDate(BuildContext context) async { final DateTime? picked = await showDatePicker( context: context, initialDate: endDate, firstDate: DateTime(2020), lastDate: DateTime(2101), ); if (picked != null && picked != endDate) { setState(() { endDate = picked; }); fetchData(); } } Future fetchData() async { final Uri uri = Uri.parse( 'https://isipiringku.esolusindo.com/api/Makanan/allKonsumsi?id_user=$Id'); final response = await http.get(uri); print('urinya' + uri.toString()); if (response.statusCode == 200) { final jsonData = json.decode(response.body); final responseList = jsonData['response']; setState(() { makananList = responseList.map((item) => Makanan.fromJson(item)).toList(); // Filter data makanan berdasarkan rentang waktu makananList = makananList.where((makanan) { final makananDate = makanan.waktu.toLocal(); return makananDate .isAfter(startDate.subtract(const Duration(days: 1))) && makananDate.isBefore(endDate.add(const Duration(days: 1))); }).toList(); // Kelompokkan data dan hitung total kalori per tanggal totalCaloriesByDate.clear(); // Bersihkan totalCaloriesByDate makananList.forEach((makanan) { String dateKey = makanan.waktu.toLocal().toString().split(' ')[0]; if (totalCaloriesByDate.containsKey(dateKey)) { totalCaloriesByDate[dateKey] ??= 0.0; totalCaloriesByDate[dateKey] = totalCaloriesByDate[dateKey]! + makanan.energi!; } else { totalCaloriesByDate[dateKey] = makanan.energi; } }); }); } else { print(response.body); } } @override void initState() { super.initState(); loadUserData(); fetchData(); } @override Widget build(BuildContext context) { return Scaffold( bottomNavigationBar: const BottomNavBar(selected: 3), body: SingleChildScrollView( child: Stack(children: [ Container( height: 130, width: double.infinity, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/head2.jpg'), fit: BoxFit.cover)), ), SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0), child: Container( width: MediaQuery.of(context).size.width, child: Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding(padding: EdgeInsets.only(top: 64)), const SizedBox(height: 20), Center( child: Container( width: MediaQuery.of(context).size.height * 0.4, height: 30, decoration: BoxDecoration( gradient: const LinearGradient( colors: [ Color.fromARGB(255, 250, 154, 0), Color.fromARGB(255, 246, 80, 20), Color.fromARGB(255, 235, 38, 16), ], ), borderRadius: BorderRadius.circular(30), boxShadow: kElevationToShadow[1], ), padding: const EdgeInsets.symmetric( horizontal: 5, vertical: 0, ), child: const Center( child: Text( 'Riwayat', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, ), ), ), ), ), SizedBox( height: 20, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( child: Text( 'Grafik Konsumsi Kalori Selama 7 Hari Terakhir', style: TextStyle(fontWeight: FontWeight.bold), ), ) ], ), const SizedBox( height: 30, ), Container( height: 200, // Atur tinggi grafik sesuai kebutuhan Anda child: SfCartesianChart( isTransposed: true, // Konfigurasi jenis grafik menjadi BarSeries // series: [ series: [ BarSeries, String>( spacing: 0, dataSource: _getChartData(), // Sumber data dari listview yang difilter xValueMapper: (Map data, _) => data['date'], // Kolom tanggal dari sumber data yValueMapper: (Map data, _) => data[ 'totalCalories'], // Kolom total kalori dari sumber data name: 'Total Kalori', width: 0.4, ), ], primaryXAxis: CategoryAxis( labelStyle: TextStyle( fontSize: 5, // Adjust the font size as needed ), ), primaryYAxis: NumericAxis( title: AxisTitle(text: 'Total Kalori'), ), ), ), const SizedBox(height: 10), Padding( padding: EdgeInsets.all(10), child: Text('Detail Riwayat', style: TextStyle(fontWeight: FontWeight.bold)), ), const SizedBox(height: 10), Container( height: 300, width: double.infinity, child: ListView.separated( itemCount: totalCaloriesByDate .length, // Jumlah item adalah jumlah tanggal unik separatorBuilder: (BuildContext context, int index) => const Divider(), itemBuilder: (BuildContext context, int index) { String dateKey = totalCaloriesByDate.keys.elementAt(index); int totalCaloriesInt = totalCaloriesByDate[dateKey]?.toInt() ?? 0; // Tentukan ikon mata tergantung pada nilai totalKaloriInt Icon mataIcon = totalCaloriesInt > 0 ? Icon(Icons.info) : Icon(Icons.info); return ListTile( title: Text("Tanggal: $dateKey"), subtitle: Text("Total Kalori: $totalCaloriesInt"), trailing: GestureDetector( onTap: () { showMealDialog(context, dateKey); // Kirim dateKey ke metode showMealDialog }, child: mataIcon, // Ini akan memindahkan ikon mata ke sebelah kanan ListTile ), ); }, ), ), SizedBox( height: 20, ), // Container( // height: 200, // child: ListView.builder( // itemCount: makananList.length, // itemBuilder: (context, index) { // Makanan makanan = makananList[index]; // return Card( // // Konfigurasi tampilan kartu // child: ListTile( // title: Column( // children: [ // Text(makanan.waktu.toString().trimRight()), // Text( // "Nama Makanan: ${makanan.namaMakanan}"), // ], // ), // subtitle: Text("Kalori: ${makanan.energi}"), // // Tambahkan informasi makanan lainnya sesuai kebutuhan // ), // ); // }, // ), // ), // Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Column( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Text( // "${DateFormat('dd-MM-yyyy').format(startDate)}"), // ElevatedButton( // onPressed: () => _selectStartDate(context), // child: const Text("Pilih Tanggal Awal"), // ), // ], // ), // Column( // mainAxisAlignment: // MainAxisAlignment.spaceEvenly, // children: [ // Text( // "${DateFormat('dd-MM-yyyy').format(endDate)}"), // ElevatedButton( // onPressed: () => _selectEndDate(context), // child: const Text("Pilih Tanggal Akhir"), // ), // ], // ), // ], // ), ], ), ], ), )), ), ]), ), ); } List> _getChartData() { List> chartData = []; // Iterate melalui data makanan yang sudah difilter for (String dateKey in totalCaloriesByDate.keys) { double? totalCalories = totalCaloriesByDate[dateKey]; chartData.add({ 'date': dateKey, 'totalCalories': totalCalories, }); } // Tambahan: Gabungkan data dengan makanan yang sesuai dengan tanggal yang dipilih for (Makanan makanan in makananList) { String makananDate = makanan.waktu.toLocal().toString().split(' ')[0]; if (totalCaloriesByDate.containsKey(makananDate)) { chartData.add({ 'date': makananDate, 'totalCalories': totalCaloriesByDate[makananDate]! + makanan.energi!, }); } } return chartData; } void showMealDialog(BuildContext context, String dateKey) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Pilih Waktu Makan untuk Tanggal: $dateKey'), content: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( onPressed: () { showGreetingDialog(context, 'Sarapan', dateKey); }, child: Text('Pagi'), ), ElevatedButton( onPressed: () { showGreetingDialog(context, 'Makan Siang', dateKey); }, child: Text('Siang'), ), ElevatedButton( onPressed: () { showGreetingDialog(context, 'Makan Malam', dateKey); }, child: Text('Malam'), ), ], ), ); }, ); } void showGreetingDialog( BuildContext context, String mealTime, String datekey) async { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( content: Container( width: double.maxFinite, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), Text("Mengambil data..."), ], ), ), ), ); }, ); final apiriwayat = '$getriwayat$datekey&keterangan=$mealTime'; final response = await http.get(Uri.parse(apiriwayat)); Navigator.pop(context); if (response.statusCode == 200) { print('apiriwayat = ' + apiriwayat); final jsonData = json.decode(response.body); final List responseList = jsonData['response']; if (responseList.isEmpty) { // Tampilkan pesan "Data kosong nih" dan gambar dari 'assets/images/pas.gif' showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Data Kosong'), content: Column( mainAxisSize: MainAxisSize.min, children: [ Image.asset('assets/images/pas.gif'), SizedBox( height: 3, ), Text( 'Data kosong nih', style: TextStyle(fontWeight: FontWeight.bold), ), ], ), actions: [ TextButton( child: Text("Tutup"), onPressed: () { Navigator.of(context).pop(); // Tutup dialog }, ), ], ); }, ); } else { String makanan = ''; String energi = ''; int totalEnergi = 0; int totalKarbohidrat = 0; int totalProtein = 0; int totalLemak = 0; int totalBesi = 0; int totalVitamina = 0; int totalVitaminc = 0; for (var item in responseList) { makanan += 'Makanan: ${item['nama_makanan']}\n'; energi += 'Energi: ${item['kalori']}\n'; NutritionData nutritionData = NutritionData.fromJson(item); totalEnergi += nutritionData.energi.toInt(); totalKarbohidrat += nutritionData.karbohidrat.toInt(); totalProtein += nutritionData.protein.toInt(); totalLemak += nutritionData.lemak.toInt(); totalBesi += nutritionData.besi.toInt(); totalVitamina += nutritionData.vitamina.toInt(); totalVitaminc += nutritionData.vitaminc.toInt(); } final kaloriResponse = await http.get( Uri.parse(ceknutrisi), ); if (kaloriResponse.statusCode == 200) { final kaloriJson = json.decode(kaloriResponse.body); final int totalKalori = int.parse(kaloriJson['data']['total']); int kebutuhanKalori = totalKalori ~/ 3; print(kebutuhanKalori); String message = ''; String gambar = ''; if (totalEnergi < kebutuhanKalori) { message = "Yahh Nutrisi kamu kurang nih!"; gambar = 'assets/images/sakit.gif'; } else if (totalEnergi > kebutuhanKalori) { message = "Yahh, kamu terlalu banyak nih!"; gambar = 'assets/images/pas.gif'; } else { message = "Nutrisi kamu cukup"; gambar = 'assets/imagges/gemuk.gif'; } showDialog( context: context, builder: (BuildContext context) { return Column( children: [ AlertDialog( backgroundColor: const Color.fromARGB(255, 199, 218, 228), content: Container( height: 300, width: double.infinity, child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( height: 200, width: 250, child: SfCircularChart( series: [ PieSeries( dataSource: [ Nutritiondetail('Karbohidrat', totalKarbohidrat.toDouble()), Nutritiondetail( 'Protein', totalProtein.toDouble()), Nutritiondetail( 'Lemak', totalLemak.toDouble()), Nutritiondetail( 'Besi', totalBesi.toDouble()), Nutritiondetail('Vitamin a', totalVitamina.toDouble()), Nutritiondetail('Vitamin c', totalVitaminc.toDouble()), ], xValueMapper: (Nutritiondetail data, _) => data.nutrient, yValueMapper: (Nutritiondetail data, _) => data.value, ), ], tooltipBehavior: TooltipBehavior(enable: true), ), ), Center( child: Text( 'Total Kalori: $totalEnergi', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold), ), ), SizedBox( height: 10, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Total Karbohidrat: $totalKarbohidrat', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), Text('Total Protein: $totalProtein', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Total Lemak: $totalLemak', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), Text('Total Besi: $totalBesi', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Total Vitamina: $totalVitamina', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), Text('Total Vitaminc: $totalVitaminc', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), ], ), SizedBox( height: 10, ), Center( child: Text('kebutuhan Kalori = $kebutuhanKalori', style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)), ), Center( child: Text( message, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 10), ), ) ], ), ), ), ), AlertDialog( backgroundColor: const Color.fromARGB(255, 199, 218, 228), title: Text("Riwayat $datekey"), content: Container( height: 200, width: 200, child: SingleChildScrollView( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( makanan, style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold), ), Text(energi, style: TextStyle( fontSize: 10, fontWeight: FontWeight.bold)) ], )), ), actions: [ TextButton( child: Text("Tutup"), onPressed: () { Navigator.of(context).pop(); // Tutup dialog }, ), ], ), ], ); }, ); } } } else { showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Kesalahan'), content: Text('Gagal mengambil data. Silakan coba lagi.'), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); }, child: Text('Tutup'), ), ], ); }, ); } } }