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
This commit is contained in:
Khafidh Fuadi
2025-03-13 20:05:58 +07:00
parent 0223d457a5
commit b0310103fe

View File

@ -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/data/models/penyaluran_bantuan_model.dart';
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/jadwal_penyaluran_controller.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/routes/app_pages.dart';
import 'package:penyaluran_app/app/theme/app_theme.dart';
class JadwalSectionWidget extends StatelessWidget { class JadwalSectionWidget extends StatelessWidget {
final JadwalPenyaluranController controller; final JadwalPenyaluranController controller;
@ -26,13 +27,23 @@ class JadwalSectionWidget extends StatelessWidget {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row(
children: [
Icon(
_getStatusIcon(),
color: _getStatusColor(),
size: 24,
),
const SizedBox(width: 8),
Text( Text(
title, title,
style: textTheme.titleLarge?.copyWith( style: textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
const SizedBox(height: 10), ],
),
const SizedBox(height: 12),
Obx(() { Obx(() {
final currentJadwalList = _getCurrentJadwalList(); final currentJadwalList = _getCurrentJadwalList();
@ -44,12 +55,22 @@ class JadwalSectionWidget extends StatelessWidget {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Center( child: Center(
child: Text( child: Column(
children: [
Icon(
_getEmptyIcon(),
size: 40,
color: Colors.grey.shade400,
),
const SizedBox(height: 8),
Text(
'Tidak ada jadwal $title', 'Tidak ada jadwal $title',
style: textTheme.titleMedium?.copyWith( style: textTheme.titleMedium?.copyWith(
color: Colors.grey.shade600, 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<PenyaluranBantuanModel> _getCurrentJadwalList() { List<PenyaluranBantuanModel> _getCurrentJadwalList() {
switch (title) { switch (title) {
case 'Hari Ini': case 'Hari Ini':
@ -78,59 +138,56 @@ class JadwalSectionWidget extends StatelessWidget {
} }
Widget _buildJadwalItem(TextTheme textTheme, PenyaluranBantuanModel jadwal) { Widget _buildJadwalItem(TextTheme textTheme, PenyaluranBantuanModel jadwal) {
Color statusColor; Color statusColor = _getStatusColor();
switch (status) {
case 'Aktif':
statusColor = Colors.green;
break;
case 'Terjadwal':
statusColor = Colors.blue;
break;
case 'Selesai':
statusColor = Colors.grey;
break;
default:
statusColor = Colors.orange;
}
// Format tanggal // Format tanggal dan waktu
String formattedDate = jadwal.tanggalPenyaluran != null String formattedDateTime = jadwal.tanggalPenyaluran != null
? DateFormat('dd MMMM yyyy').format(jadwal.tanggalPenyaluran!) ? "${DateFormat('dd MMM yyyy').format(jadwal.tanggalPenyaluran!)} ${DateFormat('HH:mm').format(jadwal.tanggalPenyaluran!)}"
: 'Belum ditentukan'; : 'Belum ditentukan';
// Format waktu
String formattedTime = jadwal.tanggalPenyaluran != null
? DateFormat('HH:mm').format(jadwal.tanggalPenyaluran!)
: '-';
// Dapatkan nama lokasi dan kategori // Dapatkan nama lokasi dan kategori
String lokasiName = String lokasiName =
controller.getLokasiPenyaluranName(jadwal.lokasiPenyaluranId); controller.getLokasiPenyaluranName(jadwal.lokasiPenyaluranId);
String kategoriName = String kategoriName =
controller.getKategoriBantuanName(jadwal.kategoriBantuanId); controller.getKategoriBantuanName(jadwal.kategoriBantuanId);
return GestureDetector( 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: () { onTap: () {
// Navigasi ke halaman pelaksanaan penyaluran dengan data jadwal
Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: 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),
),
],
),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
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: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -147,10 +204,12 @@ class JadwalSectionWidget extends StatelessWidget {
), ),
), ),
Container( Container(
padding: padding: const EdgeInsets.symmetric(
const EdgeInsets.symmetric(horizontal: 8, vertical: 4), horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration( decoration: BoxDecoration(
color: statusColor.withAlpha(26), color: statusColor.withOpacity(0.1),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Text( child: Text(
@ -163,65 +222,117 @@ class JadwalSectionWidget extends StatelessWidget {
), ),
], ],
), ),
const SizedBox(height: 8), if (jadwal.deskripsi != null &&
if (jadwal.deskripsi != null && jadwal.deskripsi!.isNotEmpty) ...[ jadwal.deskripsi!.isNotEmpty) ...[
const SizedBox(height: 4),
Text( Text(
jadwal.deskripsi!, jadwal.deskripsi!,
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
const SizedBox(height: 8),
], ],
Text( ],
'Lokasi: $lokasiName',
style: textTheme.bodyMedium,
), ),
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 Divider(height: 24),
_buildInfoItem(
Icons.location_on_outlined,
'Lokasi',
lokasiName,
textTheme,
),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
Text( Expanded(
'Lihat Detail', child: _buildInfoItem(
style: textTheme.bodySmall?.copyWith( Icons.category_outlined,
color: Colors.blue, 'Kategori',
fontWeight: FontWeight.bold, kategoriName,
textTheme,
), ),
), ),
const SizedBox(width: 4), Expanded(
const Icon( child: _buildInfoItem(
Icons.arrow_forward_ios, Icons.event,
size: 12, 'Jadwal',
color: Colors.blue, 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,
),
],
),
),
],
);
}
} }