This commit is contained in:
Surendiran 2025-07-04 10:53:22 +05:30
commit ee0eabd0b7
16 changed files with 2424 additions and 1485 deletions

BIN
assets/claim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

BIN
assets/ecard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

View File

@ -46,14 +46,14 @@ class _CustomAppBarState extends State<CustomAppBar> {
final prefs = await SharedPreferences.getInstance();
final String? hrtoken = prefs.getString('hrtoken');
if (hrtoken != null && hrtoken.isNotEmpty) {
prefs.setBool('showBackToHR', false);
prefs.remove('token');
Navigator.pushNamed(context, 'hrDashboard');
} else {
await prefs.clear();
Navigator.pushNamed(context, 'phone');
}
// if (hrtoken != null && hrtoken.isNotEmpty) {
// prefs.setBool('showBackToHR', false);
// prefs.remove('token');
// Navigator.pushNamed(context, 'hrDashboard');
// } else {
// await prefs.clear();
// Navigator.pushNamed(context, 'phone');
// }
}
Future<void> logout(BuildContext context) async {

View File

@ -26,7 +26,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
Future<void> _checkTokens() async {
final prefs = await SharedPreferences.getInstance();
final String? hrtoken = prefs.getString('hrtoken');
// final String? hrtoken = prefs.getString('hrtoken');
final String? hrtoken = prefs.getString('enrollToken');
final String? token = prefs.getString('token');
// showBackToHR = prefs.getBool('showBackToHR')!;

View File

@ -21,7 +21,8 @@ import 'package:spreadsheet_decoder/spreadsheet_decoder.dart';
import 'customAppBar/customFooter.dart';
class excelVerify extends StatefulWidget {
const excelVerify({Key? key}) : super(key: key);
final String Token;
const excelVerify({Key? key, required this.Token}) : super(key: key);
@override
State<excelVerify> createState() => _excelVerifyState();
@ -77,7 +78,8 @@ class _excelVerifyState extends State<excelVerify> {
Future<void> _loadToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('hrtoken');
// final token = prefs.getString('hrtoken');
final token = widget.Token;
if (token != null && token.isNotEmpty) {
setState(() {
_token = token;

View File

@ -199,6 +199,7 @@ class _hrDashboardState extends State<hrDashboard>
empClientId: empClientId,
empClientBranchId: empClientBranchId,
empHrId: empHrId,
postToken: _postToken,
),
);
}
@ -420,556 +421,169 @@ class _hrDashboardState extends State<hrDashboard>
return Scaffold(
appBar: CustomAppBar(),
body: Stack(children: [
SingleChildScrollView(
child: Container(
padding:
EdgeInsets.only(top: 30, bottom: 200, left: 50, right: 50),
color: Color(0xFFEFF3F6),
child: Column(
children: [
Container(
color: Colors.white,
width: double.infinity,
height: 75,
padding: Responsive.isDesktop(context)
? EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 20)
: EdgeInsets.only(
top: 12,
bottom: 12,
left: 10,
right: 10), // Add padding to the container
child: Row(
children: [
Expanded(
flex: 6,
child: Container(
width: 150,
height: 150,
alignment: Alignment.centerLeft,
child: Image.network(
clientLogo ?? '',
width: 80, // Set the width here
height: 80, // Set the height here
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value:
loadingProgress.expectedTotalBytes !=
null
? loadingProgress
.cumulativeBytesLoaded /
loadingProgress
.expectedTotalBytes!
: null,
),
);
},
errorBuilder: (BuildContext context,
Object error, StackTrace? stackTrace) {
return Image.asset(
'assets/Solid_gray.png', // Replace 'default_image.png' with your default image asset path
width: 80,
height: 80,
fit: BoxFit.cover,
);
},
),
Container(
padding: const EdgeInsets.all(40),
// padding: const EdgeInsets.only(
// top: 20, bottom: 20, left: 50, right: 50),
color: const Color(0xFFEFF3F6),
child: Column(
children: [
Container(
color: Colors.white,
width: double.infinity,
// height: 75,
height: MediaQuery.of(context).size.height * 0.12,
padding: Responsive.isDesktop(context)
? const EdgeInsets.only(
top: 10, bottom: 10, left: 20, right: 20)
: EdgeInsets.only(
top: 12,
bottom: 12,
left: 10,
right: 10), // Add padding to the container
child: Row(
children: [
Expanded(
flex: 6,
child: Container(
width: 150,
height: 150,
alignment: Alignment.centerLeft,
child: Image.network(
clientLogo ?? '',
width: 80, // Set the width here
height: 80, // Set the height here
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: CircularProgressIndicator(
value: loadingProgress.expectedTotalBytes !=
null
? loadingProgress
.cumulativeBytesLoaded /
loadingProgress.expectedTotalBytes!
: null,
),
);
},
errorBuilder: (BuildContext context, Object error,
StackTrace? stackTrace) {
return Image.asset(
'assets/Solid_gray.png', // Replace 'default_image.png' with your default image asset path
width: 80,
height: 80,
fit: BoxFit.cover,
);
},
),
),
Expanded(
flex: 9,
child: Text(
clientName ?? '',
textAlign: TextAlign.right,
style: GoogleFonts.poppins(
fontSize:
Responsive.isDesktop(context) ? 20 : 18,
fontWeight: FontWeight.w600,
),
),
Expanded(
flex: 9,
child: Text(
clientName ?? '',
textAlign: TextAlign.right,
style: GoogleFonts.poppins(
fontSize: Responsive.isDesktop(context) ? 20 : 18,
fontWeight: FontWeight.w600,
),
)
],
),
),
SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Color(
0xFFC4E3E6), // 🔹 Background behind the TabBar
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.transparent),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 4,
offset: const Offset(0, 4),
),
],
),
child: TabBar(
controller: _tabController,
isScrollable: true,
labelPadding: const EdgeInsets.symmetric(
horizontal: 0, vertical: 0),
// indicator: BoxDecoration(
// color: const Color(0xFF00999E), // Selected tab background
// borderRadius: BorderRadius.circular(12),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.2),
// blurRadius: 4,
// offset: const Offset(0, 2),
// )
// ],
// ),
dividerColor: Colors.transparent,
indicatorColor: Colors.transparent,
labelColor: Colors.white,
unselectedLabelColor: const Color(0xFF828282),
// tabs: visibleTabs,
tabs: List.generate(tabData.length, (index) {
final data = tabData[index];
return CustomTab(
icon: data['icon'],
label: data['label'],
isSelected: selectedIndex == index,
);
}),
// tabs: [
// CustomTab(
// icon: Icons.grid_view,
// label: 'Pre Enrollment',
// isSelected: selectedIndex == 0),
// CustomTab(
// icon: Icons.verified_user,
// label: 'Active Policies',
// isSelected: selectedIndex == 1),
// CustomTab(
// icon: Icons.desktop_windows,
// label: 'CD',
// isSelected: selectedIndex == 2),
// CustomTab(
// icon: Icons.receipt_long,
// label: 'Claims',
// isSelected: selectedIndex == 3),
// ],
),
)
],
),
SizedBox(height: 16),
// Expanded TabBarView
SizedBox(
height: 500, // Adjust height based on your layout
),
SizedBox(height: 16),
Container(
padding: const EdgeInsets.all(5),
height: MediaQuery.of(context).size.height * 0.08,
decoration: BoxDecoration(
color:
Color(0xFFC4E3E6), // 🔹 Background behind the TabBar
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.transparent),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 4,
offset: const Offset(0, 4),
),
],
),
child: TabBar(
controller: _tabController,
isScrollable: true,
labelPadding: const EdgeInsets.symmetric(
horizontal: 0, vertical: 0),
// indicator: BoxDecoration(
// color: const Color(0xFF00999E), // Selected tab background
// borderRadius: BorderRadius.circular(12),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.2),
// blurRadius: 4,
// offset: const Offset(0, 2),
// )
// ],
// ),
dividerColor: Colors.transparent,
indicatorColor: Colors.transparent,
labelColor: Colors.white,
unselectedLabelColor: const Color(0xFF828282),
// tabs: visibleTabs,
tabs: List.generate(tabData.length, (index) {
final data = tabData[index];
return CustomTab(
icon: data['icon'],
label: data['label'],
isSelected: selectedIndex == index,
);
}),
// tabs: [
// CustomTab(
// icon: Icons.grid_view,
// label: 'Pre Enrollment',
// isSelected: selectedIndex == 0),
// CustomTab(
// icon: Icons.verified_user,
// label: 'Active Policies',
// isSelected: selectedIndex == 1),
// CustomTab(
// icon: Icons.desktop_windows,
// label: 'CD',
// isSelected: selectedIndex == 2),
// CustomTab(
// icon: Icons.receipt_long,
// label: 'Claims',
// isSelected: selectedIndex == 3),
// ],
),
),
SizedBox(height: 16),
// Expanded TabBarView
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: TabBarView(
controller: _tabController,
children: tabViews,
),
// child: TabBarView(
// controller: _tabController,
// children: [
// // Pre Enrollment Tab
// Card(
// elevation: 5,
// color: Colors.white,
// child: Container(
// child: GridView.builder(
// itemCount: getCardArrays.length,
// gridDelegate:
// const SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount:
// 4, // Adjust for screen size (e.g., use 2 or 3 for tablets)
// crossAxisSpacing: 16,
// mainAxisSpacing: 0,
// childAspectRatio: 2,
// ),
// itemBuilder: (context, index) {
// return buildPolicyCard(
// getCardArrays[index]);
// },
// ),
// )),
//
// Center(child: Text("Active Policies")),
// Center(child: Text("CD")),
// Center(child: Text("Claims")),
// ],
// ),
),
// if (getCardArrays.length != 0)
// Card(
// elevation: 0,
// color: Colors.white,
// child: Container(
// width: double.infinity,
// padding: Responsive.isDesktop(context)
// ? EdgeInsets.all(20)
// : EdgeInsets.all(
// 10), // Add padding to the container
// child: Column(children: [
// Row(children: [
// Text(
// 'Cash Transaction',
// style: GoogleFonts.poppins(
// fontSize: 18,
// fontWeight: FontWeight.w600,
// color: Colors.black,
// ),
// )
// ]),
// SizedBox(height: 8),
// Row(
// children: [
// // Create an Expanded widget with flex of 4 for each card
// for (var cardData in getCardArrays)
// Container(
// width:
// 300, // Set a fixed width for the card
// height: cardHeight,
// child: Card(
// elevation: 3,
// color: cardColors[
// getCardArrays.indexOf(cardData) %
// cardColors.length],
// child: Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// ListTile(
// title: SizedBox(
// height: 50,
// child: Text(
// cardData['insurerName'],
// style: GoogleFonts.poppins(
// fontSize: 18,
// fontWeight: FontWeight.w500,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// ),
// subtitle: Text(
// 'Balance: ₹ ${cardData['balance']}',
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w400,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// ),
// SizedBox(height: 10),
// Padding(
// padding: EdgeInsets.symmetric(
// horizontal: 15),
// child: GestureDetector(
// onTap: () {
// openForm(
// cardData['depositData'],
// cardData['insurerName'],
// cardData['clientId'],
// cardData['insurerId'],
// cardColors[getCardArrays
// .indexOf(cardData) %
// cardColors.length],
// );
// },
// child: MouseRegion(
// cursor:
// SystemMouseCursors.click,
// child: Align(
// alignment:
// Alignment.centerRight,
// child: Text(
// 'View Details',
// style:
// GoogleFonts.poppins(
// color:
// Color(0xFF000000),
// fontSize: 14,
// fontWeight:
// FontWeight.w300,
// height: 1.5,
// ),
// ),
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ])),
// ),
// SizedBox(height: 16),
// if (getCardArrays.length != 0)
// Card(
// elevation: 0,
// color: Colors.white,
// child: Padding(
// padding: Responsive.isDesktop(context)
// ? EdgeInsets.all(20)
// : EdgeInsets.all(10),
// child: Column(
// children: [
// Row(
// children: [
// Expanded(
// child: Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: List.generate(
// numExpanded,
// (index) {
// var insurerName = getCardArrays[index]
// ['insurerName'];
// var policyDetails =
// getCardArrays[index]
// ['policyDetails'];
//
// // Determine the color for the policyDetails based on the index of the card in getCardArrays
// var cardColorIndex =
// getCardArrays.indexOf(
// getCardArrays[index]) %
// cardColors.length;
// var cardColor =
// cardColors[cardColorIndex];
//
// return Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// insurerName,
// style: GoogleFonts.poppins(
// fontSize: 18,
// fontWeight: FontWeight.w600,
// color: Colors.black,
// ),
// ),
// SizedBox(height: 8),
// Row(
// children: [
// IconButton(
// icon:
// Icon(Icons.arrow_back),
// onPressed: () {
// _scrollController
// .animateTo(
// _scrollController
// .offset -
// 300,
// duration: Duration(
// milliseconds: 500),
// curve: Curves.easeInOut,
// );
// },
// ),
// Expanded(
// child:
// SingleChildScrollView(
// scrollDirection:
// Axis.horizontal,
// controller:
// _scrollController,
// dragStartBehavior:
// DragStartBehavior
// .start,
// child: Row(
// children: List.generate(
// policyDetails.length,
// (index) => Container(
// width: 300,
// height:
// policyHeight,
// child:
// GestureDetector(
// onTap: () {
// Navigator.pushNamed(
// context,
// 'hrPolicyDetails',
// arguments:
// policyDetails[
// index]);
// },
// child:
// MouseRegion(
// cursor:
// SystemMouseCursors
// .click,
// child: Card(
// elevation: 3,
// color:
// cardColor,
// child: Column(
// crossAxisAlignment:
// CrossAxisAlignment
// .start,
// children: [
// ListTile(
// title:
// SizedBox(
// height:
// 50,
// child:
// Text(
// '${policyDetails[index]['policy_name']} - (${policyDetails[index]['type']})',
// style:
// GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// softWrap:
// true,
// ),
// ),
// ),
// SizedBox(
// height:
// 8),
// Padding(
// padding: EdgeInsets.only(
// left:
// 15,
// right:
// 15),
// child:
// Row(
// children: [
// Expanded(
// flex: 4,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Text(
// 'Draft',
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// Text(
// policyDetails[index]['membersCountOfDraft'].toString(),
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w400,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// ],
// ),
// ),
// Expanded(
// flex: 4,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Text(
// 'Enrolled',
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// Text(
// policyDetails[index]['membersCountOfEnrolled'].toString(),
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w400,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// ],
// ),
// ),
// Expanded(
// flex: 4,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// Text(
// 'Total',
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w500,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// Text(
// policyDetails[index]['totalMembersCount'].toString(),
// style: GoogleFonts.poppins(
// fontSize: 16,
// fontWeight: FontWeight.w400,
// color: Color(0xFF000000),
// height: 1.5,
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ),
// ),
// ),
// ),
// ),
// IconButton(
// icon: Icon(
// Icons.arrow_forward),
// onPressed: () {
// _scrollController
// .animateTo(
// _scrollController
// .offset +
// 300,
// duration: Duration(
// milliseconds: 500),
// curve: Curves.easeInOut,
// );
// },
// ),
// ],
// ),
// SizedBox(height: 20),
// ],
// );
// },
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
// )
],
),
),
// SizedBox(
// height: MediaQuery.of(context).size.height * 0.55,
// // height: 500, // Adjust height based on your layout
// child: TabBarView(
// controller: _tabController,
// children: tabViews,
// ),
// ),
],
),
),
if (isLoading)

