Skip to content

Latest commit

 

History

History
945 lines (901 loc) · 31.2 KB

002.7.APP_APOTEK_FLUTTERFIRE.md

File metadata and controls

945 lines (901 loc) · 31.2 KB

UPDATE BAGIAN VIEW JADI CLEAN DAN BERWARNA 🌈

serta juga menguser friendlykan UI nya dari yang ngantuk banget jadi wow GG ❤️‍🔥.

1.1. NGODING TIPIS-TIPIS DI ⛑️ /lib/main.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'screens/home_screen.dart';
import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Poliklinik App',
      theme: ThemeData(
        primaryColor: Color(0xFF5D9CEC),
        scaffoldBackgroundColor: Colors.white,
        textTheme: TextTheme(
          titleLarge: TextStyle(color: Color(0xFF5D9CEC), fontSize: 22),
          bodyMedium: TextStyle(color: Colors.black87, fontSize: 16),
        ),
        elevatedButtonTheme: ElevatedButtonThemeData(
          style: ElevatedButton.styleFrom(
            foregroundColor: Colors.white,
            backgroundColor: Color(0xFF48C78E), // Text color
            textStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            padding: EdgeInsets.symmetric(vertical: 12, horizontal: 24),
          ),
        ),
      ),
      home: const HomeScreen(),
    );
  }
}

1.2. NGODING TIPIS-TIPIS DI 🏡 /lib/screens/home_screen.dart

