E32221349_Medibox/lib/atur_jadwal2_screen.dart

486 lines
16 KiB
Dart

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'bottom_navigation.dart';
class AturJadwal2Screen extends StatefulWidget {
const AturJadwal2Screen({super.key});
@override
State<AturJadwal2Screen> createState() => _AturJadwal2ScreenState();
}
class _AturJadwal2ScreenState extends State<AturJadwal2Screen> {
final _namaObatController = TextEditingController();
final _jumlahObatController = TextEditingController();
bool isJamManual = true;
int dosisCount = 1;
List<TimeOfDay> manualTimes = [];
List<TimeOfDay> dosisTimes = [
TimeOfDay(hour: 6, minute: 0),
TimeOfDay(hour: 14, minute: 0),
TimeOfDay(hour: 22, minute: 0),
TimeOfDay(hour: 0, minute: 0),
];
final dbRef = FirebaseDatabase.instance.ref();
bool _isFirstEntry =
true; // Untuk cek apakah jadwal pertama sudah ada obat dan jumlah
@override
void initState() {
super.initState();
_checkExistingObatJumlah();
}
Future<void> _checkExistingObatJumlah() async {
try {
final obatSnap = await dbRef.child("jadwal/kotak2/obat2").get();
final jumlahSnap = await dbRef.child("jadwal/kotak2/jumlahObat").get();
if (obatSnap.exists &&
obatSnap.value != null &&
obatSnap.value.toString().trim().isNotEmpty &&
jumlahSnap.exists &&
jumlahSnap.value != null &&
jumlahSnap.value.toString().trim().isNotEmpty) {
// Jika data ada, artinya jadwal pertama sudah ada obat dan jumlah obat
setState(() {
_isFirstEntry = false;
// Set controller agar user tetap melihat data yang sudah ada (optional)
_namaObatController.text = obatSnap.value.toString();
_jumlahObatController.text = jumlahSnap.value.toString();
});
}
} catch (e) {
print('Error checking existing obat/jumlah: $e');
}
}
void simpanData() async {
final user = FirebaseAuth.instance.currentUser;
if (user == null) return;
final namaObat = _namaObatController.text.trim();
final jumlahObatText = _jumlahObatController.text.trim();
if (_isFirstEntry) {
if (namaObat.isEmpty || jumlahObatText.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
"Lengkapi data nama obat dan jumlah obat terlebih dahulu",
),
),
);
return;
}
if (int.tryParse(jumlahObatText) == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Jumlah obat harus berupa angka")),
);
return;
}
}
final int inputJumlahObat = int.tryParse(jumlahObatText) ?? 0;
final times =
isJamManual ? manualTimes : dosisTimes.take(dosisCount).toList();
final DatabaseReference kotakRef = dbRef.child("jadwal/kotak2");
try {
final snapshot = await kotakRef.get();
int index = 0;
final existingTimes = <String>[];
for (final child in snapshot.children) {
if (child.key != 'jumlahObat' &&
child.key != 'obat2' &&
child.key != 'userId') {
index++;
final jam = child.child('jam').value;
final menit = child.child('menit').value;
if (jam != null && menit != null) {
existingTimes.add('$jam:$menit');
}
}
}
if (index + times.length > 4) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Maksimal 4 jadwal diperbolehkan')),
);
return;
}
int existingJumlahObat = 0;
final jumlahSnap = snapshot.child('jumlahObat');
if (jumlahSnap.exists && jumlahSnap.value != null) {
existingJumlahObat =
(jumlahSnap.value is int)
? jumlahSnap.value as int
: int.tryParse(jumlahSnap.value.toString()) ?? 0;
}
int totalJumlahObat =
_isFirstEntry ? inputJumlahObat : existingJumlahObat;
if (_isFirstEntry && totalJumlahObat > 15) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Jumlah obat maksimal 15')),
);
return;
}
for (final time in times) {
final newTime = "${time.hour}:${time.minute}";
if (existingTimes.contains(newTime)) {
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Jadwal ini sudah ada')));
return;
}
}
// Simpan data utama (hanya sekali)
if (_isFirstEntry) {
await kotakRef.child('obat2').set(namaObat);
await kotakRef.child('jumlahObat').set(inputJumlahObat);
await kotakRef.child('userId').set(user.uid); // dipindah ke sini
}
// Simpan jadwal jam dan menit saja
for (final time in times) {
await kotakRef.child('$index').set({
'jam': time.hour,
'menit': time.minute,
});
index++;
}
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Jadwal berhasil disimpan')));
Navigator.pop(context);
} catch (e) {
print('Gagal menyimpan data: $e');
ScaffoldMessenger.of(
context,
).showSnackBar(const SnackBar(content: Text('Gagal menyimpan jadwal')));
}
}
Future<void> pilihJamManual() async {
if (manualTimes.length >= 4) return;
TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (picked != null) {
setState(() {
manualTimes.add(picked);
});
}
}
Future<void> ubahJamDosis(int index) async {
TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: dosisTimes[index],
);
if (picked != null) {
setState(() {
dosisTimes[index] = picked;
});
}
}
Widget buildInputField(
String label,
TextEditingController controller, {
bool isNumber = false,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label),
SizedBox(height: 6),
TextField(
controller: controller,
keyboardType: isNumber ? TextInputType.number : TextInputType.text,
decoration: InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
),
),
SizedBox(height: 12),
],
);
}
Widget buildManualTimePicker() {
return Column(
children: [
for (int i = 0; i < manualTimes.length; i++)
ListTile(
title: Text(manualTimes[i].format(context)),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => setState(() => manualTimes.removeAt(i)),
),
),
if (manualTimes.length < 4)
ElevatedButton(onPressed: pilihJamManual, child: Text('Tambah Jam')),
],
);
}
Widget buildDosisTimePicker() {
return Column(
children: [
Wrap(
spacing: 10,
children:
[1, 2, 3, 4].map((e) {
return ChoiceChip(
label: Text('Obat ${e}x1'),
selected: dosisCount == e,
onSelected: (_) => setState(() => dosisCount = e),
);
}).toList(),
),
for (int i = 0; i < dosisCount; i++)
ListTile(
title: Text(dosisTimes[i].format(context)),
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () => ubahJamDosis(i),
),
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF3FA535),
body: Column(
children: [
SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
child: Row(
children: [
IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.pop(context),
),
SizedBox(width: 8),
Text(
"Atur Jadwal Obat",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
Expanded(
child: Container(
width: double.infinity,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (_isFirstEntry) ...[
buildInputField("Masukan Nama Obat", _namaObatController),
buildInputField(
"Masukan Jumlah Obat (Maksimal 15 Obat)",
_jumlahObatController,
isNumber: true,
),
] else ...[
Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Text(
"Nama obat dan jumlah obat sudah ada. Tidak perlu mengisi ulang.",
style: TextStyle(
color: const Color.fromARGB(255, 245, 5, 13),
fontWeight: FontWeight.bold,
),
),
),
buildInputField(
"Nama Obat",
_namaObatController..text = _namaObatController.text,
isNumber: false,
),
buildInputField(
"Jumlah Obat",
_jumlahObatController
..text = _jumlahObatController.text,
isNumber: true,
),
],
SizedBox(height: 10),
Text(
"Pilih Aturan Jam:",
style: TextStyle(fontWeight: FontWeight.bold),
),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () => setState(() => isJamManual = true),
style: ElevatedButton.styleFrom(
backgroundColor:
isJamManual ? Colors.green : Colors.white,
foregroundColor:
isJamManual ? Colors.white : Colors.green,
side: BorderSide(color: Colors.green),
),
child: Text("Jam Manual"),
),
),
SizedBox(width: 8),
Expanded(
child: ElevatedButton(
onPressed:
() => setState(() => isJamManual = false),
style: ElevatedButton.styleFrom(
backgroundColor:
!isJamManual ? Colors.green : Colors.white,
foregroundColor:
!isJamManual ? Colors.white : Colors.green,
side: BorderSide(color: Colors.green),
),
child: Text("Jam Dosis"),
),
),
],
),
SizedBox(height: 16),
isJamManual
? buildManualTimePicker()
: buildDosisTimePicker(),
SizedBox(height: 20),
Center(
child: ElevatedButton(
onPressed: simpanData,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
child: const Text(
"Simpan",
style: TextStyle(
color: Color.fromARGB(255, 255, 255, 255),
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
),
),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: 0, // sesuaikan dengan index aktif halaman sekarang
type: BottomNavigationBarType.fixed,
selectedItemColor: const Color(0xFF3FA535),
unselectedItemColor: Colors.grey.shade600,
showUnselectedLabels: true,
selectedLabelStyle: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
),
unselectedLabelStyle: const TextStyle(
fontWeight: FontWeight.normal,
fontSize: 12,
),
elevation: 8,
backgroundColor: Colors.white,
iconSize: 28,
onTap: (index) {
switch (index) {
case 0:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => MainNavigation(currentIndex: 0),
),
);
break;
case 1:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => MainNavigation(currentIndex: 1),
),
);
break;
case 2:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => MainNavigation(currentIndex: 2),
),
);
break;
case 3:
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => MainNavigation(currentIndex: 3),
),
);
break;
}
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.history_outlined),
activeIcon: Icon(Icons.history),
label: 'History',
),
BottomNavigationBarItem(
icon: Icon(Icons.notifications_outlined),
activeIcon: Icon(Icons.notifications),
label: 'Notification',
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
label: 'Account',
),
],
),
//bottomNavigationBar: MainNavigation(currentIndex: ),
);
}
}