File diff suppressed because it is too large Load Diff

887
lib/hrPolicyDetials Normal file
View File

@ -0,0 +1,887 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhancepolicy/customAppBar/enrollmentAppBar.dart';
import 'package:nhancepolicy/excel_verification.dart';
import 'package:nhancepolicy/models/environment.dart';
import 'package:nhancepolicy/service/api_service.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jwt_decode/jwt_decode.dart';
import 'dart:convert';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:nhancepolicy/customAppBar/toastHelper.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:typed_data';
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:intl/intl.dart';
import 'package:excel/excel.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'customAppBar/customFooter.dart';
class hrPolicyDetails extends StatefulWidget {
const hrPolicyDetails({Key? key}) : super(key: key);
@override
State<hrPolicyDetails> createState() => _HrPolicyDetailsState();
}
class _HrPolicyDetailsState extends State<hrPolicyDetails>
with TickerProviderStateMixin {
Uint8List? fileBytes;
late String _token;
List<Map<String, dynamic>> getEmpDependenceByClintId = [];
bool isLoading = false;
bool _isLoading = false;
// dynamic clintID;
late TabController _tabController;
// List<dynamic> dataPolicy = [];
List<dynamic> reversedDataPolicy = [];
List<Map<String, dynamic>> originalData = []; // Original data source
List<Map<String, dynamic>> filteredData = []; // Filtered data source
dynamic argumentsData;
dynamic policyType;
dynamic policyName;
dynamic clientPolicyId;
dynamic clientId;
dynamic empRefId;
int inceptionType = 0;
TextEditingController searchController = TextEditingController();
late ApiService apiService;
@override
void initState() {
super.initState();
apiService = ApiService(context); // Initialize ApiService here
_tabController = TabController(length: 4, vsync: this);
_loadToken();
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
Future<void> _loadToken() async {
print('1');
final SharedPreferences prefs = await SharedPreferences.getInstance();
final token = prefs.getString('hrtoken');
if (token != null && token.isNotEmpty) {
print('2');
setState(() {
_token = token;
});
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
empRefId = prefs.getString('empRefId');
// clintID = decodedToken['client_id'];
getPolicyDetails();
} else {
// Token is empty or null, handle accordingly (e.g., navigate to login screen)
// For now, let's navigate to the login screen
ToastHelper.showErrorToast(context, 'Session Out');
Navigator.pushReplacementNamed(context, 'hrLogin');
}
}
Future<void> _saveArgumentsDataToLocalStorage(argumentsData) async {
print('6');
print('argumentsData');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('hrSelectArgumentsData', jsonEncode(argumentsData));
}
Future<void> getPolicyDetails() async {
print('3');
try {
print('4');
setState(() {
if (argumentsData != null && argumentsData is Map<String, dynamic>) {
print('5');
_saveArgumentsDataToLocalStorage(argumentsData);
print('7');
if (argumentsData['type'] == 'GPA') {
print('8');
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'GMC') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'GMC - Parents') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'GMC - Topup') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'GMC - Topup(Parents)') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'EDLI') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
} else if (argumentsData['type'] == 'GTLI') {
_isLoading = true;
clientPolicyId = argumentsData['client_policy_id'];
clientId = argumentsData['client_id'];
policyType = argumentsData['type'];
policyName = argumentsData['policy_name'];
String int_inception_type = argumentsData['inception_type'];
inceptionType = int.parse(int_inception_type);
getEmployeeAndDependence(clientId, clientPolicyId);
}
}
});
} catch (e) {
_isLoading = false;
print('Exception occurred: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> getEmployeeAndDependence(clintID, getPolicyNo) async {
print('9');
setState(() {
isLoading = true;
});
try {
print('10');
final response = await apiService.getEmployeeAndDependenceToApi(
clintID!, getPolicyNo!, empRefId!);
if (response['status'] == 'success') {
setState(() {
isLoading = false;
});
setState(() {
getEmpDependenceByClintId =
List<Map<String, dynamic>>.from(response['data']);
originalData = getEmpDependenceByClintId;
filteredData = List.from(originalData);
print('filteredData');
print(filteredData);
});
} else {
setState(() {
isLoading = false;
});
// ToastHelper.showWarningToast(
// context, 'Request failed with status: ${response.statusCode}');
print('Request failed with status: ${response['code']}');
}
} catch (e) {
setState(() {
isLoading = false;
});
print('Exception occurred: $e');
} finally {
setState(() {
_isLoading = false;
});
}
}
void _uploadFile(type) async {
var argumentType;
if (type == 'GPA') {
// argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails2;
argumentType = 'GPA';
} else if (type == 'GMC') {
// argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails1;
argumentType = 'GMC';
}
// else if (importPolicyName == 'SI-TopUp') {
// // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails0;
// argumentDetails = 'SI-TopUp';
// } else if (importPolicyName == 'Dependent-AddOn') {
// // argumentDetails = importPolicyName + ' - ' + getPolicyNameDetails0;
// argumentDetails = 'Dependent-AddOn';
// }
Navigator.pushNamed(context, 'excelVerify', arguments: argumentsData);
// return;
// if (kIsWeb) {
// final input = html.FileUploadInputElement();
// input.accept = '.xlsx';
// input.click();
// input.onChange.listen((event) async {
// final file = input.files!.first;
// final reader = html.FileReader();
// reader.readAsArrayBuffer(file);
// reader.onLoadEnd.listen((event) async {
// final Uint8List? fileBytes = reader.result as Uint8List?;
// if (fileBytes != null) {
// // Call function to process Excel data
// }
// });
// });
// }
}
// Implement a method to handle the search functionality
void search(String query) {
print(query);
// Check if the query is empty
if (query.isEmpty) {
// If search query is empty, show all data
setState(() {
filteredData = List.from(originalData);
});
} else {
// Filter the original data based on the search query
setState(() {
filteredData = originalData.where((row) {
// Implement your filter logic here
// For example, check if any field in the row contains the query
// Adjust this logic based on your data structure
return row['emp_code']
.toString()
.toLowerCase()
.contains(query.toLowerCase()) ||
row['name']
.toString()
.toLowerCase()
.contains(query.toLowerCase()) ||
row['relationship']
.toString()
.toLowerCase()
.contains(query.toLowerCase()) ||
row['dob']
.toString()
.toLowerCase()
.contains(query.toLowerCase()) ||
row['gender']
.toString()
.toLowerCase()
.contains(query.toLowerCase()) ||
row['mobile']
.toString()
.toLowerCase()
.contains(query.toLowerCase());
}).toList();
});
}
print(filteredData.length);
}
Future<void> downloadExcel() async {
// API endpoint to download the Excel file
// Send GET request to the API
var url = Uri.parse(Environment.apiUrl +
'exportDataByClientPolicyId?client_id=$clientId&client_policy_id=$clientPolicyId&client_branch_id=$empRefId');
var response = await http.get(
url,
headers: {
'Authorization': 'Bearer $_token',
},
);
// Check if the request was successful (status code 200)
// Check if the request was successful (status code 200)
// Check if the request was successful (status code 200)
if (response.statusCode == 200) {
// Create a blob from the response body
final blob = html.Blob([response.bodyBytes]);
// Generate a download URL for the blob
final url = html.Url.createObjectUrlFromBlob(blob);
// Create a link element to trigger the download
final anchor = html.AnchorElement(href: url)
..setAttribute('download', '$policyName - ($policyType).xlsx')
..click();
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url);
} else {
// Handle error
print('Failed to download Excel file: ${response.statusCode}');
}
}
@override
Widget build(BuildContext context) {
dynamic arguments = ModalRoute.of(context)!.settings.arguments;
print('arguments');
print(arguments);
if (arguments != null && arguments is Map<String, dynamic>) {
argumentsData = arguments;
print('argumentsData $argumentsData');
}
if (filteredData == []) {
return Scaffold(
appBar: CustomAppBar(),
body: Stack(children: [
SingleChildScrollView(
child: Container(
color: Color(0xFFEFF3F6),
child: Column(
children: [
Center(
child: Text('No Data Available'),
)
],
),
),
),
if (isLoading)
Container(
color: Color(0x98FFFCE5), // Semi-transparent background
child: Center(
child: // Your GIF loader widget
Image.asset(
height: 60,
width: 60,
'assets/nhance-loader.gif'), // Adjust path to your GIF loader
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity, // Make the footer full width
child: CustomFooter(),
),
),
]));
} else {
return Scaffold(
appBar: CustomAppBar(),
body: Stack(children: [
Container(
padding: const EdgeInsets.only(
top: 30, bottom: 70, left: 30, right: 30),
color: Color(0xFFEFF3F6),
height: MediaQuery.of(context).size.height,
child: Card(
elevation: 0,
color: Colors.white,
child: SingleChildScrollView(
child: Column(
children: [
Center(
child: Padding(
padding: const EdgeInsets.all(20),
child: _isLoading
? Center(child: CircularProgressIndicator())
: originalData.isNotEmpty
? SingleChildScrollView(
child: Column(
children: [
Container(
padding: EdgeInsets.all(
10), // Set your desired padding
color: Color(
0xFFE26728), // Set your desired background color
child: Row(
children: [
Expanded(
flex: 6,
child: Container(
alignment: Alignment
.centerLeft, // Align text to the center
child: Text(
'$policyName - ($policyType)',
textAlign: TextAlign
.center, // Align text to the center
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight:
FontWeight.w500,
color: Colors.white,
),
),
),
),
Expanded(
flex: 6,
child: Container(
alignment: Alignment
.centerRight, // Align text to the center
child: MouseRegion(
cursor: SystemMouseCursors
.click,
child: GestureDetector(
onTap: () async {
final prefs =
await SharedPreferences
.getInstance();
await prefs.remove(
'hrSelectArgumentsData');
Navigator.pushNamed(
context,
'hrDashboard');
},
child: Icon(
Icons
.close, // Replace with your desired icon
color: Colors
.white, // Replace with your desired icon color
),
),
),
),
),
],
),
),
SizedBox(height: 20),
Row(
children: [
Expanded(
flex: (policyType == 'GPA' ||
policyType == 'GMC')
? 8
: 10,
child: Container(
alignment:
Alignment.centerLeft,
child: Container(
width:
350, // Set your desired width here
height:
40, // Set your desired height here
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Color.fromRGBO(
255,
255,
255,
0.5), // Shadow color with opacity
offset: Offset(5,
5), // Shadow position (horizontal, vertical)
blurRadius:
10, // Blur radius
spreadRadius:
0, // Spread radius
),
],
borderRadius:
BorderRadius
.circular(5),
),
child: TextField(
textAlignVertical:
TextAlignVertical
.center, // Center the text vertically
decoration:
InputDecoration(
hintText: 'Search',
suffixIcon: Icon(
Icons.search),
contentPadding:
EdgeInsets.all(
10), // Adjust the horizontal padding
border:
OutlineInputBorder(
borderSide: BorderSide(
color: Color(
0xFFf5f5f7)), // Set border color to gray
),
),
controller:
searchController,
onChanged:
search, // Call the search method on text change
),
)),
),
Expanded(
flex: 2,
child: Container(
alignment:
Alignment.centerRight,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Expanded(
child: ElevatedButton(
onPressed: () =>
{downloadExcel()},
child: Text(
'Export',
style: TextStyle(
color: Colors
.white),
),
style: ElevatedButton
.styleFrom(
backgroundColor:
Color(
0xFFE26728),
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
5),
),
),
),
),
],
),
),
),
SizedBox(
width: (policyType == 'GPA' ||
policyType == 'GMC')
? 5
: 0),
if ((policyType == 'GPA' ||
policyType == 'GMC' ||
policyType == 'EDLI' ||
policyType == 'GTLI') &&
inceptionType == 2)
Expanded(
flex: 2,
child: Container(
alignment:
Alignment.centerRight,
child: Row(
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Expanded(
child: ElevatedButton(
onPressed: () =>
_uploadFile(
policyType),
child: Text(
'Import Data',
style: TextStyle(
color: Colors
.white),
),
style:
ElevatedButton
.styleFrom(
backgroundColor:
Color(
0xFFE26728),
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius
.circular(
5),
),
),
),
),
],
),
),
),
],
),
SizedBox(height: 20),
Row(
children: [
Expanded(
child: SingleChildScrollView(
child: _buildDataTableGPA(
context),
),
)
],
),
],
))
: Container(
height:
MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.all(
10), // Set your desired padding
color: Color(
0xFFE26728), // Set your desired background color
child: Row(
children: [
Expanded(
flex: 6,
child: Container(
alignment: Alignment
.centerLeft, // Align text to the center
child: Text(
(policyName != null &&
policyType !=
null)
? '$policyName - ($policyType)'
: '',
textAlign: TextAlign
.center, // Align text to the center
style:
GoogleFonts.poppins(
fontSize: 16,
fontWeight:
FontWeight.w500,
color: Colors.white,
),
),
),
),
Expanded(
flex: 6,
child: Container(
alignment: Alignment
.centerRight, // Align text to the center
child: MouseRegion(
cursor:
SystemMouseCursors
.click,
child: GestureDetector(
onTap: () {
Navigator.pushNamed(
context,
'hrDashboard');
},
child: Icon(
Icons
.close, // Replace with your desired icon
color: Colors
.white, // Replace with your desired icon color
),
),
),
),
),
],
),
),
SizedBox(height: 200),
if (inceptionType == 2)
Center(
child: ElevatedButton(
onPressed: () =>
_uploadFile(policyType),
child: Text(
'Import Data',
style: TextStyle(
color: Colors.white),
),
style:
ElevatedButton.styleFrom(
backgroundColor:
Color(0xFFE26728),
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
5),
),
),
),
)
else
Center(
child: Text(
'No Data Available',
style: GoogleFonts.poppins(
fontSize: 16,
letterSpacing: 0,
color: Colors.black,
fontWeight: FontWeight.w300,
),
),
)
],
),
),
),
),
],
),
)),
),
if (isLoading)
Container(
color: Color(0x98FFFCE5), // Semi-transparent background
child: Center(
child: // Your GIF loader widget
Image.asset(
height: 60,
width: 60,
'assets/nhance-loader.gif'), // Adjust path to your GIF loader
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: double.infinity, // Make the footer full width
child: CustomFooter(),
),
),
]));
}
}
Widget _buildDataTableGPA(context) {
if (filteredData.isEmpty) {
SizedBox(height: 25);
return Text('No available data');
} else {
return Card(
elevation: 0,
color: Colors.white, // Set elevation to 0 for no shadow
child: PaginatedDataTable(
rowsPerPage: filteredData.length, // Adjust rows per page as needed
columns: [
DataColumn(label: Text('Employee ID')),
DataColumn(label: Text('TPA ID')),
DataColumn(label: Text('Name')),
DataColumn(label: Text('Relationship')),
DataColumn(label: Text('Date of Birth')),
DataColumn(label: Text('Gender')),
DataColumn(label: Text('Mobile No')),
// DataColumn(label: Text('Date of Joining')),
DataColumn(label: Text('Date Coverage')),
DataColumn(label: Text('Email')),
DataColumn(label: Text('SI')),
DataColumn(label: Text('Grade')),
DataColumn(label: Text('Basic Pay')),
],
source: _DependenceDataSource0(filteredData, context),
),
);
}
}
}
class _DependenceDataSource0 extends DataTableSource {
final List<Map<String, dynamic>> _data;
final BuildContext context;
_DependenceDataSource0(this._data, this.context);
@override
DataRow getRow(int index) {
final row = _data[index];
Color rowColor = Colors.transparent;
TextStyle textStyle = TextStyle(color: Colors.black);
bool isClickable = false;
if (row['relationship'] == 'Self') {
rowColor = Color(0xFFFFF1DD); // Setting background color for 'Self' rows
textStyle = TextStyle(color: Colors.black);
isClickable = true; // Making 'Self' rows clickable
}
// Format date of birth to "July 10, 1996"
String dob = row['dob'] != null ? formatDateString(row['dob']) : 'N/A';
// String doj = row['doj'] != null ? formatDateString(row['doj']) : 'N/A';
String dateCoverage = row['date_coverage'] != null
? formatDateString(row['date_coverage'])
: 'N/A';
return DataRow(
color: MaterialStateColor.resolveWith(
(states) => rowColor), // Setting row background color
cells: [
DataCell(
Text(row['emp_code'].toString(), style: textStyle),
onTap: isClickable
? () => _navigateToAnotherPage(row)
: null, // Navigation only for 'Self' rows
),
DataCell(Text(row['tpa_id'].toString(), style: textStyle)),
DataCell(Text(row['name'].toString(), style: textStyle)),
DataCell(Text(row['relationship'].toString(), style: textStyle)),
DataCell(Text(dob, style: textStyle)),
DataCell(Text(row['gender'] ?? 'N/A', style: textStyle)),
DataCell(Text(row['mobile'] ?? 'N/A', style: textStyle)),
// DataCell(Text(doj, style: textStyle)),
DataCell(Text(dateCoverage, style: textStyle)),
DataCell(Text(row['email_corporate'] ?? 'N/A', style: textStyle)),
DataCell(Text(row['basic_cover_si'] ?? 'N/A', style: textStyle)),
DataCell(Text(row['grade'] ?? 'N/A', style: textStyle)),
DataCell(Text(row['basic_pay'] ?? 'N/A', style: textStyle)),
],
);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => _data.length;
@override
int get selectedRowCount => 0;
void _navigateToAnotherPage(row) async {
print(row['mobile']);
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('showBackToHR', true);
prefs.setString('employee_id', row['employee_id']);
// Navigation logic here
Navigator.pushNamed(context, 'empDetails',
arguments: {'mobile': row['mobile']});
}
String formatDateString(String dateString) {
// Parse the date string to DateTime object
DateTime dateTime = DateTime.parse(dateString);
// Format the DateTime object to "dd-mm-yyyy"
String formattedDate = DateFormat('dd-MM-yyyy').format(dateTime);
return formattedDate;
}
}
// Sample Data class representing each element in the array
class Data {
final dynamic value;
final int row;
final int column;
final String sheet;
Data(this.value, this.row, this.column, this.sheet);
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhancepolicy/addons.dart';
import 'package:nhancepolicy/empReview.dart';
import 'package:nhancepolicy/empDetails.dart';
@ -33,11 +34,24 @@ Future<void> main() async {
runApp(MaterialApp(
initialRoute: 'hrLogin',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xFF00999E), // Primary theme color
scaffoldBackgroundColor: Colors.white,
colorScheme: ColorScheme.fromSeed(
seedColor: Color(0xFF00999E),
),
textTheme: GoogleFonts.poppinsTextTheme(),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF00999E), // Button background
),
),
),
routes: {
'phone': (context) => MyPhone(),
'mailVerify': (context) => MyEmailVerify(
email: '',
),
email: '',
),
'verify': (context) => MyVerify(
verificationId: '',
mobileNumber: '',
@ -53,7 +67,9 @@ Future<void> main() async {
onResendCode: (String, int) {},
),
'hrHome': (context) => MyHrHome(),
'excelVerify': (context) => excelVerify(),
'excelVerify': (context) => excelVerify(
Token: '',
),
'empDetails': (context) => empDetails(),
'addOnsDetails': (context) => addOnsDetails(),
'empReviewDetails': (context) => empReviewDetails(),
@ -66,7 +82,18 @@ Future<void> main() async {
empClientId: '',
postToken: '',
),
'hrPolicyDetails': (context) => hrPolicyDetails(),
'hrPolicyDetails': (context) => hrPolicyDetails(
ClientId: '',
ClientPoliyId: '',
HrId: '',
Token: '',
TokenType: '',
cardType: '',
cardPolicyNo: '',
cardInsurer_name: '',
cardPolicy_name: '',
cardPolicy_ExpDate: '',
),
'oldPolicy': (context) => oldPolicy(),
},
));

