feat: fungsi rule
This commit is contained in:
parent
accd4ab167
commit
4271210c03
|
@ -8,6 +8,7 @@ const authRoutes = require('./routes/authRoutes');
|
|||
const gejalaRoutes = require('./routes/gejalaRoute');
|
||||
const hamaRoutes = require('./routes/hamaRoutes');
|
||||
const penyakitRoutes = require('./routes/penyakitRoutes');
|
||||
const ruleRoutes = require('./routes/ruleRoutes');
|
||||
const swaggerDocs = require('./swagger');
|
||||
|
||||
dotenv.config();
|
||||
|
@ -24,6 +25,8 @@ app.use("/api/auth", authRoutes);
|
|||
app.use("/api/gejala", gejalaRoutes);
|
||||
app.use("/api/hama", hamaRoutes);
|
||||
app.use("/api/penyakit", penyakitRoutes);
|
||||
app.use("/api/rules", ruleRoutes);
|
||||
|
||||
|
||||
// Swagger Documentation
|
||||
swaggerDocs(app); // Setup Swagger UI documentation
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
const { Rule, gejala, penyakit, hama } = require('../models');
|
||||
|
||||
// 🔥 Buat aturan baru
|
||||
exports.createRule = async (req, res) => {
|
||||
try {
|
||||
const { id_gejala, id_penyakit, id_hama, nilai_pakar } = req.body;
|
||||
|
||||
// Validasi minimal
|
||||
if (!id_gejala || (!id_penyakit && !id_hama) || !nilai_pakar) {
|
||||
return res.status(400).json({ message: 'Data tidak lengkap' });
|
||||
}
|
||||
|
||||
const newRule = await Rule.create({
|
||||
id_gejala,
|
||||
id_penyakit,
|
||||
id_hama,
|
||||
nilai_pakar
|
||||
});
|
||||
|
||||
res.status(201).json({ message: 'Rule berhasil dibuat', data: newRule });
|
||||
} catch (error) {
|
||||
console.error('Error createRule:', error);
|
||||
res.status(500).json({ message: 'Terjadi kesalahan server', error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
// 🔥 Ambil semua aturan
|
||||
exports.getRules = async (req, res) => {
|
||||
try {
|
||||
const rules = await Rule.findAll();
|
||||
|
||||
res.status(200).json({ message: 'Daftar Rules', data: rules });
|
||||
} catch (error) {
|
||||
console.error('Error getRules:', error);
|
||||
res.status(500).json({ message: 'Terjadi kesalahan server', error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
// 🔥 Update aturan
|
||||
exports.updateRule = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
const { id_gejala, id_penyakit, id_hama, nilai_pakar } = req.body;
|
||||
|
||||
const rule = await Rule.findByPk(id);
|
||||
if (!rule) {
|
||||
return res.status(404).json({ message: 'Rule tidak ditemukan' });
|
||||
}
|
||||
|
||||
await rule.update({
|
||||
id_gejala,
|
||||
id_penyakit,
|
||||
id_hama,
|
||||
nilai_pakar
|
||||
});
|
||||
|
||||
res.status(200).json({ message: 'Rule berhasil diperbarui', data: rule });
|
||||
} catch (error) {
|
||||
console.error('Error updateRule:', error);
|
||||
res.status(500).json({ message: 'Terjadi kesalahan server', error: error.message });
|
||||
}
|
||||
};
|
||||
|
||||
// 🔥 Hapus aturan
|
||||
exports.deleteRule = async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
const rule = await Rule.findByPk(id);
|
||||
if (!rule) {
|
||||
return res.status(404).json({ message: 'Rule tidak ditemukan' });
|
||||
}
|
||||
|
||||
await rule.destroy();
|
||||
|
||||
res.status(200).json({ message: 'Rule berhasil dihapus' });
|
||||
} catch (error) {
|
||||
console.error('Error deleteRule:', error);
|
||||
res.status(500).json({ message: 'Terjadi kesalahan server', error: error.message });
|
||||
}
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
'use strict';
|
||||
/** @type {import('sequelize-cli').Migration} */
|
||||
module.exports = {
|
||||
async up(queryInterface, Sequelize) {
|
||||
await queryInterface.createTable('Rules', {
|
||||
id: {
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
type: Sequelize.INTEGER
|
||||
},
|
||||
id_gejala: {
|
||||
type: Sequelize.INTEGER,
|
||||
references:{
|
||||
model: 'gejala',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
nilai_pakar: {
|
||||
type: Sequelize.FLOAT,
|
||||
allowNull: false
|
||||
},
|
||||
id_penyakit: {
|
||||
type: Sequelize.INTEGER,
|
||||
references:{
|
||||
model: 'penyakit',
|
||||
key:'id'
|
||||
}
|
||||
},
|
||||
id_hama: {
|
||||
type: Sequelize.INTEGER,
|
||||
references:{
|
||||
model: 'hama',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
async down(queryInterface, Sequelize) {
|
||||
await queryInterface.dropTable('Rules');
|
||||
}
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
const { Model, DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Gejala extends Model {}
|
||||
|
||||
Gejala.init(
|
||||
|
@ -29,4 +29,5 @@ Gejala.init(
|
|||
}
|
||||
);
|
||||
|
||||
module.exports = Gejala;
|
||||
return Gejala; // Pastikan model dikembalikan dengan benar
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const { Model, DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class Hama extends Model {}
|
||||
|
||||
Hama.init(
|
||||
|
@ -40,5 +41,5 @@ Hama.init(
|
|||
paranoid: false, // Jika menggunakan soft delete, ubah ke true
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = Hama;
|
||||
return Hama;
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
const { Model, DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
|
||||
|
||||
module.exports =(sequelize) => {
|
||||
class Penyakit extends Model {}
|
||||
|
||||
Penyakit.init(
|
||||
|
@ -37,4 +38,5 @@ Penyakit.init(
|
|||
}
|
||||
);
|
||||
|
||||
module.exports = Penyakit;
|
||||
return Penyakit;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
const { Model, DataTypes } = require('sequelize');
|
||||
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
|
||||
class Rule extends Model {
|
||||
static associate(models) {
|
||||
// Asosiasi dengan model Gejala
|
||||
Rule.belongsTo(models.Gejala, {
|
||||
foreignKey: 'id_gejala',
|
||||
as: 'gejala', // Nama asosiasi yang bisa digunakan saat melakukan query
|
||||
});
|
||||
|
||||
// Asosiasi dengan model Penyakit
|
||||
Rule.belongsTo(models.Penyakit, {
|
||||
foreignKey: 'id_penyakit',
|
||||
as: 'penyakit',
|
||||
});
|
||||
|
||||
// Asosiasi dengan model Hama
|
||||
Rule.belongsTo(models.Hama, {
|
||||
foreignKey: 'id_hama',
|
||||
as: 'hama',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Rule.init(
|
||||
{
|
||||
id_gejala: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: 'gejala', // Mengacu ke tabel 'gejala'
|
||||
key: 'id', // Mengacu ke kolom 'id' pada tabel 'gejala'
|
||||
},
|
||||
},
|
||||
nilai_pakar: {
|
||||
type: DataTypes.FLOAT,
|
||||
allowNull: false,
|
||||
},
|
||||
id_penyakit: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: 'penyakit', // Mengacu ke tabel 'penyakit'
|
||||
key: 'id', // Mengacu ke kolom 'id' pada tabel 'penyakit'
|
||||
},
|
||||
},
|
||||
id_hama: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: 'hama', // Mengacu ke tabel 'hama'
|
||||
key: 'id', // Mengacu ke kolom 'id' pada tabel 'hama'
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
sequelize,
|
||||
modelName: 'Rule',
|
||||
tableName: 'rules',
|
||||
timestamps: false,
|
||||
paranoid: false,
|
||||
}
|
||||
);
|
||||
|
||||
return Rule;
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
const { Model, DataTypes } = require('sequelize');
|
||||
const sequelize = require('../config/database');
|
||||
|
||||
|
||||
module.exports = (sequelize) => {
|
||||
class User extends Model {}
|
||||
|
||||
User.init(
|
||||
|
@ -49,5 +50,5 @@ class User extends Model {}
|
|||
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = User;
|
||||
return User;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const ruleController = require('../controller/rulesController');
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* tags:
|
||||
* name: Rules
|
||||
* description: API untuk mengelola aturan (rules)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/rules:
|
||||
* post:
|
||||
* summary: Membuat aturan baru
|
||||
* tags: [Rules]
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* required:
|
||||
* - id_gejala
|
||||
* - nilai_pakar
|
||||
* properties:
|
||||
* id_gejala:
|
||||
* type: integer
|
||||
* id_penyakit:
|
||||
* type: integer
|
||||
* id_hama:
|
||||
* type: integer
|
||||
* nilai_pakar:
|
||||
* type: number
|
||||
* format: float
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Rule berhasil dibuat
|
||||
* 400:
|
||||
* description: Data tidak lengkap
|
||||
* 500:
|
||||
* description: Terjadi kesalahan server
|
||||
*/
|
||||
router.post('/', ruleController.createRule);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/rules:
|
||||
* get:
|
||||
* summary: Menampilkan semua aturan
|
||||
* tags: [Rules]
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Daftar rules berhasil diambil
|
||||
* 500:
|
||||
* description: Terjadi kesalahan server
|
||||
*/
|
||||
router.get('/', ruleController.getRules);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/rules/{id}:
|
||||
* put:
|
||||
* summary: Memperbarui aturan berdasarkan ID
|
||||
* tags: [Rules]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* description: ID rule yang ingin diperbarui
|
||||
* schema:
|
||||
* type: integer
|
||||
* requestBody:
|
||||
* required: true
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
* type: object
|
||||
* properties:
|
||||
* id_gejala:
|
||||
* type: integer
|
||||
* id_penyakit:
|
||||
* type: integer
|
||||
* id_hama:
|
||||
* type: integer
|
||||
* nilai_pakar:
|
||||
* type: number
|
||||
* format: float
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Rule berhasil diperbarui
|
||||
* 404:
|
||||
* description: Rule tidak ditemukan
|
||||
* 500:
|
||||
* description: Terjadi kesalahan server
|
||||
*/
|
||||
router.put('/:id', ruleController.updateRule);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* /api/rules/{id}:
|
||||
* delete:
|
||||
* summary: Menghapus aturan berdasarkan ID
|
||||
* tags: [Rules]
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: id
|
||||
* required: true
|
||||
* description: ID rule yang ingin dihapus
|
||||
* schema:
|
||||
* type: integer
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Rule berhasil dihapus
|
||||
* 404:
|
||||
* description: Rule tidak ditemukan
|
||||
* 500:
|
||||
* description: Terjadi kesalahan server
|
||||
*/
|
||||
router.delete('/:id', ruleController.deleteRule);
|
||||
|
||||
module.exports = router;
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class DetailHamaPage extends StatelessWidget {
|
||||
final Map<String, String> detailRiwayat;
|
||||
final Map<String, dynamic> detailHama;
|
||||
|
||||
const DetailHamaPage({required this.detailRiwayat});
|
||||
const DetailHamaPage({required this.detailHama});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -25,11 +25,11 @@ class DetailHamaPage extends StatelessWidget {
|
|||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
if (detailRiwayat["gambar"] != null && detailRiwayat["gambar"]!.isNotEmpty)
|
||||
if (detailHama["gambar"] != null && detailHama["gambar"]!.isNotEmpty)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Image.asset(
|
||||
detailRiwayat["gambar"]!,
|
||||
detailHama["gambar"]!,
|
||||
height: 200,
|
||||
width: 200, // Biar gambar full lebar
|
||||
fit: BoxFit.cover,
|
||||
|
@ -54,7 +54,7 @@ class DetailHamaPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
detailRiwayat["nama hama"] ?? "Nama hama tidak tersedia",
|
||||
detailHama["nama"] ?? "Nama hama tidak tersedia",
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
|
@ -81,7 +81,7 @@ class DetailHamaPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
detailRiwayat["deskripsi"] ?? "Deskripsi tidak tersedia",
|
||||
detailHama["deskripsi"] ?? "Deskripsi tidak tersedia",
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
|
@ -91,7 +91,7 @@ class DetailHamaPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
detailRiwayat["penanganan"] ?? "Penanganan tidak tersedia",
|
||||
detailHama["penanganan"] ?? "Penanganan tidak tersedia",
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class DetailPenyakitPage extends StatelessWidget {
|
||||
final Map<String, String> detailPenyakit;
|
||||
final Map<String, dynamic> detailPenyakit;
|
||||
|
||||
const DetailPenyakitPage({required this.detailPenyakit});
|
||||
|
||||
|
@ -54,7 +54,7 @@ class DetailPenyakitPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
detailPenyakit["nama penyakit"] ?? "Nama penyakit tidak tersedia",
|
||||
detailPenyakit["nama"] ?? "Nama penyakit tidak tersedia",
|
||||
style: TextStyle(fontSize: 16),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,33 +1,20 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'detail_hama_page.dart';
|
||||
import 'package:frontend/api_services/api_services.dart';
|
||||
|
||||
class HamaPage extends StatelessWidget {
|
||||
final List<Map<String, String>> hamaList = [
|
||||
{
|
||||
"nama hama": "Karat Putih",
|
||||
"deskripsi": "Penyakit yang umum pada bayam.",
|
||||
"penanganan": "Gunakan fungisida sesuai anjuran dan potong daun yang terinfeksi.",
|
||||
"gambar": "assets/images/karat putih.jpeg",
|
||||
},
|
||||
{
|
||||
"nama hama": "Virus Keriting",
|
||||
"deskripsi": "Disebabkan oleh infeksi virus.",
|
||||
"penanganan": "Musnahkan tanaman terinfeksi dan kontrol vektor seperti kutu daun.",
|
||||
"gambar": "assets/images/virus_keriting.jpeg",
|
||||
},
|
||||
{
|
||||
"nama hama": "Kekurangan Mangan",
|
||||
"deskripsi": "Kekurangan unsur hara mikro.",
|
||||
"penanganan": "Tambahkan pupuk yang mengandung mangan (Mn).",
|
||||
"gambar": "assets/images/kekurangan_mangan.jpeg",
|
||||
},
|
||||
{
|
||||
"nama hama": "Downy Mildew",
|
||||
"deskripsi": "Penyakit jamur pada bayam.",
|
||||
"penanganan": "Gunakan fungisida berbahan aktif metalaxyl dan perbaiki drainase tanah.",
|
||||
"gambar": "assets/images/downy_mildew.jpeg",
|
||||
},
|
||||
];
|
||||
class HamaPage extends StatefulWidget {
|
||||
@override
|
||||
_HamaPageState createState() => _HamaPageState();
|
||||
}
|
||||
|
||||
class _HamaPageState extends State<HamaPage> {
|
||||
late Future<List<Map<String, dynamic>>> _hamaListFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_hamaListFuture = ApiService().getHama();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -52,11 +39,19 @@ class HamaPage extends StatelessWidget {
|
|||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
child: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: _hamaListFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator(color: Colors.white));
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(child: Text('Gagal memuat data', style: TextStyle(color: Colors.white)));
|
||||
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Center(child: Text('Tidak ada data tersedia', style: TextStyle(color: Colors.white)));
|
||||
} else {
|
||||
final hamaList = snapshot.data!;
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: hamaList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final diagnosa = hamaList[index];
|
||||
|
@ -65,7 +60,7 @@ class HamaPage extends StatelessWidget {
|
|||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
diagnosa["nama hama"] ?? "Tidak ada data",
|
||||
diagnosa["nama"] ?? "Tidak ada data",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text(diagnosa["deskripsi"] ?? "Deskripsi tidak tersedia"),
|
||||
|
@ -73,16 +68,16 @@ class HamaPage extends StatelessWidget {
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailHamaPage(detailRiwayat: diagnosa),
|
||||
builder: (context) => DetailHamaPage(detailHama: diagnosa),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,33 +1,20 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'detail_penyakit_page.dart';
|
||||
import 'package:frontend/api_services/api_services.dart';
|
||||
|
||||
class PenyakitPage extends StatelessWidget {
|
||||
final List<Map<String, String>> penyakitList= [
|
||||
{
|
||||
"nama penyakit": "Karat Putih",
|
||||
"deskripsi": "Penyakit yang umum pada bayam.",
|
||||
"penanganan": "Gunakan fungisida sesuai anjuran dan potong daun yang terinfeksi.",
|
||||
"gambar": "assets/images/karat putih.jpeg",
|
||||
},
|
||||
{
|
||||
"nama penyakit": "Virus Keriting",
|
||||
"deskripsi": "Disebabkan oleh infeksi virus.",
|
||||
"penanganan": "Musnahkan tanaman terinfeksi dan kontrol vektor seperti kutu daun.",
|
||||
"gambar": "assets/images/virus_keriting.jpeg",
|
||||
},
|
||||
{
|
||||
"nama penyakit": "Kekurangan Mangan",
|
||||
"deskripsi": "Kekurangan unsur hara mikro.",
|
||||
"penanganan": "Tambahkan pupuk yang mengandung mangan (Mn).",
|
||||
"gambar": "assets/images/kekurangan_mangan.jpeg",
|
||||
},
|
||||
{
|
||||
"nama penyakit": "Downy Mildew",
|
||||
"deskripsi": "Penyakit jamur pada bayam.",
|
||||
"penanganan": "Gunakan fungisida berbahan aktif metalaxyl dan perbaiki drainase tanah.",
|
||||
"gambar": "assets/images/downy_mildew.jpeg",
|
||||
},
|
||||
];
|
||||
class PenyakitPage extends StatefulWidget {
|
||||
@override
|
||||
_PenyakitPageState createState() => _PenyakitPageState();
|
||||
}
|
||||
|
||||
class _PenyakitPageState extends State<PenyakitPage> {
|
||||
late Future<List<Map<String, dynamic>>> _penyakitListFuture;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_penyakitListFuture = ApiService().getPenyakit();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -52,37 +39,45 @@ class PenyakitPage extends StatelessWidget {
|
|||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
child: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: _penyakitListFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator(color: Colors.white));
|
||||
} else if (snapshot.hasError) {
|
||||
return Center(child: Text('Gagal memuat data', style: TextStyle(color: Colors.white)));
|
||||
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||
return Center(child: Text('Tidak ada data tersedia', style: TextStyle(color: Colors.white)));
|
||||
} else {
|
||||
final penyakitList = snapshot.data!;
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: penyakitList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final diagnosa = penyakitList[index];
|
||||
final penyakit = penyakitList[index];
|
||||
return Card(
|
||||
elevation: 4,
|
||||
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
diagnosa["nama penyakit"] ?? "Tidak ada data",
|
||||
penyakit["nama"] ?? "Tidak ada data",
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text(diagnosa["deskripsi"] ?? "Deskripsi tidak tersedia"),
|
||||
subtitle: Text(penyakit["deskripsi"] ?? "Deskripsi tidak tersedia"),
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DetailPenyakitPage(detailPenyakit: diagnosa),
|
||||
builder: (context) => DetailPenyakitPage(detailPenyakit: penyakit),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue