Perbarui model PenyaluranBantuan dan tampilan terkait untuk mendukung kategori bantuan dan informasi tambahan

- Ganti properti 'judul' menjadi 'nama' di model PenyaluranBantuanModel
- Tambahkan properti baru: kategoriBantuanId, tanggalPermintaan, jumlahPenerima, dan skemaId
- Perbarui tampilan JadwalSectionWidget dan PermintaanPenjadwalanSummaryWidget untuk menggunakan PenyaluranBantuanModel
- Tambahkan format tanggal dan waktu di tampilan
- Perbarui controller untuk memuat data lokasi penyaluran dan kategori bantuan
This commit is contained in:
Khafidh Fuadi
2025-03-13 19:56:17 +07:00
parent d9cc7aaf92
commit 0223d457a5
8 changed files with 243 additions and 78 deletions

View File

@ -2,7 +2,7 @@ import 'dart:convert';
class PenyaluranBantuanModel { class PenyaluranBantuanModel {
final String? id; final String? id;
final String? judul; final String? nama;
final String? deskripsi; final String? deskripsi;
final String? lokasiPenyaluranId; final String? lokasiPenyaluranId;
final String? petugasId; final String? petugasId;
@ -10,12 +10,16 @@ class PenyaluranBantuanModel {
final String? alasanPenolakan; final String? alasanPenolakan;
final DateTime? tanggalPenjadwalan; final DateTime? tanggalPenjadwalan;
final DateTime? tanggalPenyaluran; final DateTime? tanggalPenyaluran;
final String? kategoriBantuanId;
final DateTime? tanggalPermintaan;
final int? jumlahPenerima;
final String? skemaId;
final DateTime? createdAt; final DateTime? createdAt;
final DateTime? updatedAt; final DateTime? updatedAt;
PenyaluranBantuanModel({ PenyaluranBantuanModel({
this.id, this.id,
this.judul, this.nama,
this.deskripsi, this.deskripsi,
this.lokasiPenyaluranId, this.lokasiPenyaluranId,
this.petugasId, this.petugasId,
@ -23,6 +27,10 @@ class PenyaluranBantuanModel {
this.alasanPenolakan, this.alasanPenolakan,
this.tanggalPenjadwalan, this.tanggalPenjadwalan,
this.tanggalPenyaluran, this.tanggalPenyaluran,
this.kategoriBantuanId,
this.tanggalPermintaan,
this.jumlahPenerima,
this.skemaId,
this.createdAt, this.createdAt,
this.updatedAt, this.updatedAt,
}); });
@ -35,7 +43,7 @@ class PenyaluranBantuanModel {
factory PenyaluranBantuanModel.fromJson(Map<String, dynamic> json) => factory PenyaluranBantuanModel.fromJson(Map<String, dynamic> json) =>
PenyaluranBantuanModel( PenyaluranBantuanModel(
id: json["id"], id: json["id"],
judul: json["judul"], nama: json["nama"],
deskripsi: json["deskripsi"], deskripsi: json["deskripsi"],
lokasiPenyaluranId: json["lokasi_penyaluran_id"], lokasiPenyaluranId: json["lokasi_penyaluran_id"],
petugasId: json["petugas_id"], petugasId: json["petugas_id"],
@ -47,6 +55,12 @@ class PenyaluranBantuanModel {
tanggalPenyaluran: json["tanggal_penyaluran"] != null tanggalPenyaluran: json["tanggal_penyaluran"] != null
? DateTime.parse(json["tanggal_penyaluran"]) ? DateTime.parse(json["tanggal_penyaluran"])
: null, : null,
kategoriBantuanId: json["kategori_bantuan_id"],
tanggalPermintaan: json["tanggal_permintaan"] != null
? DateTime.parse(json["tanggal_permintaan"])
: null,
jumlahPenerima: json["jumlah_penerima"],
skemaId: json["skema_id"],
createdAt: json["created_at"] != null createdAt: json["created_at"] != null
? DateTime.parse(json["created_at"]) ? DateTime.parse(json["created_at"])
: null, : null,
@ -57,7 +71,7 @@ class PenyaluranBantuanModel {
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"judul": judul, "nama": nama,
"deskripsi": deskripsi, "deskripsi": deskripsi,
"lokasi_penyaluran_id": lokasiPenyaluranId, "lokasi_penyaluran_id": lokasiPenyaluranId,
"petugas_id": petugasId, "petugas_id": petugasId,
@ -65,6 +79,10 @@ class PenyaluranBantuanModel {
"alasan_penolakan": alasanPenolakan, "alasan_penolakan": alasanPenolakan,
"tanggal_penjadwalan": tanggalPenjadwalan?.toIso8601String(), "tanggal_penjadwalan": tanggalPenjadwalan?.toIso8601String(),
"tanggal_penyaluran": tanggalPenyaluran?.toIso8601String(), "tanggal_penyaluran": tanggalPenyaluran?.toIso8601String(),
"kategori_bantuan_id": kategoriBantuanId,
"tanggal_permintaan": tanggalPermintaan?.toIso8601String(),
"jumlah_penerima": jumlahPenerima,
"skema_id": skemaId,
"created_at": createdAt?.toIso8601String(), "created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(), "updated_at": updatedAt?.toIso8601String(),
}; };

View File

@ -1,12 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
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/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';
class JadwalSectionWidget extends StatelessWidget { class JadwalSectionWidget extends StatelessWidget {
final JadwalPenyaluranController controller; final JadwalPenyaluranController controller;
final String title; final String title;
final List<dynamic> jadwalList; final List<PenyaluranBantuanModel> jadwalList;
final String status; final String status;
const JadwalSectionWidget({ const JadwalSectionWidget({
@ -62,7 +64,7 @@ class JadwalSectionWidget extends StatelessWidget {
); );
} }
List<dynamic> _getCurrentJadwalList() { List<PenyaluranBantuanModel> _getCurrentJadwalList() {
switch (title) { switch (title) {
case 'Hari Ini': case 'Hari Ini':
return controller.jadwalHariIni.toList(); return controller.jadwalHariIni.toList();
@ -75,11 +77,7 @@ class JadwalSectionWidget extends StatelessWidget {
} }
} }
Widget _buildJadwalItem(TextTheme textTheme, dynamic jadwal) { Widget _buildJadwalItem(TextTheme textTheme, PenyaluranBantuanModel jadwal) {
// Konversi jadwal ke Map jika itu adalah PenyaluranBantuanModel
final Map<String, dynamic> jadwalData =
jadwal is Map<String, dynamic> ? jadwal : jadwal.toJson();
Color statusColor; Color statusColor;
switch (status) { switch (status) {
case 'Aktif': case 'Aktif':
@ -95,10 +93,26 @@ class JadwalSectionWidget extends StatelessWidget {
statusColor = Colors.orange; statusColor = Colors.orange;
} }
// Format tanggal
String formattedDate = jadwal.tanggalPenyaluran != null
? DateFormat('dd MMMM yyyy').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( return GestureDetector(
onTap: () { onTap: () {
// Navigasi ke halaman pelaksanaan penyaluran dengan data jadwal // Navigasi ke halaman pelaksanaan penyaluran dengan data jadwal
Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwalData); Get.toNamed(Routes.pelaksanaanPenyaluran, arguments: jadwal);
}, },
child: Container( child: Container(
width: double.infinity, width: double.infinity,
@ -123,10 +137,13 @@ class JadwalSectionWidget extends StatelessWidget {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Expanded(
jadwalData['lokasi'] ?? '', child: Text(
style: textTheme.titleMedium?.copyWith( jadwal.nama ?? 'Tanpa Nama',
fontWeight: FontWeight.bold, style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
), ),
), ),
Container( Container(
@ -147,24 +164,38 @@ class JadwalSectionWidget extends StatelessWidget {
], ],
), ),
const SizedBox(height: 8), 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( Text(
'Kategori Bantuan: ${jadwalData['kategori_bantuan'] ?? ''}', 'Lokasi: $lokasiName',
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Tanggal: ${jadwalData['tanggal'] ?? ''}', 'Kategori: $kategoriName',
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Waktu: ${jadwalData['waktu'] ?? ''}', 'Tanggal: $formattedDate',
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
), ),
if (jadwalData['jumlah_penerima'] != null) ...[ const SizedBox(height: 4),
Text(
'Waktu: $formattedTime',
style: textTheme.bodyMedium,
),
if (jadwal.jumlahPenerima != null) ...[
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Jumlah Penerima: ${jadwalData['jumlah_penerima']}', 'Jumlah Penerima: ${jadwal.jumlahPenerima}',
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
), ),
], ],

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
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/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'; import 'package:penyaluran_app/app/theme/app_theme.dart';
@ -134,10 +136,16 @@ class PermintaanPenjadwalanSummaryWidget extends StatelessWidget {
}); });
} }
Widget _buildPermintaanPreview(TextTheme textTheme, dynamic permintaan) { Widget _buildPermintaanPreview(
// Konversi permintaan ke Map jika itu adalah PenyaluranBantuanModel TextTheme textTheme, PenyaluranBantuanModel permintaan) {
final Map<String, dynamic> permintaanData = // Format tanggal
permintaan is Map<String, dynamic> ? permintaan : permintaan.toJson(); String formattedDate = permintaan.tanggalPermintaan != null
? DateFormat('dd MMMM yyyy').format(permintaan.tanggalPermintaan!)
: 'Belum ditentukan';
// Dapatkan nama kategori
String kategoriName =
controller.getKategoriBantuanName(permintaan.kategoriBantuanId);
return Container( return Container(
width: double.infinity, width: double.infinity,
@ -155,7 +163,7 @@ class PermintaanPenjadwalanSummaryWidget extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
permintaanData['nama'] ?? '', permintaan.nama ?? 'Tanpa Nama',
style: textTheme.titleSmall?.copyWith( style: textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -180,13 +188,20 @@ class PermintaanPenjadwalanSummaryWidget extends StatelessWidget {
], ],
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
if (permintaan.deskripsi != null && permintaan.deskripsi!.isNotEmpty)
Text(
permintaan.deskripsi!,
style: textTheme.bodySmall,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
Text( Text(
'Kategori: ${permintaanData['kategori_bantuan'] ?? ''}', 'Kategori: $kategoriName',
style: textTheme.bodySmall, style: textTheme.bodySmall,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
Text( Text(
'Tanggal: ${permintaanData['tanggal_permintaan'] ?? ''}', 'Tanggal: $formattedDate',
style: textTheme.bodySmall, style: textTheme.bodySmall,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -120,7 +120,7 @@ class PermintaanPenjadwalanWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
permintaan.judul ?? '', permintaan.nama ?? '',
style: textTheme.titleMedium?.copyWith( style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -149,7 +149,7 @@ class PermintaanPenjadwalanWidget extends StatelessWidget {
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( Text(
'Jenis Bantuan: ${permintaan.judul ?? ''}', 'Jenis Bantuan: ${permintaan.kategoriBantuanId ?? ''}',
style: textTheme.bodyMedium, style: textTheme.bodyMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
@ -200,7 +200,7 @@ class PermintaanPenjadwalanWidget extends StatelessWidget {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: jadwal.id, value: jadwal.id,
child: Text( child: Text(
'${jadwal.tanggalPenjadwalan?.toString().substring(0, 10) ?? ''} - ${jadwal.lokasiPenyaluranId ?? ''} (${jadwal.judul ?? ''})'), '${jadwal.tanggalPenjadwalan?.toString().substring(0, 10) ?? ''} - ${jadwal.lokasiPenyaluranId ?? ''} (${jadwal.nama ?? ''})'),
); );
}).toList(); }).toList();
@ -220,7 +220,7 @@ class PermintaanPenjadwalanWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Anda akan mengkonfirmasi permintaan penjadwalan dari ${permintaan.judul}.'), 'Anda akan mengkonfirmasi permintaan penjadwalan dari ${permintaan.nama}.'),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text('Pilih jadwal penyaluran:'), const Text('Pilih jadwal penyaluran:'),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -290,7 +290,7 @@ class PermintaanPenjadwalanWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Anda akan menolak permintaan penjadwalan dari ${permintaan.judul}.'), 'Anda akan menolak permintaan penjadwalan dari ${permintaan.nama}.'),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text('Alasan penolakan:'), const Text('Alasan penolakan:'),
const SizedBox(height: 8), const SizedBox(height: 8),

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.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/data/models/lokasi_penyaluran_model.dart';
import 'package:penyaluran_app/app/data/models/kategori_bantuan_model.dart';
import 'package:penyaluran_app/app/data/models/user_model.dart'; import 'package:penyaluran_app/app/data/models/user_model.dart';
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart'; import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
import 'package:penyaluran_app/app/services/supabase_service.dart'; import 'package:penyaluran_app/app/services/supabase_service.dart';
@ -27,6 +29,12 @@ class JadwalPenyaluranController extends GetxController {
<PenyaluranBantuanModel>[].obs; <PenyaluranBantuanModel>[].obs;
final RxInt jumlahPermintaanPenjadwalan = 0.obs; final RxInt jumlahPermintaanPenjadwalan = 0.obs;
// Cache untuk lokasi penyaluran dan kategori bantuan
final RxMap<String, LokasiPenyaluranModel> lokasiPenyaluranCache =
<String, LokasiPenyaluranModel>{}.obs;
final RxMap<String, KategoriBantuanModel> kategoriBantuanCache =
<String, KategoriBantuanModel>{}.obs;
// Controller untuk pencarian // Controller untuk pencarian
final TextEditingController searchController = TextEditingController(); final TextEditingController searchController = TextEditingController();
@ -37,6 +45,8 @@ class JadwalPenyaluranController extends GetxController {
super.onInit(); super.onInit();
loadJadwalData(); loadJadwalData();
loadPermintaanPenjadwalanData(); loadPermintaanPenjadwalanData();
loadLokasiPenyaluranData();
loadKategoriBantuanData();
} }
@override @override
@ -92,6 +102,50 @@ class JadwalPenyaluranController extends GetxController {
} }
} }
Future<void> loadLokasiPenyaluranData() async {
try {
final lokasiData = await _supabaseService.getAllLokasiPenyaluran();
if (lokasiData != null) {
for (var lokasi in lokasiData) {
final lokasiModel = LokasiPenyaluranModel.fromJson(lokasi);
lokasiPenyaluranCache[lokasiModel.id] = lokasiModel;
}
}
} catch (e) {
print('Error loading lokasi penyaluran data: $e');
}
}
Future<void> loadKategoriBantuanData() async {
try {
final kategoriData = await _supabaseService.getAllKategoriBantuan();
if (kategoriData != null) {
for (var kategori in kategoriData) {
final kategoriModel = KategoriBantuanModel.fromJson(kategori);
if (kategoriModel.id != null) {
kategoriBantuanCache[kategoriModel.id!] = kategoriModel;
}
}
}
} catch (e) {
print('Error loading kategori bantuan data: $e');
}
}
// Mendapatkan nama lokasi penyaluran berdasarkan ID
String getLokasiPenyaluranName(String? lokasiId) {
if (lokasiId == null) return 'Lokasi tidak diketahui';
final lokasi = lokasiPenyaluranCache[lokasiId];
return lokasi?.nama ?? 'Lokasi tidak diketahui';
}
// Mendapatkan nama kategori bantuan berdasarkan ID
String getKategoriBantuanName(String? kategoriId) {
if (kategoriId == null) return 'Kategori tidak diketahui';
final kategori = kategoriBantuanCache[kategoriId];
return kategori?.nama ?? 'Kategori tidak diketahui';
}
Future<void> approveJadwal(String jadwalId) async { Future<void> approveJadwal(String jadwalId) async {
isLoading.value = true; isLoading.value = true;
try { try {
@ -176,6 +230,8 @@ class JadwalPenyaluranController extends GetxController {
try { try {
await loadJadwalData(); await loadJadwalData();
await loadPermintaanPenjadwalanData(); await loadPermintaanPenjadwalanData();
await loadLokasiPenyaluranData();
await loadKategoriBantuanData();
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }

View File

@ -10,50 +10,65 @@ class PenyaluranView extends GetView<JadwalPenyaluranController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SingleChildScrollView( return RefreshIndicator(
child: Padding( onRefresh: () => controller.refreshData(),
padding: const EdgeInsets.all(16.0), child: SingleChildScrollView(
child: Column( physics: const AlwaysScrollableScrollPhysics(),
crossAxisAlignment: CrossAxisAlignment.start, child: Padding(
children: [ padding: const EdgeInsets.all(16.0),
// Ringkasan jadwal child: Obx(() {
_buildJadwalSummary(context), if (controller.isLoading.value) {
return const Center(
child: Padding(
padding: EdgeInsets.all(32.0),
child: CircularProgressIndicator(),
),
);
}
const SizedBox(height: 20), return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Ringkasan jadwal
_buildJadwalSummary(context),
// Ringkasan Permintaan Penjadwalan const SizedBox(height: 20),
PermintaanPenjadwalanSummaryWidget(controller: controller),
const SizedBox(height: 20), // Ringkasan Permintaan Penjadwalan
PermintaanPenjadwalanSummaryWidget(controller: controller),
// Jadwal hari ini const SizedBox(height: 20),
JadwalSectionWidget(
controller: controller,
title: 'Hari Ini',
jadwalList: controller.jadwalHariIni,
status: 'Aktif',
),
const SizedBox(height: 20), // Jadwal hari ini
JadwalSectionWidget(
controller: controller,
title: 'Hari Ini',
jadwalList: controller.jadwalHariIni,
status: 'Aktif',
),
// Jadwal mendatang const SizedBox(height: 20),
JadwalSectionWidget(
controller: controller,
title: 'Mendatang',
jadwalList: controller.jadwalMendatang,
status: 'Terjadwal',
),
const SizedBox(height: 20), // Jadwal mendatang
JadwalSectionWidget(
controller: controller,
title: 'Mendatang',
jadwalList: controller.jadwalMendatang,
status: 'Terjadwal',
),
// Jadwal selesai const SizedBox(height: 20),
JadwalSectionWidget(
controller: controller, // Jadwal selesai
title: 'Selesai', JadwalSectionWidget(
jadwalList: controller.jadwalSelesai, controller: controller,
status: 'Selesai', title: 'Selesai',
), jadwalList: controller.jadwalSelesai,
], status: 'Selesai',
),
],
);
}),
), ),
), ),
); );

View File

@ -237,7 +237,8 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
); );
} }
Widget _buildPermintaanItem(BuildContext context, PenyaluranBantuanModel item) { Widget _buildPermintaanItem(
BuildContext context, PenyaluranBantuanModel item) {
Color statusColor = Colors.orange; Color statusColor = Colors.orange;
IconData statusIcon = Icons.pending_actions; IconData statusIcon = Icons.pending_actions;
@ -266,7 +267,7 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
item.judul ?? '', item.nama ?? '',
style: Theme.of(context).textTheme.titleMedium?.copyWith( style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -317,7 +318,7 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
context, context,
icon: Icons.category, icon: Icons.category,
label: 'Jenis Bantuan', label: 'Jenis Bantuan',
value: item.judul ?? '', value: item.nama ?? '',
), ),
), ),
], ],
@ -429,7 +430,7 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
return DropdownMenuItem<String>( return DropdownMenuItem<String>(
value: jadwal.id, value: jadwal.id,
child: Text( child: Text(
'${jadwal.tanggalPenjadwalan?.toString().substring(0, 10) ?? ''} - ${jadwal.lokasiPenyaluranId ?? ''} (${jadwal.judul ?? ''})'), '${jadwal.tanggalPenjadwalan?.toString().substring(0, 10) ?? ''} - ${jadwal.lokasiPenyaluranId ?? ''} (${jadwal.nama ?? ''})'),
); );
}).toList(); }).toList();
@ -449,7 +450,7 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Anda akan mengkonfirmasi permintaan penjadwalan dari ${permintaan.judul ?? 'Penerima'}.'), 'Anda akan mengkonfirmasi permintaan penjadwalan dari ${permintaan.nama ?? 'Penerima'}.'),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text('Pilih jadwal penyaluran:'), const Text('Pilih jadwal penyaluran:'),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -519,7 +520,7 @@ class PermintaanPenjadwalanView extends GetView<JadwalPenyaluranController> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
'Anda akan menolak permintaan penjadwalan dari ${permintaan.judul ?? 'Penerima'}.'), 'Anda akan menolak permintaan penjadwalan dari ${permintaan.nama ?? 'Penerima'}.'),
const SizedBox(height: 16), const SizedBox(height: 16),
const Text('Alasan penolakan:'), const Text('Alasan penolakan:'),
const SizedBox(height: 8), const SizedBox(height: 8),

View File

@ -249,13 +249,14 @@ class SupabaseService extends GetxService {
Future<List<Map<String, dynamic>>?> getJadwalMendatang() async { Future<List<Map<String, dynamic>>?> getJadwalMendatang() async {
try { try {
final now = DateTime.now(); final now = DateTime.now();
final tomorrow = final today = DateTime(now.year, now.month, now.day);
DateTime(now.year, now.month, now.day).add(const Duration(days: 1)); final week = today.add(const Duration(days: 7));
final response = await client final response = await client
.from('penyaluran_bantuan') .from('penyaluran_bantuan')
.select('*') .select('*')
.gte('tanggal_penyaluran', tomorrow.toIso8601String()) .gte('tanggal_penyaluran', today.toIso8601String())
.lt('tanggal_penyaluran', week.toIso8601String())
.inFilter('status', ['DISETUJUI', 'DIJADWALKAN']); .inFilter('status', ['DISETUJUI', 'DIJADWALKAN']);
return response; return response;
@ -961,4 +962,32 @@ class SupabaseService extends GetxService {
return null; return null;
} }
} }
// Metode untuk mendapatkan semua lokasi penyaluran
Future<List<Map<String, dynamic>>?> getAllLokasiPenyaluran() async {
try {
final response = await client
.from('lokasi_penyaluran')
.select('*')
.order('nama', ascending: true);
return response;
} catch (e) {
print('Error getting all lokasi penyaluran: $e');
return null;
}
}
// Metode untuk mendapatkan semua kategori bantuan
Future<List<Map<String, dynamic>>?> getAllKategoriBantuan() async {
try {
final response = await client
.from('kategori_bantuan')
.select('*')
.order('nama', ascending: true);
return response;
} catch (e) {
print('Error getting all kategori bantuan: $e');
return null;
}
}
} }