View File

@ -415,13 +415,30 @@ class ApiService {
String clintID, String empRefId, String hr_id, String token) async {
print("getCashDepositDetailsToApi1");
if (token == null) {
await _initializeToken();
}
final url = Uri.parse(
'${Environment.apiUrl}getPolicyLevelEmployeeSummaryData?client_id=$clintID&client_branch_id=$empRefId&hr_id=470');
final headers = {
'Authorization': 'Bearer $token' ?? '',
};
final response = await _makeGetRequest(url, headers);
return response;
}
Future<Map<String, dynamic>> getActiveCashDepositDetailsToApi(String clintID,
String empRefId, String hr_id, String token, int emp_status) async {
print("getCashDepositDetailsToApi1");
if (token == null) {
await _initializeToken();
}
// final url = Uri.parse(
// '${Environment.apiUrl}getPolicyLevelEmployeeSummaryData?client_id=$clintID&client_branch_id=$empRefId&hr_id=470');
final url = Uri.parse(
'${Environment.apiUrl}getPolicyLevelEmployeeSummaryData?client_id=$clintID&client_branch_id=$empRefId&hr_id=$hr_id');
'${Environment.apiUrlPost}getPolicyLevelEmployeeSummaryData?client_id=$clintID&client_branch_id=$empRefId&policy_status=$emp_status&hr_id=$hr_id');
final headers = {
'Authorization': 'Bearer $token' ?? '',
@ -457,15 +474,30 @@ class ApiService {
}
Future<Map<String, dynamic>> getEmployeeAndDependenceToApi(
String clintID, String getPolicyNo, String empRefId) async {
String clintID, String getPolicyNo, String empRefId, String token) async {
print(_hrtoken);
if (_hrtoken == null) {
if (token == null) {
await _initializeToken();
}
final url = Uri.parse(
'${Environment.apiUrlPost}getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo&client_branch_id=$empRefId');
final headers = {
'Authorization': 'Bearer $token' ?? '',
};
final response = await _makeGetRequest(url, headers);
return response;
}
Future<Map<String, dynamic>> getEmployeeAndDependenceToApiPre(
String clintID, String getPolicyNo, String empRefId, String token) async {
print(_hrtoken);
if (token == null) {
await _initializeToken();
}
final url = Uri.parse(
'${Environment.apiUrl}getEmployeeAndDependenceByClientId?client_id=$clintID&client_policy_id=$getPolicyNo&client_branch_id=$empRefId');
final headers = {
'Authorization': 'Bearer $_hrtoken' ?? '',
'Authorization': 'Bearer $token' ?? '',
};
final response = await _makeGetRequest(url, headers);
return response;

View File

@ -5,17 +5,20 @@ import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import '../../hrPolicyDetails.dart';
import '../api_service.dart';
class ActivePolicies extends StatefulWidget {
final String empClientId;
final String empClientBranchId;
final String empHrId;
final String postToken;
const ActivePolicies(
{Key? key,
required this.empClientId,
required this.empClientBranchId,
required this.postToken,
required this.empHrId});
@override
@ -25,21 +28,159 @@ class ActivePolicies extends StatefulWidget {
class _ActivePolicieState extends State<ActivePolicies> {
late ApiService apiService;
dynamic getCardArrays = [];
int selectedIndex = 0;
int selectedIndex = 1;
int stausVal = 1;
// List<Map<String, dynamic>> getCardArrays = [
// {
// "client_policy_id": 392,
// "client_id": 58,
// "policy_type_id": 2,
// "is_addon": 1,
// "OpenForEnrollment": 1,
// "inception_type": 2,
// "policy_no": "GMC-MA8596745566998855885",
// "insurer_id": 1,
// "type": "GMC",
// "policy_name": "Group Medical Coverage",
// "insurer_name": "Life Insurance Corporation of India (LIC)",
// "insurer_short_name": "LIC",
// "totalMembersCount": 7,
// "membersCountOfEnrolled": 0,
// "membersCountOfDraft": 7
// },
// {
// "client_policy_id": 392,
// "client_id": 58,
// "policy_type_id": 2,
// "is_addon": 1,
// "OpenForEnrollment": 1,
// "inception_type": 2,
// "policy_no": "GMC-MA8596745566998855885",
// "insurer_id": 1,
// "type": "GMC",
// "policy_name": "Group Medical Coverage",
// "insurer_name": "Life Insurance Corporation of India (LIC)",
// "insurer_short_name": "LIC",
// "totalMembersCount": 7,
// "membersCountOfEnrolled": 0,
// "membersCountOfDraft": 7
// },
// {
// "client_policy_id": 396,
// "client_id": 58,
// "policy_type_id": 4,
// "is_addon": 2,
// "OpenForEnrollment": 1,
// "inception_type": 2,
// "policy_no": "GMC-MA8596745566998855885",
// "insurer_id": 1,
// "type": "GMC - Topup",
// "policy_name": "Group Medical Coverage Topup",
// "insurer_name": "Life Insurance Corporation of India (LIC)",
// "insurer_short_name": "LIC",
// "totalMembersCount": 7,
// "membersCountOfEnrolled": 0,
// "membersCountOfDraft": 7
// },
// ];
@override
void initState() {
super.initState();
apiService = ApiService(context);
_loadData();
print("_PreEnrollmentState 1");
}
Future<void> _loadData() async {
await getCashDepositDetails(widget.empClientBranchId, widget.empClientId,
widget.empHrId, widget.postToken);
}
Future<void> getCashDepositDetails(
clintBranchId, clintID, hr_id, token) async {
print("_PreEnrollmentState 2");
print('IN');
print("clintBranchId -$clintBranchId");
print("clintID -$clintID");
print("hr_id -$hr_id");
print("token -$token");
// isLoading = true;
// setState(() {
// _isLoading = true;
// });
try {
if (clintBranchId == null || clintID == null) {
return;
}
final response = await apiService.getActiveCashDepositDetailsToApi(
clintID!, clintBranchId!, hr_id, token, stausVal);
// final response = await apiService.getCashDepositDetailsToApi(
// clintID!, clintBranchId!, hr_id, token);
print('IN1');
if (response['status'] == 'success') {
// isLoading = false;
setState(() {
print('response');
print(response['data']);
print("_PreEnrollmentState 3");
setState(() {
getCardArrays = List<Map<String, dynamic>>.from(response['data']);
});
print('getCardArrays');
print(getCardArrays);
});
print('IN2');
print("getCardArrays9 - $getCardArrays");
} else {
print('API request failed with status');
setState(() {
getCardArrays = [];
});
}
} catch (e) {
print('Exception occurred: $e');
}
}
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
final crossAxisCount = 4;
final spacing = 20.0; // crossAxisSpacing
final totalSpacing = (crossAxisCount - 1) * spacing;
final itemWidth = (screenWidth - totalSpacing) / crossAxisCount;
// Example: target card height
final itemHeight = screenHeight * 0.2;
// Dynamic aspect ratio:
final aspectRatio = screenWidth / screenHeight;
print("_PreEnrollmentState 4");
// TODO: implement build
return Container(
color: Colors.white,
// height: MediaQuery.of(context).size.height * 0.2,
// height: 400,
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
// color: Colors.yellow.shade100,
borderRadius: BorderRadius.circular(16),
),
//
child: Column(
children: [
Row(
@ -70,36 +211,217 @@ class _ActivePolicieState extends State<ActivePolicies> {
),
],
),
// Container(
// color: Colors.amber,
// child: Card(
// elevation: 5,
// color: Colors.white,
// child: GridView.builder(
// itemCount: getCardArrays.length,
// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 4,
// crossAxisSpacing: 16,
// mainAxisSpacing: 0,
// childAspectRatio: 2,
// ),
// itemBuilder: (context, index) {
// return buildPolicyCard(getCardArrays[index]);
// },
// ),
// ),
// ),
SizedBox(
height: 15,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
// color: Colors.redAccent.shade100,
// color: Colors.white,
// color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 16.0),
height: MediaQuery.of(context).size.height * 0.4,
// height: 400,
child: getCardArrays.isEmpty
? Center(
child: Text(
'No data found',
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
),
),
)
: GridView.builder(
itemCount: getCardArrays.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
// childAspectRatio: 2,
childAspectRatio: aspectRatio,
// childAspectRatio: 2.1,
),
itemBuilder: (context, index) {
return buildPolicyCard(getCardArrays[index]);
},
),
),
],
),
],
),
);
}
Widget buildTab(String title, int index) {
final isSelected = selectedIndex == index;
Widget buildPolicyCard(Map<String, dynamic> policy) {
print("buildPolicyCard - $policy");
final mediaQuery = MediaQuery.of(context);
final devicePixelRatio = mediaQuery.devicePixelRatio;
final logicalWidth = 230 / devicePixelRatio;
final logicalHeight = 115 / devicePixelRatio;
print("logicalWidth - $logicalWidth");
print("logicalHeight - $logicalHeight");
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
print("policytab - $policy");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => hrPolicyDetails(
ClientId: policy['client_id'].toString(), // <-- from map
ClientPoliyId: policy['client_policy_id'].toString(),
HrId: widget.empClientBranchId,
Token: widget.postToken,
TokenType: 'post',
cardType: policy['type'].toString(),
cardPolicyNo: policy['policy_no'].toString(),
cardInsurer_name: policy['insurer_short_name'].toString(),
cardPolicy_name: policy['policy_name'].toString(),
cardPolicy_ExpDate: policy['policy_expiry_date'].toString(),
),
),
);
});
},
// height: MediaQuery.of(context).size.height * 0.1,
// width: MediaQuery.of(context).size.height * 0.1,
// width: logicalWidth,
// height: logicalHeight,
child: Container(
margin: EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
// height: MediaQuery.of(context).size.height * 1,
// width: MediaQuery.of(context).size.height * 0.1,
// margin: EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(
// color: Colors.yellow.shade50,
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 6,
spreadRadius: 1,
offset: Offset(0, 0), // Equal shadow in all directions
),
],
),
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.07,
// color: Colors.green.shade100,
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${policy['type']} - ${policy['policy_no']} " ?? '',
style: const TextStyle(
fontFamily: "Inter",
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
Text(
"${policy['insurer_short_name']} - ${policy['policy_name']} " ??
'',
style: const TextStyle(
fontSize: 11,
color: Colors.grey,
),
),
],
),
],
),
),
// Spacer(),
Container(
// color: Colors.pink.shade50,
height: MediaQuery.of(context).size.height * 0.09,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildCountBox(
policy['membersCountOfActive'].toString(),
"Active",
Color(0xFF7BD9B6),
),
// Spacer(),
_buildCountBox(
policy['membersCountOfInactive'].toString(),
"Inactive",
Color(0xFFFFA6A6),
),
// Spacer(),
// _buildCountBox(
// policy['totalMembersCount'].toString(), "Total"),
// Spacer(),
],
),
),
],
),
),
),
);
}
Widget _buildCountBox(String count, String label, Color boxColor) {
return Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
// width: 70,
// height: 40,
height: MediaQuery.of(context).size.height * 0.05,
width: MediaQuery.of(context).size.height * 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: boxColor,
// color: const Color(0xFFDFF1F3),
borderRadius: BorderRadius.circular(8),
),
child: Text(
count,
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
),
),
// Spacer(),
const SizedBox(height: 8),
Text(label,
style: const TextStyle(fontSize: 10, color: Color(0xFF848484))),
],
);
}
Widget buildTab(String title, int index) {
final isSelected = selectedIndex == index + 1;
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index + 1;
if (selectedIndex == 2) {
stausVal = 0;
} else {
stausVal = 1;
}
_loadData();
});
},
child: Container(
@ -123,73 +445,10 @@ class _ActivePolicieState extends State<ActivePolicies> {
),
child: Text(title,
style: GoogleFonts.poppins(
fontSize: 11,
color: isSelected ? Colors.white : Colors.black,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w500,
))),
);
}
Widget buildPolicyCard(Map<String, dynamic> policy) {
return Card(
elevation: 3,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
policy['type'] ?? '',
style: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
const SizedBox(height: 4),
Text(
policy['policy_name'] ?? '',
style: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildCountBox(
policy['membersCountOfDraft'].toString(), "Draft"),
_buildCountBox(
policy['membersCountOfEnrolled'].toString(), "Enrolled"),
_buildCountBox(policy['totalMembersCount'].toString(), "Total"),
],
),
],
),
),
);
}
Widget _buildCountBox(String count, String label) {
return Column(
children: [
Container(
width: 50,
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFDFF1F3),
borderRadius: BorderRadius.circular(8),
),
child: Text(
count,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
),
),
const SizedBox(height: 6),
Text(label,
style: const TextStyle(fontSize: 12, color: Colors.black87)),
],
);
}
}

