Files
penyaluran_app/lib/app/modules/petugas_desa/views/notifikasi_view.dart
Khafidh Fuadi 7c94b85434 Perbarui dependensi dan konfigurasi lokal untuk mendukung fitur baru
- Tambahkan dependensi baru: syncfusion_flutter_calendar, syncfusion_localizations, dan flutter_localizations di pubspec.yaml
- Perbarui konfigurasi lokal di main.dart untuk mendukung bahasa Indonesia dan menambahkan delegasi lokal
- Modifikasi model PenyaluranBantuan untuk memastikan format tanggal menggunakan UTC
- Perbarui tampilan dan logika di beberapa widget untuk meningkatkan pengalaman pengguna dan konsistensi data
- Ganti posisi snack bar dari bawah ke atas untuk notifikasi yang lebih baik
2025-03-14 08:09:54 +07:00

232 lines
7.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/petugas_desa_controller.dart';
import 'package:penyaluran_app/app/theme/app_theme.dart';
class NotifikasiView extends GetView<PetugasDesaController> {
const NotifikasiView({super.key});
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(
title: const Text('Notifikasi'),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Get.back(),
),
actions: [
IconButton(
icon: const Icon(Icons.check_circle_outline),
tooltip: 'Tandai Semua Dibaca',
onPressed: () {
// Implementasi untuk menandai semua notifikasi sebagai dibaca
},
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Notifikasi hari ini
_buildNotifikasiSection(
textTheme,
title: 'Hari Ini',
notifikasiList: [
{
'judul': 'Jadwal Penyaluran Baru',
'pesan':
'Jadwal penyaluran beras telah ditambahkan untuk hari ini',
'waktu': '08:30',
'dibaca': false,
},
{
'judul': 'Pengajuan Bantuan Baru',
'pesan':
'Ada 3 pengajuan bantuan baru yang perlu diverifikasi',
'waktu': '10:15',
'dibaca': false,
},
],
),
const SizedBox(height: 20),
// Notifikasi kemarin
_buildNotifikasiSection(
textTheme,
title: 'Kemarin',
notifikasiList: [
{
'judul': 'Laporan Penyaluran',
'pesan':
'Laporan penyaluran bantuan tanggal 14 April 2023 telah selesai',
'waktu': '16:45',
'dibaca': true,
},
{
'judul': 'Pengaduan Warga',
'pesan':
'Ada pengaduan baru dari warga yang perlu ditindaklanjuti',
'waktu': '14:20',
'dibaca': true,
},
],
),
const SizedBox(height: 20),
// Notifikasi minggu ini
_buildNotifikasiSection(
textTheme,
title: 'Minggu Ini',
notifikasiList: [
{
'judul': 'Perubahan Jadwal',
'pesan':
'Jadwal penyaluran bantuan di Balai Desa A diubah menjadi tanggal 17 April 2023',
'waktu': 'Sen, 13:00',
'dibaca': true,
},
{
'judul': 'Donasi Baru',
'pesan':
'PT Sejahtera telah mengirimkan donasi baru berupa sembako',
'waktu': 'Sen, 09:30',
'dibaca': true,
},
],
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Implementasi untuk menandai semua notifikasi sebagai dibaca
Get.snackbar(
'Notifikasi',
'Semua notifikasi telah ditandai sebagai dibaca',
snackPosition: SnackPosition.TOP,
backgroundColor: AppTheme.primaryColor,
colorText: Colors.white,
);
},
backgroundColor: AppTheme.primaryColor,
tooltip: 'Tandai Semua Dibaca',
child: const Icon(Icons.done_all),
),
);
}
Widget _buildNotifikasiSection(
TextTheme textTheme, {
required String title,
required List<Map<String, dynamic>> notifikasiList,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
...notifikasiList
.map((notifikasi) => _buildNotifikasiItem(textTheme, notifikasi)),
],
);
}
Widget _buildNotifikasiItem(
TextTheme textTheme, Map<String, dynamic> notifikasi) {
final bool dibaca = notifikasi['dibaca'] as bool;
return Container(
width: double.infinity,
margin: const EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: dibaca ? Colors.white : Colors.blue.shade50,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.grey.withAlpha(26),
spreadRadius: 1,
blurRadius: 3,
offset: const Offset(0, 1),
),
],
),
child: InkWell(
onTap: () {
// Implementasi untuk menandai notifikasi sebagai dibaca
if (!dibaca) {
Get.snackbar(
'Notifikasi',
'Notifikasi ditandai sebagai dibaca',
snackPosition: SnackPosition.TOP,
backgroundColor: AppTheme.primaryColor,
colorText: Colors.white,
);
}
},
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!dibaca)
Container(
width: 10,
height: 10,
margin: const EdgeInsets.only(top: 5, right: 10),
decoration: const BoxDecoration(
color: AppTheme.primaryColor,
shape: BoxShape.circle,
),
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
notifikasi['judul'] ?? '',
style: textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
Text(
notifikasi['waktu'] ?? '',
style: textTheme.bodySmall?.copyWith(
color: Colors.grey,
),
),
],
),
const SizedBox(height: 8),
Text(
notifikasi['pesan'] ?? '',
style: textTheme.bodyMedium,
),
],
),
),
],
),
),
),
);
}
}