833 lines
25 KiB
Dart
Executable File
833 lines
25 KiB
Dart
Executable File
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';
|
|
|
|
import 'package:nhance_app_pwa/logger.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 {
|
|
logDebug('_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);
|
|
logDebug(decodedToken);
|
|
empMobileNo = session.mobileNo ?? '';
|
|
empEmailID = session.empEmailCorporate ?? '';
|
|
client_branch_id = session.empClientBranchId;
|
|
empCodeString = session.empCodeString;
|
|
logDebug(empCodeString); // Check if emp_code is correct
|
|
empPrimaryId = session.empPrimaryId;
|
|
client_id = session.client_id;
|
|
logDebug(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) {
|
|
logDebug('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;
|
|
}
|
|
|
|
TextStyle _faqSectionTitleStyle(BuildContext context) {
|
|
return GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 16 : 15,
|
|
fontWeight: FontWeight.w600,
|
|
color: const Color(0xFF000000),
|
|
);
|
|
}
|
|
|
|
TextStyle _faqSubSectionTitleStyle(BuildContext context) {
|
|
return GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 15 : 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: const Color(0xFF000000),
|
|
);
|
|
}
|
|
|
|
TextStyle _faqQuestionStyle(BuildContext context, {bool isOpen = false}) {
|
|
return GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 14 : 13,
|
|
fontWeight: isOpen ? FontWeight.w600 : FontWeight.w500,
|
|
color: const Color(0xFF000000),
|
|
);
|
|
}
|
|
|
|
Widget _buildFaqsHeader(BuildContext context) {
|
|
return InkWell(
|
|
onTap: () => context.pop(),
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Row(
|
|
children: [
|
|
const Icon(
|
|
Icons.chevron_left,
|
|
color: Color(0xFF000000),
|
|
size: 30,
|
|
),
|
|
const SizedBox(width: 5),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'FAQs',
|
|
style: GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 20 : 16,
|
|
fontWeight: FontWeight.w600,
|
|
color: const Color(0xFF000000),
|
|
),
|
|
),
|
|
Text(
|
|
'Frequently Asked Questions',
|
|
style: GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 13 : 12,
|
|
fontWeight: FontWeight.w400,
|
|
color: const Color(0xFF777777),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTabsContainer(BuildContext context) {
|
|
return Container(
|
|
width: double.infinity,
|
|
padding: EdgeInsets.all(Responsive.isDesktop(context) ? 12 : 10),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFECF2FF),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: const Color(0xFFD9D9D9)),
|
|
),
|
|
child: Responsive.isDesktop(context)
|
|
? buildTabs()
|
|
: SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: buildTabs(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildFaqListCard(BuildContext context, Widget child) {
|
|
const radius = 12.0;
|
|
return Container(
|
|
width: double.infinity,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(radius),
|
|
border: Border.all(color: const Color(0xFFD9D9D9)),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.04),
|
|
blurRadius: 12,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(radius),
|
|
child: child,
|
|
),
|
|
);
|
|
}
|
|
|
|
BorderRadius? _faqItemBorderRadius({
|
|
required bool isFirst,
|
|
required bool isLast,
|
|
}) {
|
|
if (isFirst && isLast) {
|
|
return BorderRadius.circular(11);
|
|
}
|
|
if (isFirst) {
|
|
return const BorderRadius.vertical(top: Radius.circular(11));
|
|
}
|
|
if (isLast) {
|
|
return const BorderRadius.vertical(bottom: Radius.circular(11));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Widget _buildExpandableHeader({
|
|
required BuildContext context,
|
|
required String title,
|
|
required bool isOpen,
|
|
required VoidCallback onTap,
|
|
required TextStyle titleStyle,
|
|
double horizontalPadding = 16,
|
|
Color? backgroundColor,
|
|
bool isFirst = false,
|
|
bool isLast = false,
|
|
bool showBottomBorder = true,
|
|
}) {
|
|
final borderRadius = _faqItemBorderRadius(
|
|
isFirst: isFirst,
|
|
isLast: isLast && !isOpen,
|
|
);
|
|
|
|
return Material(
|
|
color: backgroundColor ?? Colors.white,
|
|
borderRadius: borderRadius,
|
|
clipBehavior: Clip.antiAlias,
|
|
child: InkWell(
|
|
onTap: onTap,
|
|
borderRadius: borderRadius,
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: horizontalPadding,
|
|
vertical: 14,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: backgroundColor,
|
|
border: showBottomBorder && !(isLast && !isOpen)
|
|
? const Border(
|
|
bottom: BorderSide(color: Color(0xFFE8E8E8)),
|
|
)
|
|
: null,
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
title,
|
|
style: titleStyle,
|
|
),
|
|
),
|
|
AnimatedRotation(
|
|
turns: isOpen ? 0.5 : 0,
|
|
duration: const Duration(milliseconds: 450),
|
|
curve: Curves.easeInOutCubic,
|
|
child: const Icon(
|
|
Icons.keyboard_arrow_down,
|
|
color: Color(0xFFE26728),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@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(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
_buildFaqsHeader(context),
|
|
const SizedBox(height: 16),
|
|
_buildTabsContainer(context),
|
|
const SizedBox(height: 16),
|
|
_buildFaqListCard(context, buildContent()),
|
|
SizedBox(height: Responsive.isDesktop(context) ? 40 : 80),
|
|
],
|
|
),
|
|
)),
|
|
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 = GestureDetector(
|
|
onTap: () {
|
|
setState(() {
|
|
selectedTab = tab;
|
|
openSection = null;
|
|
openSubSection = null;
|
|
openQuestionId = null;
|
|
});
|
|
},
|
|
child: active
|
|
? Material(
|
|
elevation: 4,
|
|
borderRadius: BorderRadius.circular(10),
|
|
color: Colors.white,
|
|
child: Container(
|
|
alignment: Alignment.center,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: isDesktop ? 24 : 16,
|
|
vertical: isDesktop ? 12 : 10,
|
|
),
|
|
child: Text(
|
|
tab,
|
|
textAlign: TextAlign.center,
|
|
style: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 15 : 13,
|
|
color: const Color(0xFF000000),
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
)
|
|
: Container(
|
|
alignment: Alignment.center,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: isDesktop ? 24 : 16,
|
|
vertical: isDesktop ? 12 : 10,
|
|
),
|
|
child: Text(
|
|
tab,
|
|
textAlign: TextAlign.center,
|
|
style: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 15 : 13,
|
|
color: const Color(0xFF636363),
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
if (isDesktop) {
|
|
return Expanded(
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(right: 8),
|
|
child: tabWidget,
|
|
),
|
|
);
|
|
}
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(right: 8),
|
|
child: SizedBox(
|
|
width: 100,
|
|
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) {
|
|
final faqs = node.faqs;
|
|
return Column(
|
|
children: [
|
|
for (int i = 0; i < faqs.length; i++)
|
|
buildQuestion(
|
|
faqs[i],
|
|
isFirst: i == 0,
|
|
isLast: i == faqs.length - 1,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
// Others → Fire Insurance → General
|
|
final sections = node.children;
|
|
return Column(
|
|
children: [
|
|
for (int i = 0; i < sections.length; i++)
|
|
buildSection(
|
|
sections[i],
|
|
isFirst: i == 0,
|
|
isLast: i == sections.length - 1,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// ---------------- SECTION ----------------
|
|
Widget buildSection(
|
|
FaqNode node, {
|
|
bool isFirst = false,
|
|
bool isLast = false,
|
|
}) {
|
|
final bool isOpen = openSection == node.title;
|
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
|
|
|
return Column(
|
|
children: [
|
|
_buildExpandableHeader(
|
|
context: context,
|
|
title: node.title,
|
|
isOpen: isOpen,
|
|
onTap: () {
|
|
setState(() {
|
|
openSection = isOpen ? null : node.title;
|
|
openSubSection = null;
|
|
openQuestionId = null;
|
|
});
|
|
},
|
|
titleStyle: _faqSectionTitleStyle(context),
|
|
backgroundColor: isOpen ? const Color(0xFFECF2FF) : Colors.white,
|
|
isFirst: isFirst,
|
|
isLast: isLast,
|
|
),
|
|
AnimatedSize(
|
|
duration: kExpandDuration,
|
|
curve: kExpandCurve,
|
|
child: isOpen
|
|
? Column(
|
|
children: [
|
|
if (node.children.isNotEmpty)
|
|
...node.children.asMap().entries.map((entry) {
|
|
final index = entry.key;
|
|
final child = entry.value;
|
|
return buildSubSection(
|
|
child,
|
|
isLast: isLast && index == node.children.length - 1,
|
|
);
|
|
}),
|
|
if (node.children.isEmpty)
|
|
...node.faqs.asMap().entries.map((entry) {
|
|
final index = entry.key;
|
|
final faq = entry.value;
|
|
return buildQuestion(
|
|
faq,
|
|
isLast: isLast && index == node.faqs.length - 1,
|
|
);
|
|
}),
|
|
],
|
|
)
|
|
: const SizedBox.shrink(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// ---------------- SUB SECTION ----------------
|
|
Widget buildSubSection(
|
|
FaqNode node, {
|
|
bool isLast = false,
|
|
}) {
|
|
final bool isOpen = openSubSection == node.title;
|
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
|
|
|
return Column(
|
|
children: [
|
|
_buildExpandableHeader(
|
|
context: context,
|
|
title: node.title,
|
|
isOpen: isOpen,
|
|
onTap: () {
|
|
setState(() {
|
|
openSubSection = isOpen ? null : node.title;
|
|
openQuestionId = null;
|
|
});
|
|
},
|
|
titleStyle: _faqSubSectionTitleStyle(context),
|
|
horizontalPadding: 20,
|
|
backgroundColor: isOpen ? const Color(0xFFF6FAFF) : Colors.white,
|
|
isLast: isLast,
|
|
),
|
|
AnimatedSize(
|
|
duration: kExpandDuration,
|
|
curve: kExpandCurve,
|
|
child: isOpen
|
|
? Column(
|
|
children: [
|
|
for (int i = 0; i < node.faqs.length; i++)
|
|
buildQuestion(
|
|
node.faqs[i],
|
|
isLast: isLast && i == node.faqs.length - 1,
|
|
),
|
|
],
|
|
)
|
|
: const SizedBox.shrink(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
/// ---------------- QUESTION ----------------
|
|
Widget buildQuestion(
|
|
FaqItem faq, {
|
|
bool isFirst = false,
|
|
bool isLast = false,
|
|
}) {
|
|
final bool isOpen = openQuestionId == faq.id;
|
|
const Duration kExpandDuration = Duration(milliseconds: 450);
|
|
const Curve kExpandCurve = Curves.easeInOutCubic;
|
|
final borderRadius = _faqItemBorderRadius(
|
|
isFirst: isFirst,
|
|
isLast: isLast && !isOpen,
|
|
);
|
|
|
|
return Column(
|
|
children: [
|
|
Material(
|
|
color: Colors.white,
|
|
borderRadius: borderRadius,
|
|
clipBehavior: Clip.antiAlias,
|
|
child: InkWell(
|
|
onTap: () {
|
|
setState(() {
|
|
openQuestionId = isOpen ? null : faq.id;
|
|
});
|
|
},
|
|
borderRadius: borderRadius,
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
|
decoration: BoxDecoration(
|
|
border: isLast && !isOpen
|
|
? null
|
|
: const Border(
|
|
bottom: BorderSide(color: Color(0xFFE8E8E8)),
|
|
),
|
|
),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 2),
|
|
child: Icon(
|
|
Icons.help_outline,
|
|
size: 18,
|
|
color: isOpen
|
|
? const Color(0xFFE26728)
|
|
: const Color(0xFF999999),
|
|
),
|
|
),
|
|
const SizedBox(width: 10),
|
|
Expanded(
|
|
child: Text(
|
|
faq.question,
|
|
style: _faqQuestionStyle(context, isOpen: isOpen),
|
|
),
|
|
),
|
|
AnimatedRotation(
|
|
turns: isOpen ? 0.5 : 0,
|
|
duration: kExpandDuration,
|
|
curve: kExpandCurve,
|
|
child: const Icon(
|
|
Icons.keyboard_arrow_down,
|
|
size: 20,
|
|
color: Color(0xFFE26728),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
AnimatedSize(
|
|
duration: kExpandDuration,
|
|
curve: kExpandCurve,
|
|
child: isOpen
|
|
? Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.fromLTRB(16, 12, 16, 16),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFFAFAFA),
|
|
borderRadius: isLast
|
|
? const BorderRadius.vertical(
|
|
bottom: Radius.circular(11),
|
|
)
|
|
: null,
|
|
),
|
|
child: Html(
|
|
data: faq.answer ?? '',
|
|
style: {
|
|
"body": Style(
|
|
margin: Margins.zero,
|
|
padding: HtmlPaddings.zero,
|
|
fontSize: FontSize(
|
|
Responsive.isDesktop(context) ? 14 : 13,
|
|
),
|
|
fontFamily: GoogleFonts.poppins().fontFamily,
|
|
color: const Color(0xFF444444),
|
|
lineHeight: LineHeight(1.5),
|
|
),
|
|
"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;
|
|
}
|
|
|
|
}
|