nhance_partner/lib/presentation/screens/UserManagement/Profile/profile_web.dart
2026-04-03 15:04:34 +05:30

528 lines
19 KiB
Dart

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<ProfilePopUp> createState() => ProfilePopUpState();
}
class ProfilePopUpState extends ConsumerState<ProfilePopUp> {
late ApiService apiService;
List<Map<String, dynamic>> filteredIncentiveData = [];
List<Map<String, dynamic>> getAgentIncentiveFileData = [];
Map<String, dynamic>? 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<void> _initializeToken() async {
_token = await AuthService.getToken();
print("profileDataAPISERTOKEN - $_token");
final Map<String, dynamic> 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<void> 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<void> 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<Map<String, dynamic>>.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),
),
),
],
),
);
}
}