113 lines
3.9 KiB
Dart
113 lines
3.9 KiB
Dart
// lib/features/home/tabs/dashboard_tab.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/models/academic_history_model.dart';
|
|
import 'package:smpn1_lengkong/features/home/widgets/home_app_bar.dart';
|
|
import 'package:smpn1_lengkong/features/home/widgets/home_status_card.dart';
|
|
import 'package:smpn1_lengkong/features/home/widgets/home_menu_grid.dart';
|
|
import 'package:smpn1_lengkong/core/service/student_service.dart';
|
|
|
|
class DashboardTab extends StatefulWidget {
|
|
final StudentModel student;
|
|
final String viewingClass;
|
|
final String viewingYear;
|
|
final VoidCallback onRefresh; // Callback untuk memberitahu parent agar ambil data ulang
|
|
|
|
const DashboardTab({
|
|
super.key,
|
|
required this.student,
|
|
required this.viewingClass,
|
|
required this.viewingYear,
|
|
required this.onRefresh,
|
|
});
|
|
|
|
@override
|
|
State<DashboardTab> createState() => _DashboardTabState();
|
|
}
|
|
|
|
class _DashboardTabState extends State<DashboardTab> {
|
|
/// Fungsi untuk menangani Pull-to-Refresh
|
|
Future<void> _handleRefresh() async {
|
|
try {
|
|
// Memicu fungsi refresh yang ada di HomeScreen
|
|
widget.onRefresh();
|
|
|
|
// Memberikan sedikit delay agar animasi loading terlihat smooth
|
|
await Future.delayed(const Duration(milliseconds: 800));
|
|
} catch (e) {
|
|
if (mounted) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text("Gagal memperbarui data: $e")),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// 1. Mencari data history yang sesuai dengan kelas yang sedang dilihat
|
|
final currentHistory = widget.student.history.firstWhere(
|
|
(h) => h.className == widget.viewingClass,
|
|
orElse: () => AcademicHistory(
|
|
className: widget.viewingClass,
|
|
academicYear: widget.viewingYear,
|
|
averageScore: 0,
|
|
category: '-',
|
|
),
|
|
);
|
|
|
|
// 2. HITUNG POIN SECARA DINAMIS (Berdasarkan kelas yang dipilih)
|
|
final int dynamicTotalPoints = widget.student.violationHistory
|
|
.where((v) => v.className == widget.viewingClass)
|
|
.fold(0, (sum, item) => sum + item.point);
|
|
|
|
return RefreshIndicator(
|
|
onRefresh: _handleRefresh,
|
|
color: AppColors.primaryBlue,
|
|
backgroundColor: Colors.white,
|
|
edgeOffset: 20, // Menyesuaikan posisi munculnya indikator
|
|
child: CustomScrollView(
|
|
// AlwaysScrollableScrollPhysics wajib ada agar RefreshIndicator berfungsi
|
|
physics: const AlwaysScrollableScrollPhysics(
|
|
parent: BouncingScrollPhysics(),
|
|
),
|
|
slivers: [
|
|
HomeAppBar(
|
|
studentName: widget.student.name,
|
|
className: widget.viewingClass,
|
|
academicYear: currentHistory.academicYear,
|
|
),
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(20.w),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Mengirimkan totalPoin hasil perhitungan dinamis
|
|
HomeStatusCard(
|
|
category: currentHistory.category,
|
|
studentId: widget.student.id,
|
|
studentName: widget.student.name,
|
|
className: widget.viewingClass,
|
|
totalPoin: dynamicTotalPoints,
|
|
averageScore: currentHistory.averageScore.toString(),
|
|
),
|
|
SizedBox(height: 24.h),
|
|
const Text(
|
|
"Menu Utama",
|
|
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
|
),
|
|
SizedBox(height: 16.h),
|
|
HomeMenuGrid(student: widget.student),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
} |