import 'package:flutter/material.dart';
import 'registration_screen.dart';
import 'medical_check_screen.dart';
import 'patient_report_screen.dart';
import 'medical_report_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('POLIKLINIK APP 🏥'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _buildFeatureCard(
              context,
              title: 'Pendaftaran Pasien',
              icon: Icons.person_add_alt_1,
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => RegistrationScreen()),
                );
              },
            ),
            const SizedBox(height: 20),
            _buildFeatureCard(
              context,
              title: 'Pemeriksaan Pasien',
              icon: Icons.local_hospital,
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MedicalCheckScreen()),
                );
              },
            ),
            const SizedBox(height: 20),
            _buildFeatureCard(
              context,
              title: 'Laporan Data Pasien',
              icon: Icons.description,
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => PatientReportScreen()),
                );
              },
            ),
            const SizedBox(height: 20),
            _buildFeatureCard(
              context,
              title: 'Laporan Hasil Pemeriksaan',
              icon: Icons.medical_services,
              onTap: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (context) => MedicalReportScreen()),
                );
              },
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFeatureCard(BuildContext context,
      {required String title,
      required IconData icon,
      required VoidCallback onTap}) {
    return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      elevation: 4,
      child: InkWell(
        borderRadius: BorderRadius.circular(12),
        onTap: onTap,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            children: [
              Icon(icon, size: 40, color: Theme.of(context).primaryColor),
              const SizedBox(width: 16),
              Text(
                title,
                style: Theme.of(context).textTheme.titleLarge,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

1.3. NGODING TIPIS-TIPIS DI ®️ /lib/screens/registration_screen.dart.dart

import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';
import '../services/firebase_service.dart';

class RegistrationScreen extends StatefulWidget {
  @override
  _RegistrationScreenState createState() => _RegistrationScreenState();
}

class _RegistrationScreenState extends State<RegistrationScreen> {
  final _formKey = GlobalKey<FormState>();
  final _firebaseService = FirebaseService();

  // Field Data Pasien
  String nama = '';
  String alamat = '';
  String noHp = '';
  String tempatLahir = '';
  DateTime tglLahir = DateTime.now();
  String pekerjaan = '';
  String keluhan = '';

  void _submitForm() async {
    if (_formKey.currentState!.validate()) {
      String id = Uuid().v4(); // Generate unique ID

      Map<String, dynamic> patientData = {
        'id': id,
        'nama': nama,
        'alamat': alamat,
        'noHp': noHp,
        'tempatLahir': tempatLahir,
        'tglLahir': tglLahir.toIso8601String(),
        'pekerjaan': pekerjaan,
        'keluhan': keluhan,
      };

      try {
        await _firebaseService.addPatient(patientData);
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Pasien berhasil didaftarkan!'),
            backgroundColor: Theme.of(context).primaryColor,
          ),
        );
        _formKey.currentState!.reset(); // Reset form
      } catch (e) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Gagal menyimpan data: $e'),
            backgroundColor: Colors.redAccent,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pendaftaran Pasien'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: ListView(
            children: [
              _buildTextField(
                label: 'Nama',
                onChanged: (value) => nama = value,
                validator: (value) =>
                    value!.isEmpty ? 'Nama tidak boleh kosong' : null,
              ),
              _buildTextField(
                label: 'Alamat',
                onChanged: (value) => alamat = value,
                validator: (value) =>
                    value!.isEmpty ? 'Alamat tidak boleh kosong' : null,
              ),
              _buildTextField(
                label: 'No. HP',
                keyboardType: TextInputType.phone,
                onChanged: (value) => noHp = value,
                validator: (value) =>
                    value!.isEmpty ? 'No. HP tidak boleh kosong' : null,
              ),
              _buildTextField(
                label: 'Tempat Lahir',
                onChanged: (value) => tempatLahir = value,
              ),
              _buildTextField(
                label: 'Pekerjaan',
                onChanged: (value) => pekerjaan = value,
              ),
              _buildTextField(
                label: 'Keluhan',
                onChanged: (value) => keluhan = value,
              ),
              const SizedBox(height: 20),
              ElevatedButton.icon(
                onPressed: _submitForm,
                icon: const Icon(Icons.save),
                label: const Text('Daftar Pasien'),
                style: ElevatedButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Theme.of(context).primaryColor,
                  textStyle: const TextStyle(fontSize: 16),
                  padding: const EdgeInsets.symmetric(vertical: 14),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTextField({
    required String label,
    required ValueChanged<String> onChanged,
    String? Function(String?)? validator,
    TextInputType keyboardType = TextInputType.text,
  }) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 16.0),
      child: TextFormField(
        decoration: InputDecoration(
          labelText: label,
          labelStyle: TextStyle(color: Theme.of(context).primaryColor),
          focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Theme.of(context).primaryColor),
          ),
          enabledBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Colors.grey.shade400),
          ),
          errorBorder: const OutlineInputBorder(
            borderSide: BorderSide(color: Colors.red),
          ),
        ),
        onChanged: onChanged,
        validator: validator,
        keyboardType: keyboardType,
      ),
    );
  }
}

1.4. NGODING TIPIS-TIPIS DI 🩺 /lib/screens/medical_check_screen.dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../models/medical_check.dart';

class MedicalCheckScreen extends StatefulWidget {
  @override
  _MedicalCheckScreenState createState() => _MedicalCheckScreenState();
}

class _MedicalCheckScreenState extends State<MedicalCheckScreen> {
  final _formKey = GlobalKey<FormState>();
  String patientId = '';
  double suhu = 0.0;
  String tekananDarah = '';
  bool alergi = false;
  String? namaObatAlergi = '';
  String diagnosa = '';
  String obat = '';
  String dosis = '';

  Future<Map<String, dynamic>?> _fetchPatient(String id) async {
    try {
      DocumentSnapshot doc =
          await FirebaseFirestore.instance.collection('patients').doc(id).get();
      return doc.exists ? doc.data() as Map<String, dynamic> : null;
    } catch (e) {
      print('Error fetching patient: $e');
      return null;
    }
  }

