import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:intl/intl.dart'; import 'package:monitoring/config.dart'; class NilaiScreen extends StatefulWidget { final String token; const NilaiScreen({super.key, required this.token}); @override State createState() => _NilaiScreenState(); } class _NilaiScreenState extends State { List data = []; bool loading = true; @override void initState() { super.initState(); fetchNilai(); } Future fetchNilai() async { final url = '$baseUrl/nilai'; try { final response = await http.get( Uri.parse(url), headers: { 'Accept': 'application/json', 'Authorization': 'Bearer ${widget.token}', }, ); if (response.statusCode == 200) { final res = json.decode(response.body); setState(() { data = res['data'] ?? []; loading = false; }); } else { debugPrint( 'Gagal ambil nilai: ${response.statusCode} - ${response.body}', ); setState(() => loading = false); } } catch (e) { debugPrint('Error nilai: $e'); setState(() => loading = false); } } String formatTanggal(String? tanggal) { if (tanggal == null) return '-'; try { final date = DateTime.parse(tanggal); return DateFormat('dd MMM yyyy', 'id_ID').format(date); } catch (e) { return tanggal; } } Widget _buildCard(Map item) { return Card( elevation: 3, margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item['mapel'] ?? '-', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Row( children: [ Chip( label: Text(item['jenis_nilai'] ?? '-'), backgroundColor: Colors.indigo.shade50, labelStyle: const TextStyle(color: Colors.indigo), ), const SizedBox(width: 8), Text( 'Nilai: ${item['nilai']}', style: const TextStyle(fontSize: 14), ), ], ), const SizedBox(height: 8), _infoRow( Icons.calendar_today, 'Tanggal', formatTanggal(item['tanggal']), ), _infoRow(Icons.school, 'Semester', item['semester']), if ((item['keterangan'] ?? '').toString().isNotEmpty) _infoRow(Icons.info_outline, 'Catatan', item['keterangan']), ], ), ), ); } Widget _infoRow(IconData icon, String label, String? value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Row( children: [ Icon(icon, size: 18, color: Colors.grey.shade600), const SizedBox(width: 8), Text('$label: ', style: const TextStyle(fontWeight: FontWeight.bold)), Expanded( child: Text( value ?? '-', style: const TextStyle(color: Colors.black87), ), ), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Nilai Akademik')), body: loading ? const Center(child: CircularProgressIndicator()) : data.isEmpty ? const Center(child: Text('Belum ada data nilai.')) : RefreshIndicator( onRefresh: fetchNilai, child: ListView.builder( physics: const AlwaysScrollableScrollPhysics(), itemCount: data.length, itemBuilder: (context, i) => _buildCard(data[i]), ), ), ); } }