import 'package:flutter/material.dart'; import 'package:qyuota/config/colors.dart'; import 'package:qyuota/view/home/home_view.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; import 'package:qyuota/models/leave.dart'; import 'package:qyuota/config/api_config.dart'; import 'package:qyuota/services/api_service.dart'; import 'package:intl/intl.dart'; import 'package:qyuota/services/auth_service.dart'; class StatusCuti extends StatefulWidget { const StatusCuti({Key? key}) : super(key: key); @override _StatusCutiState createState() => _StatusCutiState(); } class _StatusCutiState extends State { List leaves = []; bool isLoading = true; bool _isSessionValid = true; final ApiService _apiService = ApiService(); @override void initState() { super.initState(); _checkSessionAndLoadData(); } Future _checkSessionAndLoadData() async { final isValid = await AuthService().checkSession(context); if (isValid) { setState(() { _isSessionValid = true; }); await _fetchLeaves(); } else { setState(() { _isSessionValid = false; }); } } Future _fetchLeaves() async { setState(() { isLoading = true; }); try { final leaves = await _apiService.getLeaves(); setState(() { this.leaves = leaves; isLoading = false; }); } catch (e) { setState(() { leaves = []; isLoading = false; }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Error: ${e.toString()}'), backgroundColor: Colors.red, ), ); } } } String formatDate(String date) { try { final DateTime parsed = DateTime.parse(date); return DateFormat('dd MMM yyyy').format(parsed); } catch (e) { return date; } } Color getStatusColor(String status) { switch (status.toLowerCase()) { case 'disetujui': return Colors.green; case 'ditolak': return Colors.red; case 'pending': return Colors.orange; default: return Colors.grey; } } IconData getStatusIcon(String status) { switch (status.toLowerCase()) { case 'disetujui': return Icons.check_circle; case 'ditolak': return Icons.cancel; case 'pending': return Icons.access_time; default: return Icons.help; } } @override Widget build(BuildContext context) { if (!_isSessionValid) { return const Scaffold( body: Center( child: CircularProgressIndicator(), ), ); } return Scaffold( backgroundColor: Colors.grey[50], appBar: AppBar( elevation: 0, title: const Text( "Status Cuti", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), centerTitle: true, backgroundColor: ConstColors.primaryColor, leading: IconButton( icon: const Icon(Icons.arrow_back_ios, color: Colors.white), onPressed: () => Navigator.of(context).pop(), ), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( bottom: Radius.circular(20), ), ), ), body: RefreshIndicator( onRefresh: () async { await _checkSessionAndLoadData(); }, child: isLoading ? const Center(child: CircularProgressIndicator()) : leaves.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.note_alt_outlined, size: 64, color: Colors.grey[400], ), const SizedBox(height: 16), Text( 'Belum ada pengajuan cuti', style: TextStyle( fontSize: 16, color: Colors.grey[600], ), ), ], ), ) : ListView.builder( padding: const EdgeInsets.only(top: 12, bottom: 12), itemCount: leaves.length, itemBuilder: (context, index) { final leave = leaves[index]; return Align( alignment: Alignment.center, child: Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.1), spreadRadius: 1, blurRadius: 10, offset: const Offset(0, 1), ), ], ), child: Column( children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: getStatusColor(leave.status).withOpacity(0.1), borderRadius: const BorderRadius.vertical( top: Radius.circular(15), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Row( children: [ Icon( getStatusIcon(leave.status), color: getStatusColor(leave.status), size: 24, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Pengajuan Cuti', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Text( leave.reason, style: TextStyle( fontSize: 14, color: Colors.grey[600], ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ), const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: getStatusColor(leave.status).withOpacity(0.1), borderRadius: BorderRadius.circular(20), border: Border.all( color: getStatusColor(leave.status).withOpacity(0.5), ), ), child: Text( leave.status, style: TextStyle( color: getStatusColor(leave.status), fontWeight: FontWeight.bold, fontSize: 12, ), ), ), ], ), ), Padding( padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'Tanggal Mulai', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), const SizedBox(height: 4), Text( formatDate(leave.startDate), style: const TextStyle( fontWeight: FontWeight.w500, ), ), ], ), ), Container( height: 30, width: 1, color: Colors.grey[300], ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'Tanggal Selesai', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), const SizedBox(height: 4), Text( formatDate(leave.endDate), style: const TextStyle( fontWeight: FontWeight.w500, ), ), ], ), ), ], ), ), if (leave.status.toLowerCase() != 'pending') Padding( padding: const EdgeInsets.fromLTRB(16, 0, 16, 16), child: Row( children: [ Icon( leave.status.toLowerCase() == 'disetujui' ? Icons.check_circle_outline : Icons.person_off, size: 16, color: Colors.grey[600], ), const SizedBox(width: 8), Text( leave.status.toLowerCase() == 'disetujui' ? 'Disetujui oleh: ${leave.approvedBy ?? "Admin"}' : 'Ditolak oleh: ${leave.rejectedBy ?? "Admin"}', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), ), ], ), ), ); }, ), ), ); } }