TIF_E41221079/lib/features/home/widgets/home_menu_grid.dart

178 lines
5.5 KiB
Dart

import 'package:cloud_firestore/cloud_firestore.dart';
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';
class HomeMenuGrid extends StatelessWidget {
final StudentModel student;
const HomeMenuGrid({super.key, required this.student});
@override
Widget build(BuildContext context) {
final int filteredPoints = student.violationHistory
.where((v) => v.className == student.className)
.fold(0, (sum, item) => sum + item.point);
return GridView.count(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 2,
crossAxisSpacing: 16.w,
mainAxisSpacing: 16.h,
childAspectRatio: 1.1,
children: [
_menuItem(
context,
Icons.analytics_rounded,
"Nilai Akademik",
"Lihat transkrip",
Colors.blueAccent,
AppRoutes.academic,
student,
),
_menuItem(
context,
Icons.rule_rounded,
"Kedisiplinan",
"$filteredPoints Poin",
Colors.orangeAccent,
AppRoutes.discipline,
student,
),
_menuItem(
context,
Icons.calendar_month_rounded,
"Kehadiran",
"Rekap absensi",
Colors.green,
AppRoutes.attendance,
student,
),
// Integrasi StreamBuilder untuk Badge Notifikasi
StreamBuilder<QuerySnapshot>(
stream:
FirebaseFirestore.instance
.collection('notifikasi')
.where('id_user', isEqualTo: student.id)
.where(
'kelas',
isEqualTo: student.className,
) // TAMBAHKAN FILTER INI
.where('status', isEqualTo: 'unread')
.snapshots(),
builder: (context, snapshot) {
int unreadCount = 0;
if (snapshot.hasData) {
unreadCount = snapshot.data!.docs.length;
}
return _menuItem(
context,
Icons.notifications_active_rounded,
"Pemberitahuan",
unreadCount > 0
? "$unreadCount Pemberitahuan Baru"
: "Info Sekolah",
Colors.purpleAccent,
AppRoutes.notification,
student,
badgeCount: unreadCount,
);
},
),
],
);
}
Widget _menuItem(
BuildContext context,
IconData icon,
String title,
String sub,
Color color,
String route,
dynamic args, {
int badgeCount = 0,
}) {
return Material(
color: Colors.white,
borderRadius: BorderRadius.circular(16.r),
child: InkWell(
onTap: () => Navigator.pushNamed(context, route, arguments: args),
borderRadius: BorderRadius.circular(16.r),
child: Stack(
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.r),
border: Border.all(color: Colors.grey.shade100),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(icon, color: color, size: 28.sp),
),
SizedBox(height: 12.h),
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14.sp,
color: AppColors.textPrimary,
),
),
Text(
sub,
style: TextStyle(
fontSize: 12.sp,
color:
badgeCount > 0
? AppColors.dangerRed
: AppColors.textSecondary,
fontWeight:
badgeCount > 0 ? FontWeight.bold : FontWeight.normal,
),
),
],
),
),
if (badgeCount > 0)
Positioned(
top: 12.h,
right: 12.w,
child: Container(
padding: EdgeInsets.all(6.w),
decoration: const BoxDecoration(
color: AppColors.dangerRed,
shape: BoxShape.circle,
),
constraints: BoxConstraints(minWidth: 22.w, minHeight: 22.w),
child: Text(
badgeCount > 9 ? "9+" : badgeCount.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 10.sp,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
),
],
),
),
);
}
}