View File

@ -23,15 +23,14 @@ class CdPolicies extends StatefulWidget {
{Key? key,
required this.empClientId,
required this.empClientBranchId,
required this.empHrId, required this.postToken
});
required this.empHrId,
required this.postToken});
@override
State<CdPolicies> createState() => _CdPolicieState();
}
class _CdPolicieState extends State<CdPolicies> {
Uint8List? fileBytes;
List<Map<String, dynamic>> getCDPolicies = [];
bool isLoading = false;
@ -41,7 +40,17 @@ class _CdPolicieState extends State<CdPolicies> {
// List<dynamic> dataPolicy = [];
List<dynamic> reversedDataPolicy = [];
List<Map<String, dynamic>> originalData = []; // Original data source
List<Map<String, dynamic>> filteredData = []; // Filtered data source
// List<Map<String, dynamic>> filteredData = []; // Filtered data source
List<Map<String, dynamic>> filteredData = [
{
"client_id": "58",
"insurer_id": "2",
"cd_ac_pk": "94",
"insurer_name": "ICICI Prudential Life Insurance Co. Ltd",
"cd_master_account_no": "CD-IOCL-887744559966",
"balance": "10000000.00"
}
]; // Filtered data source
dynamic argumentsData;
dynamic policyType;
dynamic policyName;
@ -71,7 +80,8 @@ class _CdPolicieState extends State<CdPolicies> {
});
try {
print('10');
final response = await apiService.getCDPoliciesToApi(widget.empClientId,widget.empHrId,widget.postToken);
final response = await apiService.getCDPoliciesToApi(
widget.empClientId, widget.empHrId, widget.postToken);
if (response['status'] == 'success') {
setState(() {
// isLoading = false;
@ -194,8 +204,10 @@ class _CdPolicieState extends State<CdPolicies> {
decoration: InputDecoration(
hintText: 'Search',
prefixIcon: Icon(Icons.search, size: 18),
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
border: InputBorder.none, // No border since Container handles it
contentPadding:
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
border: InputBorder
.none, // No border since Container handles it
),
controller: searchController,
onChanged: search,
@ -221,9 +233,11 @@ class _CdPolicieState extends State<CdPolicies> {
backgroundColor: Color(0xFFE26728),
padding: EdgeInsets.all(10), // Internal padding
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), // Border radius
borderRadius:
BorderRadius.circular(10), // Border radius
side: BorderSide(
color: Colors.transparent, // Optional border color
color:
Colors.transparent, // Optional border color
width: 1, // Border width
),
),
@ -235,7 +249,6 @@ class _CdPolicieState extends State<CdPolicies> {
),
),
),
],
),
),
@ -315,7 +328,7 @@ class _CdPolicieState extends State<CdPolicies> {
...filteredData.mapIndexed((index, item) {
return Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(vertical: 5 , horizontal: 16),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 16),
decoration: BoxDecoration(
color: index % 2 == 0 ? Color(0xFFE6FAFB) : Colors.white,
borderRadius: BorderRadius.circular(6),
@ -380,9 +393,6 @@ class _CdPolicieState extends State<CdPolicies> {
],
);
}
}
class _DependenceDataSource0 extends DataTableSource {
@ -429,7 +439,6 @@ class _DependenceDataSource0 extends DataTableSource {
int get selectedRowCount => 0;
}
// Sample Data class representing each element in the array
class Data {
final dynamic value;
@ -438,4 +447,4 @@ class Data {
final String sheet;
Data(this.value, this.row, this.column, this.sheet);
}
}

View File

@ -24,7 +24,18 @@ class _ClaimsPolicieState extends State<ClaimsPolicies> {
Widget build(BuildContext context) {
// TODO: implement build
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10), // 👈 set your desired radius
),
padding: const EdgeInsets.all(16.0),
child: Text("Claims policy data"),
);
}
// Widget _buildName(context){
// return TextField(
//
// )
// }
}

