add claims pop live issue
This commit is contained in:
parent
5f49e8a4f6
commit
9a61f628ee
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import '../customAppBar/base_layout.dart';
|
import '../customAppBar/base_layout.dart';
|
||||||
import '../customAppBar/toastHelper.dart';
|
import '../customAppBar/toastHelper.dart';
|
||||||
import '../service/api_service.dart';
|
import '../service/api_service.dart';
|
||||||
|
import '../service/secure_pop_scope.dart';
|
||||||
import '../service/token_storage_service.dart';
|
import '../service/token_storage_service.dart';
|
||||||
import 'branch_card_widget.dart';
|
import 'branch_card_widget.dart';
|
||||||
import 'dart:html' as html;
|
import 'dart:html' as html;
|
||||||
@ -105,8 +106,7 @@ class _BranchSelectionPageState extends State<BranchSelectionPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseLayout(
|
return BaseLayout(
|
||||||
child: PopScope(
|
child: SecurePopScope(
|
||||||
canPop: false,
|
|
||||||
child: _buildContent(context),
|
child: _buildContent(context),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -726,7 +726,7 @@ class _RaiseClaimDialogState extends State<RaiseClaimDialog> {
|
|||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: MediaQuery.of(context).size.width * 0.75, // Desktop popup width
|
width: MediaQuery.of(context).size.width * 0.75, // Desktop popup width
|
||||||
// height: MediaQuery.of(context).size.height * 0.85,
|
height: MediaQuery.of(context).size.height * 0.85, // 🔥 ADD THIS
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
/// MAIN CONTENT (YOUR EXISTING UI)
|
/// MAIN CONTENT (YOUR EXISTING UI)
|
||||||
@ -1052,6 +1052,7 @@ class _RaiseClaimDialogState extends State<RaiseClaimDialog> {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 14),
|
padding: const EdgeInsets.only(bottom: 14),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: children
|
children: children
|
||||||
.map((e) => Expanded(
|
.map((e) => Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'package:nhancepolicy/presentation/policies.dart';
|
import 'package:nhancepolicy/presentation/policies.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
|
import '../service/secure_pop_scope.dart';
|
||||||
import 'cdTransactionDetails.dart';
|
import 'cdTransactionDetails.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
@ -63,21 +64,6 @@ class _CdPoliciesListState extends State<CdPoliciesList> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
apiService = ApiService(context); // Initialize ApiService here
|
apiService = ApiService(context); // Initialize ApiService here
|
||||||
html.window.onPopState.listen((event) async {
|
|
||||||
final shouldLogout = await _showLogoutDialog();
|
|
||||||
if (shouldLogout) {
|
|
||||||
await apiService.logout();
|
|
||||||
if (!mounted) return;
|
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
'hrLogin',
|
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Push state back to prevent browser navigation
|
|
||||||
html.window.history.pushState(null, '', html.window.location.href);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
checkIds();
|
checkIds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,8 +235,7 @@ class _CdPoliciesListState extends State<CdPoliciesList> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseLayout(
|
return BaseLayout(
|
||||||
child: PopScope(
|
child: SecurePopScope(
|
||||||
canPop: false,
|
|
||||||
child: _buildContent(context),
|
child: _buildContent(context),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:jwt_decode/jwt_decode.dart';
|
import 'package:jwt_decode/jwt_decode.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
|
import '../service/secure_pop_scope.dart';
|
||||||
import 'claimshistory.dart';
|
import 'claimshistory.dart';
|
||||||
import '../customAppBar/base_layout.dart';
|
import '../customAppBar/base_layout.dart';
|
||||||
import '../service/api_service.dart';
|
import '../service/api_service.dart';
|
||||||
@ -109,22 +110,6 @@ class _ClaimsPolicieState extends State<ClaimsPolicies> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
apiService = ApiService(context);
|
apiService = ApiService(context);
|
||||||
|
|
||||||
html.window.onPopState.listen((event) async {
|
|
||||||
final shouldLogout = await _showLogoutDialog();
|
|
||||||
if (shouldLogout) {
|
|
||||||
await apiService.logout();
|
|
||||||
if (!mounted) return;
|
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
'hrLogin',
|
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Push state back to prevent browser navigation
|
|
||||||
html.window.history.pushState(null, '', html.window.location.href);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (String field in tabHeader) {
|
for (String field in tabHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
}
|
}
|
||||||
@ -475,8 +460,7 @@ class _ClaimsPolicieState extends State<ClaimsPolicies> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseLayout(
|
return BaseLayout(
|
||||||
child: PopScope(
|
child: SecurePopScope(
|
||||||
canPop: false,
|
|
||||||
child: _buildContent(context),
|
child: _buildContent(context),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import 'package:universal_html/html.dart' as html;
|
|||||||
|
|
||||||
import '../config/environment.dart';
|
import '../config/environment.dart';
|
||||||
import '../customAppBar/base_layout.dart';
|
import '../customAppBar/base_layout.dart';
|
||||||
|
import '../service/secure_pop_scope.dart';
|
||||||
|
|
||||||
class hrDashboard extends StatefulWidget {
|
class hrDashboard extends StatefulWidget {
|
||||||
hrDashboard({Key? key}) : super(key: key);
|
hrDashboard({Key? key}) : super(key: key);
|
||||||
@ -45,21 +46,6 @@ class _hrDashboardState extends State<hrDashboard> with SingleTickerProviderStat
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
apiService = ApiService(context);
|
apiService = ApiService(context);
|
||||||
html.window.onPopState.listen((event) async {
|
|
||||||
final shouldLogout = await _showLogoutDialog();
|
|
||||||
if (shouldLogout) {
|
|
||||||
await apiService.logout();
|
|
||||||
if (!mounted) return;
|
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
'hrLogin',
|
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// Push state back to prevent browser navigation
|
|
||||||
html.window.history.pushState(null, '', html.window.location.href);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_loadToken();
|
_loadToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,8 +167,7 @@ class _hrDashboardState extends State<hrDashboard> with SingleTickerProviderStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildContent(BuildContext context) {
|
Widget _buildContent(BuildContext context) {
|
||||||
return PopScope(
|
return SecurePopScope(
|
||||||
canPop: false,
|
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
// ✅ REMOVED 'Expanded' from directly inside body.
|
// ✅ REMOVED 'Expanded' from directly inside body.
|
||||||
body: Container(
|
body: Container(
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import 'package:intl/intl.dart';
|
|||||||
import '../config/environment.dart';
|
import '../config/environment.dart';
|
||||||
import '../customAppBar/base_layout.dart';
|
import '../customAppBar/base_layout.dart';
|
||||||
import '../customAppBar/toastHelper.dart';
|
import '../customAppBar/toastHelper.dart';
|
||||||
|
import '../service/secure_pop_scope.dart';
|
||||||
import 'hrPolicyDetails.dart';
|
import 'hrPolicyDetails.dart';
|
||||||
|
|
||||||
class policies extends StatefulWidget {
|
class policies extends StatefulWidget {
|
||||||
@ -331,23 +332,7 @@ class _policiesState extends State<policies>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BaseLayout(
|
return BaseLayout(
|
||||||
child: WillPopScope(
|
child: SecurePopScope(
|
||||||
onWillPop: () async {
|
|
||||||
|
|
||||||
final shouldLogout = await _showLogoutDialog();
|
|
||||||
|
|
||||||
if (shouldLogout) {
|
|
||||||
await apiService.logout();
|
|
||||||
if (!mounted) return false;
|
|
||||||
|
|
||||||
Navigator.pushNamedAndRemoveUntil(
|
|
||||||
context,
|
|
||||||
'hrLogin',
|
|
||||||
(route) => false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
child: buildPoliciesBody(
|
child: buildPoliciesBody(
|
||||||
openEnrollment: openForEnrollmentList,
|
openEnrollment: openForEnrollmentList,
|
||||||
activePolicies: activePoliciesList,
|
activePolicies: activePoliciesList,
|
||||||
|
|||||||
90
lib/service/secure_pop_scope.dart
Normal file
90
lib/service/secure_pop_scope.dart
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
|
import '../service/token_storage_service.dart';
|
||||||
|
import '../service/api_service.dart';
|
||||||
|
|
||||||
|
class SecurePopScope extends StatefulWidget {
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
|
const SecurePopScope({Key? key, required this.child}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<SecurePopScope> createState() => _SecurePopScopeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SecurePopScopeState extends State<SecurePopScope> {
|
||||||
|
final TokenStorageService _tokenService = TokenStorageService();
|
||||||
|
late ApiService _apiService;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_apiService = ApiService(context);
|
||||||
|
|
||||||
|
// 🔥 Push dummy state (IMPORTANT for Firefox)
|
||||||
|
html.window.history.pushState(null, '', html.window.location.href);
|
||||||
|
|
||||||
|
html.window.onPopState.listen((event) async {
|
||||||
|
await _handleBack();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _handleBack() async {
|
||||||
|
final token = await _tokenService.getCurrentToken();
|
||||||
|
|
||||||
|
// If no token → force login
|
||||||
|
if (token == null || token.isEmpty) {
|
||||||
|
_redirectToLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final shouldLogout = await _showLogoutDialog();
|
||||||
|
|
||||||
|
if (shouldLogout) {
|
||||||
|
await _tokenService.clearAll();
|
||||||
|
await _apiService.logout();
|
||||||
|
_redirectToLogin();
|
||||||
|
} else {
|
||||||
|
// 🔥 Re-push state (VERY IMPORTANT for Firefox)
|
||||||
|
html.window.history.pushState(null, '', html.window.location.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _redirectToLogin() {
|
||||||
|
if (!mounted) return;
|
||||||
|
|
||||||
|
Navigator.pushNamedAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
'hrLogin',
|
||||||
|
(route) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> _showLogoutDialog() async {
|
||||||
|
return await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text("Confirm Logout"),
|
||||||
|
content: const Text("Do you want to logout?"),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, false),
|
||||||
|
child: const Text("Cancel"),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, true),
|
||||||
|
child: const Text("Logout"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return widget.child; // ❌ Don't rely on PopScope for web
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user