Sistem-Pakar-Diagnosa-Penya.../frontend/lib/user/detail_penyakit_page.dart

249 lines
8.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:frontend/api_services/api_services.dart';
import 'dart:typed_data';
class DetailPenyakitPage extends StatefulWidget {
final Map<String, dynamic> DetailPenyakit;
final int? penyakitId;
const DetailPenyakitPage({Key? key, required this.DetailPenyakit, this.penyakitId})
: super(key: key);
@override
_DetailPenyakitPageState createState() => _DetailPenyakitPageState();
}
class _DetailPenyakitPageState extends State<DetailPenyakitPage> {
late Future<Map<String, dynamic>> _detailPenyakitFuture;
late Map<String, dynamic> _currentDetailPenyakit;
@override
void initState() {
super.initState();
_currentDetailPenyakit = widget.DetailPenyakit;
// Jika hamaId tersedia, fetch data terbaru dari API
if (widget.penyakitId != null) {
_detailPenyakitFuture = _fetchDetailPenyakit(widget.penyakitId!);
} else {
// Jika tidak ada ID, gunakan data yang sudah diberikan
_detailPenyakitFuture = Future.value(widget.DetailPenyakit);
}
}
Future<Map<String, dynamic>> _fetchDetailPenyakit(int id) async {
try {
final detailData = await ApiService().getPenyakitById(id);
setState(() {
_currentDetailPenyakit = detailData;
});
return detailData;
} catch (e) {
print('Error fetching detail penyakit: $e');
// Jika gagal fetch, gunakan data yang sudah ada
return widget.DetailPenyakit;
}
}
// Fungsi untuk memvalidasi URL gambar
bool _isValidImageUrl(String? url) {
if (url == null || url.isEmpty) return false;
// Periksa apakah URL berakhir dengan ekstensi gambar yang umum
final validExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
return validExtensions.any((ext) => url.toLowerCase().endsWith(ext));
}
// Widget untuk menampilkan gambar dengan penanganan error yang lebih baik
Widget _buildImageWidget(String? filename) {
if (filename == null || filename.isEmpty) {
return _buildPlaceholderImage(
"Tidak ada gambar tersedia",
Icons.image_not_supported,
);
}
return FutureBuilder<Uint8List?>(
future: ApiService().getPenyakitImageBytesByFilename(filename),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return SizedBox(
height: 200,
width: double.infinity,
child: Center(child: CircularProgressIndicator()),
);
} else if (snapshot.hasError || snapshot.data == null) {
return _buildPlaceholderImage(
"Gagal memuat gambar",
Icons.broken_image,
);
} else {
return ClipRRect(
borderRadius: BorderRadius.circular(12),
child: Image.memory(
snapshot.data!,
height: 200,
width: double.infinity,
fit: BoxFit.contain, // untuk memastikan proporsional & penuh
),
);
}
},
);
}
// Widget untuk placeholder gambar
Widget _buildPlaceholderImage(String message, IconData icon) {
return Container(
height: 200,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 64, color: Colors.grey[600]),
SizedBox(height: 8),
Text(
message,
style: TextStyle(
color: Colors.grey[600],
fontWeight: FontWeight.bold,
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF9DC08D),
appBar: AppBar(
backgroundColor: Color(0xFF9DC08D),
title: Text("Detail Penyakit", style: TextStyle(color: Colors.white)),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () => Navigator.of(context).pop(),
),
),
body: FutureBuilder<Map<String, dynamic>>(
future: _detailPenyakitFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(color: Colors.white),
);
}
if (snapshot.hasError) {
print('Error: ${snapshot.error}');
// Tampilkan data yang sudah ada jika terjadi error
return _buildDetailContent(_currentDetailPenyakit);
}
print("Snapshot data runtimeType: ${snapshot.data.runtimeType}");
print("Snapshot data content: ${snapshot.data}");
// Jika berhasil fetch data baru, tampilkan data tersebut
final detailData = snapshot.data ?? _currentDetailPenyakit;
return _buildDetailContent(detailData);
},
),
);
}
Widget _buildDetailContent(Map<String, dynamic> detailData) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// Tampilkan foto dari database dengan penanganan error yang lebih baik
_buildImageWidget(detailData["foto"]),
SizedBox(height: 16),
// Card Nama Hama
SizedBox(
width: double.infinity,
child: Card(
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Nama Penyakit:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
detailData["nama"] ?? "Nama hama tidak tersedia",
style: TextStyle(fontSize: 16),
),
],
),
),
),
),
SizedBox(height: 16),
// Card Deskripsi + Penanganan
SizedBox(
width: double.infinity,
child: Card(
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Deskripsi:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
detailData["deskripsi"] ?? "Deskripsi tidak tersedia",
style: TextStyle(fontSize: 16),
),
SizedBox(height: 16),
Text(
"Penanganan:",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text(
detailData["penanganan"] ?? "Penanganan tidak tersedia",
style: TextStyle(fontSize: 16),
),
],
),
),
),
),
],
),
),
);
}
}