  void _submitForm() async {
    if (_formKey.currentState!.validate()) {
      var medicalCheck = MedicalCheck(
        patientId: patientId,
        suhu: suhu,
        tekananDarah: tekananDarah,
        alergi: alergi,
        namaObatAlergi: alergi ? namaObatAlergi : null,
        diagnosa: diagnosa,
        obat: obat,
        dosis: dosis,
      );

      try {
        await FirebaseFirestore.instance
            .collection('medical_checks')
            .add(medicalCheck.toMap());
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: const Text('Pemeriksaan berhasil disimpan!'),
            backgroundColor: Theme.of(context).primaryColor,
          ),
        );
        _formKey.currentState!.reset(); // Reset form
      } catch (e) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Gagal menyimpan data: $e'),
            backgroundColor: Colors.redAccent,
          ),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Pemeriksaan Pasien'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Form(
          key: _formKey,
          child: ListView(
            children: [
              _buildTextField(
                label: 'ID Pasien',
                onChanged: (value) => patientId = value,
                validator: (value) =>
                    value!.isEmpty ? 'ID tidak boleh kosong' : null,
              ),
              _buildTextField(
                label: 'Suhu Tubuh',
                keyboardType: TextInputType.number,
                onChanged: (value) => suhu = double.parse(value),
                validator: (value) =>
                    value!.isEmpty ? 'Suhu tidak boleh kosong' : null,
              ),
              _buildTextField(
                label: 'Tekanan Darah',
                onChanged: (value) => tekananDarah = value,
              ),
              SwitchListTile(
                title: Text(
                  'Alergi Obat?',
                  style: TextStyle(color: Theme.of(context).primaryColor),
                ),
                value: alergi,
                onChanged: (value) {
                  setState(() {
                    alergi = value;
                  });
                },
              ),
              if (alergi)
                _buildTextField(
                  label: 'Nama Obat Alergi',
                  onChanged: (value) => namaObatAlergi = value,
                ),
              _buildTextField(
                label: 'Diagnosa',
                onChanged: (value) => diagnosa = value,
              ),
              _buildTextField(
                label: 'Obat',
                onChanged: (value) => obat = value,
              ),
              _buildTextField(
                label: 'Dosis',
                onChanged: (value) => dosis = value,
              ),
              const SizedBox(height: 20),
              ElevatedButton.icon(
                onPressed: _submitForm,
                icon: const Icon(Icons.save),
                label: const Text('Simpan Pemeriksaan'),
                style: ElevatedButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Theme.of(context).primaryColor,
                  textStyle: const TextStyle(fontSize: 16),
                  padding: const EdgeInsets.symmetric(vertical: 14),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTextField({
    required String label,
    required ValueChanged<String> onChanged,
    String? Function(String?)? validator,
    TextInputType keyboardType = TextInputType.text,
  }) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 16.0),
      child: TextFormField(
        decoration: InputDecoration(
          labelText: label,
          labelStyle: TextStyle(color: Theme.of(context).primaryColor),
          focusedBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Theme.of(context).primaryColor),
          ),
          enabledBorder: OutlineInputBorder(
            borderSide: BorderSide(color: Colors.grey.shade400),
          ),
          errorBorder: const OutlineInputBorder(
            borderSide: BorderSide(color: Colors.red),
          ),
        ),
        onChanged: onChanged,
        validator: validator,
        keyboardType: keyboardType,
      ),
    );
  }
}

1.5. NGODING TIPIS-TIPIS DI 📓 /lib/screens/patient_report_screen.dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'edit_patient_screen.dart';

class PatientReportScreen extends StatelessWidget {
  const PatientReportScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Laporan Data Pasien'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance.collection('patients').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
            return const Center(
              child: Text(
                'Tidak ada data pasien.',
                style: TextStyle(fontSize: 16),
              ),
            );
          }

          final patients = snapshot.data!.docs;

          return ListView.builder(
            itemCount: patients.length,
            itemBuilder: (context, index) {
              final data = patients[index].data() as Map<String, dynamic>;
              return Card(
                margin:
                    const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
                elevation: 4,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
                child: ListTile(
                  contentPadding: const EdgeInsets.all(16.0),
                  title: Text(
                    data['nama'],
                    style: const TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 18,
                    ),
                  ),
                  subtitle: Text(
                    'Alamat: ${data['alamat']}\nNo. HP: ${data['noHp']}',
                    style: const TextStyle(fontSize: 14, color: Colors.grey),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.edit, color: Colors.blueAccent),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) =>
                              EditPatientScreen(patientId: patients[index].id),
                        ),
                      );
                    },
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