View File

@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import '../../hrPolicyDetails.dart';
import '../api_service.dart';
class PreEnrollment extends StatefulWidget {
@ -28,6 +29,44 @@ class _PreEnrollmentState extends State<PreEnrollment> {
late ApiService apiService;
dynamic getCardArrays = [];
int selectedIndex = 0;
// List<Map<String, dynamic>> getCardArrays = [
// {
// "client_policy_id": 392,
// "client_id": 58,
// "policy_type_id": 2,
// "is_addon": 1,
// "OpenForEnrollment": 1,
// "inception_type": 2,
// "policy_no": "GMC-MA8596745566998855885",
// "insurer_id": 1,
// "type": "GMC",
// "policy_name": "Group Medical Coverage",
// "insurer_name": "Life Insurance Corporation of India (LIC)",
// "insurer_short_name": "LIC",
// "totalMembersCount": 7,
// "membersCountOfEnrolled": 0,
// "membersCountOfDraft": 7
// },
// {
// "client_policy_id": 396,
// "client_id": 58,
// "policy_type_id": 4,
// "is_addon": 2,
// "OpenForEnrollment": 1,
// "inception_type": 2,
// "policy_no": "GMC-MA8596745566998855885",
// "insurer_id": 1,
// "type": "GMC - Topup",
// "policy_name": "Group Medical Coverage Topup",
// "insurer_name": "Life Insurance Corporation of India (LIC)",
// "insurer_short_name": "LIC",
// "totalMembersCount": 7,
// "membersCountOfEnrolled": 0,
// "membersCountOfDraft": 7
// },
//
//
// ];
@override
void initState() {
@ -79,6 +118,7 @@ class _PreEnrollmentState extends State<PreEnrollment> {
});
print('IN2');
print("getCardArrays9 - $getCardArrays");
} else {
print('API request failed with status');
}
@ -89,123 +129,200 @@ class _PreEnrollmentState extends State<PreEnrollment> {
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
final crossAxisCount = 4;
final spacing = 20.0; // crossAxisSpacing
final totalSpacing = (crossAxisCount - 1) * spacing;
final itemWidth = (screenWidth - totalSpacing) / crossAxisCount;
// Example: target card height
final itemHeight = screenHeight * 0.2;
// Dynamic aspect ratio:
final aspectRatio = screenWidth / screenHeight;
print("_PreEnrollmentState 4");
// TODO: implement build
return Container(
color: Colors.white,
// height: MediaQuery.of(context).size.height * 0.2,
// height: 400,
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
color: Colors.white,
// color: Colors.yellow.shade100,
borderRadius: BorderRadius.circular(16),
),
//
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
color: Colors.white,
child: SizedBox(
height: 400,
child: GridView.builder(
itemCount: getCardArrays.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 16,
mainAxisSpacing: 0,
childAspectRatio: 2,
),
itemBuilder: (context, index) {
return buildPolicyCard(getCardArrays[index]);
},
),
),
// color: Colors.redAccent.shade100,
// color: Colors.white,
// color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 16.0),
height: MediaQuery.of(context).size.height * 0.45,
// height: 400,
child: getCardArrays.isEmpty
? Center(
child: Text(
'No data found',
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade600,
),
),
)
: GridView.builder(
itemCount: getCardArrays.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
// childAspectRatio: 2,
childAspectRatio: aspectRatio,
// childAspectRatio: 2.1,
),
itemBuilder: (context, index) {
return buildPolicyCard(getCardArrays[index]);
},
),
),
],
),
);
}
Widget buildTab(String title, int index) {
final isSelected = selectedIndex == index;
Widget buildPolicyCard(Map<String, dynamic> policy) {
final mediaQuery = MediaQuery.of(context);
final devicePixelRatio = mediaQuery.devicePixelRatio;
final logicalWidth = 230 / devicePixelRatio;
final logicalHeight = 115 / devicePixelRatio;
print("logicalWidth - $logicalWidth");
print("logicalHeight - $logicalHeight");
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
print("policytab - $policy");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => hrPolicyDetails(
ClientId: policy['client_id'].toString(), // <-- from map
ClientPoliyId: policy['client_policy_id'].toString(),
HrId: widget.enrollmentClientBranchId,
Token: widget.enrollToken,
TokenType: "pre",
cardType: policy['type'].toString(),
cardPolicyNo: policy['policy_no'].toString(),
cardInsurer_name: policy['insurer_short_name'].toString(),
cardPolicy_name: policy['policy_name'].toString(),
cardPolicy_ExpDate: policy['policy_expiry_date'].toString(),
),
),
);
});
},
child: Container(
padding: const EdgeInsets.only(
top: 6.5, bottom: 6.0, left: 20.0, right: 20.0),
decoration: BoxDecoration(
color: isSelected ? const Color(0xFF009195) : Colors.transparent,
boxShadow: isSelected
? [
BoxShadow(
color: isSelected
? const Color(0xFF009195)
: Colors.transparent, // Grey shadow
spreadRadius: 0.2,
blurRadius: 1,
offset: const Offset(0, 1), // Horizontal, Vertical
),
]
: [],
borderRadius: BorderRadius.circular(16),
),
child: Text(title,
style: GoogleFonts.poppins(
color: isSelected ? Colors.white : Colors.black,
fontWeight: FontWeight.w600,
))),
);
}
Widget buildPolicyCard(Map<String, dynamic> policy) {
return Card(
color: Colors.white,
elevation: 3,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
policy['type'] ?? '',
style: const TextStyle(
fontFamily: "Inter",
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
const SizedBox(height: 2),
Text(
policy['policy_name'] ?? '',
style: const TextStyle(
fontSize: 12,
color: Colors.grey,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildCountBox(
policy['membersCountOfDraft'].toString(), "Draft"),
_buildCountBox(
policy['membersCountOfEnrolled'].toString(), "Enrolled"),
_buildCountBox(policy['totalMembersCount'].toString(), "Total"),
],
// height: MediaQuery.of(context).size.height * 0.1,
// width: MediaQuery.of(context).size.height * 0.1,
// width: logicalWidth,
// height: logicalHeight,
child: Container(
margin: EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
// height: MediaQuery.of(context).size.height * 1,
// width: MediaQuery.of(context).size.height * 0.1,
// margin: EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(
// color: Colors.yellow.shade50,
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 6,
spreadRadius: 1,
offset: Offset(0, 0), // Equal shadow in all directions
),
],
),
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.07,
// color: Colors.green.shade100,
child: Row(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${policy['type']} - ${policy['policy_no']} " ?? '',
style: const TextStyle(
fontFamily: "Inter",
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
Text(
"${policy['insurer_short_name']} - ${policy['policy_name']} " ??
'',
style: const TextStyle(
fontSize: 11,
color: Colors.grey,
),
),
],
),
],
),
),
// Spacer(),
Container(
// color: Colors.pink.shade50,
height: MediaQuery.of(context).size.height * 0.09,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
_buildCountBox(
policy['membersCountOfDraft'].toString(), "Draft"),
Spacer(),
_buildCountBox(policy['membersCountOfEnrolled'].toString(),
"Enrolled"),
Spacer(),
_buildCountBox(
policy['totalMembersCount'].toString(), "Total"),
// Spacer(),
],
),
),
],
),
),
),
);
}
Widget _buildCountBox(String count, String label) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 70,
height: 40,
// width: 70,
// height: 40,
height: MediaQuery.of(context).size.height * 0.05,
width: MediaQuery.of(context).size.height * 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: const Color(0xFFDFF1F3),
@ -213,9 +330,10 @@ class _PreEnrollmentState extends State<PreEnrollment> {
),
child: Text(
count,
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
),
),
// Spacer(),
const SizedBox(height: 8),
Text(label,
style: const TextStyle(fontSize: 10, color: Color(0xFF848484))),

View File

@ -5,6 +5,7 @@
import FlutterMacOS
import Foundation
import file_picker
import firebase_auth
import firebase_core
import google_sign_in_ios
@ -14,6 +15,7 @@ import smart_auth
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))

View File

@ -94,6 +94,7 @@ flutter:
- .env.production
- .env.uat
- .env.test
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see