590 lines
24 KiB
Dart
590 lines
24 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
|
import 'package:http/http.dart' as http;
|
|
// import 'package:piring/bloc/nav/bottom_nav.dart';
|
|
// import 'package:piring/kalori/kalorirvisi.dart';
|
|
// import 'package:piring/model/user.dart';
|
|
import 'package:piring_baru/bloc/nav/bottom_nav.dart';
|
|
import 'package:piring_baru/kalori/kalorirvisi.dart';
|
|
import 'package:piring_baru/model/user.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
class TesAlert extends StatefulWidget {
|
|
@override
|
|
_TesAlertState createState() => _TesAlertState();
|
|
}
|
|
|
|
class _TesAlertState extends State<TesAlert> {
|
|
List<Map<String, dynamic>> data = [];
|
|
TextEditingController filterController = TextEditingController();
|
|
final TextEditingController searchController = TextEditingController();
|
|
String ApiMakanan = '';
|
|
String Iduser = '';
|
|
String selectedMakanan = "";
|
|
List<Map<String, String>> makananList = [];
|
|
double totalKaloriSemua = 0.0;
|
|
String selectedKalori = "";
|
|
String selectedId = "";
|
|
String totalKalori = "";
|
|
List<String> IDMakananarray = [];
|
|
List<String> Kuantitasarray = [];
|
|
|
|
List<Map<String, dynamic>> makananData = [];
|
|
|
|
final TextEditingController makananController = TextEditingController();
|
|
final TextEditingController jenisController = TextEditingController();
|
|
final TextEditingController kuantitasController = TextEditingController();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
loadUserData();
|
|
}
|
|
|
|
Future<void> postDataToAPI() async {
|
|
final String apiUrl =
|
|
"https://isipiringku.esolusindo.com/api/Konsumsi/Konsumsi";
|
|
|
|
// Membuat objek body yang berisi parameter yang akan dikirimkan ke API
|
|
final Map<String, dynamic> data = {
|
|
"id_user": Iduser,
|
|
"total_kalori": totalKaloriSemua,
|
|
"keterangan": 'Sarapan',
|
|
"bahan_makanan_nama_makanan": IDMakananarray,
|
|
"kuantitas": Kuantitasarray,
|
|
};
|
|
|
|
// Mengirim permintaan POST ke API
|
|
final response = await http.post(
|
|
Uri.parse(apiUrl),
|
|
body: jsonEncode(data),
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
);
|
|
|
|
if (response.statusCode == 200) {
|
|
print("Data berhasil dikirim ke API");
|
|
print("Respon API: ${response.body}");
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => RevKalori(),
|
|
));
|
|
Fluttertoast.showToast(
|
|
msg: "Berhasil Tambahkan Data",
|
|
backgroundColor: Colors.green,
|
|
toastLength: Toast.LENGTH_SHORT);
|
|
} else {
|
|
throw Exception("Gagal mengirim data ke API");
|
|
}
|
|
}
|
|
|
|
Future<void> loadUserData() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userDataString = prefs.getString('user_data');
|
|
|
|
if (userDataString != null) {
|
|
final userData = UserData.fromJson(json.decode(userDataString));
|
|
|
|
setState(() {
|
|
Iduser = userData.idUser.toString();
|
|
ApiMakanan = 'https://isipiringku.esolusindo.com/api/Makanan/makanan';
|
|
});
|
|
}
|
|
}
|
|
|
|
void _showPenjelasanWarna() {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) {
|
|
return AlertDialog(
|
|
backgroundColor: Color.fromARGB(255, 167, 177, 167),
|
|
title: Text('Penjelasan Warna'),
|
|
content: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Image.asset('assets/images/artiwarna.gif'),
|
|
SizedBox(height: 16),
|
|
Text(
|
|
'Warna pada bulatan kiri setiap item menunjukkan kategori makanan:',
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 10),
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'Merah: Makanan Pokok',
|
|
style: TextStyle(
|
|
color: Colors.red,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Biru: Lauk-Pauk',
|
|
style: TextStyle(
|
|
color: Colors.blue,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
],
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'Kuning: Sayuran',
|
|
style: TextStyle(
|
|
color: Colors.yellow,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Hijau: Buah-Buahan',
|
|
style: TextStyle(
|
|
color: Colors.green,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
],
|
|
),
|
|
Center(
|
|
child: Text(
|
|
'Ungu: Jajanan',
|
|
style: TextStyle(
|
|
color: Colors.purple,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> fetchDataFromAPI() async {
|
|
final response = await http.get(
|
|
Uri.parse('https://isipiringku.esolusindo.com/api/Makanan/makanan'));
|
|
|
|
if (response.statusCode == 200) {
|
|
final responseData = jsonDecode(response.body)['response'];
|
|
|
|
if (responseData is List) {
|
|
setState(() {
|
|
data = List<Map<String, dynamic>>.from(responseData);
|
|
});
|
|
|
|
_showDataDialog();
|
|
} else {
|
|
// Menangani jika respons API tidak sesuai tipe yang diharapkan
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: Text('Error'),
|
|
content:
|
|
Text('Respons API tidak sesuai tipe data yang diharapkan.'),
|
|
),
|
|
);
|
|
}
|
|
} else {
|
|
// Jika HTTP request gagal
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
title: Text('Error'),
|
|
content: Text('Gagal mengambil data dari API.'),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
void _showDataDialog() {
|
|
String filterText = "";
|
|
AlertDialog alertDialog = AlertDialog(
|
|
title: Text('Data Makanan'),
|
|
content: Column(
|
|
children: <Widget>[
|
|
// Tambahkan TextFormField untuk filter berdasarkan nama_makanan
|
|
TextFormField(
|
|
controller: searchController,
|
|
decoration: InputDecoration(
|
|
labelText: 'Filter Nama Makanan',
|
|
),
|
|
onChanged: (value) {
|
|
setState(() {
|
|
filterText = value;
|
|
});
|
|
},
|
|
),
|
|
Divider(),
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: data
|
|
.where((item) => item['nama_makanan']
|
|
.toLowerCase()
|
|
.contains(filterText.toLowerCase()))
|
|
.map<Widget>((item) {
|
|
Color bulletColor = Colors.red; // Warna default
|
|
if (item['nama_kategori'] == 'Lauk-Pauk') {
|
|
bulletColor = Colors.blue;
|
|
} else if (item['nama_kategori'] == 'Sayuran') {
|
|
bulletColor = Colors.yellow;
|
|
} else if (item['nama_kategori'] == 'Buah-Buahan') {
|
|
bulletColor = Colors.green;
|
|
} else if (item['nama_kategori'] == 'Jajanan') {
|
|
bulletColor = Colors.purple;
|
|
}
|
|
|
|
return ListTile(
|
|
title: RichText(
|
|
text: TextSpan(
|
|
children: [
|
|
WidgetSpan(
|
|
child: Container(
|
|
margin: EdgeInsets.only(right: 8),
|
|
width: 8,
|
|
height: 8,
|
|
decoration: BoxDecoration(
|
|
color: bulletColor,
|
|
shape: BoxShape.circle,
|
|
),
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: item['nama_makanan'],
|
|
style: TextStyle(
|
|
color: Colors
|
|
.black, // Ganti warna teks sesuai kebutuhan
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
subtitle: Text('Energi: ${item['energi']}'),
|
|
trailing: IconButton(
|
|
icon: Icon(Icons.info),
|
|
onPressed: () {
|
|
_showMakananDetail(item);
|
|
},
|
|
),
|
|
onTap: () {
|
|
setState(() {
|
|
selectedMakanan = item['nama_makanan'] ?? '';
|
|
makananController.text = selectedMakanan;
|
|
jenisController.text = item['nama_kategori'] ?? '';
|
|
selectedKalori = item['energi'] ?? '';
|
|
selectedId = item['id_makanan'] ?? '';
|
|
});
|
|
Navigator.pop(context);
|
|
},
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
filterController.text = '';
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: Text('Tutup'),
|
|
),
|
|
],
|
|
);
|
|
|
|
showDialog(context: context, builder: (context) => alertDialog);
|
|
}
|
|
|
|
Future<void> _showMakananDetail(Map<String, dynamic> makanan) async {
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) {
|
|
return AlertDialog(
|
|
title: Text('Detail Makanan'),
|
|
content: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Besaran: ${makanan['besaran']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'URT: ${makanan['urt']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Energi: ${makanan['energi']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Karbohidrat: ${makanan['karbohidrat']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Protein: ${makanan['protein']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Lemak: ${makanan['lemak']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Besi: ${makanan['besi']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Vitamin A: ${makanan['vitamina']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Vitamin C: ${makanan['vitaminc']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
Text(
|
|
'Kategori: ${makanan['nama_kategori']}',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
bottomNavigationBar: BottomNavBar(selected: 1),
|
|
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(
|
|
'Kalori Harian',
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Column(
|
|
children: <Widget>[
|
|
TextFormField(
|
|
controller: makananController,
|
|
readOnly:
|
|
true, // Membuat TextFormField menjadi read-only
|
|
decoration: InputDecoration(
|
|
labelText: 'Makanan',
|
|
suffixIcon: IconButton(
|
|
icon: Icon(Icons.search),
|
|
onPressed: () {
|
|
fetchDataFromAPI();
|
|
},
|
|
),
|
|
),
|
|
),
|
|
TextFormField(
|
|
controller: jenisController,
|
|
decoration: InputDecoration(
|
|
labelText: 'Jenis',
|
|
),
|
|
),
|
|
TextFormField(
|
|
controller: kuantitasController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: InputDecoration(
|
|
labelText: 'Kuantitas',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
if (selectedMakanan.isNotEmpty &&
|
|
selectedKalori.isNotEmpty) {
|
|
try {
|
|
int kuantitas = int.tryParse(
|
|
kuantitasController.text) ??
|
|
0;
|
|
double energi =
|
|
double.tryParse(selectedKalori) ??
|
|
0.0;
|
|
double result = kuantitas * energi;
|
|
|
|
// Buat Map untuk data makanan
|
|
Map<String, String> makananData = {
|
|
'nama': selectedMakanan,
|
|
'jenis': jenisController.text,
|
|
'kuantitas': kuantitas.toString(),
|
|
'totalKalori': result.toString(),
|
|
'id': selectedId,
|
|
};
|
|
|
|
setState(() {
|
|
makananList.add(
|
|
makananData); // Tambahkan data makanan ke dalam List
|
|
totalKalori = result
|
|
.toString(); // Perbarui total kalori
|
|
});
|
|
|
|
// Bersihkan TextFormField
|
|
makananController.clear();
|
|
jenisController.clear();
|
|
kuantitasController.clear();
|
|
} catch (e) {
|
|
print("Error: $e");
|
|
}
|
|
}
|
|
},
|
|
child: Text("Tambah"),
|
|
),
|
|
Container(
|
|
height: 300,
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: makananList.length,
|
|
itemBuilder: (context, index) {
|
|
Map<String, String> makananData =
|
|
makananList[index];
|
|
|
|
return Dismissible(
|
|
key: Key(makananData[
|
|
'id']!), // Gunakan key yang unik untuk setiap item
|
|
onDismissed: (direction) {
|
|
setState(() {
|
|
makananList.removeAt(
|
|
index); // Hapus item dari list saat di-dismiss
|
|
});
|
|
},
|
|
background: Container(
|
|
color: Colors
|
|
.red, // Warna latar belakang saat menggeser untuk menghapus
|
|
alignment: Alignment.centerRight,
|
|
padding: EdgeInsets.only(right: 20.0),
|
|
child: Icon(
|
|
Icons.delete,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
child: ListTile(
|
|
title: Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
"${makananData['id']}",
|
|
style: TextStyle(fontSize: 0),
|
|
),
|
|
Text(
|
|
"${makananData['kuantitas']}",
|
|
style: TextStyle(fontSize: 0),
|
|
),
|
|
Text("${makananData['nama']}"),
|
|
],
|
|
),
|
|
subtitle: Text(
|
|
"${makananData['jenis']} || ${makananData['totalKalori']}",
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
Container(
|
|
alignment: Alignment.bottomRight,
|
|
child: ElevatedButton(
|
|
onPressed: makananList.isNotEmpty
|
|
? () {
|
|
// Lakukan semua operasi saat tombol Submit ditekan
|
|
for (Map<String, String> makananData
|
|
in makananList) {
|
|
double totalKaloriItem =
|
|
double.tryParse(makananData[
|
|
'totalKalori']!) ??
|
|
0.0;
|
|
totalKaloriSemua +=
|
|
totalKaloriItem;
|
|
}
|
|
for (var item in makananList) {
|
|
IDMakananarray.add(item['id']!);
|
|
Kuantitasarray.add(
|
|
item['kuantitas']!);
|
|
}
|
|
print('IDMakanan: $IDMakananarray');
|
|
print('Kuantitas: $Kuantitasarray');
|
|
|
|
// Lakukan sesuatu dengan totalKaloriSemua, misalnya tampilkan dalam pesan atau simpan di variabel lain
|
|
print(
|
|
'Total Kalori Semua: $totalKaloriSemua');
|
|
postDataToAPI();
|
|
}
|
|
: null,
|
|
child: Text("Submit"),
|
|
)),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => TesAlert()));
|
|
},
|
|
child: Text('tes'))
|
|
])
|
|
]))))
|
|
])));
|
|
}
|
|
}
|