1.6. NGODING TIPIS-TIPIS DI 🗒️ /lib/screens/medical_report_screen.dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'edit_medical_check_screen.dart';

class MedicalReportScreen extends StatelessWidget {
  const MedicalReportScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Laporan Hasil Pemeriksaan'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream:
            FirebaseFirestore.instance.collection('medical_checks').snapshots(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
            return const Center(
              child: Text(
                'Tidak ada hasil pemeriksaan.',
                style: TextStyle(fontSize: 16),
              ),
            );
          }

          final checks = snapshot.data!.docs;

          return ListView.builder(
            itemCount: checks.length,
            itemBuilder: (context, index) {
              final data = checks[index].data() as Map<String, dynamic>;
              return Card(
                margin:
                    const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
                elevation: 4,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10),
                ),
                child: ListTile(
                  contentPadding: const EdgeInsets.all(16.0),
                  title: Text(
                    'ID Pasien: ${data['patientId']}',
                    style: const TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 16,
                    ),
                  ),
                  subtitle: Text(
                    'Suhu: ${data['suhu']} °C\n'
                    'Tekanan Darah: ${data['tekananDarah']}\n'
                    'Diagnosa: ${data['diagnosa']}\n'
                    'Obat: ${data['obat']} (${data['dosis']})',
                    style: const TextStyle(fontSize: 14, color: Colors.grey),
                  ),
                  trailing: IconButton(
                    icon: const Icon(Icons.edit, color: Colors.blueAccent),
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => EditMedicalCheckScreen(
                            checkId: checks[index].id,
                          ),
                        ),
                      );
                    },
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

1.7. NGODING TIPIS-TIPIS DI 📝🧔🏻 /lib/screens/edit_patient_screen.dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class EditPatientScreen extends StatefulWidget {
  final String patientId;

  const EditPatientScreen({Key? key, required this.patientId})
      : super(key: key);

  @override
  _EditPatientScreenState createState() => _EditPatientScreenState();
}

class _EditPatientScreenState extends State<EditPatientScreen> {
  final _formKey = GlobalKey<FormState>();
  Map<String, dynamic> patientData = {};

  @override
  void initState() {
    super.initState();
    _fetchPatientData();
  }

  void _fetchPatientData() async {
    try {
      DocumentSnapshot doc = await FirebaseFirestore.instance
          .collection('patients')
          .doc(widget.patientId)
          .get();
      if (doc.exists) {
        setState(() {
          patientData = doc.data() as Map<String, dynamic>;
        });
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Gagal memuat data: $e')),
      );
    }
  }

  void _saveChanges() async {
    if (_formKey.currentState!.validate()) {
      try {
        await FirebaseFirestore.instance
            .collection('patients')
            .doc(widget.patientId)
            .update(patientData);
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Data berhasil diperbarui!')),
        );
        Navigator.pop(context);
      } catch (e) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Gagal memperbarui data: $e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Edit Data Pasien'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: patientData.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : Padding(
              padding: const EdgeInsets.all(16.0),
              child: Form(
                key: _formKey,
                child: ListView(
                  children: [
                    TextFormField(
                      initialValue: patientData['nama'],
                      decoration: InputDecoration(
                        labelText: 'Nama',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onChanged: (value) => patientData['nama'] = value,
                      validator: (value) =>
                          value!.isEmpty ? 'Nama tidak boleh kosong' : null,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: patientData['alamat'],
                      decoration: InputDecoration(
                        labelText: 'Alamat',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onChanged: (value) => patientData['alamat'] = value,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: patientData['noHp'],
                      decoration: InputDecoration(
                        labelText: 'No HP',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      keyboardType: TextInputType.phone,
                      onChanged: (value) => patientData['noHp'] = value,
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: _saveChanges,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Theme.of(context).primaryColor,
                        padding: const EdgeInsets.symmetric(vertical: 16),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      child: const Text(
                        'Simpan Perubahan',
                        style: TextStyle(fontSize: 16),
                      ),
                    ),
                  ],
                ),
              ),
            ),
    );
  }
}

1.8. NGODING TIPIS-TIPIS DI 📝🩺 /lib/screens/edit_medical_check_screen.dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class EditMedicalCheckScreen extends StatefulWidget {
  final String checkId;

  const EditMedicalCheckScreen({Key? key, required this.checkId})
      : super(key: key);

  @override
  _EditMedicalCheckScreenState createState() => _EditMedicalCheckScreenState();
}

class _EditMedicalCheckScreenState extends State<EditMedicalCheckScreen> {
  final _formKey = GlobalKey<FormState>();
  Map<String, dynamic> checkData = {};

