// lib/core/widgets/data_handler.dart import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:smpn1_lengkong/core/constants/app_colors.dart'; class DataHandler extends StatelessWidget { final AsyncSnapshot snapshot; final Widget child; final VoidCallback onRetry; final Future Function() onRefresh; final String? emptyMessage; const DataHandler({ super.key, required this.snapshot, required this.child, required this.onRetry, required this.onRefresh, this.emptyMessage, }); @override Widget build(BuildContext context) { // 1. KONDISI LOADING: Muncul saat halaman pertama kali dibuka if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator(color: AppColors.primaryBlue), ); } // 2. KONDISI ERROR: Muncul jika gagal koneksi/timeout saat inisialisasi if (snapshot.hasError) { return RefreshIndicator( onRefresh: onRefresh, color: AppColors.primaryBlue, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Container( height: 0.7.sh, // Mengambil 70% tinggi layar padding: EdgeInsets.all(24.w), alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.wifi_off_rounded, size: 80.sp, color: Colors.grey[400], ), SizedBox(height: 16.h), Text( "Koneksi Bermasalah", style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), SizedBox(height: 8.h), Text( "Gagal mengambil data dari server. Periksa internet Anda atau tarik layar untuk mencoba lagi.", textAlign: TextAlign.center, style: TextStyle( color: AppColors.textSecondary, fontSize: 14.sp, ), ), SizedBox(height: 24.h), ElevatedButton.icon( onPressed: onRetry, icon: const Icon(Icons.refresh_rounded), label: const Text("Coba Lagi"), style: ElevatedButton.styleFrom( backgroundColor: AppColors.primaryBlue, foregroundColor: Colors.white, padding: EdgeInsets.symmetric( horizontal: 24.w, vertical: 12.h, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10.r), ), ), ), ], ), ), ), ); } // 3. KONDISI KOSONG: Jika data berhasil diambil tapi list-nya kosong final data = snapshot.data; if (data is List && data.isEmpty) { return RefreshIndicator( onRefresh: onRefresh, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Container( height: 0.7.sh, alignment: Alignment.center, child: Text( emptyMessage ?? "Data tidak ditemukan", style: TextStyle(color: Colors.grey, fontSize: 14.sp), ), ), ), ); } // 4. KONDISI SUKSES: Menampilkan konten asli dengan RefreshIndicator return RefreshIndicator( onRefresh: onRefresh, color: AppColors.primaryBlue, backgroundColor: Colors.white, child: child, ); } }