feat: show missing requirements on dashboard student hover, fix student grade/sec resolution, and scope teacher stats to assigned sections
This commit is contained in:
1 parent
42d97dd32a
commit
f2c259891d
5 files changed
+226
-157
No files matched your search
+5
-2
@@ -431,9 +431,12 @@ Files backup/restore - mirror mode or zip -->
|
||||
|
||||
# TEACHERS & ACADEMIC SETUP
|
||||
- hide or remove from the list all users have deactivated status -->
|
||||
|
||||
<!--
|
||||
# STUDENT SCREEN
|
||||
- student profile modal -> make the lrn can be copy add icon button to automatically copy
|
||||
- student profile modal -> make the lrn can be copy add icon button to automatically copy -->
|
||||
|
||||
# DASHBOARD SCREEN
|
||||
- "Top students by documents" and "needs attention" view all -> list of students count of missing documents when hover shows missing requirements separate jhs shs
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ class StudentDocCount {
|
||||
final int uploadedCount;
|
||||
final int totalRequired;
|
||||
final int missingCount;
|
||||
final List<String> missingRequirements;
|
||||
final double percent;
|
||||
final int? gradeLevel;
|
||||
final String category;
|
||||
@@ -242,6 +243,7 @@ class StudentDocCount {
|
||||
this.uploadedCount = 0,
|
||||
this.totalRequired = 0,
|
||||
this.missingCount = 0,
|
||||
this.missingRequirements = const [],
|
||||
this.percent = 0.0,
|
||||
this.gradeLevel,
|
||||
this.category = 'JHS',
|
||||
@@ -256,6 +258,11 @@ class StudentDocCount {
|
||||
final pct = (j['percent'] as num?)?.toDouble() ??
|
||||
(total == 0 ? (uploaded > 0 ? 1.0 : 0.0) : uploaded / total);
|
||||
|
||||
final missingReqs = (j['missingRequirements'] as List<dynamic>?)
|
||||
?.map((e) => e.toString())
|
||||
.toList() ??
|
||||
const [];
|
||||
|
||||
return StudentDocCount(
|
||||
id: (j['id'] as num?)?.toInt() ?? 0,
|
||||
name: j['name'] as String? ?? '',
|
||||
@@ -263,6 +270,7 @@ class StudentDocCount {
|
||||
uploadedCount: uploaded,
|
||||
totalRequired: total,
|
||||
missingCount: missing,
|
||||
missingRequirements: missingReqs,
|
||||
percent: pct,
|
||||
gradeLevel: (j['gradeLevel'] as num?)?.toInt(),
|
||||
category: j['category'] as String? ?? 'JHS',
|
||||
|
||||
@@ -1633,16 +1633,49 @@ class _StudentDocCard extends StatelessWidget {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${s.uploadedCount} / ${s.totalRequired} (${s.missingCount} missing)',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: s.missingCount == 0
|
||||
? (isDark ? const Color(0xFF66BB6A) : AppColors.primaryGreen)
|
||||
: (isTop
|
||||
? Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7)
|
||||
: Colors.orange.shade700),
|
||||
Tooltip(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark ? const Color(0xFF1E293B) : const Color(0xFF0F172A),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.2),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
textStyle: const TextStyle(fontSize: 11, color: Colors.white, height: 1.4),
|
||||
message: s.missingCount == 0
|
||||
? '[${s.category}] All ${s.totalRequired} required documents submitted! ✅'
|
||||
: '[${s.category} Missing Requirements (${s.missingCount})]:\n• ${s.missingRequirements.join('\n• ')}',
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${s.uploadedCount} / ${s.totalRequired} (${s.missingCount} missing)',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: s.missingCount == 0
|
||||
? (isDark ? const Color(0xFF66BB6A) : AppColors.primaryGreen)
|
||||
: (isTop
|
||||
? Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7)
|
||||
: Colors.orange.shade700),
|
||||
),
|
||||
),
|
||||
if (s.missingCount > 0) ...[
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
Icons.info_outline_rounded,
|
||||
size: 12,
|
||||
color: s.missingCount == 0
|
||||
? AppColors.primaryGreen
|
||||
: Colors.orange.shade700,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -2060,23 +2093,54 @@ class _StudentDocRankingModalState extends State<_StudentDocRankingModal> {
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
|
||||
// Status Pill
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
// Status Pill with hover tooltip showing missing requirements separated by category
|
||||
Tooltip(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isComplete
|
||||
? AppColors.primaryGreen.withValues(alpha: isDark ? 0.25 : 0.12)
|
||||
: Colors.orange.withValues(alpha: isDark ? 0.25 : 0.12),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
color: isDark ? const Color(0xFF1E293B) : const Color(0xFF0F172A),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.2),
|
||||
blurRadius: 6,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
isComplete ? 'Complete' : '${s.missingCount} Missing',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
textStyle: const TextStyle(fontSize: 11, color: Colors.white, height: 1.4),
|
||||
message: isComplete
|
||||
? '[${s.category}] All ${s.totalRequired} required documents submitted! ✅'
|
||||
: '[${s.category} Missing Requirements (${s.missingCount})]:\n• ${s.missingRequirements.join('\n• ')}',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: isComplete
|
||||
? (isDark ? const Color(0xFF66BB6A) : AppColors.primaryGreen)
|
||||
: (isDark ? Colors.orange.shade300 : Colors.orange.shade800),
|
||||
? AppColors.primaryGreen.withValues(alpha: isDark ? 0.25 : 0.12)
|
||||
: Colors.orange.withValues(alpha: isDark ? 0.25 : 0.12),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
isComplete ? 'Complete' : '${s.missingCount} Missing',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: isComplete
|
||||
? (isDark ? const Color(0xFF66BB6A) : AppColors.primaryGreen)
|
||||
: (isDark ? Colors.orange.shade300 : Colors.orange.shade800),
|
||||
),
|
||||
),
|
||||
if (!isComplete) ...[
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
Icons.info_outline_rounded,
|
||||
size: 11,
|
||||
color: isDark ? Colors.orange.shade300 : Colors.orange.shade800,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user