import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:jwt_decode/jwt_decode.dart'; import '../../../../core/services/api_service.dart'; import '../../../../data/services/auth_service.dart'; import '../../../layouts/main_layout.dart'; import '../../../layouts/responsive_layout.dart'; import '../../../providers/manager_provider.dart'; import '../../../providers/userRoleProvider.dart'; class ProfilePopUp extends ConsumerStatefulWidget { const ProfilePopUp({super.key}); @override ConsumerState createState() => ProfilePopUpState(); } class ProfilePopUpState extends ConsumerState { late ApiService apiService; List> filteredIncentiveData = []; List> getAgentIncentiveFileData = []; Map? profileData; dynamic roleIdRaw; dynamic roleId; dynamic role; bool isProfile = true; bool isLoading = false; String? _token; dynamic latestId; @override void initState() { super.initState(); apiService = ApiService(); // getAgentList(); _initializeToken(); // Future.microtask(() { // final id = ref.read(managerIdProvider); // if (id != null) { // getAgentList(id); // // // staff/managerIncentiveFileList?manager_id=1 // } // }); } Future _initializeToken() async { _token = await AuthService.getToken(); print("profileDataAPISERTOKEN - $_token"); final Map decodedToken = Jwt.parseJwt(_token!); setState(() { profileData = decodedToken['data']; }); print('profileDatadecodedTokenProfile : $decodedToken'); print('profileDatadecodedTokenProfile : $profileData'); // await getList(); Future.microtask(() { role = ref.read(userRoleProvider); if (role != null) { getList(); } }); } Future getList() async { setState(() { isLoading = true; }); roleIdRaw = profileData?['role_id']; roleId = roleIdRaw is String ? int.tryParse(roleIdRaw) : roleIdRaw as int?; if (roleId == 1) { final managerIdRaw = profileData?['manager_id']; final managerId = managerIdRaw is String ? int.tryParse(managerIdRaw) : managerIdRaw as int?; if (managerId != null) { getIncenctiveFileList(managerId); } } else if (roleId != 1 && roleId != 2 && roleId != 3) { final agentIdRaw = profileData?['id']; final agentId = agentIdRaw is String ? int.tryParse(agentIdRaw) : agentIdRaw as int?; if (agentId != null) { getIncenctiveFileList(agentId); } } setState(() { isLoading = false; }); } Future getIncenctiveFileList(id) async { // print('getClaimList agentId - $agentId'); setState(() { isLoading = true; }); try { final response; final roleIdRaw = profileData?['role_id']; final roleId = roleIdRaw is String ? int.tryParse(roleIdRaw) : roleIdRaw as int?; if (roleId == 1) { response = await apiService.fetchManagerIncentiveList(id); } else { response = await apiService.fetchAgentIncentiveList(id, type: 'incentive'); } if (response['status'] == 'success') { print('AgentIncentive - ${response['data']}'); setState(() { getAgentIncentiveFileData = List>.from( response['data'], ); print('API AgentIncentive - $getAgentIncentiveFileData'); filteredIncentiveData = List.from(getAgentIncentiveFileData); print('originalData - $filteredIncentiveData'); // Sort descending by created_on filteredIncentiveData.sort((a, b) { final dateA = DateTime.tryParse(a['created_on'].toString()) ?? DateTime(1970); final dateB = DateTime.tryParse(b['created_on'].toString()) ?? DateTime(1970); return dateB.compareTo(dateA); // newest first }); // Get the latest ID (from the first element after sorting) if (filteredIncentiveData.isNotEmpty) { latestId = filteredIncentiveData.first['id']; print("Latest incentive id: $latestId"); } print('sortedData - $filteredIncentiveData'); }); } else { getAgentIncentiveFileData = []; } } catch (e) { print('Exception occurred: $e'); } finally { setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { return SelectionArea( child:Container( padding: const EdgeInsets.all(6), width: 450, color: Colors.white, // color: Colors.white, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( isProfile ? 'My Profile' : 'Incentive Files', style: _topheaderStyle, ), Spacer(), Container( width: 25, height: 25, decoration: BoxDecoration( color: Colors.white, // color: const Color(0xFFF1F1F1), borderRadius: BorderRadius.circular(10.0), ), child: InkWell( borderRadius: BorderRadius.circular(10.0), onTap: () { Navigator.of(context).pop(); // closes the popup }, child: Tooltip( message: 'Close', child: const Icon(Icons.close, size: 18), ), ), ), ], ), isProfile ? Container( color: Colors.white, padding: ResponsiveLayout.isMobile(context) ? EdgeInsets.all(16.0) : null, child: isLoading ? const Center(child: CircularProgressIndicator()) : Column( children: [ const SizedBox(height: 25), Container( width: 70, height: 70, decoration: BoxDecoration( // color: Color(0xFFD9D9D9), color: Colors.white, borderRadius: BorderRadius.circular(30.0), ), child: Icon( Icons.person_outline, size: 50, color: Colors.black, ), ), const SizedBox(height: 10), Text( profileData?['name'] ?? '-', style: _headerStyle, ), Text( (role == 'agent') ? 'partner' : role ?? '-', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF000000), ), ), const SizedBox(height: 26), if (hasValidValue(profileData?['mobile'])) ...[ Row( children: [ const Icon( Icons.phone_outlined, size: 20, color: Colors.black, ), const SizedBox(width: 8), Text( profileData?['mobile'] ?? '-', style: _dataBold, ), ], ), const SizedBox(height: 8), ], if (hasValidValue(profileData?['email'])) ...[ Row( children: [ const Icon( Icons.email_outlined, size: 18, color: Colors.black, ), const SizedBox(width: 8), Text( profileData?['email'] ?? '-', style: _dataBold, ), ], ), const SizedBox(height: 16), ], if (hasValidValue(profileData?['address'])) ...[ if ((roleId != 1) && (roleId != 2) && (roleId != 3)) ...[ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon( Icons.location_on_outlined, size: 18, color: Colors.black, ), const SizedBox(width: 8), Expanded( child: Text( profileData?['address'] ?? '-', style: _dataBold, softWrap: true, ), ), ], ), const SizedBox(height: 20), ], ], if ((roleId == 5)) ...[ // Staff, Handler doesn't have this part Only Manager and agent have Container( padding: const EdgeInsets.all(6), color: Color(0xffEDF6F5), child: GestureDetector( onTap: () { print("Download - $latestId"); dynamic path; if (roleId == 1) { path = 'staff/downloadManagerIncentiveFile?id=$latestId'; } else if (roleId != 1 && roleId != 2) { path = 'agent/downloadAgentIncentiveFile?id=$latestId'; } apiService.getPdfDownload(path, latestId); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.download), SizedBox(width: 8), Text( "Download Incentive file", style: _dataSub, ), ], ), ), ), const SizedBox(height: 10), TextButton( onPressed: () { setState(() { isProfile = false; }); }, child: Text( "View Previous Files", style: TextStyle( color: Color(0xff425B5B), decoration: TextDecoration .underline, // 👈 underline decorationThickness: 1.5, ), ), ), ], const SizedBox(height: 16), ], ), ) : Container( color: Colors.white, padding: ResponsiveLayout.isMobile(context) ? EdgeInsets.all(16.0) : null, child: Column( children: [ const SizedBox(height: 10), isLoading ? const Center(child: CircularProgressIndicator()) : filteredIncentiveData.isEmpty ? const Center( child: Text("No incentive files found"), ) : SizedBox( height: ResponsiveLayout.isMobile(context) ? MediaQuery.of(context).size.height * 0.4 : 450, child: ListView.builder( // padding: const EdgeInsets.all(8), itemCount: filteredIncentiveData.length, itemBuilder: (context, index) { final file = filteredIncentiveData[index]; return Padding( padding: const EdgeInsets.symmetric( vertical: 2.0, ), child: IncentiveFileRow( fileName: file['incentive_file_name'] ?? "Unknown", date: file['incentive_month'] ?? "-", onUpload: () { print("Upload ${file['id']}"); final selectedId = file['id']; dynamic path; if (roleId == 1) { path = 'staff/downloadManagerIncentiveFile?id=$selectedId'; } else if (roleId != 1 && roleId != 2) { path = 'agent/downloadAgentIncentiveFile?id=$selectedId'; } apiService.getPdfDownload( path, selectedId, ); }, ), ); }, ), ), ], ), ), ], ), )); } bool hasValidValue(dynamic value) { if (value == null) return false; if (value is String) return value.trim().isNotEmpty; return true; // for numbers, bool, etc. } static final _dataBold = TextStyle( fontSize: 11.8, fontWeight: FontWeight.w400, color: Color(0xFF000000), ); static final _dataSub = TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xFF000000), ); static const _headerStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.w700, fontSize: 20, ); static const _topheaderStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 18, ); } class IncentiveFileRow extends StatelessWidget { final String fileName; final String date; final VoidCallback? onUpload; // final VoidCallback? onDelete; const IncentiveFileRow({ super.key, required this.fileName, required this.date, this.onUpload, // this.onDelete, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(vertical: 7.0), // margin: const EdgeInsets.only(bottom: 5), // spacing between rows decoration: BoxDecoration( // color: Colors.amber.shade50, border: Border( bottom: BorderSide(width: 0.6, color: const Color(0xFFE3E3E3)), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(6.0), decoration: BoxDecoration( color: const Color(0xFFF4F6F8), borderRadius: BorderRadius.circular(8.0), border: Border.all(color: const Color(0xFFE3E3E3)), ), child: const Icon(Icons.file_present, color: Color(0xFF838587)), ), const SizedBox(width: 10), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 100, child: Text( fileName, style: const TextStyle( fontWeight: FontWeight.w600, color: Color(0xFF1D1B20), ), overflow: TextOverflow.ellipsis, softWrap: true, maxLines: 1, ), ), Text(date, style: const TextStyle(color: Color(0xFF6E6E6E))), ], ), const Spacer(), GestureDetector( onTap: onUpload, child: const Icon( Icons.file_download_outlined, color: Color(0xFF6E6E6E), ), ), ], ), ); } }