import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:flutter_quill/flutter_quill.dart' as quill; // Tambahkan library ini import '../../layout/main_layout.dart'; import '../ibu_drawer.dart'; import '../dashboard_ibu.dart'; class EdukasiHamilPage extends StatefulWidget { const EdukasiHamilPage({super.key}); @override State createState() => _EdukasiHamilPageState(); } class _EdukasiHamilPageState extends State { List _listEdukasi = []; bool _isLoading = true; // Base URL Gambar disesuaikan dengan referensi kode Bidan Anda final String baseImageUrl = "http://ta.myhost.id/E31230549/mposyandu_api/upload/edukasi/"; @override void initState() { super.initState(); _fetchData(); } Future _fetchData() async { try { final response = await http.get( Uri.parse( "http://ta.myhost.id/E31230549/mposyandu_api/edukasi_ibu_hamil/get_edukasi_ibu_hamil.php", ), ); if (response.statusCode == 200) { final data = jsonDecode(response.body); if (data['success'] == true) { setState(() { _listEdukasi = data['data']; _isLoading = false; }); } else { setState(() => _isLoading = false); } } else { setState(() => _isLoading = false); } } catch (e) { setState(() => _isLoading = false); debugPrint("Error fetching data: $e"); } } // Fungsi untuk membersihkan JSON Quill menjadi teks paragraf biasa String _parseDescription(String? description) { String cleanText = description ?? ""; if (cleanText.startsWith('[') && cleanText.endsWith(']')) { try { final List json = jsonDecode(cleanText); final doc = quill.Document.fromJson(json); return doc.toPlainText().trim(); } catch (e) { return cleanText; } } return cleanText; } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) async { if (didPop) return; Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => const DashboardIbuPage()), (route) => false, ); }, child: MainLayout( title: "", drawer: const IbuDrawer(), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: Column( children: [ Text( "Edukasi Ibu Hamil", style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.w600, color: const Color.fromARGB(255, 24, 25, 26), ), ), const SizedBox(height: 16), Expanded( child: _isLoading ? const Center(child: CircularProgressIndicator()) : _listEdukasi.isEmpty ? const Center( child: Text("Belum ada data edukasi hamil.")) : RefreshIndicator( onRefresh: _fetchData, child: ListView.builder( itemCount: _listEdukasi.length, itemBuilder: (context, index) { final item = _listEdukasi[index]; // Gabungkan Base URL dengan nama file gambar dari database String fullImageUrl = ""; if (item['gambar'] != null && item['gambar'].toString().isNotEmpty) { fullImageUrl = "$baseImageUrl${item['gambar']}"; } return _EdukasiHamilCard( title: item['judul'] ?? '', content: _parseDescription(item['deskripsi']), info: "Saran untuk usia kehamilan ${item['usia_min']} - ${item['usia_max']} minggu", imageUrl: fullImageUrl, icon: Icons.pregnant_woman, ); }, ), ), ), ], ), ), ), ); } } class _EdukasiHamilCard extends StatelessWidget { final String title; final String content; final String info; final String imageUrl; final IconData icon; const _EdukasiHamilCard({ required this.title, required this.content, required this.info, required this.imageUrl, required this.icon, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.only(bottom: 20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// ===== GAMBAR EDUKASI ===== if (imageUrl.isNotEmpty) ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(14)), child: Image.network( imageUrl, width: double.infinity, height: 200, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( width: double.infinity, height: 150, color: Colors.grey[200], child: const Icon(Icons.broken_image, color: Colors.grey, size: 50), ); }, ), ), Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: const Color(0xFFFFE8F0), borderRadius: BorderRadius.circular(8), ), child: Icon(icon, color: Colors.pink, size: 20), ), const SizedBox(width: 12), Expanded( child: Text( title, style: GoogleFonts.poppins( fontWeight: FontWeight.bold, fontSize: 15, color: Colors.black87, ), ), ), ], ), const SizedBox(height: 12), Text( info, style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w600, color: Colors.pinkAccent, ), ), const SizedBox(height: 8), /// DESKRIPSI (Teks Paragraf Rapi) Text( content, textAlign: TextAlign.justify, // Agar paragraf rapi rata kanan-kiri style: GoogleFonts.poppins( fontSize: 13, height: 1.6, color: Colors.black54, ), ), ], ), ), ], ), ); } }