FAQs
This commit is contained in:
parent
6de1ea4a49
commit
45fcefeb81
@ -1,151 +0,0 @@
|
|||||||
<!--<!DOCTYPE html>-->
|
|
||||||
<!--<html lang="en">-->
|
|
||||||
<!--<head>-->
|
|
||||||
<!-- <meta charset="UTF-8" />-->
|
|
||||||
<!-- <style>-->
|
|
||||||
<!-- #botmanWidgetRoot svg {-->
|
|
||||||
<!-- display: none !important;-->
|
|
||||||
<!-- }-->
|
|
||||||
<!-- </style>-->
|
|
||||||
<!-- <script>-->
|
|
||||||
<!-- const APIENDPOINT = 'https://venbait.in/nhance/dev';-->
|
|
||||||
<!-- const APIAPIENDPOINT = 'https://venbait.in/nhance/dev';-->
|
|
||||||
|
|
||||||
<!-- var emp_name = 'Kumar';-->
|
|
||||||
<!-- var uid = Math.floor(100000 + Math.random() * 900000);-->
|
|
||||||
<!-- console.log('CURRENT_USER' + uid);-->
|
|
||||||
|
|
||||||
<!-- window.botmanWidget = {-->
|
|
||||||
<!-- chatServer: APIENDPOINT + '/chat',-->
|
|
||||||
<!-- frameEndpoint: APIAPIENDPOINT + '/widget',-->
|
|
||||||
<!-- title: 'Ask ILA',-->
|
|
||||||
<!-- introMessage: '',-->
|
|
||||||
<!-- bubbleBackground: '#007bff',-->
|
|
||||||
<!-- mainColor: '#007bff',-->
|
|
||||||
<!-- placeholderText: 'Type your message here...',-->
|
|
||||||
<!-- aboutText: 'Insurance Assistant ILA',-->
|
|
||||||
<!-- enableAttachments: false,-->
|
|
||||||
<!-- parameters: {-->
|
|
||||||
<!-- employee_id: '12288',-->
|
|
||||||
<!-- session_id: 'XYZ789',-->
|
|
||||||
<!-- origin: 'mobile',-->
|
|
||||||
<!-- emp_code: 'HTL-007',-->
|
|
||||||
<!-- client_id: 159,-->
|
|
||||||
<!-- client_branch_id: 125,-->
|
|
||||||
<!-- },-->
|
|
||||||
<!-- };-->
|
|
||||||
|
|
||||||
<!-- </script>-->
|
|
||||||
|
|
||||||
<!-- <script src="https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js"></script>-->
|
|
||||||
<!--</head>-->
|
|
||||||
<!--<body></body>-->
|
|
||||||
<!--</html>-->
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Ask ILA</title>
|
|
||||||
<style>
|
|
||||||
#botmanWidgetRoot svg {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="botmanWidgetRoot"></div>
|
|
||||||
|
|
||||||
<!--<script>-->
|
|
||||||
<!-- function initBotman(params) {-->
|
|
||||||
<!--<!– console.log('[Botman] Params:', params);–>-->
|
|
||||||
<!-- console.log('[Botman] Received Params:', JSON.stringify(params, null, 2));-->
|
|
||||||
|
|
||||||
<!-- window.botmanWidget = {-->
|
|
||||||
<!-- chatServer: 'https://venbait.in/nhance/dev/chat',-->
|
|
||||||
<!-- frameEndpoint: 'https://venbait.in/nhance/dev/widget',-->
|
|
||||||
<!-- title: 'Ask ILA',-->
|
|
||||||
<!-- introMessage: '',-->
|
|
||||||
<!-- bubbleBackground: '#007bff',-->
|
|
||||||
<!-- mainColor: '#007bff',-->
|
|
||||||
<!-- placeholderText: 'Type your message here...',-->
|
|
||||||
<!-- aboutText: 'Insurance Assistant ILA',-->
|
|
||||||
<!-- enableAttachments: false,-->
|
|
||||||
<!-- parameters: params-->
|
|
||||||
<!-- };-->
|
|
||||||
|
|
||||||
<!-- const script = document.createElement('script');-->
|
|
||||||
<!-- script.src = "https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js";-->
|
|
||||||
|
|
||||||
<!-- script.onload = () => {-->
|
|
||||||
<!-- const checkWidget = setInterval(() => {-->
|
|
||||||
<!-- if (typeof botmanChatWidget !== 'undefined') {-->
|
|
||||||
<!-- botmanChatWidget.open();-->
|
|
||||||
<!-- botmanChatWidget.sayAsBot(`Hi ${params.emp_name}, ILA here to assist you.`);-->
|
|
||||||
<!-- clearInterval(checkWidget);-->
|
|
||||||
<!-- }-->
|
|
||||||
<!-- }, 300);-->
|
|
||||||
<!-- };-->
|
|
||||||
|
|
||||||
<!-- document.body.appendChild(script);-->
|
|
||||||
<!-- }-->
|
|
||||||
<!--</script>-->
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function initBotman(params) {
|
|
||||||
console.log('Params:', params);
|
|
||||||
console.log('[Botman] Received Params:', JSON.stringify(params, null, 2));
|
|
||||||
|
|
||||||
window.botmanWidget = {
|
|
||||||
chatServer: 'https://venbait.in/nhance/dev/chat',
|
|
||||||
frameEndpoint: 'https://venbait.in/nhance/dev/widget',
|
|
||||||
title: 'Ask ILA',
|
|
||||||
introMessage: '', // Must be empty if using sayAsBot()
|
|
||||||
bubbleBackground: '#007bff',
|
|
||||||
mainColor: '#007bff',
|
|
||||||
placeholderText: 'Type your message here...',
|
|
||||||
aboutText: 'Insurance Assistant ILA',
|
|
||||||
enableAttachments: false,
|
|
||||||
parameters: params
|
|
||||||
};
|
|
||||||
|
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = "https://cdn.jsdelivr.net/npm/botman-web-widget@0/build/js/widget.js";
|
|
||||||
|
|
||||||
script.onload = function () {
|
|
||||||
console.log("✅ Botman script loaded");
|
|
||||||
|
|
||||||
const waitForWidget = setInterval(() => {
|
|
||||||
if (typeof botmanChatWidget !== 'undefined' && botmanChatWidget.open) {
|
|
||||||
clearInterval(waitForWidget);
|
|
||||||
|
|
||||||
botmanChatWidget.open();
|
|
||||||
|
|
||||||
// Send default message after slight delay
|
|
||||||
setTimeout(() => {
|
|
||||||
botmanChatWidget.sayAsBot(`Hi ${params.emp_name || 'User'}, ILA here to assist you.`);
|
|
||||||
}, 800); // Allow chat to render
|
|
||||||
} else {
|
|
||||||
console.log("⏳ Waiting for botmanChatWidget...");
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
};
|
|
||||||
|
|
||||||
script.onerror = function () {
|
|
||||||
console.error("❌ Failed to load Botman widget.js");
|
|
||||||
};
|
|
||||||
|
|
||||||
document.body.appendChild(script);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
const queryParams = new URLSearchParams(window.location.search);
|
|
||||||
const entries = Object.fromEntries(queryParams.entries());
|
|
||||||
document.write('<pre>' + JSON.stringify(entries, null, 2) + '</pre>');
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
assets/faqs.jpg
Normal file
BIN
assets/faqs.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 780 KiB |
@ -117,12 +117,25 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
|||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
NavBarItem(
|
||||||
|
text: "FAQs",
|
||||||
|
onTap: () => handleMenuTap(() {
|
||||||
|
context.push('/faqs');
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
NavBarItem(
|
||||||
|
text: "Profile",
|
||||||
|
onTap: () => handleMenuTap(() {
|
||||||
|
context.push('/profile');
|
||||||
|
}),
|
||||||
|
),
|
||||||
NavBarItem(
|
NavBarItem(
|
||||||
text: "Help",
|
text: "Help",
|
||||||
onTap: () => handleMenuTap(() {
|
onTap: () => handleMenuTap(() {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
|
||||||
// NavBarItem(
|
// NavBarItem(
|
||||||
// text: "Wellness",
|
// text: "Wellness",
|
||||||
// onTap: () => handleMenuTap(() {
|
// onTap: () => handleMenuTap(() {
|
||||||
@ -133,12 +146,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
|||||||
// );
|
// );
|
||||||
// }),
|
// }),
|
||||||
// ),
|
// ),
|
||||||
NavBarItem(
|
|
||||||
text: "Profile",
|
|
||||||
onTap: () => handleMenuTap(() {
|
|
||||||
context.push('/profile');
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
NavBarItem(
|
NavBarItem(
|
||||||
text: "Logout",
|
text: "Logout",
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import 'package:nhance_app_pwa/pages/postEnrollment/AddPolicyScreen.dart';
|
|||||||
import 'package:nhance_app_pwa/pages/postEnrollment/botman_chat.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/botman_chat.dart';
|
||||||
import 'package:nhance_app_pwa/pages/postEnrollment/claimprocess.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/claimprocess.dart';
|
||||||
import 'package:nhance_app_pwa/pages/postEnrollment/claims.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/claims.dart';
|
||||||
|
import 'package:nhance_app_pwa/pages/postEnrollment/faqs.dart';
|
||||||
import 'package:nhance_app_pwa/pages/postEnrollment/generalexclusionsdeductibles.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/generalexclusionsdeductibles.dart';
|
||||||
import 'package:nhance_app_pwa/pages/postEnrollment/help.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/help.dart';
|
||||||
import 'package:nhance_app_pwa/pages/postEnrollment/home.dart';
|
import 'package:nhance_app_pwa/pages/postEnrollment/home.dart';
|
||||||
@ -230,6 +231,10 @@ Future<void> startApp() async {
|
|||||||
path: '/empDetails',
|
path: '/empDetails',
|
||||||
builder: (context, state) => empDetails(),
|
builder: (context, state) => empDetails(),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/faqs',
|
||||||
|
builder: (context, state) => faqs(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/addOnsDetails', builder: (context, state) => addOnsDetails()),
|
path: '/addOnsDetails', builder: (context, state) => addOnsDetails()),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
|
|||||||
@ -1502,15 +1502,15 @@ class _loginState extends State<login> {
|
|||||||
value.isEmpty) {
|
value.isEmpty) {
|
||||||
return 'Please enter your password';
|
return 'Please enter your password';
|
||||||
}
|
}
|
||||||
if (value.length < 6) {
|
// if (value.length < 6) {
|
||||||
return 'Password must be at least 6 characters';
|
// return 'Password must be at least 6 characters';
|
||||||
}
|
// }
|
||||||
// Optional strong password rule
|
// // Optional strong password rule
|
||||||
if (!RegExp(
|
// if (!RegExp(
|
||||||
r'^(?=.*[A-Z])(?=.*[0-9]).{6,}$')
|
// r'^(?=.*[A-Z])(?=.*[0-9]).{6,}$')
|
||||||
.hasMatch(value)) {
|
// .hasMatch(value)) {
|
||||||
return 'Include at least 1 uppercase letter and 1 number';
|
// return 'Include at least 1 uppercase letter and 1 number';
|
||||||
}
|
// }
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -367,17 +367,19 @@ class _AddPolicyScreenState extends State<AddPolicyScreen> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help", "Wellness"],
|
labels: ["Home", "Claims", "FAQs", "Profile", "Help"],
|
||||||
initialIndex: 3,
|
initialIndex: 0,
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
if (index == 0) context.go('/home');
|
if (index == 0) context.go('/home');
|
||||||
if (index == 1) context.go('/claims');
|
if (index == 1) context.go('/claims');
|
||||||
if (index == 2) context.go('/profile');
|
if (index == 2) context.go('/faqs');
|
||||||
if (index == 3) context.go('/help');
|
if (index == 3) context.go('/profile');
|
||||||
|
if (index == 4) {context.push('/help');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -584,7 +584,7 @@ class _claimsState extends State<claims> {
|
|||||||
.isDesktop(
|
.isDesktop(
|
||||||
context)
|
context)
|
||||||
? 140
|
? 140
|
||||||
: 50,
|
: 10 ,
|
||||||
vertical: Responsive
|
vertical: Responsive
|
||||||
.isDesktop(
|
.isDesktop(
|
||||||
context)
|
context)
|
||||||
@ -593,7 +593,7 @@ class _claimsState extends State<claims> {
|
|||||||
// primary: Color(0xFF000000),
|
// primary: Color(0xFF000000),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
'Your Plan',
|
'Register a Claim',
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: Responsive
|
fontSize: Responsive
|
||||||
.isDesktop(
|
.isDesktop(
|
||||||
@ -609,7 +609,7 @@ class _claimsState extends State<claims> {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
'Your Plan',
|
'Register a Claim',
|
||||||
style:
|
style:
|
||||||
GoogleFonts.poppins(
|
GoogleFonts.poppins(
|
||||||
fontSize: Responsive
|
fontSize: Responsive
|
||||||
@ -766,8 +766,10 @@ class _claimsState extends State<claims> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -784,12 +786,12 @@ class _claimsState extends State<claims> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 1, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
692
lib/pages/postEnrollment/faqs.dart
Normal file
692
lib/pages/postEnrollment/faqs.dart
Normal file
@ -0,0 +1,692 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:jwt_decode/jwt_decode.dart';
|
||||||
|
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
||||||
|
|
||||||
|
import '../../customAppBar/customAppBar.dart';
|
||||||
|
import '../../customAppBar/customFooter.dart';
|
||||||
|
import '../../customAppBar/responsive.dart';
|
||||||
|
import '../../customAppBar/tabs.dart';
|
||||||
|
import '../../customAppBar/toastHelper.dart';
|
||||||
|
import '../service/SessionManager.dart';
|
||||||
|
import '../service/TokenService.dart';
|
||||||
|
import '../service/data_manager.dart';
|
||||||
|
import 'package:flutter_html/flutter_html.dart';
|
||||||
|
|
||||||
|
import '../service/video_player_widget.dart';
|
||||||
|
|
||||||
|
class faqs extends StatefulWidget {
|
||||||
|
const faqs({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<faqs> createState() => _faqsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class FaqItem {
|
||||||
|
final String id;
|
||||||
|
final String category;
|
||||||
|
final String question;
|
||||||
|
final String? answer;
|
||||||
|
|
||||||
|
FaqItem({
|
||||||
|
required this.id,
|
||||||
|
required this.category,
|
||||||
|
required this.question,
|
||||||
|
this.answer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class FaqNode {
|
||||||
|
final String title;
|
||||||
|
final List<FaqNode> children = [];
|
||||||
|
final List<FaqItem> faqs = [];
|
||||||
|
|
||||||
|
FaqNode({required this.title});
|
||||||
|
}
|
||||||
|
|
||||||
|
class _faqsState extends State<faqs> {
|
||||||
|
bool isLoading = false;
|
||||||
|
late ApiService apiService;
|
||||||
|
dynamic empCodeString;
|
||||||
|
dynamic empPrimaryId;
|
||||||
|
dynamic empEmailID;
|
||||||
|
dynamic client_id;
|
||||||
|
dynamic client_branch_id;
|
||||||
|
dynamic empMobileNo;
|
||||||
|
final session = SessionManager();
|
||||||
|
final dataManager = DataManager();
|
||||||
|
|
||||||
|
/// ---------------- STATE ----------------
|
||||||
|
Map<String, FaqNode> faqTree = {};
|
||||||
|
String selectedTab = 'Others';
|
||||||
|
|
||||||
|
String? openSection;
|
||||||
|
String? openSubSection;
|
||||||
|
String? openQuestionId;
|
||||||
|
|
||||||
|
/// ---------------- SAMPLE DATA (Replace with API) ----------------
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
apiService = ApiService(context);
|
||||||
|
_loadToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadToken() async {
|
||||||
|
print('_loadToken');
|
||||||
|
final String? token = await TokenService.getPostToken();
|
||||||
|
if (token != null && token.isNotEmpty) {
|
||||||
|
// Decode the JWT token received from the API response
|
||||||
|
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
||||||
|
print(decodedToken);
|
||||||
|
empMobileNo = session.mobileNo ?? '';
|
||||||
|
empEmailID = session.empEmailCorporate ?? '';
|
||||||
|
client_branch_id = session.empClientBranchId;
|
||||||
|
empCodeString = session.empCodeString;
|
||||||
|
print(empCodeString); // Check if emp_code is correct
|
||||||
|
empPrimaryId = session.empPrimaryId;
|
||||||
|
client_id = session.client_id;
|
||||||
|
print(client_id);
|
||||||
|
getFAQsDetails();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getFAQsDetails() async {
|
||||||
|
setState(() => isLoading = true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final response = await apiService.getFAQsApiData();
|
||||||
|
|
||||||
|
if (response['status'] == 'success') {
|
||||||
|
final List list = response['data']['faq_list'] ?? [];
|
||||||
|
|
||||||
|
// ✅ Convert API data → FaqItem list
|
||||||
|
final List<FaqItem> apiFaqs =
|
||||||
|
list.where((e) => e['is_active'] == '1').map<FaqItem>((e) {
|
||||||
|
return FaqItem(
|
||||||
|
id: e['id'].toString(),
|
||||||
|
category: e['category']?.toString().trim() ?? '',
|
||||||
|
question: e['question']?.toString() ?? '',
|
||||||
|
answer: e['answer']?.toString(),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// ✅ Build tree
|
||||||
|
final tree = buildFaqTree(apiFaqs);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
faqTree = tree;
|
||||||
|
|
||||||
|
// ✅ Set default tab safely
|
||||||
|
if (faqTree.isNotEmpty) {
|
||||||
|
selectedTab = faqTree.keys.first;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ToastHelper.showErrorToast(context, 'No FAQs found');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('FAQ Error: $e');
|
||||||
|
ToastHelper.showErrorToast(context, 'Failed to load FAQs');
|
||||||
|
} finally {
|
||||||
|
if (mounted) {
|
||||||
|
setState(() => isLoading = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- TREE BUILDER ----------------
|
||||||
|
Map<String, FaqNode> buildFaqTree(List<FaqItem> faqs) {
|
||||||
|
final Map<String, FaqNode> root = {};
|
||||||
|
|
||||||
|
for (var faq in faqs) {
|
||||||
|
final parts = faq.category.split('/').map((e) => e.trim()).toList();
|
||||||
|
|
||||||
|
final main = parts.first;
|
||||||
|
|
||||||
|
root.putIfAbsent(main, () => FaqNode(title: main));
|
||||||
|
FaqNode current = root[main]!;
|
||||||
|
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
final part = parts[i];
|
||||||
|
final existing =
|
||||||
|
current.children.where((e) => e.title == part).toList();
|
||||||
|
|
||||||
|
if (existing.isEmpty) {
|
||||||
|
final node = FaqNode(title: part);
|
||||||
|
current.children.add(node);
|
||||||
|
current = node;
|
||||||
|
} else {
|
||||||
|
current = existing.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current.faqs.add(faq);
|
||||||
|
}
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return PopScope(
|
||||||
|
canPop: false,
|
||||||
|
onPopInvokedWithResult: (didPop, result) {
|
||||||
|
if (didPop) return;
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
child: Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
appBar: CustomAppBar(),
|
||||||
|
body: Stack(children: [
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: Container(
|
||||||
|
padding: Responsive.isDesktop(context)
|
||||||
|
? EdgeInsets.symmetric(
|
||||||
|
horizontal: MediaQuery.of(context).size.width *
|
||||||
|
0.1, // 30% of screen width as horizontal padding
|
||||||
|
vertical: MediaQuery.of(context).size.height *
|
||||||
|
0.03, // 5% of screen height as vertical padding
|
||||||
|
)
|
||||||
|
: EdgeInsets.all(10),
|
||||||
|
color: Colors.white,
|
||||||
|
child: Column(children: [
|
||||||
|
Container(
|
||||||
|
padding: Responsive.isDesktop(context)
|
||||||
|
? EdgeInsets.only(
|
||||||
|
top: 15, bottom: 15, left: 25, right: 25)
|
||||||
|
: EdgeInsets.only(top: 0, bottom: 0, left: 0, right: 0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 12,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.pop();
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons
|
||||||
|
.chevron_left, // Replace with your desired icon
|
||||||
|
color: Color(0xFF000000),
|
||||||
|
size: 30,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width:
|
||||||
|
5), // Adjust space between icon and text
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'FAQs',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF000000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Frequently Asked Questions',
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize:
|
||||||
|
12, // Adjust the font size as needed
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Color(0xFF000000),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Color(0xFFEEF5FF),
|
||||||
|
// Set background color for the container
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
5), // Set border radius for the container
|
||||||
|
),
|
||||||
|
padding: Responsive.isDesktop(context)
|
||||||
|
? EdgeInsets.only(
|
||||||
|
top: 10, bottom: 10, left: 25, right: 25)
|
||||||
|
: EdgeInsets.only(
|
||||||
|
top: 10, bottom: 10, left: 10, right: 10),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft, // ✅ LEFT ALIGN TABS
|
||||||
|
child: Responsive.isDesktop(context)
|
||||||
|
? buildTabs() // no scroll on web
|
||||||
|
: SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
child: buildTabs(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
buildContent(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// NhanceVideoWrapper(context)
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
)),
|
||||||
|
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
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (Responsive.isDesktop(context))
|
||||||
|
Align(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity, // Make the footer full width
|
||||||
|
child: CustomFooter(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
// floatingActionButton: Responsive.isDesktop(context)
|
||||||
|
// ? null
|
||||||
|
// : FloatingActionButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// Navigator.pushNamed(context, 'chatbot');
|
||||||
|
// },
|
||||||
|
// child: Icon(Icons.chat),
|
||||||
|
// ),
|
||||||
|
floatingActionButtonLocation: Responsive.isDesktop(context)
|
||||||
|
? null
|
||||||
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
|
? null
|
||||||
|
: CustomBottomNavigationBar(
|
||||||
|
onTabChanged: (index) {
|
||||||
|
// Add your navigation logic here
|
||||||
|
// repositionBotman();
|
||||||
|
if (index == 0) {
|
||||||
|
context.push('/home');
|
||||||
|
} else if (index == 1) {
|
||||||
|
context.push('/claims');
|
||||||
|
} else if (index == 2) {
|
||||||
|
context.push('/faqs');
|
||||||
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
|
context.push('/help');
|
||||||
|
}
|
||||||
|
// else if (index == 4) {
|
||||||
|
// // context.push('/wellness');
|
||||||
|
// // Wellness tab clicked → show popup
|
||||||
|
// if(!isRetailLoggedIn)
|
||||||
|
// PopupHelper.showRedirectPopup(
|
||||||
|
// context: context,
|
||||||
|
// apiService: apiService,
|
||||||
|
// empPrimaryId: session.empPrimaryId,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
icons: [
|
||||||
|
Icons.home_outlined,
|
||||||
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
|
Icons.person_outline_outlined,
|
||||||
|
Icons.headset_mic_outlined,
|
||||||
|
],
|
||||||
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
|
initialIndex: 2, // Initial index of the bottom navigation bar
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- MAIN TABS ----------------
|
||||||
|
Widget buildTabs() {
|
||||||
|
final bool isDesktop = Responsive.isDesktop(context);
|
||||||
|
|
||||||
|
return Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: faqTree.keys.map((tab) {
|
||||||
|
final active = selectedTab == tab;
|
||||||
|
|
||||||
|
final tabWidget = InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
selectedTab = tab;
|
||||||
|
openSection = null;
|
||||||
|
openSubSection = null;
|
||||||
|
openQuestionId = null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: active ? Colors.deepOrange : Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(
|
||||||
|
color: active ? Colors.deepOrange : const Color(0xFFE0E0E0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
tab,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
color: active ? Colors.white : Colors.deepOrange,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// 🔥 DESKTOP → FULL WIDTH TAB
|
||||||
|
if (isDesktop) {
|
||||||
|
return Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 10),
|
||||||
|
child: tabWidget,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 📱 MOBILE → CONTENT WIDTH TAB
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 8),
|
||||||
|
child: SizedBox(
|
||||||
|
width: 110,
|
||||||
|
child: tabWidget,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- CONTENT ----------------
|
||||||
|
Widget buildContent() {
|
||||||
|
final node = faqTree[selectedTab];
|
||||||
|
|
||||||
|
if (node == null) {
|
||||||
|
return const Center(child: Text('No FAQs'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Health / Travel without hierarchy
|
||||||
|
if (node.children.isEmpty) {
|
||||||
|
return Column(
|
||||||
|
children: node.faqs.map(buildQuestion).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Others → Fire Insurance → General
|
||||||
|
return Column(
|
||||||
|
children: node.children.map(buildSection).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- SECTION ----------------
|
||||||
|
Widget buildSection(FaqNode node) {
|
||||||
|
final bool isOpen = openSection == node.title;
|
||||||
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
||||||
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
openSection = isOpen ? null : node.title;
|
||||||
|
openSubSection = null;
|
||||||
|
openQuestionId = null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: Color(0xFFE0E0E0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
node.title,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedRotation(
|
||||||
|
turns: isOpen ? 0.5 : 0,
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: Colors.deepOrange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/// SECTION CONTENT
|
||||||
|
AnimatedSize(
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: isOpen
|
||||||
|
? Column(
|
||||||
|
children: [
|
||||||
|
if (node.children.isNotEmpty)
|
||||||
|
...node.children.map(buildSubSection),
|
||||||
|
if (node.children.isEmpty) ...node.faqs.map(buildQuestion),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- SUB SECTION ----------------
|
||||||
|
Widget buildSubSection(FaqNode node) {
|
||||||
|
final bool isOpen = openSubSection == node.title;
|
||||||
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
||||||
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
openSubSection = isOpen ? null : node.title;
|
||||||
|
openQuestionId = null;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: Color(0xFFEDEDED)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
node.title,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedRotation(
|
||||||
|
turns: isOpen ? 0.5 : 0,
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
size: 20,
|
||||||
|
color: Colors.deepOrange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedSize(
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: isOpen
|
||||||
|
? Column(
|
||||||
|
children: node.faqs.map(buildQuestion).toList(),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- QUESTION ----------------
|
||||||
|
Widget buildQuestion(FaqItem faq) {
|
||||||
|
final bool isOpen = openQuestionId == faq.id;
|
||||||
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
||||||
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
openQuestionId = isOpen ? null : faq.id;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 14),
|
||||||
|
decoration: const BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: Color(0xFFF0F0F0)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
faq.question,
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedRotation(
|
||||||
|
turns: isOpen ? 0.5 : 0,
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
size: 18,
|
||||||
|
color: Colors.deepOrange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AnimatedSize(
|
||||||
|
duration: kExpandDuration,
|
||||||
|
curve: kExpandCurve,
|
||||||
|
child: isOpen
|
||||||
|
? Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
|
||||||
|
color: const Color(0xFFFAFAFA),
|
||||||
|
child: Html(
|
||||||
|
data: faq.answer ?? '',
|
||||||
|
style: {
|
||||||
|
"body": Style(
|
||||||
|
margin: Margins.zero,
|
||||||
|
padding: HtmlPaddings.zero,
|
||||||
|
fontSize: FontSize(13),
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
"table": Style(
|
||||||
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
"td": Style(
|
||||||
|
padding: HtmlPaddings.all(8),
|
||||||
|
border: Border.all(color: Colors.grey.shade300),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ---------------- ARROW ----------------
|
||||||
|
Widget buildArrow(bool open) {
|
||||||
|
return AnimatedRotation(
|
||||||
|
turns: open ? 0.5 : 0,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: Colors.deepOrange,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Widget NhanceVideoWrapper(BuildContext context) {
|
||||||
|
final video = NetworkVideoPlayer(
|
||||||
|
videoUrl: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Responsive.isDesktop(context)) {
|
||||||
|
return Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: 500,
|
||||||
|
height: 250,
|
||||||
|
child: video,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 📱 Mobile → default behavior
|
||||||
|
return video;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -806,7 +806,7 @@ class _generalExclusionsDeductiblesState
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -815,8 +815,10 @@ class _generalExclusionsDeductiblesState
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -833,11 +835,11 @@ class _generalExclusionsDeductiblesState
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|||||||
@ -583,6 +583,90 @@ class _helpState extends State<help> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
|
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
context.go('/faqs');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: Responsive.isDesktop(context) ? 140 : 120,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(0xFF2F80ED),
|
||||||
|
width: 2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
/// LEFT IMAGE BLOCK
|
||||||
|
Container(
|
||||||
|
width: Responsive.isDesktop(context) ? 180 : 120,
|
||||||
|
height: double.infinity,
|
||||||
|
color: Colors.white,
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/faqs.jpg',
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/// RIGHT CONTENT BLOCK
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
color: const Color(0xFF93C01F),
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
horizontal: Responsive.isDesktop(context) ? 32 : 16,
|
||||||
|
vertical: Responsive.isDesktop(context) ? 24 : 16,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
/// TEXT CONTENT
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'FAQs',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize:
|
||||||
|
Responsive.isDesktop(context) ? 36 : 20,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'Find answers to commonly asked questions',
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize:
|
||||||
|
Responsive.isDesktop(context) ? 18 : 14,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/// RIGHT ARROW
|
||||||
|
Icon(
|
||||||
|
Icons.chevron_right,
|
||||||
|
size: Responsive.isDesktop(context) ? 36 : 28,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
|
||||||
// SizedBox(height: 15),
|
// SizedBox(height: 15),
|
||||||
// Container(
|
// Container(
|
||||||
// decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
@ -1045,7 +1129,7 @@ class _helpState extends State<help> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -1054,8 +1138,10 @@ class _helpState extends State<help> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -1072,12 +1158,12 @@ class _helpState extends State<help> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 4, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,19 +276,19 @@ class _HomeState extends State<Home> {
|
|||||||
emp_name = response['emp_name'];
|
emp_name = response['emp_name'];
|
||||||
policyList = List.from(response['data'] ?? []);
|
policyList = List.from(response['data'] ?? []);
|
||||||
retailPolicyDetails = List.from(response['retail_policy_data'] ?? []);
|
retailPolicyDetails = List.from(response['retail_policy_data'] ?? []);
|
||||||
print('policyList $policyList');
|
print('policyList $policyList');
|
||||||
pre_policy_count = response['pre_policy_count'] ?? '';
|
pre_policy_count = response['pre_policy_count'] ?? '';
|
||||||
final empNotEnrolledCount = response['emp_not_enrolled_count'] ?? '';
|
final empNotEnrolledCount = response['emp_not_enrolled_count'] ?? '';
|
||||||
final wellnessStatus = response['wellness_data']['status'] ?? 'failed';
|
final wellnessStatus = response['wellness_data']['status'] ?? 'failed';
|
||||||
print('wellnessStatus $wellnessStatus');
|
print('wellnessStatus $wellnessStatus');
|
||||||
if (wellnessStatus == 'success') {
|
if (wellnessStatus == 'success') {
|
||||||
wellnessURL = response['wellness_data']['data'];
|
wellnessURL = response['wellness_data']['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
isTokenAvailable = pre_policy_count != 0;
|
isTokenAvailable = pre_policy_count != 0;
|
||||||
emp_not_enrolled_count = empNotEnrolledCount != 0;
|
emp_not_enrolled_count = empNotEnrolledCount != 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (emp_not_enrolled_count) {
|
if (emp_not_enrolled_count) {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
@ -630,7 +630,7 @@ class _HomeState extends State<Home> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
if(!isRetailLoggedIn)
|
if(!isRetailLoggedIn && isTokenAvailable)
|
||||||
Card(
|
Card(
|
||||||
elevation: 2,
|
elevation: 2,
|
||||||
color: Color(0xFFDDF3FF),
|
color: Color(0xFFDDF3FF),
|
||||||
@ -1189,40 +1189,42 @@ class _HomeState extends State<Home> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
if(!isRetailLoggedIn) context.push('/home');
|
context.push('/home');
|
||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
if(!isRetailLoggedIn) context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
if(!isRetailLoggedIn) context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
if(!isRetailLoggedIn) context.push('/help');
|
context.push('/profile');
|
||||||
}
|
} else if (index == 4) {
|
||||||
// else if (index == 4) {
|
context.push('/help');
|
||||||
// // context.push('/wellness');
|
}
|
||||||
// // Wellness tab clicked → show popup
|
// else if (index == 4) {
|
||||||
// if(!isRetailLoggedIn)
|
// // context.push('/wellness');
|
||||||
// PopupHelper.showRedirectPopup(
|
// // Wellness tab clicked → show popup
|
||||||
// context: context,
|
// if(!isRetailLoggedIn)
|
||||||
// apiService: apiService,
|
// PopupHelper.showRedirectPopup(
|
||||||
// empPrimaryId: session.empPrimaryId,
|
// context: context,
|
||||||
// );
|
// apiService: apiService,
|
||||||
// }
|
// empPrimaryId: session.empPrimaryId,
|
||||||
},
|
// );
|
||||||
icons: [
|
// }
|
||||||
Icons.home_outlined,
|
},
|
||||||
Icons.sticky_note_2_outlined,
|
icons: [
|
||||||
Icons.person_outline_outlined,
|
Icons.home_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
Icons.question_answer_outlined,
|
||||||
],
|
Icons.person_outline_outlined,
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
Icons.headset_mic_outlined,
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
],
|
||||||
),
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1882,6 +1884,11 @@ class _HomeState extends State<Home> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildCarouselSlider(List<Widget> cards) {
|
Widget _buildCarouselSlider(List<Widget> cards) {
|
||||||
|
final int totalCards = cards.length;
|
||||||
|
final bool hasAddCard = isActive; // because you add AddCard only when isActive
|
||||||
|
final int displayCardCount =
|
||||||
|
hasAddCard ? totalCards - 1 : totalCards;
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@ -1897,13 +1904,17 @@ class _HomeState extends State<Home> {
|
|||||||
aspectRatio: 2.0,
|
aspectRatio: 2.0,
|
||||||
initialPage: 0,
|
initialPage: 0,
|
||||||
onPageChanged: (index, reason) {
|
onPageChanged: (index, reason) {
|
||||||
setState(() => currentIndex = index);
|
setState(() {
|
||||||
|
currentIndex = index >= displayCardCount
|
||||||
|
? displayCardCount - 1
|
||||||
|
: index;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// 🔵 CARD COUNTER (4/10)
|
// 🔵 CARD COUNTER (4/10)
|
||||||
if(isActive)
|
if(isActive && displayCardCount > 0)
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 10,
|
bottom: 10,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -1913,7 +1924,7 @@ class _HomeState extends State<Home> {
|
|||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${currentIndex + 1} / ${cards.length}",
|
"${(currentIndex + 1).clamp(1, displayCardCount)} / $displayCardCount",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -2158,7 +2169,7 @@ class _HomeState extends State<Home> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"OPT & Wellness",
|
"OPD & Wellness",
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
|
|||||||
@ -1455,7 +1455,7 @@ SizedBox(height: 15),
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -1464,8 +1464,10 @@ SizedBox(height: 15),
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -1482,11 +1484,11 @@ SizedBox(height: 15),
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1105,7 +1105,7 @@ class _policiesState extends State<policies> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -1114,8 +1114,10 @@ class _policiesState extends State<policies> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -1132,11 +1134,11 @@ class _policiesState extends State<policies> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -888,7 +888,7 @@ class _profileState extends State<profile> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -897,8 +897,10 @@ class _profileState extends State<profile> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -915,12 +917,12 @@ class _profileState extends State<profile> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 3, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -303,7 +303,7 @@ class _raisedTicketHistoryState extends State<raisedTicketHistory> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -312,8 +312,10 @@ class _raisedTicketHistoryState extends State<raisedTicketHistory> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -330,11 +332,11 @@ class _raisedTicketHistoryState extends State<raisedTicketHistory> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -468,7 +468,7 @@ class _retailClaimFormsState extends State<retailClaimForm> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -477,8 +477,10 @@ class _retailClaimFormsState extends State<retailClaimForm> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -495,11 +497,11 @@ class _retailClaimFormsState extends State<retailClaimForm> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|||||||
@ -93,6 +93,19 @@ class ApiService {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Map<String, dynamic>> getFAQsApiData() async {
|
||||||
|
print(_postToken);
|
||||||
|
if (_postToken == null) {
|
||||||
|
await _initializeToken();
|
||||||
|
}
|
||||||
|
final url = Uri.parse('${Environment.apiUrl}FAQ');
|
||||||
|
final headers = {
|
||||||
|
'Authorization': 'Bearer $_postToken' ?? '',
|
||||||
|
};
|
||||||
|
final response = await _makeGetRequest(url, headers);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> getTrackClaimsList(String empPrimaryId,mobileNo,emailID) async {
|
Future<Map<String, dynamic>> getTrackClaimsList(String empPrimaryId,mobileNo,emailID) async {
|
||||||
print(_postToken);
|
print(_postToken);
|
||||||
if (_postToken == null) {
|
if (_postToken == null) {
|
||||||
|
|||||||
@ -603,7 +603,7 @@ class _ticketsState extends State<tickets> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -612,8 +612,10 @@ class _ticketsState extends State<tickets> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -630,11 +632,11 @@ class _ticketsState extends State<tickets> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|||||||
@ -674,7 +674,7 @@ class _tickettracklistState extends State<tickettracklist> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -683,8 +683,10 @@ class _tickettracklistState extends State<tickettracklist> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -701,11 +703,11 @@ class _tickettracklistState extends State<tickettracklist> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -364,7 +364,7 @@ class _wellnessState extends State<wellness> {
|
|||||||
: FloatingActionButtonLocation.miniEndFloat,
|
: FloatingActionButtonLocation.miniEndFloat,
|
||||||
bottomNavigationBar: Responsive.isDesktop(context)
|
bottomNavigationBar: Responsive.isDesktop(context)
|
||||||
? null
|
? null
|
||||||
: CustomBottomNavigationBar(
|
: CustomBottomNavigationBar(
|
||||||
onTabChanged: (index) {
|
onTabChanged: (index) {
|
||||||
// Add your navigation logic here
|
// Add your navigation logic here
|
||||||
// repositionBotman();
|
// repositionBotman();
|
||||||
@ -373,8 +373,10 @@ class _wellnessState extends State<wellness> {
|
|||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
context.push('/claims');
|
context.push('/claims');
|
||||||
} else if (index == 2) {
|
} else if (index == 2) {
|
||||||
context.push('/profile');
|
context.push('/faqs');
|
||||||
} else if (index == 3) {
|
} else if (index == 3) {
|
||||||
|
context.push('/profile');
|
||||||
|
} else if (index == 4) {
|
||||||
context.push('/help');
|
context.push('/help');
|
||||||
}
|
}
|
||||||
// else if (index == 4) {
|
// else if (index == 4) {
|
||||||
@ -391,11 +393,11 @@ class _wellnessState extends State<wellness> {
|
|||||||
icons: [
|
icons: [
|
||||||
Icons.home_outlined,
|
Icons.home_outlined,
|
||||||
Icons.sticky_note_2_outlined,
|
Icons.sticky_note_2_outlined,
|
||||||
|
Icons.question_answer_outlined,
|
||||||
Icons.person_outline_outlined,
|
Icons.person_outline_outlined,
|
||||||
Icons.headset_mic_outlined,
|
Icons.headset_mic_outlined,
|
||||||
// Icons.health_and_safety_outlined,
|
|
||||||
],
|
],
|
||||||
labels: ["Home", "Claims", "Profile", "Help"],
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
||||||
initialIndex: 0, // Initial index of the bottom navigation bar
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
560
lib/pages/service/multi_video_player.dart
Normal file
560
lib/pages/service/multi_video_player.dart
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
|
class NhanceMultiVideoWrapper extends StatefulWidget {
|
||||||
|
final List<String> videoUrls;
|
||||||
|
|
||||||
|
const NhanceMultiVideoWrapper({
|
||||||
|
super.key,
|
||||||
|
required this.videoUrls,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NhanceMultiVideoWrapper> createState() =>
|
||||||
|
_NhanceMultiVideoWrapperState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NhanceMultiVideoWrapperState extends State<NhanceMultiVideoWrapper> {
|
||||||
|
final PageController _pageController = PageController();
|
||||||
|
final List<VideoPlayerController> _controllers = [];
|
||||||
|
|
||||||
|
int _currentIndex = 0;
|
||||||
|
bool _isMuted = false;
|
||||||
|
|
||||||
|
/// Optional static cover image
|
||||||
|
final String coverImage =
|
||||||
|
"https://picsum.photos/900/500"; // replace with API thumbnail if available
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_initControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _initControllers() async {
|
||||||
|
for (final url in widget.videoUrls) {
|
||||||
|
final controller = VideoPlayerController.networkUrl(Uri.parse(url));
|
||||||
|
await controller.initialize();
|
||||||
|
controller.setLooping(true);
|
||||||
|
controller.setVolume(1);
|
||||||
|
_controllers.add(controller);
|
||||||
|
}
|
||||||
|
if (mounted) setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
for (final c in _controllers) {
|
||||||
|
c.dispose();
|
||||||
|
}
|
||||||
|
_pageController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _next() {
|
||||||
|
if (_currentIndex < _controllers.length - 1) {
|
||||||
|
_pageController.nextPage(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _previous() {
|
||||||
|
if (_currentIndex > 0) {
|
||||||
|
_pageController.previousPage(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _seek(VideoPlayerController c, int seconds) {
|
||||||
|
final pos = c.value.position + Duration(seconds: seconds);
|
||||||
|
c.seekTo(
|
||||||
|
pos < Duration.zero ? Duration.zero : pos,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _toggleMute(VideoPlayerController c) {
|
||||||
|
setState(() {
|
||||||
|
_isMuted = !_isMuted;
|
||||||
|
c.setVolume(_isMuted ? 0 : 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _openFullscreen(VideoPlayerController controller) {
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => Scaffold(
|
||||||
|
backgroundColor: Colors.black,
|
||||||
|
body: Center(
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: controller.value.aspectRatio,
|
||||||
|
child: VideoPlayer(controller),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_controllers.isEmpty) {
|
||||||
|
return const SizedBox(
|
||||||
|
height: 250,
|
||||||
|
child: Center(child: CircularProgressIndicator()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// const Text(
|
||||||
|
// "Videos",
|
||||||
|
// style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
|
||||||
|
// ),
|
||||||
|
// const SizedBox(height: 10),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
height: kIsWeb ? 340 : 240,
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
PageView.builder(
|
||||||
|
controller: _pageController,
|
||||||
|
itemCount: _controllers.length,
|
||||||
|
onPageChanged: (index) {
|
||||||
|
setState(() {
|
||||||
|
_controllers[_currentIndex].pause();
|
||||||
|
_currentIndex = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final controller = _controllers[index];
|
||||||
|
|
||||||
|
return Center(
|
||||||
|
child: SizedBox(
|
||||||
|
width: kIsWeb ? 520 : double.infinity,
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: controller.value.aspectRatio,
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
/// 🎥 VIDEO
|
||||||
|
VideoPlayer(controller),
|
||||||
|
|
||||||
|
/// 🖼 COVER IMAGE
|
||||||
|
if (!controller.value.isPlaying)
|
||||||
|
// Positioned.fill(
|
||||||
|
// child: Image.network(
|
||||||
|
// coverImage,
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
|
||||||
|
/// ▶ PLAY / PAUSE
|
||||||
|
IconButton(
|
||||||
|
iconSize: 64,
|
||||||
|
icon: Icon(
|
||||||
|
controller.value.isPlaying
|
||||||
|
? Icons.pause_circle
|
||||||
|
: Icons.play_circle,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
controller.value.isPlaying
|
||||||
|
? controller.pause()
|
||||||
|
: controller.play();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
/// 🎛 BOTTOM CONTROLS
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10, vertical: 6),
|
||||||
|
color: Colors.black.withOpacity(0.55),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.replay_10,
|
||||||
|
color: Colors.white),
|
||||||
|
onPressed: () =>
|
||||||
|
_seek(controller, -10),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.forward_10,
|
||||||
|
color: Colors.white),
|
||||||
|
onPressed: () =>
|
||||||
|
_seek(controller, 10),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_isMuted
|
||||||
|
? Icons.volume_off
|
||||||
|
: Icons.volume_up,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () =>
|
||||||
|
_toggleMute(controller),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: VideoProgressIndicator(
|
||||||
|
controller,
|
||||||
|
allowScrubbing: true,
|
||||||
|
colors: VideoProgressColors(
|
||||||
|
playedColor:
|
||||||
|
const Color(0xFF593AFF),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.fullscreen,
|
||||||
|
color: Colors.white),
|
||||||
|
onPressed: () =>
|
||||||
|
_openFullscreen(controller),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
/// ⬅ PREVIOUS (WEB)
|
||||||
|
if (kIsWeb)
|
||||||
|
Positioned(
|
||||||
|
left: 12,
|
||||||
|
child: _ArrowButton(
|
||||||
|
icon: Icons.chevron_left,
|
||||||
|
enabled: _currentIndex > 0,
|
||||||
|
onTap: _previous,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
/// ➡ NEXT (WEB)
|
||||||
|
if (kIsWeb)
|
||||||
|
Positioned(
|
||||||
|
right: 12,
|
||||||
|
child: _ArrowButton(
|
||||||
|
icon: Icons.chevron_right,
|
||||||
|
enabled: _currentIndex < _controllers.length - 1,
|
||||||
|
onTap: _next,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
|
||||||
|
/// 🔘 DOT INDICATOR
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(
|
||||||
|
_controllers.length,
|
||||||
|
(i) => AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 250),
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
height: 8,
|
||||||
|
width: _currentIndex == i ? 20 : 8,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: _currentIndex == i
|
||||||
|
? const Color(0xFF593AFF)
|
||||||
|
: Colors.grey.shade400,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 🔘 Arrow Button
|
||||||
|
class _ArrowButton extends StatelessWidget {
|
||||||
|
final IconData icon;
|
||||||
|
final bool enabled;
|
||||||
|
final VoidCallback onTap;
|
||||||
|
|
||||||
|
const _ArrowButton({
|
||||||
|
required this.icon,
|
||||||
|
required this.enabled,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IgnorePointer(
|
||||||
|
ignoring: !enabled,
|
||||||
|
child: AnimatedOpacity(
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
opacity: enabled ? 1 : 0.3,
|
||||||
|
child: Material(
|
||||||
|
color: Colors.black.withOpacity(0.6),
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
elevation: 4,
|
||||||
|
child: InkWell(
|
||||||
|
customBorder: const CircleBorder(),
|
||||||
|
onTap: onTap,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
child: Icon(icon, size: 36, color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// import 'package:flutter/foundation.dart';
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:video_player/video_player.dart';
|
||||||
|
//
|
||||||
|
// class NhanceMultiVideoWrapper extends StatefulWidget {
|
||||||
|
// final List<String> videoUrls;
|
||||||
|
//
|
||||||
|
// const NhanceMultiVideoWrapper({
|
||||||
|
// super.key,
|
||||||
|
// required this.videoUrls,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// State<NhanceMultiVideoWrapper> createState() =>
|
||||||
|
// _NhanceMultiVideoWrapperState();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// class _NhanceMultiVideoWrapperState extends State<NhanceMultiVideoWrapper> {
|
||||||
|
// final PageController _pageController = PageController();
|
||||||
|
// int _currentIndex = 0;
|
||||||
|
//
|
||||||
|
// final List<VideoPlayerController> _controllers = [];
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
// _initControllers();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Future<void> _initControllers() async {
|
||||||
|
// for (final url in widget.videoUrls) {
|
||||||
|
// final controller = VideoPlayerController.networkUrl(Uri.parse(url));
|
||||||
|
// await controller.initialize();
|
||||||
|
// controller.setLooping(true);
|
||||||
|
// controller.setVolume(1);
|
||||||
|
// _controllers.add(controller);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (mounted) setState(() {});
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void dispose() {
|
||||||
|
// for (final c in _controllers) {
|
||||||
|
// c.dispose();
|
||||||
|
// }
|
||||||
|
// _pageController.dispose();
|
||||||
|
// super.dispose();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _next() {
|
||||||
|
// if (_currentIndex < widget.videoUrls.length - 1) {
|
||||||
|
// _pageController.nextPage(
|
||||||
|
// duration: const Duration(milliseconds: 300),
|
||||||
|
// curve: Curves.easeInOut,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _previous() {
|
||||||
|
// if (_currentIndex > 0) {
|
||||||
|
// _pageController.previousPage(
|
||||||
|
// duration: const Duration(milliseconds: 300),
|
||||||
|
// curve: Curves.easeInOut,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// if (_controllers.isEmpty) {
|
||||||
|
// return const SizedBox(
|
||||||
|
// height: 250,
|
||||||
|
// child: Center(child: CircularProgressIndicator()),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return Column(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// // Text(
|
||||||
|
// // "Videos",
|
||||||
|
// // style: Theme.of(context)
|
||||||
|
// // .textTheme
|
||||||
|
// // .titleMedium
|
||||||
|
// // ?.copyWith(fontWeight: FontWeight.w600),
|
||||||
|
// // ),
|
||||||
|
// // const SizedBox(height: 10),
|
||||||
|
//
|
||||||
|
// /// 🎥 VIDEO WITH WEB CONTROLS
|
||||||
|
// SizedBox(
|
||||||
|
// height: kIsWeb ? 320 : 220,
|
||||||
|
// child: Stack(
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// children: [
|
||||||
|
// PageView.builder(
|
||||||
|
// controller: _pageController,
|
||||||
|
// itemCount: _controllers.length,
|
||||||
|
// onPageChanged: (index) {
|
||||||
|
// setState(() {
|
||||||
|
// _controllers[_currentIndex].pause();
|
||||||
|
// _currentIndex = index;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// final controller = _controllers[index];
|
||||||
|
//
|
||||||
|
// return Center(
|
||||||
|
// child: SizedBox(
|
||||||
|
// width: kIsWeb ? 520 : double.infinity,
|
||||||
|
// child: AspectRatio(
|
||||||
|
// aspectRatio: controller.value.aspectRatio,
|
||||||
|
// child: Stack(
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// children: [
|
||||||
|
// VideoPlayer(controller),
|
||||||
|
//
|
||||||
|
// IconButton(
|
||||||
|
// iconSize: 60,
|
||||||
|
// icon: Icon(
|
||||||
|
// controller.value.isPlaying
|
||||||
|
// ? Icons.pause_circle
|
||||||
|
// : Icons.play_circle,
|
||||||
|
// color: Colors.white,
|
||||||
|
// ),
|
||||||
|
// onPressed: () {
|
||||||
|
// setState(() {
|
||||||
|
// controller.value.isPlaying
|
||||||
|
// ? controller.pause()
|
||||||
|
// : controller.play();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// /// ⬅ PREVIOUS (WEB ONLY)
|
||||||
|
// if (kIsWeb)
|
||||||
|
// Positioned(
|
||||||
|
// left: 16,
|
||||||
|
// child: _VideoArrowButton(
|
||||||
|
// icon: Icons.chevron_left,
|
||||||
|
// enabled: _currentIndex > 0,
|
||||||
|
// onTap: _previous,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /// ➡ NEXT (WEB ONLY)
|
||||||
|
// if (kIsWeb)
|
||||||
|
// Positioned(
|
||||||
|
// right: 16,
|
||||||
|
// child: _VideoArrowButton(
|
||||||
|
// icon: Icons.chevron_right,
|
||||||
|
// enabled: _currentIndex < _controllers.length - 1,
|
||||||
|
// onTap: _next,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// const SizedBox(height: 8),
|
||||||
|
//
|
||||||
|
// /// 🔘 DOT INDICATOR
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: List.generate(
|
||||||
|
// _controllers.length,
|
||||||
|
// (index) => AnimatedContainer(
|
||||||
|
// duration: const Duration(milliseconds: 250),
|
||||||
|
// margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
// height: 8,
|
||||||
|
// width: _currentIndex == index ? 20 : 8,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// color: _currentIndex == index
|
||||||
|
// ? const Color(0xFF593AFF)
|
||||||
|
// : Colors.grey.shade400,
|
||||||
|
// borderRadius: BorderRadius.circular(4),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// class _VideoArrowButton extends StatelessWidget {
|
||||||
|
// final IconData icon;
|
||||||
|
// final bool enabled;
|
||||||
|
// final VoidCallback onTap;
|
||||||
|
//
|
||||||
|
// const _VideoArrowButton({
|
||||||
|
// required this.icon,
|
||||||
|
// required this.enabled,
|
||||||
|
// required this.onTap,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return IgnorePointer(
|
||||||
|
// ignoring: !enabled,
|
||||||
|
// child: AnimatedOpacity(
|
||||||
|
// duration: const Duration(milliseconds: 200),
|
||||||
|
// opacity: enabled ? 1 : 0.3,
|
||||||
|
// child: Material(
|
||||||
|
// color: Colors.black.withOpacity(0.55),
|
||||||
|
// shape: const CircleBorder(),
|
||||||
|
// elevation: 4,
|
||||||
|
// child: InkWell(
|
||||||
|
// customBorder: const CircleBorder(),
|
||||||
|
// onTap: onTap,
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(10),
|
||||||
|
// child: Icon(
|
||||||
|
// icon,
|
||||||
|
// size: 36,
|
||||||
|
// color: Colors.white,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
81
lib/pages/service/network_video_player.dart
Normal file
81
lib/pages/service/network_video_player.dart
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
|
class NetworkVideoPlayer extends StatefulWidget {
|
||||||
|
final String videoUrl;
|
||||||
|
|
||||||
|
const NetworkVideoPlayer({
|
||||||
|
super.key,
|
||||||
|
required this.videoUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NetworkVideoPlayer> createState() => _NetworkVideoPlayerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NetworkVideoPlayerState extends State<NetworkVideoPlayer> {
|
||||||
|
late VideoPlayerController _controller;
|
||||||
|
bool isInitialized = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_controller = VideoPlayerController.networkUrl(
|
||||||
|
Uri.parse(widget.videoUrl),
|
||||||
|
)..initialize().then((_) {
|
||||||
|
if (!mounted) return;
|
||||||
|
setState(() => isInitialized = true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AspectRatio(
|
||||||
|
aspectRatio: isInitialized
|
||||||
|
? _controller.value.aspectRatio
|
||||||
|
: 16 / 9,
|
||||||
|
child: isInitialized
|
||||||
|
? Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
VideoPlayer(_controller),
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
iconSize: 60,
|
||||||
|
icon: Icon(
|
||||||
|
_controller.value.isPlaying
|
||||||
|
? Icons.pause_circle
|
||||||
|
: Icons.play_circle,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_controller.value.isPlaying
|
||||||
|
? _controller.pause()
|
||||||
|
: _controller.play();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: VideoProgressIndicator(
|
||||||
|
_controller,
|
||||||
|
allowScrubbing: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const Center(child: CircularProgressIndicator()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
74
lib/pages/service/video_player_widget.dart
Normal file
74
lib/pages/service/video_player_widget.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:video_player/video_player.dart';
|
||||||
|
|
||||||
|
class NetworkVideoPlayer extends StatefulWidget {
|
||||||
|
final String videoUrl;
|
||||||
|
|
||||||
|
const NetworkVideoPlayer({super.key, required this.videoUrl});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<NetworkVideoPlayer> createState() => _NetworkVideoPlayerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _NetworkVideoPlayerState extends State<NetworkVideoPlayer> {
|
||||||
|
late VideoPlayerController _controller;
|
||||||
|
bool isInitialized = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_controller = VideoPlayerController.networkUrl(
|
||||||
|
Uri.parse(widget.videoUrl),
|
||||||
|
)
|
||||||
|
..initialize().then((_) {
|
||||||
|
setState(() {
|
||||||
|
isInitialized = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AspectRatio(
|
||||||
|
aspectRatio:
|
||||||
|
isInitialized ? _controller.value.aspectRatio : 16 / 9,
|
||||||
|
child: isInitialized
|
||||||
|
? Stack(
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
children: [
|
||||||
|
VideoPlayer(_controller),
|
||||||
|
VideoProgressIndicator(
|
||||||
|
_controller,
|
||||||
|
allowScrubbing: true,
|
||||||
|
),
|
||||||
|
Center(
|
||||||
|
child: IconButton(
|
||||||
|
iconSize: 60,
|
||||||
|
icon: Icon(
|
||||||
|
_controller.value.isPlaying
|
||||||
|
? Icons.pause_circle
|
||||||
|
: Icons.play_circle,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_controller.value.isPlaying
|
||||||
|
? _controller.pause()
|
||||||
|
: _controller.play();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: const Center(child: CircularProgressIndicator()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -72,6 +72,8 @@ dependencies:
|
|||||||
carousel_slider: ^5.1.1
|
carousel_slider: ^5.1.1
|
||||||
dropdown_search: ^6.0.2
|
dropdown_search: ^6.0.2
|
||||||
ribbon_widget: ^1.0.5
|
ribbon_widget: ^1.0.5
|
||||||
|
flutter_html: ^3.0.0
|
||||||
|
video_player: ^2.10.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -98,7 +100,6 @@ flutter:
|
|||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- assets/
|
- assets/
|
||||||
- assets/botman_chat.html
|
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user