  @override
  void initState() {
    super.initState();
    _fetchCheckData();
  }

  void _fetchCheckData() async {
    try {
      DocumentSnapshot doc = await FirebaseFirestore.instance
          .collection('medical_checks')
          .doc(widget.checkId)
          .get();
      if (doc.exists) {
        setState(() {
          checkData = doc.data() as Map<String, dynamic>;
        });
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Gagal memuat data: $e')),
      );
    }
  }

  void _saveChanges() async {
    if (_formKey.currentState!.validate()) {
      try {
        await FirebaseFirestore.instance
            .collection('medical_checks')
            .doc(widget.checkId)
            .update(checkData);
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
              content: Text('Data pemeriksaan berhasil diperbarui!')),
        );
        Navigator.pop(context);
      } catch (e) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Gagal memperbarui data: $e')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Edit Data Pemeriksaan'),
        backgroundColor: Theme.of(context).primaryColor,
      ),
      body: checkData.isEmpty
          ? const Center(child: CircularProgressIndicator())
          : Padding(
              padding: const EdgeInsets.all(16.0),
              child: Form(
                key: _formKey,
                child: ListView(
                  children: [
                    TextFormField(
                      initialValue: checkData['suhu'].toString(),
                      decoration: InputDecoration(
                        labelText: 'Suhu (°C)',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      keyboardType: TextInputType.number,
                      onChanged: (value) =>
                          checkData['suhu'] = double.tryParse(value) ?? 0.0,
                      validator: (value) =>
                          value!.isEmpty ? 'Suhu tidak boleh kosong' : null,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: checkData['tekananDarah'],
                      decoration: InputDecoration(
                        labelText: 'Tekanan Darah',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onChanged: (value) => checkData['tekananDarah'] = value,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: checkData['diagnosa'],
                      decoration: InputDecoration(
                        labelText: 'Diagnosa',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onChanged: (value) => checkData['diagnosa'] = value,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: checkData['obat'],
                      decoration: InputDecoration(
                        labelText: 'Obat',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      onChanged: (value) => checkData['obat'] = value,
                    ),
                    const SizedBox(height: 16),
                    TextFormField(
                      initialValue: checkData['dosis'].toString(),
                      decoration: InputDecoration(
                        labelText: 'Dosis (per hari)',
                        labelStyle: const TextStyle(fontSize: 16),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      keyboardType: TextInputType.number,
                      onChanged: (value) =>
                          checkData['dosis'] = int.tryParse(value) ?? 0,
                    ),
                    const SizedBox(height: 20),
                    ElevatedButton(
                      onPressed: _saveChanges,
                      style: ElevatedButton.styleFrom(
                        backgroundColor: Theme.of(context).primaryColor,
                        padding: const EdgeInsets.symmetric(vertical: 16),
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                      child: const Text(
                        'Simpan Perubahan',
                        style: TextStyle(fontSize: 16),
                      ),
                    ),
                  ],
                ),
              ),
            ),
    );
  }
}

DAN BOOM 💥 JADI GAK NGANTUK LAGI DENGAN UI SEKARANG

SEE NEXT TIME 😏