policy list page new design
This commit is contained in:
parent
d4706f1dd0
commit
b8bd8952ed
@ -911,23 +911,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _resetPreStatusFilter() {
|
void _resetPreStatusFilter() {
|
||||||
setState(() {
|
_resetToLanding();
|
||||||
_preStatusFilter = null;
|
|
||||||
_currentPage = 1;
|
|
||||||
});
|
|
||||||
_searchDebounce?.cancel();
|
|
||||||
final query = searchController.text.trim();
|
|
||||||
if (query.isEmpty) {
|
|
||||||
setState(() {
|
|
||||||
_hasSearched = false;
|
|
||||||
_isSearching = false;
|
|
||||||
originalData = [];
|
|
||||||
filteredData = [];
|
|
||||||
getCDPolicies = [];
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_searchEmployeesViaApi(query);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> downloadEmployeeListExcel() async {
|
Future<void> downloadEmployeeListExcel() async {
|
||||||
@ -1745,6 +1729,21 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
void _resetToLanding() {
|
||||||
|
_searchDebounce?.cancel();
|
||||||
|
searchController.clear();
|
||||||
|
setState(() {
|
||||||
|
_preStatusFilter = null;
|
||||||
|
_hasSearched = false;
|
||||||
|
_isSearching = false;
|
||||||
|
isLoading = false;
|
||||||
|
originalData = [];
|
||||||
|
filteredData = [];
|
||||||
|
getCDPolicies = [];
|
||||||
|
_currentPage = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseLayout(
|
return BaseLayout(
|
||||||
child: _buildContent(context),
|
child: _buildContent(context),
|
||||||
@ -1752,15 +1751,534 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContent(BuildContext context) {
|
Widget _buildContent(BuildContext context) {
|
||||||
|
final showResults = _hasSearched || _isSearching;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: const Color(0xFFF8FAFC),
|
backgroundColor: Colors.white,
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: Stack(
|
child: AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 280),
|
||||||
|
switchInCurve: Curves.easeOutCubic,
|
||||||
|
switchOutCurve: Curves.easeInCubic,
|
||||||
|
child: showResults
|
||||||
|
? KeyedSubtree(
|
||||||
|
key: const ValueKey('results'),
|
||||||
|
child: _buildResultsWorkspace(),
|
||||||
|
)
|
||||||
|
: KeyedSubtree(
|
||||||
|
key: const ValueKey('landing'),
|
||||||
|
child: _buildGoogleLandingView(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String get _policyTitleLine =>
|
||||||
|
'${localCardType ?? ''} - ${localCardPolicyNo ?? ''}'.trim();
|
||||||
|
|
||||||
|
String get _policySubtitleLine => localTokenType == 'pre'
|
||||||
|
? '${localCardPolicyName ?? ''} (${localCardPolicyExpDate ?? ''})'
|
||||||
|
: '${localCardInsurerName ?? ''} - ${localCardPolicyName ?? ''} (${localCardPolicyExpDate ?? ''})';
|
||||||
|
|
||||||
|
/// First-entry Google-style home: title → search → action icons → filter icons.
|
||||||
|
Widget _buildGoogleLandingView() {
|
||||||
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
// ===================== MAIN CONTENT =====================
|
Positioned(
|
||||||
Column(
|
top: 12,
|
||||||
|
left: 12,
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: 'Previous Page',
|
||||||
|
onPressed: () async {
|
||||||
|
await clearPolicyStorage();
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => policies()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.arrow_back_ios_new_rounded,
|
||||||
|
size: 18,
|
||||||
|
color: Color(0xFF0F172A),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: const EdgeInsets.fromLTRB(24, 48, 24, 32),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 720),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_policyTitleLine,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
color: const Color(0xFF0F172A),
|
||||||
|
fontSize: 34,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
_policySubtitleLine,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
color: const Color(0xFF64748B),
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 36),
|
||||||
|
_buildLandingSearchPill(),
|
||||||
|
const SizedBox(height: 28),
|
||||||
|
_buildLandingShortcutRow(
|
||||||
|
items: _landingActionShortcuts(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 22),
|
||||||
|
if (_isLoadingCards)
|
||||||
|
const Padding(
|
||||||
|
padding: EdgeInsets.only(top: 12),
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
color: Color(0xFF009195),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else if (_filterChips.isNotEmpty)
|
||||||
|
_buildLandingFilterMetricsRow(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLandingSearchPill() {
|
||||||
|
return Container(
|
||||||
|
height: 54,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(999),
|
||||||
|
border: Border.all(color: const Color(0xFFE2E8F0)),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black.withValues(alpha: 0.06),
|
||||||
|
blurRadius: 16,
|
||||||
|
offset: const Offset(0, 6),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: TextField(
|
||||||
|
controller: searchController,
|
||||||
|
onChanged: search,
|
||||||
|
onSubmitted: (_) {
|
||||||
|
_searchDebounce?.cancel();
|
||||||
|
_searchEmployees();
|
||||||
|
},
|
||||||
|
textInputAction: TextInputAction.search,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: const Color(0xFF0F172A),
|
||||||
|
),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: 'Search by name, emp code, mobile, email…',
|
||||||
|
hintStyle: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
color: const Color(0xFF94A3B8),
|
||||||
|
),
|
||||||
|
prefixIcon: const Icon(
|
||||||
|
Icons.search_rounded,
|
||||||
|
color: Color(0xFF64748B),
|
||||||
|
),
|
||||||
|
suffixIcon: searchController.text.isNotEmpty
|
||||||
|
? IconButton(
|
||||||
|
tooltip: 'Clear',
|
||||||
|
onPressed: () {
|
||||||
|
searchController.clear();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.close_rounded, size: 18),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
border: InputBorder.none,
|
||||||
|
contentPadding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<({String label, IconData icon, Color color, VoidCallback? onTap})>
|
||||||
|
_landingActionShortcuts() {
|
||||||
|
return [
|
||||||
|
if (localTokenType == 'pre') ...[
|
||||||
|
(
|
||||||
|
label: 'Reminder',
|
||||||
|
icon: Icons.tune_rounded,
|
||||||
|
color: const Color(0xFF009195),
|
||||||
|
onTap: _openReminderConfigDialog,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
label: 'Mail Template',
|
||||||
|
icon: Icons.mail_outline_rounded,
|
||||||
|
color: const Color(0xFFE26728),
|
||||||
|
onTap: _isSendingReminder ? null : _openReminderTemplateDialog,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
if (localTokenType == 'post') ...[
|
||||||
|
(
|
||||||
|
label: 'Policy Terms',
|
||||||
|
icon: Icons.description_outlined,
|
||||||
|
color: const Color(0xFF009195),
|
||||||
|
onTap: _isLoadingPolicyTerms ? null : _openPolicyTermsDialog,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
label: 'Hospitals',
|
||||||
|
icon: Icons.local_hospital_outlined,
|
||||||
|
color: const Color(0xFF009195),
|
||||||
|
onTap: _isLoadingHospitalList ? null : _openNetworkHospitalListDialog,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
(
|
||||||
|
label: 'Import',
|
||||||
|
icon: Icons.upload_file_rounded,
|
||||||
|
color: const Color(0xFFE26728),
|
||||||
|
onTap: _openImportFlow,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
label: 'Export',
|
||||||
|
icon: Icons.download_rounded,
|
||||||
|
color: const Color(0xFFE26728),
|
||||||
|
onTap: localTokenType == 'pre'
|
||||||
|
? null
|
||||||
|
: (_isExportingExcel ? null : downloadEmployeeListExcel),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<({String key, String label, int count, IconData icon, Color color})>
|
||||||
|
_landingFilterMetrics() {
|
||||||
|
return _filterChips.map((filter) {
|
||||||
|
final key = filter['key'].toString();
|
||||||
|
return (
|
||||||
|
key: key,
|
||||||
|
label: (filter['label'] ?? _chipLabelForKey(key)).toString(),
|
||||||
|
count: int.tryParse('${filter['count']}') ?? 0,
|
||||||
|
icon: _landingFilterIcon(key),
|
||||||
|
color: _landingFilterColor(key),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Filter metrics with rounded-square icons and stylish dividers between.
|
||||||
|
Widget _buildLandingFilterMetricsRow() {
|
||||||
|
final items = _landingFilterMetrics();
|
||||||
|
if (items.isEmpty) return const SizedBox.shrink();
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFF8FAFC),
|
||||||
|
borderRadius: BorderRadius.circular(22),
|
||||||
|
border: Border.all(color: const Color(0xFFE2E8F0)),
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < items.length; i++) ...[
|
||||||
|
if (i > 0) _buildLandingFilterDivider(),
|
||||||
|
_buildLandingFilterMetricTile(items[i]),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLandingFilterDivider() {
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
|
width: 1.5,
|
||||||
|
height: 52,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(999),
|
||||||
|
gradient: const LinearGradient(
|
||||||
|
begin: Alignment.topCenter,
|
||||||
|
end: Alignment.bottomCenter,
|
||||||
|
colors: [
|
||||||
|
Color(0x00CBD5E1),
|
||||||
|
Color(0xFF94A3B8),
|
||||||
|
Color(0x00CBD5E1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLandingFilterMetricTile(
|
||||||
|
({String key, String label, int count, IconData icon, Color color}) item,
|
||||||
|
) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () => _onPreStatusFilterTap(item.key),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 52,
|
||||||
|
height: 52,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: item.color.withValues(alpha: 0.12),
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
border: Border.all(
|
||||||
|
color: item.color.withValues(alpha: 0.22),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Icon(item.icon, color: item.color, size: 24),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'${item.count}',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.1,
|
||||||
|
color: const Color(0xFF0F172A),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
Text(
|
||||||
|
item.label,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 11,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: const Color(0xFF64748B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
IconData _landingFilterIcon(String key) {
|
||||||
|
switch (key.toLowerCase()) {
|
||||||
|
case 'emp_count':
|
||||||
|
return Icons.groups_rounded;
|
||||||
|
case 'submitted':
|
||||||
|
return Icons.verified_rounded;
|
||||||
|
case 'logged_in':
|
||||||
|
return Icons.login_rounded;
|
||||||
|
case 'not_logged_in':
|
||||||
|
return Icons.person_off_rounded;
|
||||||
|
case 'draft':
|
||||||
|
return Icons.edit_note_rounded;
|
||||||
|
default:
|
||||||
|
return Icons.filter_alt_rounded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Color _landingFilterColor(String key) {
|
||||||
|
switch (key.toLowerCase()) {
|
||||||
|
case 'emp_count':
|
||||||
|
return const Color(0xFF3B82F6);
|
||||||
|
case 'submitted':
|
||||||
|
return const Color(0xFF16A34A);
|
||||||
|
case 'logged_in':
|
||||||
|
return const Color(0xFF009195);
|
||||||
|
case 'not_logged_in':
|
||||||
|
return const Color(0xFF6366F1);
|
||||||
|
case 'draft':
|
||||||
|
return const Color(0xFFE26728);
|
||||||
|
default:
|
||||||
|
return const Color(0xFF009195);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLandingShortcutRow({
|
||||||
|
required List<
|
||||||
|
({String label, IconData icon, Color color, VoidCallback? onTap})>
|
||||||
|
items,
|
||||||
|
}) {
|
||||||
|
return Wrap(
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 18,
|
||||||
|
runSpacing: 16,
|
||||||
|
children: [
|
||||||
|
for (final item in items)
|
||||||
|
_buildLandingShortcutTile(
|
||||||
|
label: item.label,
|
||||||
|
icon: item.icon,
|
||||||
|
color: item.color,
|
||||||
|
onTap: item.onTap,
|
||||||
|
isExportMenu: item.label == 'Export' && localTokenType == 'pre',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildLandingShortcutTile({
|
||||||
|
required String label,
|
||||||
|
required IconData icon,
|
||||||
|
required Color color,
|
||||||
|
required VoidCallback? onTap,
|
||||||
|
bool isExportMenu = false,
|
||||||
|
}) {
|
||||||
|
final tile = SizedBox(
|
||||||
|
width: 84,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 56,
|
||||||
|
height: 56,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: color.withValues(alpha: 0.1),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(color: color.withValues(alpha: 0.18)),
|
||||||
|
),
|
||||||
|
child: Icon(icon, color: color, size: 24),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 11,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.2,
|
||||||
|
color: const Color(0xFF334155),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isExportMenu) {
|
||||||
|
return PopupMenuButton<String>(
|
||||||
|
tooltip: 'Export',
|
||||||
|
offset: const Offset(0, 8),
|
||||||
|
onSelected: (value) {
|
||||||
|
if (value == 'csv') {
|
||||||
|
downloadEmployeeListExcel();
|
||||||
|
} else if (value == 'inception') {
|
||||||
|
downloadInceptionExport();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemBuilder: (context) => [
|
||||||
|
PopupMenuItem(
|
||||||
|
value: 'csv',
|
||||||
|
child: Text('Export Excel', style: GoogleFonts.poppins(fontSize: 13)),
|
||||||
|
),
|
||||||
|
PopupMenuItem(
|
||||||
|
value: 'inception',
|
||||||
|
child: Text(
|
||||||
|
'Inception Export',
|
||||||
|
style: GoogleFonts.poppins(fontSize: 13),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: tile,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
child: tile,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _openImportFlow() async {
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_ClientId', widget.ClientId.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_policyTypeId', widget.policyTypeId.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_ClientPoliyId', widget.ClientPoliyId.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_clientBranchId', widget.clientBranchId.toString());
|
||||||
|
await tokenService.writeValue('upload_Token', widget.Token.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_TokenType', widget.TokenType.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_cardType', widget.cardType.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_cardPolicyNo', widget.cardPolicyNo.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_cardInsurer_name', widget.cardInsurer_name.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_cardPolicy_name', widget.cardPolicy_name.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_cardPolicy_ExpDate', widget.cardPolicy_ExpDate.toString());
|
||||||
|
await tokenService.writeValue(
|
||||||
|
'upload_total_premium', widget.total_premium.toString());
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: localTokenType != "post"
|
||||||
|
? const RouteSettings(name: 'preFileUpload')
|
||||||
|
: const RouteSettings(name: 'postFileUpload'),
|
||||||
|
builder: (context) => localTokenType != "post"
|
||||||
|
? preFileUpload(
|
||||||
|
ClientId: widget.ClientId,
|
||||||
|
policyTypeId: widget.policyTypeId,
|
||||||
|
ClientPoliyId: widget.ClientPoliyId,
|
||||||
|
clientBranchId: widget.clientBranchId,
|
||||||
|
Token: widget.Token,
|
||||||
|
TokenType: widget.TokenType,
|
||||||
|
cardType: widget.cardType,
|
||||||
|
cardPolicyNo: widget.cardPolicyNo,
|
||||||
|
cardInsurer_name: widget.cardInsurer_name,
|
||||||
|
cardPolicy_name: widget.cardPolicy_name,
|
||||||
|
cardPolicy_ExpDate: widget.cardPolicy_ExpDate,
|
||||||
|
total_premium: widget.total_premium,
|
||||||
|
)
|
||||||
|
: postFileUpload(
|
||||||
|
ClientId: widget.ClientId,
|
||||||
|
policyTypeId: widget.policyTypeId,
|
||||||
|
ClientPoliyId: widget.ClientPoliyId,
|
||||||
|
clientBranchId: widget.clientBranchId,
|
||||||
|
Token: widget.Token,
|
||||||
|
TokenType: widget.TokenType,
|
||||||
|
cardType: widget.cardType,
|
||||||
|
cardPolicyNo: widget.cardPolicyNo,
|
||||||
|
cardInsurer_name: widget.cardInsurer_name,
|
||||||
|
cardPolicy_name: widget.cardPolicy_name,
|
||||||
|
cardPolicy_ExpDate: widget.cardPolicy_ExpDate,
|
||||||
|
total_premium: widget.total_premium,
|
||||||
|
allocgType: 'EB',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Current design: header actions + find members + table.
|
||||||
|
Widget _buildResultsWorkspace() {
|
||||||
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
// ---------------- HEADER ----------------
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(
|
||||||
@ -1770,19 +2288,11 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Previous Page',
|
tooltip: 'Back to home',
|
||||||
onPressed: () async => {
|
onPressed: _resetToLanding,
|
||||||
await clearPolicyStorage(),
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => policies(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.arrow_back_ios_new_rounded,
|
Icons.arrow_back_ios_new_rounded,
|
||||||
size: 18,
|
size: 18,
|
||||||
@ -1797,8 +2307,9 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"${localCardType} - ${localCardPolicyNo} " ??
|
_policyTitleLine,
|
||||||
'',
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
color: const Color(0xFF0F172A),
|
color: const Color(0xFF0F172A),
|
||||||
fontSize: isCompact ? 15 : 17,
|
fontSize: isCompact ? 15 : 17,
|
||||||
@ -1807,9 +2318,9 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 2),
|
||||||
Text(
|
Text(
|
||||||
localTokenType == 'pre'
|
_policySubtitleLine,
|
||||||
? "${localCardPolicyName} (${localCardPolicyExpDate})"
|
maxLines: 1,
|
||||||
: "${localCardInsurerName} - ${localCardPolicyName} (${localCardPolicyExpDate})",
|
overflow: TextOverflow.ellipsis,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
color: const Color(0xFF64748B),
|
color: const Color(0xFF64748B),
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -1819,22 +2330,22 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(width: 12),
|
||||||
),
|
Flexible(
|
||||||
const SizedBox(height: 14),
|
child: Align(
|
||||||
Wrap(
|
alignment: Alignment.centerRight,
|
||||||
spacing: 10,
|
child: Wrap(
|
||||||
runSpacing: 10,
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
alignment: WrapAlignment.end,
|
alignment: WrapAlignment.end,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
if (localIsEcardBulkDownload == 1)
|
if (localIsEcardBulkDownload == 1)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: getEcardBulkDownload,
|
||||||
getEcardBulkDownload();
|
|
||||||
},
|
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: const Color(0xFFE26728),
|
backgroundColor: const Color(0xFFE26728),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
@ -1855,13 +2366,13 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
_buildHeaderActionButton(
|
_buildHeaderActionButton(
|
||||||
label: 'Reminder Config',
|
label: 'Reminder Config',
|
||||||
color: const Color(0xFF009195),
|
color: const Color(0xFF009195),
|
||||||
width: 150,
|
width: isCompact ? 130 : 150,
|
||||||
onPressed: _openReminderConfigDialog,
|
onPressed: _openReminderConfigDialog,
|
||||||
),
|
),
|
||||||
_buildHeaderActionButton(
|
_buildHeaderActionButton(
|
||||||
label: 'Reminder Mail Template',
|
label: 'Reminder Mail Template',
|
||||||
color: const Color(0xFFE26728),
|
color: const Color(0xFFE26728),
|
||||||
width: 210,
|
width: isCompact ? 170 : 210,
|
||||||
onPressed: _isSendingReminder
|
onPressed: _isSendingReminder
|
||||||
? null
|
? null
|
||||||
: _openReminderTemplateDialog,
|
: _openReminderTemplateDialog,
|
||||||
@ -1892,15 +2403,16 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
_buildExportButton(),
|
_buildExportButton(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
// ---------------- SEARCH + FILTER CHIPS ----------------
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(
|
||||||
@ -1909,10 +2421,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
|
||||||
// ---------------- TABLE (after search only) ----------------
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
@ -1929,24 +2438,44 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
'assets/nhance-loader.gif',
|
'assets/nhance-loader.gif',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: !_hasSearched
|
|
||||||
? KeyedSubtree(
|
|
||||||
key: const ValueKey('prompt'),
|
|
||||||
child: _buildSearchPromptEmptyState(),
|
|
||||||
)
|
|
||||||
: filteredData.isEmpty
|
: filteredData.isEmpty
|
||||||
? Center(
|
? Center(
|
||||||
key: const ValueKey('empty'),
|
key: const ValueKey('empty'),
|
||||||
child: Text(
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
'No matching members found',
|
'No matching members found',
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: const Color(0xFF64748B),
|
color: const Color(0xFF64748B),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextButton(
|
||||||
|
onPressed: _resetToLanding,
|
||||||
|
child: Text(
|
||||||
|
'Back to home',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: const Color(0xFF009195),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
: DecoratedBox(
|
: LayoutBuilder(
|
||||||
key: const ValueKey('table'),
|
key: const ValueKey('table'),
|
||||||
|
builder: (context, constraints) {
|
||||||
|
return Align(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: BoxConstraints(
|
||||||
|
maxHeight: constraints.maxHeight,
|
||||||
|
minWidth: constraints.maxWidth,
|
||||||
|
),
|
||||||
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
@ -1964,23 +2493,18 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
),
|
),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
child: Column(
|
child: _buildCDDataTable(context),
|
||||||
children: [
|
),
|
||||||
_buildCDDataTable(context),
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
const SizedBox(height: 48),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2669,22 +3193,23 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCDDataTable(BuildContext context) {
|
Widget _buildCDDataTable(BuildContext context) {
|
||||||
return Expanded(
|
final showUHID = localPolicyTypeId != '6' && localPolicyTypeId != '7';
|
||||||
child: CustomScrollView(
|
final showLoggedIn = localTokenType == 'pre';
|
||||||
|
final showAction =
|
||||||
|
localTokenType != 'pre' && (hasAnyEcardLink || hasModule);
|
||||||
|
|
||||||
|
return CustomScrollView(
|
||||||
|
shrinkWrap: true,
|
||||||
slivers: [
|
slivers: [
|
||||||
/// 🔒 Sticky Header
|
|
||||||
SliverPersistentHeader(
|
SliverPersistentHeader(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
delegate: _CDHeaderDelegate(
|
delegate: _CDHeaderDelegate(
|
||||||
showUHID: localPolicyTypeId != '6' && localPolicyTypeId != '7',
|
showUHID: showUHID,
|
||||||
uhidHeaderLabel: localTokenType == 'post' ? 'TPA ID' : 'UHID',
|
uhidHeaderLabel: localTokenType == 'post' ? 'TPA ID' : 'UHID',
|
||||||
showLoggedIn: localTokenType == "pre",
|
showLoggedIn: showLoggedIn,
|
||||||
showAction:
|
showAction: showAction,
|
||||||
localTokenType != "pre" && (hasAnyEcardLink || hasModule),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
/// 📄 Rows
|
|
||||||
SliverList(
|
SliverList(
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
@ -2694,13 +3219,16 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
childCount: _paginatedData.length,
|
childCount: _paginatedData.length,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
/// 📌 Pagination
|
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: _buildPagination(context),
|
child: Column(
|
||||||
),
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Divider(height: 1, thickness: 1, color: Color(0xFFE2E8F0)),
|
||||||
|
_buildPagination(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3589,35 +4117,44 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
List<int> visiblePages = getVisiblePages();
|
List<int> visiblePages = getVisiblePages();
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
// Match this horizontal padding (16) to your Table Header padding for perfect alignment
|
padding: const EdgeInsets.fromLTRB(12, 6, 12, 6),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
.spaceBetween, // Pushes text to left, buttons to right
|
|
||||||
children: [
|
children: [
|
||||||
// --- LEFT SIDE: Showing Text ---
|
Flexible(
|
||||||
Text(
|
child: Text(
|
||||||
"Showing $startEntry to $endEntry of $totalItems entries",
|
"Showing $startEntry to $endEntry of $totalItems entries",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 13,
|
fontSize: 12,
|
||||||
color: const Color(0xFF585757),
|
color: const Color(0xFF585757),
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// --- RIGHT SIDE: Controls ---
|
|
||||||
Row(
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
// Dropdown for rows per page
|
Text(
|
||||||
DropdownButton<int>(
|
'Rows',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 12,
|
||||||
|
color: const Color(0xFF64748B),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 6),
|
||||||
|
DropdownButtonHideUnderline(
|
||||||
|
child: DropdownButton<int>(
|
||||||
value: _rowsPerPage,
|
value: _rowsPerPage,
|
||||||
focusColor: Colors
|
isDense: true,
|
||||||
.transparent, // Fix: Removes the grey/blue highlight on change
|
focusColor: Colors.transparent,
|
||||||
items: [5, 10, 15, 20, 50].map((int value) {
|
items: [5, 10, 15, 20, 50].map((int value) {
|
||||||
return DropdownMenuItem<int>(
|
return DropdownMenuItem<int>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(' $value ',
|
child: Text(
|
||||||
style: GoogleFonts.poppins(fontSize: 15)),
|
'$value',
|
||||||
|
style: GoogleFonts.poppins(fontSize: 13),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: (newValue) {
|
onChanged: (newValue) {
|
||||||
@ -3627,47 +4164,43 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(width: 8),
|
|
||||||
|
|
||||||
// Previous button
|
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: 'Previous Page',
|
tooltip: 'Previous Page',
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
constraints: const BoxConstraints(minWidth: 32, minHeight: 32),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
onPressed: _currentPage > 1
|
onPressed: _currentPage > 1
|
||||||
? () => setState(() => _currentPage--)
|
? () => setState(() => _currentPage--)
|
||||||
: null,
|
: null,
|
||||||
icon: const Icon(Icons.chevron_left),
|
icon: const Icon(Icons.chevron_left, size: 20),
|
||||||
),
|
),
|
||||||
|
|
||||||
// First page + left ellipsis
|
|
||||||
if (!visiblePages.contains(1))
|
if (!visiblePages.contains(1))
|
||||||
Row(children: [
|
Row(children: [
|
||||||
_buildPageButton(1),
|
_buildPageButton(1),
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 4),
|
padding: EdgeInsets.symmetric(horizontal: 2),
|
||||||
child: Text("..."),
|
child: Text("..."),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// Visible page buttons
|
|
||||||
for (int page in visiblePages) _buildPageButton(page),
|
for (int page in visiblePages) _buildPageButton(page),
|
||||||
|
|
||||||
// Right ellipsis + last page
|
|
||||||
if (!visiblePages.contains(totalPages) && totalPages > 0)
|
if (!visiblePages.contains(totalPages) && totalPages > 0)
|
||||||
Row(children: [
|
Row(children: [
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 4),
|
padding: EdgeInsets.symmetric(horizontal: 2),
|
||||||
child: Text("..."),
|
child: Text("..."),
|
||||||
),
|
),
|
||||||
_buildPageButton(totalPages),
|
_buildPageButton(totalPages),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
// Next button
|
|
||||||
IconButton(
|
IconButton(
|
||||||
|
tooltip: 'Next Page',
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
constraints: const BoxConstraints(minWidth: 32, minHeight: 32),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
onPressed: _currentPage < totalPages
|
onPressed: _currentPage < totalPages
|
||||||
? () => setState(() => _currentPage++)
|
? () => setState(() => _currentPage++)
|
||||||
: null,
|
: null,
|
||||||
icon: const Icon(Icons.chevron_right),
|
icon: const Icon(Icons.chevron_right, size: 20),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -3678,21 +4211,32 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
|||||||
|
|
||||||
Widget _buildPageButton(int page) {
|
Widget _buildPageButton(int page) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor: _currentPage == page
|
||||||
_currentPage == page ? const Color(0xFF00A6A6) : Colors.grey[300],
|
? const Color(0xFF00A6A6)
|
||||||
foregroundColor: _currentPage == page ? Colors.white : Colors.black,
|
: Colors.grey[300],
|
||||||
minimumSize: const Size(36, 36),
|
foregroundColor:
|
||||||
|
_currentPage == page ? Colors.white : Colors.black,
|
||||||
|
minimumSize: const Size(30, 30),
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
|
elevation: 0,
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_currentPage = page;
|
_currentPage = page;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(page.toString()),
|
child: Text(
|
||||||
|
page.toString(),
|
||||||
|
style: GoogleFonts.poppins(fontSize: 12),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user