12 KiB
12 KiB
Flutter Multiple Kelas UI Documentation
Overview
Aplikasi mobile Flutter telah diupdate untuk menampilkan multiple kelas per santri dengan UI yang clean, informatif, dan responsive.
UI/UX Changes Summary
BEFORE (Version 1.0)
┌────────────────────────────────────┐
│ Profil Santri │
├────────────────────────────────────┤
│ [Foto Avatar] │
│ Ahmad Santoso │
│ S001 │
│ [Aktif] │
├────────────────────────────────────┤
│ 📋 Informasi Dasar │
│ ID Santri: S001 │
│ NIS: 2024001 │
│ Nama Lengkap: Ahmad Santoso │
│ Jenis Kelamin: Laki-laki │
│ Kelas: Lambatan B ← SINGLE KELAS
│ Status: Aktif │
└────────────────────────────────────┘
AFTER (Version 2.0)
┌────────────────────────────────────┐
│ Profil Santri │
├────────────────────────────────────┤
│ [Foto Avatar] │
│ Ahmad Santoso │
│ S001 │
│ ┌──────────────────────┐ │
│ │ 📚 Lambatan B │ ← Primary badge
│ └──────────────────────┘ │
│ +3 kelas lainnya ↓ ← Hint │
│ [Aktif] │
├────────────────────────────────────┤
│ 📋 Informasi Dasar │
│ ID Santri: S001 │
│ NIS: 2024001 │
│ Nama Lengkap: Ahmad Santoso │
│ Jenis Kelamin: Laki-laki │
│ Status: Aktif │ ← Kelas dihapus
├────────────────────────────────────┤
│ 🎓 Kelas yang Diikuti ← NEW SECTION
│ │
│ ▼ 🔵 PB (1 kelas) ← Expanded │
│ ├─ PB Putra A │
│ │ KLS001 │
│ │
│ ▼ 🟠 Lambatan (2 kelas) ← Expanded │
│ ├─ Lambatan B [⭐ Utama] ← Primary
│ │ KLS005 │
│ ├─ Lambatan A │
│ │ KLS006 │
│ │
│ ▶ 🟢 Cepatan (1 kelas) ← Collapsed│
│ │
│ ▶ 🔴 Hadist (1 kelas) ← Collapsed│
└────────────────────────────────────┘
New Features
1. Primary Kelas Badge (Header)
Location: Di header, antara ID Santri dan Status Badge
Features:
- Menampilkan kelas utama (primary kelas)
- Icon 📚 (sekolah)
- Background: Semi-transparent white
- Border: White border (subtle)
- Hint: "+X kelas lainnya" jika total kelas > 1
Code:
Widget _buildPrimaryKelasBadge() { ... }
2. Kelas yang Diikuti Section
Location: Setelah "Informasi Dasar", sebelum "Alamat & Asal"
Features:
- Section card dengan icon 🎓
- ExpansionTile per kelompok (collapsible)
- Color-coded badges per kelompok
- Sortir: Primary kelas di atas
- Badge "⭐ Utama" untuk primary kelas
Code:
Widget _buildKelasListSection() { ... }
Widget _buildKelompokExpansionTile(String kelompokName, List kelasItems) { ... }
3. Color Coding System
Setiap kelompok memiliki warna unik:
| Kelompok | Color | Hex Code | Icon |
|---|---|---|---|
| PB / Pondok | 🔵 Blue | #3b82f6 | 🏫 Icons.school |
| Lambatan | 🟠 Orange | #fb923c | 📖 Icons.menu_book |
| Cepatan | 🟢 Green | #10b981 | ⚡ Icons.speed |
| Tahfidz | 🟣 Purple | #7C3AED | 📚 Icons.auto_stories |
| Hadist | 🔵 Teal | #14b8a6 | 📗 Icons.import_contacts |
| Default | ⚫ Gray | #6b7280 | 🎓 Icons.class_ |
Code:
Color _getKelompokColor(String kelompokName) { ... }
IconData _getKelompokIcon(String kelompokName) { ... }
UI Component Breakdown
ExpansionTile Structure
Container (Border + Border Radius)
└─ Theme (Hide default divider)
└─ ExpansionTile
├─ Leading: Colored icon badge
├─ Title: Kelompok name (bold, colored)
├─ Subtitle: "X kelas" (gray)
└─ Children: List of kelas items
└─ Container (Kelas item)
├─ Left: Nama kelas + Kode kelas
└─ Right: Badge "⭐ Utama" (if primary)
Primary Badge Indicator
Styling:
- background: Gold (#fbbf24)
- Icon: ⭐ Star (white, size 12)
- Text: "Utama" (white, size 10, bold)
- Padding: 8px horizontal, 4px vertical
- Border radius: 8px
Kelas Item Styling
Primary Kelas:
- Background: Kelompok color with 10% opacity
- Border: Kelompok color with 30% opacity, width 1.5px
- Text: Bold, kelompok color
- Badge: "⭐ Utama" visible
Non-Primary Kelas:
- Background: Light gray (5% opacity)
- Border: None
- Text: Semi-bold, black87
- Badge: Hidden
Responsive Design
Screen Sizes Supported
- Min width: 320px (iPhone SE)
- Max width: 800px (iPad)
- Optimal: 360-428px (Most smartphones)
Adaptive Behavior
- ExpansionTile: Auto-adjust height
- Text overflow: Ellipsis
- Padding: Proportional to screen width
- Card elevation: 2 (consistent)
Performance Optimizations
1. Lazy Loading
- Section "Kelas yang Diikuti" hanya render saat visible
- ExpansionTile default collapsed
- Children di-render saat expanded
2. Minimal Dependencies
- NO EXTERNAL PACKAGES untuk kelas display
- Hanya Flutter built-in widgets:
- ExpansionTile
- Card
- Container
- Row, Column
- Icon, Text
3. No Heavy Assets
- Semua icon menggunakan
Icons.*(Flutter built-in) - No image assets loaded
- No SVG files
4. Efficient State Management
- Single
_santriDatamap - No redundant API calls
- Cache-first strategy dengan SharedPreferences
Code Files Modified
File: lib/features/profil/profil_page.dart
New Methods Added:
_buildPrimaryKelasBadge()- Lines ~305-360_buildKelasListSection()- Lines ~365-440_buildKelompokExpansionTile()- Lines ~445-570_getKelompokColor()- Lines ~575-595_getKelompokIcon()- Lines ~600-620
Modified Sections:
build()method - Added conditional section display_buildHeader()- Added primary kelas badge call- "Informasi Dasar" card - Removed kelas row
Total Lines: ~620 lines (dari ~300 lines sebelumnya)
Error Handling
Defensive Programming
// Handle null kelas_list
if (_santriData?['kelas_list'] != null &&
(_santriData!['kelas_list'] as List).isNotEmpty) {
_buildKelasListSection()
}
// Handle null kelompok
final kelompokName = kelompok['kelompok_name'] ?? 'Unknown';
final kelasItems = kelompok['kelas'] as List? ?? [];
// Handle null kelas properties
final namaKelas = kelas['nama_kelas'] ?? '-';
final kodeKelas = kelas['kode_kelas'] ?? '-';
final isPrimary = kelas['is_primary'] == true;
Empty State
if (kelasList.isEmpty) {
return _buildSectionCard(
title: 'Kelas yang Diikuti',
icon: Icons.class_,
children: [
Center(
child: Text(
'Belum mengikuti kelas apapun',
style: TextStyle(color: Colors.grey[600]),
),
),
],
);
}
Testing Guide
Manual Testing Steps
Test 1: Display Multiple Kelas
- Login sebagai santri yang punya multiple kelas
- Navigasi ke tab "Profil"
- Expected:
- Header menampilkan primary kelas badge
- Hint "+X kelas lainnya" muncul
- Section "Kelas yang Diikuti" visible
- Kelompok di-group dengan benar
- Primary kelas punya badge "⭐ Utama"
Test 2: Expansion/Collapse
- Tap kelompok yang collapsed
- Expected: ExpansionTile expand, menampilkan kelas items
- Tap lagi
- Expected: ExpansionTile collapse
Test 3: Primary Badge Visibility
- Cari kelas dengan
is_primary = true - Expected: Badge "⭐ Utama" muncul di kanan kelas item
- Cari kelas dengan
is_primary = false - Expected: Badge tidak muncul
Test 4: Empty State
- Login sebagai santri belum punya kelas
- Expected:
- Section "Kelas yang Diikuti" TIDAK muncul
- Field kelas di "Informasi Dasar" tidak ada
Test 5: Single Kelas
- Login sebagai santri dengan 1 kelas saja
- Expected:
- Primary kelas badge muncul
- Hint "+X kelas lainnya" TIDAK muncul (karena cuma 1)
- Section "Kelas yang Diikuti" muncul dengan 1 kelompok
Test 6: Color Coding
- Cek kelompok "PB" → Blue
- Cek kelompok "Lambatan" → Orange
- Cek kelompok "Cepatan" → Green
- Cek kelompok "Tahfidz" → Purple
- Cek kelompok "Hadist" → Teal
Test 7: Responsive
- Test di screen 320px (iPhone SE)
- Test di screen 375px (iPhone 13)
- Test di screen 428px (iPhone 13 Pro Max)
- Expected: No horizontal overflow, text ellipsis bekerja
Test 8: Pull-to-Refresh
- Swipe down di profil page
- Expected: Loading indicator muncul, data refresh dari API
Debugging Tips
Problem: Section tidak muncul
Check:
print('kelas_list: ${_santriData?['kelas_list']}');
print('is List: ${_santriData?['kelas_list'] is List}');
print('isEmpty: ${(_santriData?['kelas_list'] as List?)?.isEmpty}');
Problem: ExpansionTile tidak expand
Check:
- Pastikan
Themewrapper ada (untuk hide default divider) - Cek console error saat tap
Problem: Badge "Utama" tidak muncul
Check:
print('isPrimary: ${kelas['is_primary']}');
print('isPrimary type: ${kelas['is_primary'].runtimeType}');
Problem: Color salah
Check:
print('kelompokName: $kelompokName');
print('color: ${_getKelompokColor(kelompokName)}');
Future Enhancements (Optional)
Phase 2 (Nice to Have)
-
Smooth Animation
- Add
AnimatedSwitcheruntuk smooth transition - Fade animation saat expand/collapse
- Add
-
Search/Filter
- Search box untuk cari kelas
- Filter by kelompok
-
Tap to Detail
- Tap kelas item → Navigate ke detail kelas page
- Show jadwal, materi, guru, dll
-
Statistics
- Show kehadiran per kelas
- Show nilai rata-rata per kelas
Phase 3 (Advanced)
-
Tahun Ajaran
- Display tahun ajaran per kelas
- Filter by tahun ajaran
-
Kelas History
- Show riwayat kelas tahun-tahun sebelumnya
-
QR Code
- Generate QR code untuk absensi per kelas
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2026-02-14 | Initial: Single kelas display |
| 2.0.0 | 2026-02-14 | NEW: Multiple kelas with ExpansionTile, color coding, primary badge |
Troubleshooting
Flutter Analyze Errors
cd sim_mobile
flutter analyze
Flutter Format
flutter format lib/features/profil/profil_page.dart
Build APK (Test)
flutter build apk --debug
Contact & Support
- File:
lib/features/profil/profil_page.dart - Backup:
lib/features/profil/profil_page.dart.backup - Flutter version: 3.x
- Dart version: 3.x