import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; import 'bottom_navigation.dart'; class AturJadwal1Screen extends StatefulWidget { const AturJadwal1Screen({super.key}); @override State createState() => _AturJadwal1ScreenState(); } class _AturJadwal1ScreenState extends State { final _namaObatController = TextEditingController(); final _jumlahObatController = TextEditingController(); bool isJamManual = true; int dosisCount = 1; List manualTimes = []; List 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 _checkExistingObatJumlah() async { try { final obatSnap = await dbRef.child("jadwal/kotak1/obat1").get(); final jumlahSnap = await dbRef.child("jadwal/kotak1/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/kotak1"); try { final snapshot = await kotakRef.get(); int index = 0; final existingTimes = []; for (final child in snapshot.children) { if (child.key != 'jumlahObat' && child.key != 'obat1' && 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('obat1').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 pilihJamManual() async { if (manualTimes.length >= 4) return; TimeOfDay? picked = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (picked != null) { setState(() { manualTimes.add(picked); }); } } Future 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: ), ); } }