import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:smpn1_lengkong/core/constants/app_colors.dart'; import 'package:smpn1_lengkong/core/models/student_model.dart'; import 'package:smpn1_lengkong/core/routes/app_routes.dart'; import 'package:smpn1_lengkong/core/service/student_service.dart'; import 'package:smpn1_lengkong/main.dart'; class NotificationScreen extends StatefulWidget { const NotificationScreen({super.key}); @override State createState() => _NotificationScreenState(); } class _NotificationScreenState extends State { late Future>> _notificationsFuture; late StudentModel student; bool _isInitialized = false; @override void didChangeDependencies() { super.didChangeDependencies(); if (!_isInitialized) { student = ModalRoute.of(context)!.settings.arguments as StudentModel; _notificationsFuture = StudentService().getNotifications( student.id, student.className, ); _isInitialized = true; } } Future _refreshData() async { setState(() { _notificationsFuture = StudentService().getNotifications( student.id, student.className, ); }); await _notificationsFuture; } Future _handleReadAll() async { await StudentService().markAllAsRead(student.id, student.className); await _refreshData(); if (mounted) {} } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.backgroundWhite, appBar: AppBar( title: Text( "Pemberitahuan Kelas ${student.className}", style: const TextStyle(color: Colors.white), ), backgroundColor: AppColors.primaryBlue, foregroundColor: Colors.white, elevation: 0, ), body: RefreshIndicator( onRefresh: _refreshData, color: AppColors.primaryBlue, child: FutureBuilder>>( future: _notificationsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Center( child: Text("Terjadi kesalahan: ${snapshot.error}"), ); } // Ambil data dan lakukan pengurutan (Sorting) final List> notifications = snapshot.data ?? []; if (notifications.isNotEmpty) { notifications.sort((a, b) { // Parsing tanggal, berikan fallback waktu sekarang jika null/error DateTime dateA = DateTime.tryParse(a['tanggal']?.toString() ?? '') ?? DateTime.now(); DateTime dateB = DateTime.tryParse(b['tanggal']?.toString() ?? '') ?? DateTime.now(); // b.compareTo(a) untuk urutan descending (Terbaru -> Terlama) return dateB.compareTo(dateA); }); } final int unreadCount = notifications.where((n) => n['status'] == 'unread').length; if (notifications.isEmpty) { return Stack( children: [ _buildEmptyState(), ListView(physics: const AlwaysScrollableScrollPhysics()), ], ); } return CustomScrollView( physics: const AlwaysScrollableScrollPhysics( parent: BouncingScrollPhysics(), ), slivers: [ SliverToBoxAdapter( child: Padding( padding: EdgeInsets.fromLTRB(20.w, 24.h, 20.w, 16.h), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( unreadCount > 0 ? "Anda memiliki $unreadCount pemberitahuan baru" : "Semua pemberitahuan sudah diperiksa", style: TextStyle( fontSize: 13.sp, color: AppColors.textSecondary, ), ), ], ), if (unreadCount > 0) GestureDetector( onTap: _handleReadAll, child: Container( padding: EdgeInsets.symmetric( horizontal: 12.w, vertical: 8.h, ), decoration: BoxDecoration( color: AppColors.primaryBlue.withOpacity(0.08), borderRadius: BorderRadius.circular(10.r), ), child: Text( "Baca Semua", style: TextStyle( color: AppColors.primaryBlue, fontWeight: FontWeight.bold, fontSize: 12.sp, ), ), ), ), ], ), ), ), SliverPadding( padding: EdgeInsets.symmetric(horizontal: 20.w), sliver: SliverList( delegate: SliverChildBuilderDelegate((context, index) { final item = notifications[index]; return Padding( padding: EdgeInsets.only(bottom: 12.h), child: _buildNotificationCard(context, item), ); }, childCount: notifications.length), ), ), SliverToBoxAdapter(child: SizedBox(height: 30.h)), ], ); }, ), ), ); } Widget _buildNotificationCard( BuildContext context, Map item, ) { final bool isUnread = item['status'] == 'unread'; return InkWell( onTap: () async { if (isUnread) { await StudentService().markNotificationAsRead(item['id']); await _refreshData(); } // Gunakan navigatorKey sebagai pengganti Navigator.pushNamed(context, ...) navigatorKey.currentState?.pushNamed( AppRoutes.notificationDetail, arguments: { 'title': item['title'] ?? 'Pengumuman', 'body': item['body'] ?? '', 'date': item['tanggal'] ?? '', }, ); }, borderRadius: BorderRadius.circular(16.r), child: Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16.r), border: Border.all( color: isUnread ? AppColors.primaryBlue.withOpacity(0.3) : Colors.grey.shade100, width: isUnread ? 1.5 : 1, ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.02), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: isUnread ? AppColors.primaryBlue.withOpacity(0.1) : Colors.grey.shade50, borderRadius: BorderRadius.circular(12.r), ), child: Icon( Icons.notifications_active_outlined, color: isUnread ? AppColors.primaryBlue : Colors.grey.shade400, size: 24.sp, ), ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( item['title'] ?? '-', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: isUnread ? FontWeight.w800 : FontWeight.w600, fontSize: 15.sp, color: AppColors.textPrimary, ), ), ), if (isUnread) Container( width: 8.w, height: 8.w, decoration: const BoxDecoration( color: AppColors.dangerRed, shape: BoxShape.circle, ), ), ], ), SizedBox(height: 4.h), Text( item['body'] ?? '-', maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( color: isUnread ? Colors.black87 : Colors.grey.shade600, fontSize: 13.sp, height: 1.5, ), ), SizedBox(height: 10.h), Row( children: [ Icon( Icons.access_time_rounded, size: 12.sp, color: Colors.grey, ), SizedBox(width: 4.w), Text( item['tanggal']?.toString().length == 16 ? item['tanggal'] : (item['tanggal']?.toString().substring(0, 16) ?? ''), style: TextStyle( fontSize: 11.sp, color: Colors.grey, fontWeight: FontWeight.w500, ), ), ], ), ], ), ), ], ), ), ); } Widget _buildEmptyState() { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.notifications_none_rounded, size: 60.sp, color: Colors.grey.shade300, ), SizedBox(height: 16.h), Text( "Belum Ada Notifikasi", style: TextStyle(color: Colors.grey.shade500), ), ], ), ); } }