From b0310103fef0efbf3271eff9073fe2387a301925 Mon Sep 17 00:00:00 2001 From: Khafidh Fuadi Date: Thu, 13 Mar 2025 20:05:58 +0700 Subject: [PATCH] Perbarui JadwalSectionWidget untuk menambahkan ikon status dan informasi tambahan - Tambahkan ikon status dan warna berdasarkan status penyaluran - Perbarui tampilan untuk menampilkan informasi lokasi, kategori, dan jumlah penerima - Modifikasi format tanggal dan waktu untuk tampilan yang lebih informatif - Ganti beberapa elemen UI untuk meningkatkan pengalaman pengguna --- .../components/jadwal_section_widget.dart | 353 ++++++++++++------ 1 file changed, 232 insertions(+), 121 deletions(-) diff --git a/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart b/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart index fb98682..eb665ce 100644 --- a/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart +++ b/lib/app/modules/petugas_desa/components/jadwal_section_widget.dart @@ -4,6 +4,7 @@ import 'package:intl/intl.dart'; import 'package:penyaluran_app/app/data/models/penyaluran_bantuan_model.dart'; import 'package:penyaluran_app/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.dart'; import 'package:penyaluran_app/app/routes/app_pages.dart'; +import 'package:penyaluran_app/app/theme/app_theme.dart'; class JadwalSectionWidget extends StatelessWidget { final JadwalPenyaluranController controller; @@ -26,13 +27,23 @@ class JadwalSectionWidget extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - title, - style: textTheme.titleLarge?.copyWith( - fontWeight: FontWeight.bold, - ), + Row( + children: [ + Icon( + _getStatusIcon(), + color: _getStatusColor(), + size: 24, + ), + const SizedBox(width: 8), + Text( + title, + style: textTheme.titleLarge?.copyWith( + fontWeight: FontWeight.bold, + ), + ), + ], ), - const SizedBox(height: 10), + const SizedBox(height: 12), Obx(() { final currentJadwalList = _getCurrentJadwalList(); @@ -44,11 +55,21 @@ class JadwalSectionWidget extends StatelessWidget { borderRadius: BorderRadius.circular(12), ), child: Center( - child: Text( - 'Tidak ada jadwal $title', - style: textTheme.titleMedium?.copyWith( - color: Colors.grey.shade600, - ), + child: Column( + children: [ + Icon( + _getEmptyIcon(), + size: 40, + color: Colors.grey.shade400, + ), + const SizedBox(height: 8), + Text( + 'Tidak ada jadwal $title', + style: textTheme.titleMedium?.copyWith( + color: Colors.grey.shade600, + ), + ), + ], ), ), ); @@ -64,6 +85,45 @@ class JadwalSectionWidget extends StatelessWidget { ); } + IconData _getStatusIcon() { + switch (status) { + case 'Aktif': + return Icons.event_available; + case 'Terjadwal': + return Icons.pending_actions; + case 'Selesai': + return Icons.event_busy; + default: + return Icons.event_note; + } + } + + IconData _getEmptyIcon() { + switch (status) { + case 'Aktif': + return Icons.calendar_today; + case 'Terjadwal': + return Icons.schedule; + case 'Selesai': + return Icons.task_alt; + default: + return Icons.event_note; + } + } + + Color _getStatusColor() { + switch (status) { + case 'Aktif': + return Colors.green; + case 'Terjadwal': + return Colors.blue; + case 'Selesai': + return Colors.grey; + default: + return Colors.orange; + } + } + List _getCurrentJadwalList() { switch (title) { case 'Hari Ini': @@ -78,150 +138,201 @@ class JadwalSectionWidget extends StatelessWidget { } Widget _buildJadwalItem(TextTheme textTheme, PenyaluranBantuanModel jadwal) { - Color statusColor; - switch (status) { - case 'Aktif': - statusColor = Colors.green; - break; - case 'Terjadwal': - statusColor = Colors.blue; - break; - case 'Selesai': - statusColor = Colors.grey; - break; - default: - statusColor = Colors.orange; - } + Color statusColor = _getStatusColor(); - // Format tanggal - String formattedDate = jadwal.tanggalPenyaluran != null - ? DateFormat('dd MMMM yyyy').format(jadwal.tanggalPenyaluran!) + // Format tanggal dan waktu + String formattedDateTime = jadwal.tanggalPenyaluran != null + ? "${DateFormat('dd MMM yyyy').format(jadwal.tanggalPenyaluran!)} ${DateFormat('HH:mm').format(jadwal.tanggalPenyaluran!)}" : 'Belum ditentukan'; - // Format waktu - String formattedTime = jadwal.tanggalPenyaluran != null - ? DateFormat('HH:mm').format(jadwal.tanggalPenyaluran!) - : '-'; - // Dapatkan nama lokasi dan kategori String lokasiName = controller.getLokasiPenyaluranName(jadwal.lokasiPenyaluranId); String kategoriName = controller.getKategoriBantuanName(jadwal.kategoriBantuanId); - return GestureDetector( - onTap: () { - // Navigasi ke halaman pelaksanaan penyaluran dengan data jadwal - Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwal); - }, - child: Container( - width: double.infinity, - margin: const EdgeInsets.only(bottom: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.grey.withAlpha(26), - spreadRadius: 1, - blurRadius: 3, - offset: const Offset(0, 1), - ), - ], + return Card( + margin: const EdgeInsets.only(bottom: 12), + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + side: BorderSide( + color: statusColor.withOpacity(0.3), + width: 1, ), + ), + child: InkWell( + borderRadius: BorderRadius.circular(12), + onTap: () { + Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwal); + }, child: Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ + // Container( + // padding: const EdgeInsets.all(10), + // decoration: BoxDecoration( + // color: statusColor.withOpacity(0.1), + // borderRadius: BorderRadius.circular(10), + // ), + // child: Icon( + // _getStatusIcon(), + // color: statusColor, + // size: 24, + // ), + // ), + // const SizedBox(width: 12), Expanded( - child: Text( - jadwal.nama ?? 'Tanpa Nama', - style: textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.bold, - ), - overflow: TextOverflow.ellipsis, - ), - ), - Container( - padding: - const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - decoration: BoxDecoration( - color: statusColor.withAlpha(26), - borderRadius: BorderRadius.circular(12), - ), - child: Text( - status, - style: textTheme.bodySmall?.copyWith( - color: statusColor, - fontWeight: FontWeight.bold, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + jadwal.nama ?? 'Tanpa Nama', + style: textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.ellipsis, + ), + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + color: statusColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Text( + status, + style: textTheme.bodySmall?.copyWith( + color: statusColor, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + if (jadwal.deskripsi != null && + jadwal.deskripsi!.isNotEmpty) ...[ + const SizedBox(height: 4), + Text( + jadwal.deskripsi!, + style: textTheme.bodyMedium, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ], ), ), ], ), - const SizedBox(height: 8), - if (jadwal.deskripsi != null && jadwal.deskripsi!.isNotEmpty) ...[ - Text( - jadwal.deskripsi!, - style: textTheme.bodyMedium, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 8), - ], - Text( - 'Lokasi: $lokasiName', - style: textTheme.bodyMedium, + const Divider(height: 24), + _buildInfoItem( + Icons.location_on_outlined, + 'Lokasi', + lokasiName, + textTheme, ), - const SizedBox(height: 4), - Text( - 'Kategori: $kategoriName', - style: textTheme.bodyMedium, - ), - const SizedBox(height: 4), - Text( - 'Tanggal: $formattedDate', - style: textTheme.bodyMedium, - ), - const SizedBox(height: 4), - Text( - 'Waktu: $formattedTime', - style: textTheme.bodyMedium, - ), - if (jadwal.jumlahPenerima != null) ...[ - const SizedBox(height: 4), - Text( - 'Jumlah Penerima: ${jadwal.jumlahPenerima}', - style: textTheme.bodyMedium, - ), - ], const SizedBox(height: 8), Row( - mainAxisAlignment: MainAxisAlignment.end, children: [ - Text( - 'Lihat Detail', - style: textTheme.bodySmall?.copyWith( - color: Colors.blue, - fontWeight: FontWeight.bold, + Expanded( + child: _buildInfoItem( + Icons.category_outlined, + 'Kategori', + kategoriName, + textTheme, ), ), - const SizedBox(width: 4), - const Icon( - Icons.arrow_forward_ios, - size: 12, - color: Colors.blue, + Expanded( + child: _buildInfoItem( + Icons.event, + 'Jadwal', + formattedDateTime, + textTheme, + ), ), ], ), + if (jadwal.jumlahPenerima != null) ...[ + const SizedBox(height: 8), + _buildInfoItem( + Icons.people_outline, + 'Jumlah Penerima', + '${jadwal.jumlahPenerima}', + textTheme, + ), + ], + const SizedBox(height: 8), + Align( + alignment: Alignment.centerRight, + child: TextButton.icon( + onPressed: () { + Get.toNamed(Routes.pelaksanaanPenyaluran, + arguments: jadwal); + }, + icon: const Icon(Icons.info_outline, size: 16), + label: const Text('Lihat Detail'), + style: TextButton.styleFrom( + foregroundColor: AppTheme.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 8), + visualDensity: VisualDensity.compact, + ), + ), + ), ], ), ), ), ); } + + Widget _buildInfoItem( + IconData icon, + String label, + String value, + TextTheme textTheme, + ) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + icon, + size: 16, + color: Colors.grey.shade600, + ), + const SizedBox(width: 4), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + label, + style: textTheme.bodySmall?.copyWith( + color: Colors.grey.shade600, + ), + ), + Text( + value, + style: textTheme.bodyMedium, + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + ], + ), + ), + ], + ); + } }