import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:penyaluran_app/app/routes/app_pages.dart'; import 'package:penyaluran_app/app/utils/format_helper.dart'; import 'package:percent_indicator/circular_percent_indicator.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/components/greeting_header.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/components/schedule_card.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_dashboard_controller.dart'; import 'package:penyaluran_app/app/services/supabase_service.dart'; import 'package:penyaluran_app/app/theme/app_theme.dart'; import 'package:penyaluran_app/app/widgets/cards/statistic_card.dart'; import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; class DashboardView extends GetView { const DashboardView({super.key}); @override Widget build(BuildContext context) { final textTheme = Theme.of(context).textTheme; return Scaffold( body: RefreshIndicator( onRefresh: () => controller.refreshData(), child: Obx(() => AnimationLimiter( child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Padding( padding: const EdgeInsets.all(16.0), child: controller.isLoading.value ? const Center(child: CircularProgressIndicator()) : AnimationConfiguration.staggeredList( position: 0, delay: const Duration(milliseconds: 100), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header dengan greeting yang lebih menarik FadeInAnimation( child: GreetingHeader( name: controller.namaLengkap, role: 'Petugas Desa', desa: controller.desa, nip: controller.nip, profileImageUrl: controller.profileImageUrl, ), ), const SizedBox(height: 24), // Rangkuman Statistik FadeInAnimation( delay: const Duration(milliseconds: 250), child: _buildStatistikRangkuman(), ), const SizedBox(height: 24), // Progress penyaluran FadeInAnimation( delay: const Duration(milliseconds: 300), child: _buildProgressPenyaluran(), ), const SizedBox(height: 24), // Jadwal penyaluran hari ini FadeInAnimation( delay: const Duration(milliseconds: 350), child: _buildJadwalHariIni(), ), const SizedBox(height: 24), // Grafik Penyaluran Bantuan FadeInAnimation( delay: const Duration(milliseconds: 400), child: _buildGrafikPenyaluran(), ), const SizedBox(height: 24), // Statistik performa desa FadeInAnimation( delay: const Duration(milliseconds: 450), child: _buildStatistikPerforma(), ), const SizedBox(height: 24), // Daftar penerima terbaru FadeInAnimation( delay: const Duration(milliseconds: 500), child: _buildRecipientsList(textTheme), ), const SizedBox(height: 16), ], ), ), ), ), )), ), ); } Widget _buildActionButton( String title, IconData icon, Color color, VoidCallback onTap) { return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Container( width: 75, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all(color: color.withOpacity(0.3), width: 1), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, color: color, size: 28), const SizedBox(height: 8), Text( title, textAlign: TextAlign.center, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: color, ), ), ], ), ), ); } Widget _buildStatistikRangkuman() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Ringkasan Kegiatan', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildStatItem( 'Total Penerima', controller.totalPenerima.value.toString(), Icons.people, Colors.blue, ), ), const SizedBox(width: 12), Expanded( child: _buildStatItem( 'Penyaluran', controller.totalPenyaluran.value.toString(), Icons.calendar_month, Colors.green, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildStatItem( 'Pengaduan', controller.jumlahDiproses.value.toString(), Icons.warning_amber, Colors.orange, ), ), const SizedBox(width: 12), Expanded( child: _buildStatItem( 'Penitipan', controller.totalPenitipanTerverifikasi.value.toString(), Icons.inventory, Colors.purple, ), ), ], ), ], ), ); } Widget _buildStatItem( String title, String value, IconData icon, Color color) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: color.withOpacity(0.2), shape: BoxShape.circle, ), child: Icon(icon, color: color, size: 22), ), const SizedBox(width: 10), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( value, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: color, ), ), Text( title, style: TextStyle( fontSize: 12, color: Colors.grey[600], ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ); } Widget _buildJadwalHariIni() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.event_note, color: AppTheme.primaryColor, size: 20, ), ), const SizedBox(width: 10), Text( 'Jadwal Penyaluran Hari Ini', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), ], ), ], ), const SizedBox(height: 16), FutureBuilder>?>( future: SupabaseService.to.getJadwalAktif(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: SizedBox( height: 100, child: Center(child: CircularProgressIndicator()), ), ); } if (snapshot.hasError) { return Container( height: 100, decoration: BoxDecoration( color: Colors.red.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.error_outline, color: Colors.red, size: 28), SizedBox(height: 8), Text( 'Gagal memuat jadwal', style: TextStyle(color: Colors.red), ), ], ), ), ); } final jadwalList = snapshot.data; if (jadwalList == null || jadwalList.isEmpty) { return Container( height: 100, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.blue.withOpacity(0.05), borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.blue.withOpacity(0.1), width: 1, ), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.event_busy, color: Colors.blue.shade300, size: 32, ), const SizedBox(height: 8), const Text( 'Tidak ada jadwal penyaluran hari ini', textAlign: TextAlign.center, style: TextStyle( color: Colors.blue, fontWeight: FontWeight.w500, ), ), ], ), ); } return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: jadwalList.length, itemBuilder: (context, index) { final jadwal = jadwalList[index]; final DateTime tanggal = DateTime.parse(jadwal['tanggal_penyaluran']); final String formattedDate = FormatHelper.formatDateTime(tanggal); final kategoriBantuan = jadwal['kategori_bantuan'] as Map; final lokasiPenyaluran = jadwal['lokasi_penyaluran'] as Map; return Column( children: [ if (index > 0) const SizedBox(height: 10), ScheduleCard( title: kategoriBantuan['nama'] ?? 'Jadwal Penyaluran', location: lokasiPenyaluran['nama'] ?? 'Lokasi tidak tersedia', dateTime: formattedDate, isToday: true, onTap: () => Get.toNamed(Routes.detailPenyaluran, parameters: {'id': jadwal['id']}), ), ], ); }, ); }, ), ], ), ); } Widget _buildProgressPenyaluran() { // Menghitung nilai untuk progress berdasarkan status final terlaksana = controller.penyaluranTerlaksana.value; final batal = controller.penyaluranBatal.value; final dijadwalkan = controller.penyaluranDijadwalkan.value; final aktif = controller.penyaluranAktif.value; final total = terlaksana + batal + dijadwalkan + aktif; final progressValue = total > 0 ? (terlaksana + batal) / total : 0.0; final belumTerlaksana = dijadwalkan + aktif; return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.indigo.shade700, Colors.indigo.shade500], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.indigo.withOpacity(0.3), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Progress Penyaluran', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(20), ), child: Text( 'Total: $total Penyaluran', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: Colors.white, ), ), ), ], ), const SizedBox(height: 20), Row( children: [ CircularPercentIndicator( radius: 60.0, lineWidth: 10.0, percent: progressValue > 1.0 ? 1.0 : progressValue, center: Column( mainAxisSize: MainAxisSize.min, children: [ Text( '${(progressValue * 100).toInt()}%', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), const Text( 'Selesai', style: TextStyle( fontSize: 12, color: Colors.white70, ), ), ], ), progressColor: Colors.white, backgroundColor: Colors.white.withOpacity(0.2), circularStrokeCap: CircularStrokeCap.round, animation: true, animationDuration: 1200, ), const SizedBox(width: 20), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildProgressDetailItemNew( Icons.check_circle, 'Telah Terlaksana', '$terlaksana', Colors.green.shade300, ), const SizedBox(height: 12), _buildProgressDetailItemNew( Icons.pending_actions, 'Belum Terlaksana', '$belumTerlaksana', Colors.amber.shade300, ), const SizedBox(height: 12), _buildProgressDetailItemNew( Icons.cancel, 'Dibatalkan', '$batal', Colors.red.shade300, ), ], ), ), ], ), ], ), ); } Widget _buildProgressDetailItemNew( IconData icon, String label, String value, Color iconColor) { return Row( children: [ Container( padding: const EdgeInsets.all(6), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), shape: BoxShape.circle, ), child: Icon(icon, color: iconColor, size: 16), ), const SizedBox(width: 10), Expanded( child: Text( label, style: const TextStyle( fontSize: 14, color: Colors.white70, ), ), ), Text( value, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ); } Widget _buildGrafikPenyaluran() { final terlaksana = controller.penyaluranTerlaksana.value; final batal = controller.penyaluranBatal.value; final dijadwalkan = controller.penyaluranDijadwalkan.value; final aktif = controller.penyaluranAktif.value; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.insert_chart, color: AppTheme.primaryColor, size: 20, ), ), const SizedBox(width: 10), Text( 'Status Penyaluran', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), ], ), TextButton( onPressed: () => Get.toNamed(Routes.riwayatPenyaluran), child: Text( 'Lihat Riwayat', style: TextStyle( fontSize: 12, color: AppTheme.primaryColor, ), ), ), ], ), const SizedBox(height: 20), Row( children: [ Expanded( child: _buildStatusItem( 'Terlaksana', terlaksana.toString(), Icons.check_circle, Colors.green, ), ), Expanded( child: _buildStatusItem( 'Dijadwalkan', dijadwalkan.toString(), Icons.event, Colors.blue, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: _buildStatusItem( 'Aktif', aktif.toString(), Icons.play_circle, Colors.orange, ), ), Expanded( child: _buildStatusItem( 'Dibatalkan', batal.toString(), Icons.cancel, Colors.red, ), ), ], ), const SizedBox(height: 20), Container( width: double.infinity, height: 10, decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(5), ), child: Row( children: [ if (terlaksana > 0) Flexible( flex: terlaksana, child: Container( decoration: BoxDecoration( color: Colors.green, borderRadius: BorderRadius.circular(5), ), ), ), if (aktif > 0) Flexible( flex: aktif, child: Container( decoration: BoxDecoration( color: Colors.orange, borderRadius: aktif > 0 && terlaksana == 0 ? BorderRadius.circular(5) : const BorderRadius.only( topRight: Radius.circular(5), bottomRight: Radius.circular(5), ), ), ), ), if (dijadwalkan > 0) Flexible( flex: dijadwalkan, child: Container( decoration: BoxDecoration( color: Colors.blue, borderRadius: dijadwalkan > 0 && terlaksana == 0 && aktif == 0 ? BorderRadius.circular(5) : const BorderRadius.only( topRight: Radius.circular(5), bottomRight: Radius.circular(5), ), ), ), ), if (batal > 0) Flexible( flex: batal, child: Container( decoration: BoxDecoration( color: Colors.red, borderRadius: const BorderRadius.only( topRight: Radius.circular(5), bottomRight: Radius.circular(5), ), ), ), ), ], ), ), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildLegendItem('Terlaksana', Colors.green), const SizedBox(width: 12), _buildLegendItem('Aktif', Colors.orange), const SizedBox(width: 12), _buildLegendItem('Dijadwalkan', Colors.blue), const SizedBox(width: 12), _buildLegendItem('Batal', Colors.red), ], ), ], ), ); } Widget _buildStatusItem( String label, String value, IconData icon, Color color) { return Container( padding: const EdgeInsets.all(12), margin: const EdgeInsets.symmetric(horizontal: 6), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: color.withOpacity(0.3), width: 1), ), child: Column( children: [ Icon(icon, color: color, size: 28), const SizedBox(height: 8), Text( value, style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: color, ), ), const SizedBox(height: 4), Text( label, style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ); } Widget _buildLegendItem(String label, Color color) { return Row( children: [ Container( width: 12, height: 12, decoration: BoxDecoration( color: color, shape: BoxShape.circle, ), ), const SizedBox(width: 4), Text( label, style: const TextStyle( fontSize: 10, color: Colors.grey, ), ), ], ); } Widget _buildStatistikPerforma() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.analytics, color: AppTheme.primaryColor, size: 20, ), ), const SizedBox(width: 10), Text( 'Statistik Performa', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), ), ], ), const SizedBox(height: 16), Row( children: [ Expanded( child: StatisticCard( title: 'Penitipan', count: controller.jumlahMenunggu.value.toString(), subtitle: 'Perlu Konfirmasi', height: 120, icon: Icons.inbox, gradient: LinearGradient( colors: [Colors.orange.shade600, Colors.orange.shade400], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), ), const SizedBox(width: 12), Expanded( child: StatisticCard( title: 'Penerima', count: controller.totalPenerima.value.toString(), subtitle: 'Terdaftar', height: 120, gradient: LinearGradient( colors: [Colors.blue.shade600, Colors.blue.shade400], begin: Alignment.topLeft, end: Alignment.bottomRight, ), icon: Icons.people, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: StatisticCard( title: 'Penyaluran', count: controller.penyaluranTerlaksana.value.toString(), subtitle: 'Terlaksana', height: 120, gradient: LinearGradient( colors: [Colors.green.shade600, Colors.green.shade400], begin: Alignment.topLeft, end: Alignment.bottomRight, ), icon: Icons.assignment_turned_in, ), ), const SizedBox(width: 12), Expanded( child: StatisticCard( title: 'Pengaduan', count: controller.jumlahDiproses.value.toString(), subtitle: 'Memerlukan Tindakan', height: 120, gradient: LinearGradient( colors: [Colors.red.shade600, Colors.red.shade400], begin: Alignment.topLeft, end: Alignment.bottomRight, ), icon: Icons.warning_amber, ), ), ], ), ], ), ); } Widget _buildRecipientsList(TextTheme textTheme) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.people, color: AppTheme.primaryColor, size: 20, ), ), const SizedBox(width: 10), Expanded( child: Text( 'Daftar Penerima', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppTheme.primaryColor, ), overflow: TextOverflow.ellipsis, ), ), ], ), ), InkWell( onTap: () => Get.toNamed(Routes.daftarPenerima), borderRadius: BorderRadius.circular(50), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: AppTheme.primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(50), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( 'Lihat Semua', style: TextStyle( fontSize: 12, color: AppTheme.primaryColor, fontWeight: FontWeight.w500, ), ), const SizedBox(width: 2), Icon( Icons.arrow_forward, size: 12, color: AppTheme.primaryColor, ), ], ), ), ), ], ), const SizedBox(height: 16), FutureBuilder>?>( future: SupabaseService.to.getPenerimaTerbaru(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const SizedBox( height: 100, child: Center(child: CircularProgressIndicator()), ); } if (snapshot.hasError) { return Container( height: 100, decoration: BoxDecoration( color: Colors.red.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.error_outline, color: Colors.red, size: 28), SizedBox(height: 8), Text( 'Gagal memuat data penerima', style: TextStyle(color: Colors.red), ), ], ), ), ); } final penerimaList = snapshot.data; if (penerimaList == null || penerimaList.isEmpty) { return Container( height: 100, decoration: BoxDecoration( color: Colors.grey[200], borderRadius: BorderRadius.circular(12), ), child: const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.person_off, color: Colors.grey, size: 28), SizedBox(height: 8), Text( 'Belum ada data penerima', style: TextStyle(color: Colors.grey), ), ], ), ), ); } return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: penerimaList.length > 3 ? 3 : penerimaList.length, itemBuilder: (context, index) { final penerima = penerimaList[index]; final name = penerima['nama_lengkap'] ?? 'Nama tidak tersedia'; final nik = penerima['nik'] ?? 'NIK tidak tersedia'; final status = penerima['status'] ?? 'AKTIF'; final id = penerima['id'] ?? 'ID tidak tersedia'; final fotoProfil = penerima['foto_profil'] ?? null; return Container( width: double.infinity, margin: const EdgeInsets.only(bottom: 10), decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.blue.shade700, Colors.blue.shade500], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.blue.withOpacity(0.2), blurRadius: 5, offset: const Offset(0, 2), ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: () { Get.toNamed(Routes.detailPenerima, arguments: id); }, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.all(12.0), child: Row( children: [ Stack( children: [ CircleAvatar( radius: 25, backgroundColor: Colors.white.withOpacity(0.2), backgroundImage: fotoProfil != null && fotoProfil.toString().isNotEmpty ? NetworkImage(fotoProfil) : null, child: (fotoProfil == null || fotoProfil.toString().isEmpty) ? Text( name .toString() .substring(0, 1) .toUpperCase(), style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.white, fontSize: 24, ), ) : null, ), Positioned( right: 0, bottom: 0, child: Container( padding: const EdgeInsets.all(2), decoration: BoxDecoration( color: status == 'AKTIF' ? Colors.green : Colors.red, shape: BoxShape.circle, border: Border.all( color: Colors.white, width: 1.5, ), ), width: 12, height: 12, ), ), ], ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.white, fontSize: 16, ), ), const SizedBox(height: 4), Row( children: [ const Icon( Icons.credit_card, color: Colors.white70, size: 14, ), const SizedBox(width: 4), Expanded( child: Text( 'NIK: $nik', style: const TextStyle( color: Colors.white70, fontSize: 12, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ], ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.white.withOpacity(0.2), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( status == 'AKTIF' ? Icons.check_circle : Icons.cancel, color: status == 'AKTIF' ? Colors.green.shade300 : Colors.red.shade300, size: 12, ), const SizedBox(width: 4), Text( status, style: const TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ), ), ), ); }, ); }, ), ], ), ); } }